]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 14 May 2008 17:08:24 +0000 (10:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 14 May 2008 17:08:24 +0000 (10:08 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (73 commits)
  net: Fix typo in net/core/sock.c.
  ppp: Do not free not yet unregistered net device.
  netfilter: xt_iprange: module aliases for xt_iprange
  netfilter: ctnetlink: dump conntrack ID in event messages
  irda: Fix a misalign access issue. (v2)
  sctp: Fix use of uninitialized pointer
  cipso: Relax too much careful cipso hash function.
  tcp FRTO: work-around inorder receivers
  tcp FRTO: Fix fallback to conventional recovery
  New maintainer for Intel ethernet adapters
  DM9000: Use delayed work to update MII PHY state
  DM9000: Update and fix driver debugging messages
  DM9000: Add __devinit and __devexit attributes to probe and remove
  sky2: fix simple define thinko
  [netdrvr] sfc: sfc: Add self-test support
  [netdrvr] sfc: Increment rx_reset when reported as driver event
  [netdrvr] sfc: Remove unused macro EFX_XAUI_RETRAIN_MAX
  [netdrvr] sfc: Fix code formatting
  [netdrvr] sfc: Remove kernel-doc comments for removed members of struct efx_nic
  [netdrvr] sfc: Remove garbage from comment
  ...

1039 files changed:
Documentation/DocBook/kgdb.tmpl
Documentation/cgroups.txt
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
Documentation/hwmon/adt7473
Documentation/hwmon/w83l785ts
Documentation/i2c/functionality
Documentation/i2c/smbus-protocol
Documentation/kbuild/kconfig-language.txt
Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/memory-barriers.txt
Documentation/powerpc/mpc52xx-device-tree-bindings.txt
Documentation/s390/CommonIO
Documentation/scheduler/sched-design.txt [deleted file]
Documentation/scsi/ChangeLog.megaraid_sas
Documentation/vm/slabinfo.c
MAINTAINERS
Makefile
arch/alpha/kernel/osf_sys.c
arch/arm/kernel/sys_arm.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ns9xxx/irq.c
arch/arm/mach-orion5x/addr-map.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-orion5x/common.h
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/cpu-pxa.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/spitz_pm.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-sa1100/pm.c
arch/arm/plat-s3c24xx/clock.c
arch/avr32/kernel/sys_avr32.c
arch/blackfin/Kconfig
arch/blackfin/kernel/asm-offsets.c
arch/blackfin/kernel/fixed_code.S
arch/blackfin/kernel/module.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/signal.c
arch/blackfin/kernel/sys_bfin.c
arch/blackfin/kernel/time-ts.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf537/boards/cm_bf537.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf548/boards/cm_bf548.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-common/Makefile
arch/blackfin/mach-common/cpufreq.c
arch/blackfin/mach-common/dpmc.c [new file with mode: 0644]
arch/blackfin/mach-common/dpmc_modes.S [moved from arch/blackfin/mach-common/dpmc.S with 82% similarity]
arch/blackfin/mach-common/entry.S
arch/cris/kernel/sys_cris.c
arch/frv/kernel/sys_frv.c
arch/frv/mm/Makefile
arch/h8300/kernel/sys_h8300.c
arch/ia64/ia32/ia32_signal.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/palinfo.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/smp.c
arch/ia64/kernel/time.c
arch/ia64/kernel/topology.c
arch/ia64/kvm/kvm-ia64.c
arch/m32r/Makefile
arch/m32r/defconfig [deleted file]
arch/m32r/kernel/sys_m32r.c
arch/m32r/kernel/vmlinux.lds.S
arch/m68k/kernel/sys_m68k.c
arch/m68k/kernel/traps.c
arch/m68k/mac/config.c
arch/m68knommu/Kconfig
arch/m68knommu/kernel/asm-offsets.c
arch/m68knommu/kernel/entry.S
arch/m68knommu/kernel/setup.c
arch/m68knommu/kernel/signal.c
arch/m68knommu/kernel/sys_m68k.c
arch/m68knommu/kernel/traps.c
arch/m68knommu/kernel/vmlinux.lds.S
arch/m68knommu/platform/5206e/config.c
arch/m68knommu/platform/5272/config.c
arch/m68knommu/platform/528x/config.c
arch/m68knommu/platform/5307/config.c
arch/m68knommu/platform/coldfire/entry.S
arch/mips/au1000/common/Makefile
arch/mips/au1000/common/au1xxx_irqmap.c
arch/mips/au1000/common/clocks.c
arch/mips/au1000/common/cputable.c
arch/mips/au1000/common/dbdma.c
arch/mips/au1000/common/dbg_io.c
arch/mips/au1000/common/dma.c
arch/mips/au1000/common/gpio.c
arch/mips/au1000/common/irq.c
arch/mips/au1000/common/pci.c
arch/mips/au1000/common/platform.c
arch/mips/au1000/common/power.c
arch/mips/au1000/common/prom.c
arch/mips/au1000/common/puts.c
arch/mips/au1000/common/reset.c
arch/mips/au1000/common/setup.c
arch/mips/au1000/common/time.c
arch/mips/au1000/db1x00/Makefile
arch/mips/au1000/db1x00/board_setup.c
arch/mips/au1000/db1x00/init.c
arch/mips/au1000/db1x00/irqmap.c
arch/mips/au1000/mtx-1/Makefile
arch/mips/au1000/mtx-1/board_setup.c
arch/mips/au1000/mtx-1/init.c
arch/mips/au1000/mtx-1/irqmap.c
arch/mips/au1000/mtx-1/platform.c
arch/mips/au1000/pb1000/Makefile
arch/mips/au1000/pb1000/board_setup.c
arch/mips/au1000/pb1000/init.c
arch/mips/au1000/pb1100/Makefile
arch/mips/au1000/pb1100/board_setup.c
arch/mips/au1000/pb1100/init.c
arch/mips/au1000/pb1100/irqmap.c
arch/mips/au1000/pb1200/Makefile
arch/mips/au1000/pb1200/board_setup.c
arch/mips/au1000/pb1200/init.c
arch/mips/au1000/pb1200/irqmap.c
arch/mips/au1000/pb1500/Makefile
arch/mips/au1000/pb1500/board_setup.c
arch/mips/au1000/pb1500/init.c
arch/mips/au1000/pb1500/irqmap.c
arch/mips/au1000/pb1550/Makefile
arch/mips/au1000/pb1550/board_setup.c
arch/mips/au1000/pb1550/init.c
arch/mips/au1000/pb1550/irqmap.c
arch/mips/au1000/xxs1500/Makefile
arch/mips/au1000/xxs1500/board_setup.c
arch/mips/au1000/xxs1500/init.c
arch/mips/au1000/xxs1500/irqmap.c
arch/mips/emma2rh/markeins/setup.c
arch/mips/kernel/Makefile
arch/mips/kernel/binfmt_elfn32.c
arch/mips/kernel/binfmt_elfo32.c
arch/mips/kernel/cpu-bugs64.c
arch/mips/kernel/irixelf.c
arch/mips/kernel/irixioctl.c
arch/mips/kernel/kspd.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/setup.c
arch/mips/kernel/smp.c
arch/mips/kernel/vpe.c
arch/mips/mm/highmem.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/pci/fixup-au1000.c
arch/mips/pci/ops-au1000.c
arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mn10300/Kconfig
arch/mn10300/boot/install.sh
arch/mn10300/kernel/sys_mn10300.c
arch/parisc/kernel/sys_parisc.c
arch/parisc/mm/init.c
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/boot/dts/sequoia.dts
arch/powerpc/configs/ps3_defconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/head_44x.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/isa-bridge.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/syscalls.c
arch/powerpc/kernel/time.c
arch/powerpc/kvm/booke_guest.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/devres.c [new file with mode: 0644]
arch/powerpc/mm/slb.c
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/cell/spu_priv1_mmio.c
arch/powerpc/platforms/cell/spufs/coredump.c
arch/powerpc/platforms/cell/spufs/fault.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/cell/spufs/run.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/spufs.h
arch/powerpc/platforms/cell/spufs/switch.c
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/pseries/scanlog.c
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/xilinx_intc.c
arch/powerpc/xmon/xmon.c
arch/ppc/Makefile
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/setup.c
arch/ppc/platforms/residual.c
arch/s390/Kconfig
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/ptrace.c
arch/s390/kernel/sys_s390.c
arch/s390/kvm/Kconfig
arch/s390/kvm/intercept.c
arch/s390/kvm/kvm-s390.c
arch/s390/mm/Makefile
arch/s390/mm/init.c
arch/s390/mm/page-states.c [new file with mode: 0644]
arch/sh/Kconfig
arch/sh/Kconfig.debug
arch/sh/Makefile
arch/sh/boards/mpc1211/Makefile [deleted file]
arch/sh/boards/mpc1211/pci.c [deleted file]
arch/sh/boards/mpc1211/rtc.c [deleted file]
arch/sh/boards/mpc1211/setup.c [deleted file]
arch/sh/boards/renesas/migor/setup.c
arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
arch/sh/boards/renesas/r7780rp/setup.c
arch/sh/boards/renesas/rts7751r2d/setup.c
arch/sh/boards/se/7206/setup.c
arch/sh/boards/se/7722/setup.c
arch/sh/boot/compressed/Makefile_32
arch/sh/boot/compressed/Makefile_64
arch/sh/kernel/cpu/irq/intc-sh5.c
arch/sh/kernel/cpu/irq/intc.c
arch/sh/kernel/cpu/sh2a/fpu.c
arch/sh/kernel/cpu/sh3/Makefile
arch/sh/kernel/cpu/sh3/setup-sh3.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh5/entry.S
arch/sh/kernel/cpu/sh5/probe.c
arch/sh/kernel/early_printk.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/sh_ksyms_64.c
arch/sh/kernel/sys_sh64.c
arch/sh/kernel/time_64.c
arch/sh/lib64/dbg.c
arch/sh/mm/Makefile_64
arch/sh/mm/cache-sh5.c
arch/sh/mm/ioremap_64.c
arch/sh/mm/numa.c
arch/sh/tools/mach-types
arch/sparc/kernel/entry.S
arch/sparc/kernel/process.c
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/rtrap.S
arch/sparc/kernel/setup.c
arch/sparc/kernel/signal.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/mm/fault.c
arch/sparc/prom/init.c
arch/sparc/prom/memory.c
arch/sparc64/kernel/etrap.S
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_impl.h
arch/sparc64/kernel/process.c
arch/sparc64/kernel/ptrace.c
arch/sparc64/kernel/rtrap.S
arch/sparc64/kernel/signal.c
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/sparc64/mm/init.c
arch/um/Kconfig.char
arch/um/drivers/chan_user.c
arch/um/drivers/cow_sys.h
arch/um/drivers/daemon_user.c
arch/um/drivers/fd.c
arch/um/drivers/hostaudio_kern.c
arch/um/drivers/line.c
arch/um/drivers/mcast_user.c
arch/um/drivers/net_user.c
arch/um/drivers/port_user.c
arch/um/drivers/pty.c
arch/um/drivers/random.c
arch/um/drivers/slip_user.c
arch/um/drivers/tty.c
arch/um/drivers/ubd_kern.c
arch/um/drivers/xterm.c
arch/um/include/as-layout.h
arch/um/include/line.h
arch/um/include/os.h
arch/um/include/process.h
arch/um/include/skas_ptrace.h
arch/um/include/sysdep-i386/ptrace_user.h
arch/um/include/sysdep-i386/sigcontext.h
arch/um/include/sysdep-x86_64/ptrace_user.h
arch/um/include/um_malloc.h
arch/um/kernel/dyn.lds.S
arch/um/kernel/mem.c
arch/um/kernel/syscall.c
arch/um/kernel/time.c
arch/um/kernel/um_arch.c
arch/um/kernel/uml.lds.S
arch/um/os-Linux/drivers/ethertap_user.c
arch/um/os-Linux/helper.c
arch/um/os-Linux/main.c
arch/um/os-Linux/sigio.c
arch/um/os-Linux/signal.c
arch/um/os-Linux/skas/process.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/sys-i386/registers.c
arch/um/os-Linux/time.c
arch/um/sys-i386/ptrace.c
arch/um/sys-i386/user-offsets.c
arch/um/sys-x86_64/user-offsets.c
arch/v850/kernel/syscalls.c
arch/x86/Kconfig
arch/x86/boot/compressed/relocs.c
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/Makefile
arch/x86/kernel/acpi/realmode/Makefile
arch/x86/kernel/acpi/realmode/wakeup.lds.S
arch/x86/kernel/cpu/addon_cpuid_features.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/geode_32.c
arch/x86/kernel/i387.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
arch/x86/kernel/smp.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/sys_i386_32.c
arch/x86/kernel/sys_x86_64.c
arch/x86/kernel/x8664_ksyms_64.c
arch/x86/kvm/i8254.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/mmu.h
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/vmx.h
arch/x86/kvm/x86.c
arch/x86/kvm/x86_emulate.c
arch/x86/lib/csum-partial_64.c
arch/x86/mm/discontig_32.c
arch/x86/mm/init_32.c
arch/x86/mm/pat.c
arch/x86/mm/pgtable_32.c
arch/x86/pci/Makefile_32
arch/x86/pci/acpi.c
arch/x86/pci/common.c
arch/x86/pci/fixup.c
arch/x86/pci/i386.c
arch/x86/pci/init.c
arch/x86/pci/k8-bus_64.c
arch/x86/pci/pci.h
arch/x86/vdso/vdso32-setup.c
arch/x86/video/fbdev.c
block/blk-barrier.c
block/blk-core.c
block/blk-ioc.c
block/blk-merge.c
block/blk-settings.c
block/blk-sysfs.c
block/blk-tag.c
block/blktrace.c
block/bsg.c
block/cfq-iosched.c
block/compat_ioctl.c
block/elevator.c
block/scsi_ioctl.c
crypto/authenc.c
crypto/cryptd.c
crypto/eseqiv.c
crypto/hmac.c
drivers/accessibility/Kconfig
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-sff.c
drivers/ata/pata_acpi.c
drivers/ata/pata_sch.c [new file with mode: 0644]
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/base/cpu.c
drivers/base/sys.c
drivers/block/aoe/aoecmd.c
drivers/block/cciss.c
drivers/block/ub.c
drivers/block/virtio_blk.c
drivers/char/i8k.c
drivers/char/mmtimer.c
drivers/char/serial167.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/tty_audit.c
drivers/char/tty_io.c
drivers/char/vt.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/edac/edac_core.h
drivers/edac/edac_device.c
drivers/edac/edac_mc.c
drivers/edac/edac_pci.c
drivers/firewire/fw-sbp2.c
drivers/gpio/pca953x.c
drivers/hwmon/adt7473.c
drivers/hwmon/asb100.c
drivers/hwmon/lm75.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/w83793.c
drivers/hwmon/w83l785ts.c
drivers/i2c/busses/i2c-au1550.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-sibyte.c
drivers/i2c/i2c-core.c
drivers/ide/ide-probe.c
drivers/ide/legacy/falconide.c
drivers/ieee1394/nodemgr.c
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/infiniband/hw/cxgb3/cxio_hal.h
drivers/infiniband/hw/cxgb3/cxio_resource.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_mem.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb3/iwch_provider.h
drivers/infiniband/hw/cxgb3/iwch_qp.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_iba7220.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_ruc.c
drivers/infiniband/hw/ipath/ipath_sdma.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_verbs.c
drivers/input/misc/Kconfig
drivers/input/serio/hp_sdc.c
drivers/input/serio/i8042-io.h
drivers/isdn/hysdn/hysdn_procconf.c
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/macintosh/adb.c
drivers/macintosh/therm_pm72.c
drivers/macintosh/windfarm_smu_sat.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/Makefile
drivers/media/video/cx18/cx18-driver.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/tcm825x.c
drivers/media/video/tlv320aic23b.c
drivers/media/video/tvaudio.c
drivers/misc/kgdbts.c
drivers/misc/sgi-xp/xp.h
drivers/misc/sgi-xp/xp_main.c
drivers/misc/sgi-xp/xpc.h
drivers/misc/sgi-xp/xpc_channel.c
drivers/misc/sgi-xp/xpc_main.c
drivers/misc/sgi-xp/xpc_partition.c
drivers/misc/sgi-xp/xpnet.c
drivers/mmc/host/mmci.c
drivers/mmc/host/sdhci.h
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/devices/mtdram.c
drivers/mtd/devices/phram.c
drivers/mtd/devices/pmc551.c
drivers/mtd/devices/slram.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/mpc1211.c [deleted file]
drivers/mtd/maps/uclinux.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/at91_nand.c
drivers/net/fec.c
drivers/net/fec.h
drivers/net/fec_mpc52xx.c
drivers/net/fec_mpc52xx.h
drivers/net/mlx4/mr.c
drivers/net/usb/asix.c
drivers/net/virtio_net.c
drivers/net/wireless/strip.c
drivers/pci/intel-iommu.c
drivers/pci/pci-acpi.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pcmcia/au1000_db1x00.c
drivers/pcmcia/au1000_generic.c
drivers/pcmcia/au1000_pb1x00.c
drivers/pcmcia/au1000_xxs1500.c
drivers/pcmcia/cardbus.c
drivers/pcmcia/ds.c
drivers/pcmcia/i82092.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/pxa2xx_lubbock.c
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_badge4.c
drivers/pcmcia/sa1100_cerf.c
drivers/pcmcia/sa1100_jornada720.c
drivers/pcmcia/sa1100_neponset.c
drivers/pcmcia/sa1100_shannon.c
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/soc_common.h
drivers/pnp/interface.c
drivers/pnp/pnpbios/rsparser.c
drivers/power/pda_power.c
drivers/power/pmu_battery.c
drivers/ps3/ps3-lpm.c
drivers/ps3/ps3-sys-manager.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-lib.c
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-s35390a.c
drivers/rtc/rtc-sh.c
drivers/s390/char/tty3270.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/cio.c
drivers/s390/cio/cio.h
drivers/s390/cio/cio_debug.h
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_id.c
drivers/s390/cio/device_pgid.c
drivers/s390/s390mach.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_fsf.c
drivers/sbus/char/bpp.c
drivers/scsi/53c700.c
drivers/scsi/Kconfig
drivers/scsi/a100u2w.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/comminit.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/linit.c
drivers/scsi/aha152x.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/constants.c
drivers/scsi/dpt/dpti_ioctl.h
drivers/scsi/dpt/dptsig.h
drivers/scsi/dpt/sys_info.h
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/gdth.c
drivers/scsi/hptiop.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/viosrp.h
drivers/scsi/initio.c
drivers/scsi/ipr.c
drivers/scsi/libiscsi.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mbox.h
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/mvsas.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/qla1280.c
drivers/scsi/scsi.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_tgt_lib.c
drivers/scsi/u14-34f.c
drivers/serial/8250.c
drivers/serial/8250_early.c
drivers/serial/8250_pci.c
drivers/serial/bfin_5xx.c
drivers/serial/crisv10.c
drivers/serial/jsm/jsm.h
drivers/serial/jsm/jsm_driver.c
drivers/serial/mpc52xx_uart.c
drivers/serial/serial_core.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/spi/Kconfig
drivers/spi/pxa2xx_spi.c
drivers/spi/spi_bfin5xx.c
drivers/spi/spi_mpc83xx.c
drivers/spi/spi_s3c24xx.c
drivers/usb/Makefile
drivers/usb/atm/Kconfig
drivers/usb/c67x00/Makefile [new file with mode: 0644]
drivers/usb/c67x00/c67x00-drv.c [new file with mode: 0644]
drivers/usb/c67x00/c67x00-hcd.c [new file with mode: 0644]
drivers/usb/c67x00/c67x00-hcd.h [new file with mode: 0644]
drivers/usb/c67x00/c67x00-ll-hpi.c [new file with mode: 0644]
drivers/usb/c67x00/c67x00-sched.c [new file with mode: 0644]
drivers/usb/c67x00/c67x00.h [new file with mode: 0644]
drivers/usb/core/message.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/ether.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/pxa27x_udc.c [new file with mode: 0644]
drivers/usb/gadget/pxa27x_udc.h [new file with mode: 0644]
drivers/usb/gadget/serial.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/isp1760-hcd.c [new file with mode: 0644]
drivers/usb/host/isp1760-hcd.h [new file with mode: 0644]
drivers/usb/host/isp1760-if.c [new file with mode: 0644]
drivers/usb/host/ohci-hub.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.h
drivers/usb/misc/ldusb.c
drivers/usb/misc/usbtest.c
drivers/usb/serial/aircable.c
drivers/usb/serial/airprime.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ch341.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/mos7840.c
drivers/usb/storage/Kconfig
drivers/usb/storage/cypress_atacb.c
drivers/usb/storage/isd200.c
drivers/usb/storage/libusual.c
drivers/usb/storage/onetouch.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/video/Kconfig
drivers/video/atmel_lcdfb.c
drivers/video/bw2.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/console/fbcon.c
drivers/video/ffb.c
drivers/video/leo.c
drivers/video/p9100.c
drivers/video/pnx4008/pnxrgbfb.c
drivers/video/pxafb.c
drivers/video/sbuslib.c
drivers/video/sbuslib.h
drivers/video/sunxvr2500.c
drivers/video/sunxvr500.c
drivers/video/tcx.c
drivers/video/tridentfb.c
drivers/virtio/virtio.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_pci.c
drivers/virtio/virtio_ring.c
fs/affs/affs.h
fs/affs/file.c
fs/affs/inode.c
fs/affs/namei.c
fs/affs/super.c
fs/anon_inodes.c
fs/autofs4/expire.c
fs/autofs4/root.c
fs/autofs4/waitq.c
fs/bio.c
fs/cifs/CHANGES
fs/cifs/asn1.c
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsacl.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/dns_resolve.c
fs/cifs/fcntl.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/smbencrypt.c
fs/cifs/xattr.c
fs/compat.c
fs/dnotify.c
fs/dquot.c
fs/ecryptfs/inode.c
fs/ecryptfs/miscdev.c
fs/eventfd.c
fs/eventpoll.c
fs/exec.c
fs/ext4/mballoc.c
fs/fcntl.c
fs/file.c
fs/file_table.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/hfsplus/inode.c
fs/hppfs/Makefile
fs/hppfs/hppfs.c [moved from fs/hppfs/hppfs_kern.c with 92% similarity]
fs/inode.c
fs/jbd2/journal.c
fs/jffs2/build.c
fs/jffs2/dir.c
fs/jffs2/erase.c
fs/jffs2/fs.c
fs/jffs2/gc.c
fs/jffs2/nodelist.h
fs/jffs2/nodemgmt.c
fs/jffs2/os-linux.h
fs/jffs2/readinode.c
fs/jffs2/scan.c
fs/jffs2/super.c
fs/jffs2/wbuf.c
fs/jffs2/write.c
fs/jffs2/xattr.c
fs/locks.c
fs/ocfs2/cluster/sys.c
fs/ocfs2/dlm/dlmdebug.c
fs/ocfs2/file.c
fs/ocfs2/localalloc.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/stack_user.c
fs/ocfs2/symlink.c
fs/open.c
fs/pipe.c
fs/proc/array.c
fs/proc/base.c
fs/proc/task_mmu.c
fs/proc/task_nommu.c
fs/select.c
fs/signalfd.c
fs/splice.c
fs/timerfd.c
fs/udf/namei.c
fs/udf/partition.c
fs/udf/super.c
fs/udf/udfdecl.h
fs/ufs/ufs.h
fs/utimes.c
include/asm-alpha/barrier.h
include/asm-alpha/pgtable.h
include/asm-alpha/types.h
include/asm-arm/arch-pxa/pm.h
include/asm-arm/arch-pxa/system.h
include/asm-arm/div64.h
include/asm-arm/types.h
include/asm-avr32/types.h
include/asm-blackfin/dpmc.h
include/asm-blackfin/entry.h
include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
include/asm-blackfin/mach-bf533/defBF532.h
include/asm-blackfin/mach-bf533/irq.h
include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
include/asm-blackfin/mach-bf537/irq.h
include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
include/asm-blackfin/mach-bf548/defBF54x_base.h
include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
include/asm-blackfin/mach-bf561/defBF561.h
include/asm-blackfin/mach-bf561/irq.h
include/asm-blackfin/mach-common/context.S
include/asm-blackfin/time.h
include/asm-blackfin/types.h
include/asm-cris/types.h
include/asm-frv/system.h
include/asm-frv/types.h
include/asm-frv/unaligned.h
include/asm-generic/Kbuild
include/asm-generic/div64.h
include/asm-generic/int-l64.h [new file with mode: 0644]
include/asm-generic/int-ll64.h [new file with mode: 0644]
include/asm-h8300/types.h
include/asm-ia64/cpu.h
include/asm-ia64/dmi.h
include/asm-ia64/io.h
include/asm-ia64/thread_info.h
include/asm-ia64/types.h
include/asm-m32r/types.h
include/asm-m68k/div64.h
include/asm-m68k/machw.h
include/asm-m68k/types.h
include/asm-m68knommu/dma.h
include/asm-m68knommu/param.h
include/asm-mips/bitops.h
include/asm-mips/compiler.h
include/asm-mips/div64.h
include/asm-mips/mach-au1x00/au1000.h
include/asm-mips/mach-au1x00/au1000_dma.h
include/asm-mips/mach-au1x00/au1000_gpio.h
include/asm-mips/mach-au1x00/au1550_spi.h
include/asm-mips/mach-au1x00/au1xxx.h
include/asm-mips/mach-au1x00/au1xxx_dbdma.h
include/asm-mips/mach-au1x00/au1xxx_ide.h
include/asm-mips/mach-au1x00/au1xxx_psc.h
include/asm-mips/mach-db1x00/db1200.h
include/asm-mips/mach-db1x00/db1x00.h
include/asm-mips/mach-pb1x00/pb1000.h
include/asm-mips/mach-pb1x00/pb1100.h
include/asm-mips/mach-pb1x00/pb1200.h
include/asm-mips/mach-pb1x00/pb1500.h
include/asm-mips/mach-pb1x00/pb1550.h
include/asm-mips/rtlx.h
include/asm-mips/types.h
include/asm-mn10300/div64.h
include/asm-mn10300/processor.h
include/asm-mn10300/types.h
include/asm-parisc/types.h
include/asm-powerpc/io.h
include/asm-powerpc/kvm_host.h
include/asm-powerpc/kvm_ppc.h
include/asm-powerpc/pgtable-ppc32.h
include/asm-powerpc/ps3.h
include/asm-powerpc/spu.h
include/asm-powerpc/spu_csa.h
include/asm-powerpc/syscalls.h
include/asm-powerpc/types.h
include/asm-ppc/system.h
include/asm-s390/kvm_host.h
include/asm-s390/page.h
include/asm-s390/ptrace.h
include/asm-s390/system.h
include/asm-s390/types.h
include/asm-sh/cpu-sh3/dma.h
include/asm-sh/hw_irq.h
include/asm-sh/io.h
include/asm-sh/keyboard.h [deleted file]
include/asm-sh/mmu_context.h
include/asm-sh/mmzone.h
include/asm-sh/mpc1211/dma.h [deleted file]
include/asm-sh/mpc1211/io.h [deleted file]
include/asm-sh/mpc1211/keyboard.h [deleted file]
include/asm-sh/mpc1211/m1543c.h [deleted file]
include/asm-sh/mpc1211/mc146818rtc.h [deleted file]
include/asm-sh/mpc1211/mpc1211.h [deleted file]
include/asm-sh/mpc1211/pci.h [deleted file]
include/asm-sh/r7780rp.h
include/asm-sh/tlb_64.h
include/asm-sh/topology.h
include/asm-sh/types.h
include/asm-sh/uaccess_64.h
include/asm-sparc/oplib.h
include/asm-sparc/page.h
include/asm-sparc/psr.h
include/asm-sparc/ptrace.h
include/asm-sparc/signal.h
include/asm-sparc/types.h
include/asm-sparc64/psrcompat.h
include/asm-sparc64/pstate.h
include/asm-sparc64/ptrace.h
include/asm-sparc64/signal.h
include/asm-sparc64/ttable.h
include/asm-sparc64/types.h
include/asm-um/div64.h
include/asm-um/irq.h
include/asm-um/keyboard.h [deleted file]
include/asm-um/page.h
include/asm-v850/types.h
include/asm-x86/bitops.h
include/asm-x86/bootparam.h
include/asm-x86/div64.h
include/asm-x86/dmi.h
include/asm-x86/geode.h
include/asm-x86/i387.h
include/asm-x86/io_32.h
include/asm-x86/kvm_host.h
include/asm-x86/pat.h
include/asm-x86/pgtable_32.h
include/asm-x86/pgtable_64.h
include/asm-x86/spinlock.h
include/asm-x86/topology.h
include/asm-x86/types.h
include/asm-xtensa/types.h
include/crypto/scatterwalk.h
include/linux/Kbuild
include/linux/anon_inodes.h
include/linux/bitmap.h
include/linux/calc64.h [deleted file]
include/linux/clocksource.h
include/linux/compat.h
include/linux/compiler.h
include/linux/cpumask.h
include/linux/device.h
include/linux/exportfs.h
include/linux/fdtable.h [new file with mode: 0644]
include/linux/file.h
include/linux/fs.h
include/linux/fuse.h
include/linux/genhd.h
include/linux/hardirq.h
include/linux/hrtimer.h
include/linux/i2c.h
include/linux/init_task.h
include/linux/io.h
include/linux/ioprio.h
include/linux/irq.h
include/linux/jiffies.h
include/linux/kgdb.h
include/linux/libata.h
include/linux/math64.h [new file with mode: 0644]
include/linux/mm_types.h
include/linux/module.h
include/linux/mtd/jedec.h [deleted file]
include/linux/mtd/mtd.h
include/linux/mtd/pmc551.h
include/linux/of_i2c.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pda_power.h
include/linux/poll.h
include/linux/quota.h
include/linux/rcupdate.h
include/linux/rio.h
include/linux/sched.h
include/linux/string.h
include/linux/timex.h
include/linux/usb/c67x00.h [new file with mode: 0644]
include/linux/usb/ch9.h
include/linux/usb/gadget.h
include/linux/vermagic.h
include/linux/virtio.h
include/linux/virtio_blk.h
include/linux/virtio_config.h
include/linux/virtio_net.h
include/media/v4l2-i2c-drv-legacy.h
include/media/v4l2-i2c-drv.h
include/scsi/scsi.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_eh.h
include/scsi/scsi_host.h
include/sound/soc.h
init/Kconfig
init/main.c
ipc/mqueue.c
kernel/Makefile
kernel/compat.c
kernel/cpuset.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/hrtimer.c
kernel/irq/manage.c
kernel/irq/spurious.c
kernel/kexec.c
kernel/kgdb.c
kernel/kmod.c
kernel/module.c
kernel/posix-cpu-timers.c
kernel/ptrace.c
kernel/relay.c
kernel/sched.c
kernel/sched_clock.c [new file with mode: 0644]
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/softirq.c
kernel/time.c
kernel/time/clocksource.c
kernel/time/ntp.c
kernel/time/timekeeping.c
kernel/timeconst.pl
kernel/workqueue.c
lib/Kconfig.kgdb
lib/bitmap.c
lib/devres.c
lib/div64.c
lib/idr.c
lib/kernel_lock.c
lib/string.c
mm/filemap.c
mm/memcontrol.c
mm/memory.c
mm/pdflush.c
mm/slub.c
mm/vmalloc.c
mm/vmstat.c
net/can/bcm.c
net/ipv4/tcp_cubic.c
net/netfilter/xt_connbytes.c
net/sunrpc/svc.c
scripts/kconfig/lkc.h
scripts/kconfig/lxdialog/check-lxdialog.sh
scripts/kconfig/mconf.c
scripts/mod/file2alias.c
security/selinux/hooks.c
sound/drivers/Kconfig
sound/drivers/pcsp/pcsp.c
sound/oss/kahlua.c
sound/pci/Kconfig
sound/pci/ac97/ac97_patch.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/at91/at91-pcm.c
sound/soc/at91/at91-ssc.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/fsl/fsl_ssi.c
sound/soc/omap/n810.c
sound/soc/s3c24xx/s3c24xx-i2s.c
sound/soc/s3c24xx/s3c24xx-pcm.c
sound/synth/emux/emux_synth.c
virt/kvm/kvm_main.c

index 97618bed4d657538201b4073e159147b3cfbf115..028a8444d95e252a4c0830b70eb6b71311509660 100644 (file)
@@ -72,7 +72,7 @@
     kgdb is a source level debugger for linux kernel. It is used along
     with gdb to debug a linux kernel.  The expectation is that gdb can
     be used to "break in" to the kernel to inspect memory, variables
-    and look through a cal stack information similar to what an
+    and look through call stack information similar to what an
     application developer would use gdb for.  It is possible to place
     breakpoints in kernel code and perform some limited execution
     stepping.
   <chapter id="CompilingAKernel">
     <title>Compiling a kernel</title>
     <para>
-    To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
-    and then select "KGDB: kernel debugging with remote gdb".
+    To enable <symbol>CONFIG_KGDB</symbol> you should first turn on
+    "Prompt for development and/or incomplete code/drivers"
+    (CONFIG_EXPERIMENTAL) in  "General setup", then under the
+    "Kernel debugging" select "KGDB: kernel debugging with remote gdb".
     </para>
     <para>
     Next you should choose one of more I/O drivers to interconnect debugging
index c298a6690e0d67700b08b933a65a3eb4fd97cd96..824fc02744719ecb02b29177c11c55034229af35 100644 (file)
@@ -310,8 +310,8 @@ and then start a subshell 'sh' in that cgroup:
   cd /dev/cgroup
   mkdir Charlie
   cd Charlie
-  /bin/echo 2-3 > cpus
-  /bin/echo 1 > mems
+  /bin/echo 2-3 > cpuset.cpus
+  /bin/echo 1 > cpuset.mems
   /bin/echo $$ > tasks
   sh
   # The subshell 'sh' is now running in cgroup Charlie
index c2992bc54f2f49f0f7caee130acf19205df7511a..8b22d7d8b99166b6db2e037644e9c5d7ff03695e 100644 (file)
@@ -92,7 +92,6 @@ prototypes:
        void (*destroy_inode)(struct inode *);
        void (*dirty_inode) (struct inode *);
        int (*write_inode) (struct inode *, int);
-       void (*put_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
        void (*put_super) (struct super_block *);
@@ -115,7 +114,6 @@ alloc_inode:                no      no      no
 destroy_inode:         no
 dirty_inode:           no                              (must not sleep)
 write_inode:           no
-put_inode:             no
 drop_inode:            no                              !!!inode_lock!!!
 delete_inode:          no
 put_super:             yes     yes     no
index 81e5be6e6e356e8ab3feb4e92b972fd0862db1a9..b7522c6cbae3758f77cb12e22b78825e43a3796d 100644 (file)
@@ -205,7 +205,6 @@ struct super_operations {
 
         void (*dirty_inode) (struct inode *);
         int (*write_inode) (struct inode *, int);
-        void (*put_inode) (struct inode *);
         void (*drop_inode) (struct inode *);
         void (*delete_inode) (struct inode *);
         void (*put_super) (struct super_block *);
@@ -246,9 +245,6 @@ or bottom half).
        inode to disc.  The second parameter indicates whether the write
        should be synchronous or not, not all filesystems check this flag.
 
-  put_inode: called when the VFS inode is removed from the inode
-       cache.
-
   drop_inode: called when the last access to the inode is dropped,
        with the inode_lock spinlock held.
 
index 22d8b19046abcac7a7222daa9a916c895f975f71..2126de34c71161a3e6f22ddbfe082725b01cfc24 100644 (file)
@@ -69,7 +69,8 @@ point2: Set the pwm speed at a higher temperature bound.
 
 The ADT7473 will scale the pwm between the lower and higher pwm speed when
 the temperature is between the two temperature boundaries.  PWM values range
-from 0 (off) to 255 (full speed).
+from 0 (off) to 255 (full speed).  Fan speed will be set to maximum when the
+temperature sensor associated with the PWM control exceeds temp#_max.
 
 Notes
 -----
index 1841cedc25b27d02d96d7dfac7b0763da909c8a9..bd1fa9d4468d9ba238c05c62cd562807c122e1ad 100644 (file)
@@ -33,7 +33,8 @@ Known Issues
 ------------
 
 On some systems (Asus), the BIOS is known to interfere with the driver
-and cause read errors. The driver will retry a given number of times
+and cause read errors. Or maybe the W83L785TS-S chip is simply unreliable,
+we don't really know. The driver will retry a given number of times
 (5 by default) and then give up, returning the old value (or 0 if
 there is no old value). It seems to work well enough so that you should
 not notice anything. Thanks to James Bolt for helping test this feature.
index 60cca249e452d759fcfa9dde1e04c0c431480773..42c17c1fb3cdf74e25a12e11d4416dd41e5f1f9a 100644 (file)
@@ -51,26 +51,38 @@ A few combinations of the above flags are also defined for your convenience:
                                   the transparent emulation layer)
 
 
-ALGORITHM/ADAPTER IMPLEMENTATION
---------------------------------
+ADAPTER IMPLEMENTATION
+----------------------
 
-When you write a new algorithm driver, you will have to implement a
-function callback `functionality', that gets an i2c_adapter structure
-pointer as its only parameter:
+When you write a new adapter driver, you will have to implement a
+function callback `functionality'. Typical implementations are given
+below.
 
-  struct i2c_algorithm {
-       /* Many other things of course; check <linux/i2c.h>! */
-       u32 (*functionality) (struct i2c_adapter *);
+A typical SMBus-only adapter would list all the SMBus transactions it
+supports. This example comes from the i2c-piix4 driver:
+
+  static u32 piix4_func(struct i2c_adapter *adapter)
+  {
+       return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+              I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+              I2C_FUNC_SMBUS_BLOCK_DATA;
   }
 
-A typically implementation is given below, from i2c-algo-bit.c:
+A typical full-I2C adapter would use the following (from the i2c-pxa
+driver):
 
-  static u32 bit_func(struct i2c_adapter *adap)
+  static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
   {
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-              I2C_FUNC_PROTOCOL_MANGLING;
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
   }
 
+I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
+addition of I2C block transactions) which i2c-core can emulate using
+I2C_FUNC_I2C without any help from the adapter driver. The idea is
+to let the client drivers check for the support of SMBus functions
+without having to care whether the said functions are implemented in
+hardware by the adapter, or emulated in software by i2c-core on top
+of an I2C adapter.
 
 
 CLIENT CHECKING
@@ -78,36 +90,33 @@ CLIENT CHECKING
 
 Before a client tries to attach to an adapter, or even do tests to check
 whether one of the devices it supports is present on an adapter, it should
-check whether the needed functionality is present. There are two functions
-defined which should be used instead of calling the functionality hook
-in the algorithm structure directly:
-
-  /* Return the functionality mask */
-  extern u32 i2c_get_functionality (struct i2c_adapter *adap);
-
-  /* Return 1 if adapter supports everything we need, 0 if not. */
-  extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
+check whether the needed functionality is present. The typical way to do
+this is (from the lm75 driver):
 
-This is a typical way to use these functions (from the writing-clients
-document):
-  int foo_detect_client(struct i2c_adapter *adapter, int address, 
-                          unsigned short flags, int kind)
+  static int lm75_detect(...)
   {
-       /* Define needed variables */
-
-       /* As the very first action, we check whether the adapter has the
-          needed functionality: we need the SMBus read_word_data,
-           write_word_data and write_byte functions in this example. */
-       if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
-                                            I2C_FUNC_SMBUS_WRITE_BYTE))
-               goto ERROR0;
-
-       /* Now we can do the real detection */
-
-       ERROR0:
-               /* Return an error */
+       (...)
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+                                    I2C_FUNC_SMBUS_WORD_DATA))
+               goto exit;
+       (...)
   }
 
+Here, the lm75 driver checks if the adapter can do both SMBus byte data
+and SMBus word data transactions. If not, then the driver won't work on
+this adapter and there's no point in going on. If the check above is
+successful, then the driver knows that it can call the following
+functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
+i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
+thumb, the functionality constants you test for with
+i2c_check_functionality() should match exactly the i2c_smbus_* functions
+which you driver is calling.
+
+Note that the check above doesn't tell whether the functionalities are
+implemented in hardware by the underlying adapter or emulated in
+software by i2c-core. Client drivers don't have to care about this, as
+i2c-core will transparently implement SMBus transactions on top of I2C
+adapters.
 
 
 CHECKING THROUGH /DEV
@@ -116,19 +125,19 @@ CHECKING THROUGH /DEV
 If you try to access an adapter from a userspace program, you will have
 to use the /dev interface. You will still have to check whether the
 functionality you need is supported, of course. This is done using
-the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect
-program, is below:
+the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
+below:
 
   int file;
-  if (file = open("/dev/i2c-0",O_RDWR) < 0) {
+  if (file = open("/dev/i2c-0", O_RDWR) < 0) {
        /* Some kind of error handling */
        exit(1);
   }
-  if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
+  if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
        /* Some kind of error handling */
        exit(1);
   }
-  if (! (funcs & I2C_FUNC_SMBUS_QUICK)) {
+  if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {
        /* Oops, the needed functionality (SMBus write_quick function) is
            not available! */
        exit(1);
index 8a653c60d25a22d1bde489b947e58b0847d6e324..03f08fb491ccca6edcbcc6ce6fd1e0dda6eae2ad 100644 (file)
@@ -1,5 +1,6 @@
 SMBus Protocol Summary
 ======================
+
 The following is a summary of the SMBus protocol. It applies to
 all revisions of the protocol (1.0, 1.1, and 2.0).
 Certain protocol features which are not supported by
@@ -8,6 +9,7 @@ this package are briefly described at the end of this document.
 Some adapters understand only the SMBus (System Management Bus) protocol,
 which is a subset from the I2C protocol. Fortunately, many devices use
 only the same subset, which makes it possible to put them on an SMBus.
+
 If you write a driver for some I2C device, please try to use the SMBus
 commands if at all possible (if the device uses only that subset of the
 I2C protocol). This makes it possible to use the device driver on both
@@ -15,7 +17,12 @@ SMBus adapters and I2C adapters (the SMBus command set is automatically
 translated to I2C on I2C adapters, but plain I2C commands can not be
 handled at all on most pure SMBus adapters).
 
-Below is a list of SMBus commands.
+Below is a list of SMBus protocol operations, and the functions executing
+them.  Note that the names used in the SMBus protocol specifications usually
+don't match these function names.  For some of the operations which pass a
+single data byte, the functions using SMBus protocol operation names execute
+a different protocol operation entirely.
+
 
 Key to symbols
 ==============
@@ -35,17 +42,16 @@ Count (8 bits): A data byte containing the length of a block operation.
 [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
 
 
-SMBus Write Quick
-=================
+SMBus Quick Command:  i2c_smbus_write_quick()
+=============================================
 
 This sends a single bit to the device, at the place of the Rd/Wr bit.
-There is no equivalent Read Quick command.
 
 A Addr Rd/Wr [A] P
 
 
-SMBus Read Byte
-===============
+SMBus Receive Byte:  i2c_smbus_read_byte()
+==========================================
 
 This reads a single byte from a device, without specifying a device
 register. Some devices are so simple that this interface is enough; for
@@ -55,17 +61,17 @@ the previous SMBus command.
 S Addr Rd [A] [Data] NA P
 
 
-SMBus Write Byte
-================
+SMBus Send Byte:  i2c_smbus_write_byte()
+========================================
 
-This is the reverse of Read Byte: it sends a single byte to a device.
-See Read Byte for more information.
+This operation is the reverse of Receive Byte: it sends a single byte
+to a device.  See Receive Byte for more information.
 
 S Addr Wr [A] Data [A] P
 
 
-SMBus Read Byte Data
-====================
+SMBus Read Byte:  i2c_smbus_read_byte_data()
+============================================
 
 This reads a single byte from a device, from a designated register.
 The register is specified through the Comm byte.
@@ -73,30 +79,30 @@ The register is specified through the Comm byte.
 S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
 
 
-SMBus Read Word Data
-====================
+SMBus Read Word:  i2c_smbus_read_word_data()
+============================================
 
-This command is very like Read Byte Data; again, data is read from a
+This operation is very like Read Byte; again, data is read from a
 device, from a designated register that is specified through the Comm
 byte. But this time, the data is a complete word (16 bits).
 
 S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 
-SMBus Write Byte Data
-=====================
+SMBus Write Byte:  i2c_smbus_write_byte_data()
+==============================================
 
 This writes a single byte to a device, to a designated register. The
 register is specified through the Comm byte. This is the opposite of
-the Read Byte Data command.
+the Read Byte operation.
 
 S Addr Wr [A] Comm [A] Data [A] P
 
 
-SMBus Write Word Data
-=====================
+SMBus Write Word:  i2c_smbus_write_word_data()
+==============================================
 
-This is the opposite operation of the Read Word Data command. 16 bits
+This is the opposite of the Read Word operation. 16 bits
 of data is written to a device, to the designated register that is
 specified through the Comm byte. 
 
@@ -113,8 +119,8 @@ S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
                              S Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 
-SMBus Block Read
-================
+SMBus Block Read:  i2c_smbus_read_block_data()
+==============================================
 
 This command reads a block of up to 32 bytes from a device, from a 
 designated register that is specified through the Comm byte. The amount
@@ -124,8 +130,8 @@ S Addr Wr [A] Comm [A]
            S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
 
 
-SMBus Block Write
-=================
+SMBus Block Write:  i2c_smbus_write_block_data()
+================================================
 
 The opposite of the Block Read command, this writes up to 32 bytes to 
 a device, to a designated register that is specified through the
@@ -134,10 +140,11 @@ Comm byte. The amount of data is specified in the Count byte.
 S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
 
 
-SMBus Block Process Call
-========================
+SMBus Block Write - Block Read Process Call
+===========================================
 
-SMBus Block Process Call was introduced in Revision 2.0 of the specification.
+SMBus Block Write - Block Read Process Call was introduced in
+Revision 2.0 of the specification.
 
 This command selects a device register (through the Comm byte), sends
 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return.
@@ -159,13 +166,16 @@ alerting device's address.
 
 Packet Error Checking (PEC)
 ===========================
+
 Packet Error Checking was introduced in Revision 1.1 of the specification.
 
-PEC adds a CRC-8 error-checking byte to all transfers.
+PEC adds a CRC-8 error-checking byte to transfers using it, immediately
+before the terminating STOP.
 
 
 Address Resolution Protocol (ARP)
 =================================
+
 The Address Resolution Protocol was introduced in Revision 2.0 of
 the specification. It is a higher-layer protocol which uses the
 messages above.
@@ -177,14 +187,17 @@ require PEC checksums.
 
 I2C Block Transactions
 ======================
+
 The following I2C block transactions are supported by the
 SMBus layer and are described here for completeness.
+They are *NOT* defined by the SMBus specification.
+
 I2C block transactions do not limit the number of bytes transferred
 but the SMBus layer places a limit of 32 bytes.
 
 
-I2C Block Read
-==============
+I2C Block Read:  i2c_smbus_read_i2c_block_data()
+================================================
 
 This command reads a block of bytes from a device, from a 
 designated register that is specified through the Comm byte.
@@ -203,8 +216,8 @@ S Addr Wr [A] Comm1 [A] Comm2 [A]
            S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
 
 
-I2C Block Write
-===============
+I2C Block Write:  i2c_smbus_write_i2c_block_data()
+==================================================
 
 The opposite of the Block Read command, this writes bytes to 
 a device, to a designated register that is specified through the
@@ -212,5 +225,3 @@ Comm byte. Note that command lengths of 0, 2, or more bytes are
 supported as they are indistinguishable from data.
 
 S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
-
-
index 00b950d1c1931a7b20c19c2595eb2fbf062eb424..c412c245848f9116fb05361bb78e5189b43cfd51 100644 (file)
@@ -377,27 +377,3 @@ config FOO
 
 limits FOO to module (=m) or disabled (=n).
 
-
-Build limited by a third config symbol which may be =y or =m
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A common idiom that we see (and sometimes have problems with) is this:
-
-When option C in B (module or subsystem) uses interfaces from A (module
-or subsystem), and both A and B are tristate (could be =y or =m if they
-were independent of each other, but they aren't), then we need to limit
-C such that it cannot be built statically if A is built as a loadable
-module.  (C already depends on B, so there is no dependency issue to
-take care of here.)
-
-If A is linked statically into the kernel image, C can be built
-statically or as loadable module(s).  However, if A is built as loadable
-module(s), then C must be restricted to loadable module(s) also.  This
-can be expressed in kconfig language as:
-
-config C
-       depends on A = y || A = B
-
-or for real examples, use this command in a kernel tree:
-
-$ find . -name Kconfig\* | xargs grep -ns "depends on.*=.*||.*=" | grep -v orig
-
index d0ac72cc19ff8e29667e7a2c58e21d2d0cfafcb5..b8e52c0355d3bab81760adbf62d0c8a06a9ba52a 100644 (file)
@@ -245,6 +245,8 @@ The syntax is:
     crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
     range=start-[end]
 
+    'start' is inclusive and 'end' is exclusive.
+
 For example:
 
     crashkernel=512M-2G:64M,2G-:128M
@@ -253,10 +255,11 @@ This would mean:
 
     1) if the RAM is smaller than 512M, then don't reserve anything
        (this is the "rescue" case)
-    2) if the RAM size is between 512M and 2G, then reserve 64M
+    2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M
     3) if the RAM size is larger than 2G, then reserve 128M
 
 
+
 Boot into System Kernel
 =======================
 
index a3c35446e755c7c5bedaacf47be5f6050aad2145..cdd5b934f43ea89865f1f605ecc5f295b03192d3 100644 (file)
@@ -1094,9 +1094,6 @@ and is between 256 and 4096 characters. It is defined in the file
        mac5380=        [HW,SCSI] Format:
                        <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
 
-       mac53c9x=       [HW,SCSI] Format:
-                       <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-
        machvec=        [IA64] Force the use of a particular machine-vector
                        (machvec) in a generic kernel.
                        Example: machvec=hpzx1_swiotlb
@@ -1525,6 +1522,8 @@ and is between 256 and 4096 characters. It is defined in the file
                                This is normally done in pci_enable_device(),
                                so this option is a temporary workaround
                                for broken drivers that don't call it.
+               skip_isa_align  [X86] do not align io start addr, so can
+                               handle more pci cards
                firmware        [ARM] Do not re-enumerate the bus but instead
                                just use the configuration from the
                                bootloader. This is currently used on
index 4c1fc65a8b3d1c946965db4afc2a2dc08f82c44e..3be8ab2a886acf98e2b0a45ab3690fd20fc8bedc 100644 (file)
@@ -131,6 +131,9 @@ struct device
        /* Any queues attached to this device */
        struct virtqueue *vq;
 
+       /* Handle status being finalized (ie. feature bits stable). */
+       void (*ready)(struct device *me);
+
        /* Device-specific data. */
        void *priv;
 };
@@ -925,24 +928,40 @@ static void enable_fd(int fd, struct virtqueue *vq)
        write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
 }
 
-/* When the Guest asks us to reset a device, it's is fairly easy. */
-static void reset_device(struct device *dev)
+/* When the Guest tells us they updated the status field, we handle it. */
+static void update_device_status(struct device *dev)
 {
        struct virtqueue *vq;
 
-       verbose("Resetting device %s\n", dev->name);
-       /* Clear the status. */
-       dev->desc->status = 0;
+       /* This is a reset. */
+       if (dev->desc->status == 0) {
+               verbose("Resetting device %s\n", dev->name);
 
-       /* Clear any features they've acked. */
-       memset(get_feature_bits(dev) + dev->desc->feature_len, 0,
-              dev->desc->feature_len);
+               /* Clear any features they've acked. */
+               memset(get_feature_bits(dev) + dev->desc->feature_len, 0,
+                      dev->desc->feature_len);
 
-       /* Zero out the virtqueues. */
-       for (vq = dev->vq; vq; vq = vq->next) {
-               memset(vq->vring.desc, 0,
-                      vring_size(vq->config.num, getpagesize()));
-               vq->last_avail_idx = 0;
+               /* Zero out the virtqueues. */
+               for (vq = dev->vq; vq; vq = vq->next) {
+                       memset(vq->vring.desc, 0,
+                              vring_size(vq->config.num, getpagesize()));
+                       vq->last_avail_idx = 0;
+               }
+       } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
+               warnx("Device %s configuration FAILED", dev->name);
+       } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
+               unsigned int i;
+
+               verbose("Device %s OK: offered", dev->name);
+               for (i = 0; i < dev->desc->feature_len; i++)
+                       verbose(" %08x", get_feature_bits(dev)[i]);
+               verbose(", accepted");
+               for (i = 0; i < dev->desc->feature_len; i++)
+                       verbose(" %08x", get_feature_bits(dev)
+                               [dev->desc->feature_len+i]);
+
+               if (dev->ready)
+                       dev->ready(dev);
        }
 }
 
@@ -954,9 +973,9 @@ static void handle_output(int fd, unsigned long addr)
 
        /* Check each device and virtqueue. */
        for (i = devices.dev; i; i = i->next) {
-               /* Notifications to device descriptors reset the device. */
+               /* Notifications to device descriptors update device status. */
                if (from_guest_phys(addr) == i->desc) {
-                       reset_device(i);
+                       update_device_status(i);
                        return;
                }
 
@@ -1170,6 +1189,7 @@ static struct device *new_device(const char *name, u16 type, int fd,
        dev->handle_input = handle_input;
        dev->name = name;
        dev->vq = NULL;
+       dev->ready = NULL;
 
        /* Append to device list.  Prepending to a single-linked list is
         * easier, but the user expects the devices to be arranged on the bus
@@ -1398,7 +1418,7 @@ static bool service_io(struct device *dev)
        struct vblk_info *vblk = dev->priv;
        unsigned int head, out_num, in_num, wlen;
        int ret;
-       struct virtio_blk_inhdr *in;
+       u8 *in;
        struct virtio_blk_outhdr *out;
        struct iovec iov[dev->vq->vring.num];
        off64_t off;
@@ -1416,7 +1436,7 @@ static bool service_io(struct device *dev)
                     head, out_num, in_num);
 
        out = convert(&iov[0], struct virtio_blk_outhdr);
-       in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
+       in = convert(&iov[out_num+in_num-1], u8);
        off = out->sector * 512;
 
        /* The block device implements "barriers", where the Guest indicates
@@ -1430,7 +1450,7 @@ static bool service_io(struct device *dev)
         * It'd be nice if we supported eject, for example, but we don't. */
        if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
                fprintf(stderr, "Scsi commands unsupported\n");
-               in->status = VIRTIO_BLK_S_UNSUPP;
+               *in = VIRTIO_BLK_S_UNSUPP;
                wlen = sizeof(*in);
        } else if (out->type & VIRTIO_BLK_T_OUT) {
                /* Write */
@@ -1453,7 +1473,7 @@ static bool service_io(struct device *dev)
                        errx(1, "Write past end %llu+%u", off, ret);
                }
                wlen = sizeof(*in);
-               in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
+               *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
        } else {
                /* Read */
 
@@ -1466,10 +1486,10 @@ static bool service_io(struct device *dev)
                verbose("READ from sector %llu: %i\n", out->sector, ret);
                if (ret >= 0) {
                        wlen = sizeof(*in) + ret;
-                       in->status = VIRTIO_BLK_S_OK;
+                       *in = VIRTIO_BLK_S_OK;
                } else {
                        wlen = sizeof(*in);
-                       in->status = VIRTIO_BLK_S_IOERR;
+                       *in = VIRTIO_BLK_S_IOERR;
                }
        }
 
index e5a819a4f0c99588fecaef9f96632e5922b5c4b4..f5b7127f54acb6af1d9f997a40e099b60c0b7571 100644 (file)
@@ -994,7 +994,17 @@ The Linux kernel has eight basic CPU memory barriers:
        DATA DEPENDENCY read_barrier_depends()  smp_read_barrier_depends()
 
 
-All CPU memory barriers unconditionally imply compiler barriers.
+All memory barriers except the data dependency barriers imply a compiler
+barrier. Data dependencies do not impose any additional compiler ordering.
+
+Aside: In the case of data dependencies, the compiler would be expected to
+issue the loads in the correct order (eg. `a[b]` would have to load the value
+of b before loading a[b]), however there is no guarantee in the C specification
+that the compiler may not speculate the value of b (eg. is equal to 1) and load
+a before b (eg. tmp = a[1]; if (b != 1) tmp = a[b]; ). There is also the
+problem of a compiler reloading b after having loaded a[b], thus having a newer
+copy of b than a[b]. A consensus has not yet been reached about these problems,
+however the ACCESS_ONCE macro is a good place to start looking.
 
 SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
 systems because it is assumed that a CPU will appear to be self-consistent,
index cda7a7dffa6d6376fb0b0e83f4e096a9c448ffed..6f12f1c79c0c82f4a93ffde90da6b96bd62485f9 100644 (file)
@@ -237,6 +237,17 @@ Each GPIO controller node should have the empty property gpio-controller and
 according to the bit numbers in the GPIO control registers. The second cell
 is for flags which is currently unsused.
 
+8) FEC nodes
+The FEC node can specify one of the following properties to configure
+the MII link:
+"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire
+                    mode instead of MII
+"current-speed"   - Specifies that the MII should be configured for a fixed
+                    speed.  This property should contain two cells.  The
+                    first cell specifies the speed in Mbps and the second
+                    should be '0' for half duplex and '1' for full duplex
+"phy-handle"      - Contains a phandle to an Ethernet PHY.
+
 IV - Extra Notes
 ================
 
index 8fbc0a852870f2a972b4d17adae71ba866bc5975..bf0baa19ec24e875716e09490a2afeaecb86b5e2 100644 (file)
@@ -8,17 +8,6 @@ Command line parameters
 
   Enable logging of debug information in case of ccw device timeouts.
 
-
-* cio_msg = yes | no
-  
-  Determines whether information on found devices and sensed device 
-  characteristics should be shown during startup or when new devices are
-  found, i. e. messages of the types "Detected device 0.0.4711 on subchannel
-  0.0.0042" and "SenseID: Device 0.0.4711 reports: ...".
-
-  Default is off.
-
-
 * cio_ignore = {all} |
               {<device> | <range of devices>} |
               {!<device> | !<range of devices>}
diff --git a/Documentation/scheduler/sched-design.txt b/Documentation/scheduler/sched-design.txt
deleted file mode 100644 (file)
index 1605bf0..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-                  Goals, Design and Implementation of the
-                     new ultra-scalable O(1) scheduler
-
-
-  This is an edited version of an email Ingo Molnar sent to
-  lkml on 4 Jan 2002.  It describes the goals, design, and
-  implementation of Ingo's new ultra-scalable O(1) scheduler.
-  Last Updated: 18 April 2002.
-
-
-Goal
-====
-
-The main goal of the new scheduler is to keep all the good things we know
-and love about the current Linux scheduler:
-
- - good interactive performance even during high load: if the user
-   types or clicks then the system must react instantly and must execute
-   the user tasks smoothly, even during considerable background load.
-
- - good scheduling/wakeup performance with 1-2 runnable processes.
-
- - fairness: no process should stay without any timeslice for any
-   unreasonable amount of time. No process should get an unjustly high
-   amount of CPU time.
-
- - priorities: less important tasks can be started with lower priority,
-   more important tasks with higher priority.
-
- - SMP efficiency: no CPU should stay idle if there is work to do.
-
- - SMP affinity: processes which run on one CPU should stay affine to
-   that CPU. Processes should not bounce between CPUs too frequently.
-
- - plus additional scheduler features: RT scheduling, CPU binding.
-
-and the goal is also to add a few new things:
-
- - fully O(1) scheduling. Are you tired of the recalculation loop
-   blowing the L1 cache away every now and then? Do you think the goodness
-   loop is taking a bit too long to finish if there are lots of runnable
-   processes? This new scheduler takes no prisoners: wakeup(), schedule(),
-   the timer interrupt are all O(1) algorithms. There is no recalculation
-   loop. There is no goodness loop either.
-
- - 'perfect' SMP scalability. With the new scheduler there is no 'big'
-   runqueue_lock anymore - it's all per-CPU runqueues and locks - two
-   tasks on two separate CPUs can wake up, schedule and context-switch
-   completely in parallel, without any interlocking. All
-   scheduling-relevant data is structured for maximum scalability.
-
- - better SMP affinity. The old scheduler has a particular weakness that
-   causes the random bouncing of tasks between CPUs if/when higher
-   priority/interactive tasks, this was observed and reported by many
-   people. The reason is that the timeslice recalculation loop first needs
-   every currently running task to consume its timeslice. But when this
-   happens on eg. an 8-way system, then this property starves an
-   increasing number of CPUs from executing any process. Once the last
-   task that has a timeslice left has finished using up that timeslice,
-   the recalculation loop is triggered and other CPUs can start executing
-   tasks again - after having idled around for a number of timer ticks.
-   The more CPUs, the worse this effect.
-
-   Furthermore, this same effect causes the bouncing effect as well:
-   whenever there is such a 'timeslice squeeze' of the global runqueue,
-   idle processors start executing tasks which are not affine to that CPU.
-   (because the affine tasks have finished off their timeslices already.)
-
-   The new scheduler solves this problem by distributing timeslices on a
-   per-CPU basis, without having any global synchronization or
-   recalculation.
-
- - batch scheduling. A significant proportion of computing-intensive tasks
-   benefit from batch-scheduling, where timeslices are long and processes
-   are roundrobin scheduled. The new scheduler does such batch-scheduling
-   of the lowest priority tasks - so nice +19 jobs will get
-   'batch-scheduled' automatically. With this scheduler, nice +19 jobs are
-   in essence SCHED_IDLE, from an interactiveness point of view.
-
- - handle extreme loads more smoothly, without breakdown and scheduling
-   storms.
-
- - O(1) RT scheduling. For those RT folks who are paranoid about the
-   O(nr_running) property of the goodness loop and the recalculation loop.
-
- - run fork()ed children before the parent. Andrea has pointed out the
-   advantages of this a few months ago, but patches for this feature
-   do not work with the old scheduler as well as they should,
-   because idle processes often steal the new child before the fork()ing
-   CPU gets to execute it.
-
-
-Design
-======
-
-The core of the new scheduler contains the following mechanisms:
-
- - *two* priority-ordered 'priority arrays' per CPU. There is an 'active'
-   array and an 'expired' array. The active array contains all tasks that
-   are affine to this CPU and have timeslices left. The expired array
-   contains all tasks which have used up their timeslices - but this array
-   is kept sorted as well. The active and expired array is not accessed
-   directly, it's accessed through two pointers in the per-CPU runqueue
-   structure. If all active tasks are used up then we 'switch' the two
-   pointers and from now on the ready-to-go (former-) expired array is the
-   active array - and the empty active array serves as the new collector
-   for expired tasks.
-
- - there is a 64-bit bitmap cache for array indices. Finding the highest
-   priority task is thus a matter of two x86 BSFL bit-search instructions.
-
-the split-array solution enables us to have an arbitrary number of active
-and expired tasks, and the recalculation of timeslices can be done
-immediately when the timeslice expires. Because the arrays are always
-access through the pointers in the runqueue, switching the two arrays can
-be done very quickly.
-
-this is a hybride priority-list approach coupled with roundrobin
-scheduling and the array-switch method of distributing timeslices.
-
- - there is a per-task 'load estimator'.
-
-one of the toughest things to get right is good interactive feel during
-heavy system load. While playing with various scheduler variants i found
-that the best interactive feel is achieved not by 'boosting' interactive
-tasks, but by 'punishing' tasks that want to use more CPU time than there
-is available. This method is also much easier to do in an O(1) fashion.
-
-to establish the actual 'load' the task contributes to the system, a
-complex-looking but pretty accurate method is used: there is a 4-entry
-'history' ringbuffer of the task's activities during the last 4 seconds.
-This ringbuffer is operated without much overhead. The entries tell the
-scheduler a pretty accurate load-history of the task: has it used up more
-CPU time or less during the past N seconds. [the size '4' and the interval
-of 4x 1 seconds was found by lots of experimentation - this part is
-flexible and can be changed in both directions.]
-
-the penalty a task gets for generating more load than the CPU can handle
-is a priority decrease - there is a maximum amount to this penalty
-relative to their static priority, so even fully CPU-bound tasks will
-observe each other's priorities, and will share the CPU accordingly.
-
-the SMP load-balancer can be extended/switched with additional parallel
-computing and cache hierarchy concepts: NUMA scheduling, multi-core CPUs
-can be supported easily by changing the load-balancer. Right now it's
-tuned for my SMP systems.
-
-i skipped the prev->mm == next->mm advantage - no workload i know of shows
-any sensitivity to this. It can be added back by sacrificing O(1)
-schedule() [the current and one-lower priority list can be searched for a
-that->mm == current->mm condition], but costs a fair number of cycles
-during a number of important workloads, so i wanted to avoid this as much
-as possible.
-
-- the SMP idle-task startup code was still racy and the new scheduler
-triggered this. So i streamlined the idle-setup code a bit. We do not call
-into schedule() before all processors have started up fully and all idle
-threads are in place.
-
-- the patch also cleans up a number of aspects of sched.c - moves code
-into other areas of the kernel where it's appropriate, and simplifies
-certain code paths and data constructs. As a result, the new scheduler's
-code is smaller than the old one.
-
-       Ingo
index 91c81db0ba711c3594dbcbe8b6aa930bacb06b1f..716fcc1cafb5cac5f1e13aa6be971825687a2f04 100644 (file)
@@ -1,3 +1,25 @@
+1 Release Date    : Mon. March 10 11:02:31 PDT 2008 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Sumant Patro
+                       Bo Yang
+
+2 Current Version : 00.00.03.20-RC1
+3 Older Version   : 00.00.03.16
+
+1. Rollback the sense info implementation
+       Sense buffer ptr data type in the ioctl path is reverted back
+       to u32 * as in previous versions of driver.
+
+2. Fixed the driver frame count.
+       When Driver sent wrong frame count to firmware.  As this
+       particular command is sent to drive, FW is seeing continuous
+       chip resets and so the command will timeout.
+
+3. Add the new controller(1078DE) support to the driver
+       and Increase the max_wait to 60 from 10 in the controller
+       operational status.  With this max_wait increase, driver will
+       make sure the FW will   finish the pending cmd for KDUMP case.
+
 1 Release Date    : Thur. Nov. 07 16:30:43 PST 2007 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Sumant Patro
index d3ce295bffac59ce6ca9a4be032194210e5ac41f..e4230ed16ee7d1b45e757fd0c1c3a39848542c59 100644 (file)
@@ -38,7 +38,7 @@ struct slabinfo {
        unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
        unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
        unsigned long deactivate_to_head, deactivate_to_tail;
-       unsigned long deactivate_remote_frees;
+       unsigned long deactivate_remote_frees, order_fallback;
        int numa[MAX_NODES];
        int numa_partial[MAX_NODES];
 } slabinfo[MAX_SLABS];
@@ -293,7 +293,7 @@ int line = 0;
 void first_line(void)
 {
        if (show_activity)
-               printf("Name                   Objects    Alloc     Free   %%Fast\n");
+               printf("Name                   Objects      Alloc       Free   %%Fast Fallb O\n");
        else
                printf("Name                   Objects Objsize    Space "
                        "Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n");
@@ -573,11 +573,12 @@ void slabcache(struct slabinfo *s)
                total_alloc = s->alloc_fastpath + s->alloc_slowpath;
                total_free = s->free_fastpath + s->free_slowpath;
 
-               printf("%-21s %8ld %8ld %8ld %3ld %3ld \n",
+               printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n",
                        s->name, s->objects,
                        total_alloc, total_free,
                        total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
-                       total_free ? (s->free_fastpath * 100 / total_free) : 0);
+                       total_free ? (s->free_fastpath * 100 / total_free) : 0,
+                       s->order_fallback, s->order);
        }
        else
                printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
@@ -1188,6 +1189,7 @@ void read_slab_dir(void)
                        slab->deactivate_to_head = get_obj("deactivate_to_head");
                        slab->deactivate_to_tail = get_obj("deactivate_to_tail");
                        slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
+                       slab->order_fallback = get_obj("order_fallback");
                        chdir("..");
                        if (slab->name[0] == ':')
                                alias_targets++;
index 0cc47b9942b17bf63e20abe8ae870d4aee877535..b18242f8d96bac5eb8ae5fe91e6ee40b18004efa 100644 (file)
@@ -367,12 +367,12 @@ S:        Maintained for 2.4; PCI support for 2.6.
 AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
 P:     Thomas Dahlmann
 M:     thomas.dahlmann@amd.com
-L:     info-linux@geode.amd.com        (subscribers-only)
+L:     linux-geode@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 
 AMD GEODE PROCESSOR/CHIPSET SUPPORT
 P:     Jordan Crouse
-L:     info-linux@geode.amd.com        (subscribers-only)
+L:     linux-geode@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 S:     Supported
 
@@ -1196,9 +1196,9 @@ S:        Maintained
 
 CPUSETS
 P:     Paul Jackson
-P:     Simon Derr
+P:     Paul Menage
 M:     pj@sgi.com
-M:     simon.derr@bull.net
+M:     menage@google.com
 L:     linux-kernel@vger.kernel.org
 W:     http://www.bullopensource.org/cpuset/
 S:     Supported
@@ -1557,6 +1557,14 @@ M:       raisch@de.ibm.com
 L:     general@lists.openfabrics.org
 S:     Supported
 
+EMBEDDED LINUX
+P:     Paul Gortmaker
+M:     paul.gortmaker@windriver.com
+P      David Woodhouse
+M:     dwmw2@infradead.org
+L:     linux-embedded@vger.kernel.org
+S:     Maintained
+
 EMULEX LPFC FC SCSI DRIVER
 P:     James Smart
 M:     james.smart@emulex.com
@@ -3120,7 +3128,7 @@ PCI SUBSYSTEM
 P:     Jesse Barnes
 M:     jbarnes@virtuousgeek.org
 L:     linux-kernel@vger.kernel.org
-L:     linux-pci@atrey.karlin.mff.cuni.cz
+L:     linux-pci@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
 S:     Supported
 
@@ -4041,6 +4049,12 @@ L:      linux-usb@vger.kernel.org
 S:     Maintained
 W:     http://www.kroah.com/linux-usb/
 
+USB CYPRESS C67X00 DRIVER
+P:     Peter Korsgaard
+M:     jacmet@sunsite.dk
+L:     linux-usb@vger.kernel.org
+S:     Maintained
+
 USB DAVICOM DM9601 DRIVER
 P:     Peter Korsgaard
 M:     jacmet@sunsite.dk
index d3634cd6fe35bde2a8ef73835e9f6f2559087dab..3140145fdfe2b3475a8b5f6a604ca19e9b20acae 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 25
-EXTRAVERSION =
+SUBLEVEL = 26
+EXTRAVERSION = -rc2
 NAME = Funky Weasel is Jiggy wit it
 
 # *DOCUMENTATION*
@@ -794,7 +794,7 @@ endif # ifdef CONFIG_KALLSYMS
 quiet_cmd_vmlinux-modpost = LD      $@
       cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@                          \
         $(vmlinux-init) --start-group $(vmlinux-main) --end-group             \
-        $(filter-out $(vmlinux-init) $(vmlinux-main) $(vmlinux-lds) FORCE ,$^)
+        $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
 define rule_vmlinux-modpost
        :
        +$(call cmd,vmlinux-modpost)
@@ -818,7 +818,9 @@ endif
 ifdef CONFIG_KALLSYMS
 .tmp_vmlinux1: vmlinux.o
 endif
-vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE
+
+modpost-init := $(filter-out init/built-in.o, $(vmlinux-init))
+vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
        $(call if_changed_rule,vmlinux-modpost)
 
 # The actual objects are generated when descending, 
index 9fee37e2596f34fe8d3c22558b87d248396b4dca..32ca1b9273078d7025466075e677a59e34938b33 100644 (file)
@@ -981,27 +981,18 @@ asmlinkage int
 osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
           struct timeval32 __user *tvp)
 {
-       fd_set_bits fds;
-       char *bits;
-       size_t size;
-       long timeout;
-       int ret = -EINVAL;
-       struct fdtable *fdt;
-       int max_fds;
-
-       timeout = MAX_SCHEDULE_TIMEOUT;
+       s64 timeout = MAX_SCHEDULE_TIMEOUT;
        if (tvp) {
                time_t sec, usec;
 
                if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
                    || __get_user(sec, &tvp->tv_sec)
                    || __get_user(usec, &tvp->tv_usec)) {
-                       ret = -EFAULT;
-                       goto out_nofds;
+                       return -EFAULT;
                }
 
                if (sec < 0 || usec < 0)
-                       goto out_nofds;
+                       return -EINVAL;
 
                if ((unsigned long) sec < MAX_SELECT_SECONDS) {
                        timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
@@ -1009,60 +1000,8 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
                }
        }
 
-       rcu_read_lock();
-       fdt = files_fdtable(current->files);
-       max_fds = fdt->max_fds;
-       rcu_read_unlock();
-       if (n < 0 || n > max_fds)
-               goto out_nofds;
-
-       /*
-        * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
-        * since we used fdset we need to allocate memory in units of
-        * long-words. 
-        */
-       ret = -ENOMEM;
-       size = FDS_BYTES(n);
-       bits = kmalloc(6 * size, GFP_KERNEL);
-       if (!bits)
-               goto out_nofds;
-       fds.in      = (unsigned long *)  bits;
-       fds.out     = (unsigned long *) (bits +   size);
-       fds.ex      = (unsigned long *) (bits + 2*size);
-       fds.res_in  = (unsigned long *) (bits + 3*size);
-       fds.res_out = (unsigned long *) (bits + 4*size);
-       fds.res_ex  = (unsigned long *) (bits + 5*size);
-
-       if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) ||
-           (ret = get_fd_set(n, outp->fds_bits, fds.out)) ||
-           (ret = get_fd_set(n, exp->fds_bits, fds.ex)))
-               goto out;
-       zero_fd_set(n, fds.res_in);
-       zero_fd_set(n, fds.res_out);
-       zero_fd_set(n, fds.res_ex);
-
-       ret = do_select(n, &fds, &timeout);
-
        /* OSF does not copy back the remaining time.  */
-
-       if (ret < 0)
-               goto out;
-       if (!ret) {
-               ret = -ERESTARTNOHAND;
-               if (signal_pending(current))
-                       goto out;
-               ret = 0;
-       }
-
-       if (set_fd_set(n, inp->fds_bits, fds.res_in) ||
-           set_fd_set(n, outp->fds_bits, fds.res_out) ||
-           set_fd_set(n, exp->fds_bits, fds.res_ex))
-               ret = -EFAULT;
-
- out:
-       kfree(bits);
- out_nofds:
-       return ret;
+       return core_sys_select(n, inp, outp, exp, &timeout);
 }
 
 struct rusage32 {
index 9bd1870d980ec74b5c77936828a1f7e6f481047b..0128687ba0f71ac8c65598a108bc6278f6e60c68 100644 (file)
@@ -34,23 +34,6 @@ extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
                               unsigned long new_len, unsigned long flags,
                               unsigned long new_addr);
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 inline long do_mmap2(
        unsigned long addr, unsigned long len,
index 8bc187240542e6611f051809c233796f331fcfef..1d7bca6aa441e3a092a87933a3d87e9c9a2f245f 100644 (file)
@@ -280,7 +280,7 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
        const int port = gpio >> 3;
        const int port_mask = 1 << (gpio & 7);
 
-       gpio_direction_output(gpio, gpio_get_value(gpio));
+       gpio_direction_input(gpio);
 
        switch (type) {
        case IRQT_RISING:
index 36e5835e60975127b798b28b8fe756238f354feb..ca85d24cf39f1f11553c2ac856d08b71bb9a9ff9 100644 (file)
@@ -62,7 +62,7 @@ static struct irq_chip ns9xxx_chip = {
 #if 0
 #define handle_irq handle_level_irq
 #else
-void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
+static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
        unsigned int cpu = smp_processor_id();
        struct irqaction *action;
@@ -70,27 +70,35 @@ void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
 
-       if (unlikely(desc->status & IRQ_INPROGRESS))
-               goto out_unlock;
+       BUG_ON(desc->status & IRQ_INPROGRESS);
 
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
        kstat_cpu(cpu).irqs[irq]++;
 
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-               goto out_unlock;
+               goto out_mask;
 
        desc->status |= IRQ_INPROGRESS;
        spin_unlock(&desc->lock);
 
        action_ret = handle_IRQ_event(irq, action);
 
+       /* XXX: There is no direct way to access noirqdebug, so check
+        * unconditionally for spurious irqs...
+        * Maybe this function should go to kernel/irq/chip.c? */
+       note_interrupt(irq, desc, action_ret);
+
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
-       if (!(desc->status & IRQ_DISABLED) && desc->chip->ack)
-               desc->chip->ack(irq);
 
-out_unlock:
+       if (desc->status & IRQ_DISABLED)
+out_mask:
+               desc->chip->mask(irq);
+
+       /* ack unconditionally to unmask lower prio irqs */
+       desc->chip->ack(irq);
+
        spin_unlock(&desc->lock);
 }
 #define handle_irq handle_prio_irq
index 9608503d67f5475eda40eaea8efc252f5c123a9d..e63fb05dc8931e637bbec1f6c0f7398e79ebc09a 100644 (file)
  * Non-CPU Masters address decoding --
  * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
  * banks only (the typical use case).
- * Setup access for each master to DDR is issued by common.c.
- *
- * Note: although orion_setbits() and orion_clrbits() are not atomic
- * no locking is necessary here since code in this file is only called
- * at boot time when there is no concurrency issues.
+ * Setup access for each master to DDR is issued by platform device setup.
  */
 
 /*
 #define TARGET_DEV_BUS         1
 #define TARGET_PCI             3
 #define TARGET_PCIE            4
-#define ATTR_DDR_CS(n)         (((n) ==0) ? 0xe :      \
-                               ((n) == 1) ? 0xd :      \
-                               ((n) == 2) ? 0xb :      \
-                               ((n) == 3) ? 0x7 : 0xf)
 #define ATTR_PCIE_MEM          0x59
 #define ATTR_PCIE_IO           0x51
 #define ATTR_PCIE_WA           0x79
 #define ATTR_DEV_CS1           0x1d
 #define ATTR_DEV_CS2           0x1b
 #define ATTR_DEV_BOOT          0xf
-#define WIN_EN                 1
 
 /*
  * Helpers to get DDR bank info
  */
-#define DDR_BASE_CS(n)         ORION5X_DDR_REG(0x1500 + ((n) * 8))
-#define DDR_SIZE_CS(n)         ORION5X_DDR_REG(0x1504 + ((n) * 8))
-#define DDR_MAX_CS             4
-#define DDR_REG_TO_SIZE(reg)   (((reg) | 0xffffff) + 1)
-#define DDR_REG_TO_BASE(reg)   ((reg) & 0xff000000)
-#define DDR_BANK_EN            1
+#define DDR_BASE_CS(n)         ORION5X_DDR_REG(0x1500 + ((n) << 3))
+#define DDR_SIZE_CS(n)         ORION5X_DDR_REG(0x1504 + ((n) << 3))
 
 /*
  * CPU Address Decode Windows registers
 #define CPU_WIN_REMAP_LO(n)    ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
 #define CPU_WIN_REMAP_HI(n)    ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
 
-/*
- * Gigabit Ethernet Address Decode Windows registers
- */
-#define ETH_WIN_BASE(win)      ORION5X_ETH_REG(0x200 + ((win) * 8))
-#define ETH_WIN_SIZE(win)      ORION5X_ETH_REG(0x204 + ((win) * 8))
-#define ETH_WIN_REMAP(win)     ORION5X_ETH_REG(0x280 + ((win) * 4))
-#define ETH_WIN_EN             ORION5X_ETH_REG(0x290)
-#define ETH_WIN_PROT           ORION5X_ETH_REG(0x294)
-#define ETH_MAX_WIN            6
-#define ETH_MAX_REMAP_WIN      4
-
 
 struct mbus_dram_target_info orion5x_mbus_dram_info;
 
@@ -202,39 +178,3 @@ void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
 {
        setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1);
 }
-
-void __init orion5x_setup_eth_wins(void)
-{
-       int i;
-
-       /*
-        * First, disable and clear windows
-        */
-       for (i = 0; i < ETH_MAX_WIN; i++) {
-               orion5x_write(ETH_WIN_BASE(i), 0);
-               orion5x_write(ETH_WIN_SIZE(i), 0);
-               orion5x_setbits(ETH_WIN_EN, 1 << i);
-               orion5x_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
-               if (i < ETH_MAX_REMAP_WIN)
-                       orion5x_write(ETH_WIN_REMAP(i), 0);
-       }
-
-       /*
-        * Setup windows for DDR banks.
-        */
-       for (i = 0; i < DDR_MAX_CS; i++) {
-               u32 base, size;
-               size = orion5x_read(DDR_SIZE_CS(i));
-               base = orion5x_read(DDR_BASE_CS(i));
-               if (size & DDR_BANK_EN) {
-                       base = DDR_REG_TO_BASE(base);
-                       size = DDR_REG_TO_SIZE(size);
-                       orion5x_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
-                       orion5x_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
-                                       (ATTR_DDR_CS(i) << 8) |
-                                       TARGET_DDR);
-                       orion5x_clrbits(ETH_WIN_EN, 1 << i);
-                       orion5x_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
-               }
-       }
-}
index 0ecff5a619723a468c5e4c9410c244abe56d602c..4f13fd037f0421ef039bddd38d47a712abd0a05e 100644 (file)
@@ -190,6 +190,11 @@ static struct platform_device orion5x_ehci1 = {
  * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
  ****************************************************************************/
 
+struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
+       .dram           = &orion5x_mbus_dram_info,
+       .t_clk          = ORION5X_TCLK,
+};
+
 static struct resource orion5x_eth_shared_resources[] = {
        {
                .start  = ORION5X_ETH_PHYS_BASE + 0x2000,
@@ -201,6 +206,9 @@ static struct resource orion5x_eth_shared_resources[] = {
 static struct platform_device orion5x_eth_shared = {
        .name           = MV643XX_ETH_SHARED_NAME,
        .id             = 0,
+       .dev            = {
+               .platform_data  = &orion5x_eth_shared_data,
+       },
        .num_resources  = 1,
        .resource       = orion5x_eth_shared_resources,
 };
@@ -362,7 +370,6 @@ void __init orion5x_init(void)
         * Setup Orion address map
         */
        orion5x_setup_cpu_mbus_bridge();
-       orion5x_setup_eth_wins();
 
        /*
         * Register devices.
index 14adf8d1a54ac8d96f33e23a8a92b98369faab72..bd0f05de6e18d2698087a5c72393101798477b26 100644 (file)
@@ -22,7 +22,6 @@ void orion5x_setup_dev0_win(u32 base, u32 size);
 void orion5x_setup_dev1_win(u32 base, u32 size);
 void orion5x_setup_dev2_win(u32 base, u32 size);
 void orion5x_setup_pcie_wa_win(u32 base, u32 size);
-void orion5x_setup_eth_wins(void);
 
 /*
  * Shared code used internally by other Orion core functions.
index 6a830853aa6a610e532c33040f0ab96544dc8c3e..0e6d05bb81aa9ae806ea6461078dea57679e1445 100644 (file)
@@ -5,6 +5,13 @@
 # Common support (must be linked before board specific support)
 obj-y                          += clock.o devices.o generic.o irq.o dma.o \
                                   time.o gpio.o
+obj-$(CONFIG_PM)               += pm.o sleep.o standby.o
+obj-$(CONFIG_CPU_FREQ)         += cpu-pxa.o
+
+# Generic drivers that other drivers may depend upon
+obj-$(CONFIG_PXA_SSP)          += ssp.o
+
+# SoC-specific code
 obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)           += mfp-pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o pxa3xx.o smemc.o
@@ -48,11 +55,6 @@ led-$(CONFIG_MACH_TRIZEPS4)  += leds-trizeps4.o
 
 obj-$(CONFIG_LEDS)             += $(led-y)
 
-# Misc features
-obj-$(CONFIG_PM)               += pm.o sleep.o standby.o
-obj-$(CONFIG_CPU_FREQ)         += cpu-pxa.o
-obj-$(CONFIG_PXA_SSP)          += ssp.o
-
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
 endif
index 259ca821e464444d3ae02b0d1bbad9031697cad1..b757dd7566552e6a547eaf1137f1ea3563ed5820 100644 (file)
@@ -493,8 +493,6 @@ static struct platform_device *devices[] __initdata = {
 
 static void corgi_poweroff(void)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        if (!machine_is_corgi())
                /* Green LED off tells the bootloader to halt */
                reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
@@ -503,8 +501,6 @@ static void corgi_poweroff(void)
 
 static void corgi_restart(char mode)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        if (!machine_is_corgi())
                /* Green LED on tells the bootloader to reboot */
                set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
index 4b21479332ae40c073c1f184b1980a502aca4c40..fb9ba1ab28269bddf4dc938f000f691bdaee1d29 100644 (file)
@@ -49,125 +49,216 @@ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
 #define freq_debug  0
 #endif
 
+static unsigned int pxa27x_maxfreq;
+module_param(pxa27x_maxfreq, uint, 0);
+MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
+                "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
+
 typedef struct {
        unsigned int khz;
        unsigned int membus;
        unsigned int cccr;
        unsigned int div2;
+       unsigned int cclkcfg;
 } pxa_freqs_t;
 
 /* Define the refresh period in mSec for the SDRAM and the number of rows */
-#define SDRAM_TREF          64      /* standard 64ms SDRAM */
-#define SDRAM_ROWS          4096    /* 64MB=8192 32MB=4096 */
-#define MDREFR_DRI(x)       (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
-
-#define CCLKCFG_TURBO       0x1
-#define CCLKCFG_FCS         0x2
-#define PXA25x_MIN_FREQ     99500
-#define PXA25x_MAX_FREQ     398100
-#define MDREFR_DB2_MASK     (MDREFR_K2DB2 | MDREFR_K1DB2)
-#define MDREFR_DRI_MASK     0xFFF
+#define SDRAM_TREF     64      /* standard 64ms SDRAM */
+#define SDRAM_ROWS     4096    /* 64MB=8192 32MB=4096 */
 
+#define CCLKCFG_TURBO          0x1
+#define CCLKCFG_FCS            0x2
+#define CCLKCFG_HALFTURBO      0x4
+#define CCLKCFG_FASTBUS                0x8
+#define MDREFR_DB2_MASK                (MDREFR_K2DB2 | MDREFR_K1DB2)
+#define MDREFR_DRI_MASK                0xFFF
 
+/*
+ * PXA255 definitions
+ */
 /* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
+#define CCLKCFG                        CCLKCFG_TURBO | CCLKCFG_FCS
+
 static pxa_freqs_t pxa255_run_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500,  99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50,  SDRAM=50 */
-    {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66,  SDRAM=66 */
-    {199100,  99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99,  SDRAM=99 */
-    {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
-    {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
-    {398100,  99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
-    {0,}
+       /* CPU   MEMBUS  CCCR  DIV2 CCLKCFG        run  turbo PXbus SDRAM */
+       { 99500,  99500, 0x121, 1,  CCLKCFG},   /*  99,   99,   50,   50  */
+       {132700, 132700, 0x123, 1,  CCLKCFG},   /* 133,  133,   66,   66  */
+       {199100,  99500, 0x141, 0,  CCLKCFG},   /* 199,  199,   99,   99  */
+       {265400, 132700, 0x143, 1,  CCLKCFG},   /* 265,  265,  133,   66  */
+       {331800, 165900, 0x145, 1,  CCLKCFG},   /* 331,  331,  166,   83  */
+       {398100,  99500, 0x161, 0,  CCLKCFG},   /* 398,  398,  196,   99  */
 };
-#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
-
-static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
 
 /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
 static pxa_freqs_t pxa255_turbo_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500, 99500,  0x121, 1}, /* run=99,  turbo= 99, PXbus=50, SDRAM=50 */
-    {199100, 99500,  0x221, 0}, /* run=99,  turbo=199, PXbus=50, SDRAM=99 */
-    {298500, 99500,  0x321, 0}, /* run=99,  turbo=287, PXbus=50, SDRAM=99 */
-    {298600, 99500,  0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
-    {398100, 99500,  0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
-    {0,}
+       /* CPU   MEMBUS  CCCR  DIV2 CCLKCFG        run  turbo PXbus SDRAM */
+       { 99500, 99500,  0x121, 1,  CCLKCFG},   /*  99,   99,   50,   50  */
+       {199100, 99500,  0x221, 0,  CCLKCFG},   /*  99,  199,   50,   99  */
+       {298500, 99500,  0x321, 0,  CCLKCFG},   /*  99,  287,   50,   99  */
+       {298600, 99500,  0x1c1, 0,  CCLKCFG},   /* 199,  287,   99,   99  */
+       {398100, 99500,  0x241, 0,  CCLKCFG},   /* 199,  398,   99,   99  */
+};
+
+#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
+#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
+
+static struct cpufreq_frequency_table
+       pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
+static struct cpufreq_frequency_table
+       pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
+
+/*
+ * PXA270 definitions
+ *
+ * For the PXA27x:
+ * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
+ *
+ * A = 0 => memory controller clock from table 3-7,
+ * A = 1 => memory controller clock = system bus clock
+ * Run mode frequency  = 13 MHz * L
+ * Turbo mode frequency = 13 MHz * L * N
+ * System bus frequency = 13 MHz * L / (B + 1)
+ *
+ * In CCCR:
+ * A = 1
+ * L = 16        oscillator to run mode ratio
+ * 2N = 6        2 * (turbo mode to run mode ratio)
+ *
+ * In CCLKCFG:
+ * B = 1         Fast bus mode
+ * HT = 0        Half-Turbo mode
+ * T = 1         Turbo mode
+ *
+ * For now, just support some of the combinations in table 3-7 of
+ * PXA27x Processor Family Developer's Manual to simplify frequency
+ * change sequences.
+ */
+#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
+#define CCLKCFG2(B, HT, T) \
+  (CCLKCFG_FCS | \
+   ((B)  ? CCLKCFG_FASTBUS : 0) | \
+   ((HT) ? CCLKCFG_HALFTURBO : 0) | \
+   ((T)  ? CCLKCFG_TURBO : 0))
+
+static pxa_freqs_t pxa27x_freqs[] = {
+       {104000, 104000, PXA27x_CCCR(1,  8, 2), 0, CCLKCFG2(1, 0, 1)},
+       {156000, 104000, PXA27x_CCCR(1,  8, 6), 0, CCLKCFG2(1, 1, 1)},
+       {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)},
+       {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)},
+       {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)},
+       {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)},
+       {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)}
 };
-#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
 
-static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
+#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
+static struct cpufreq_frequency_table
+       pxa27x_freq_table[NUM_PXA27x_FREQS+1];
 
 extern unsigned get_clk_frequency_khz(int info);
 
+static void find_freq_tables(struct cpufreq_policy *policy,
+                            struct cpufreq_frequency_table **freq_table,
+                            pxa_freqs_t **pxa_freqs)
+{
+       if (cpu_is_pxa25x()) {
+               if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+                       *pxa_freqs = pxa255_run_freqs;
+                       *freq_table = pxa255_run_freq_table;
+               } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+                       *pxa_freqs = pxa255_turbo_freqs;
+                       *freq_table = pxa255_turbo_freq_table;
+               } else {
+                       printk("CPU PXA: Unknown policy found. "
+                              "Using CPUFREQ_POLICY_PERFORMANCE\n");
+                       *pxa_freqs = pxa255_run_freqs;
+                       *freq_table = pxa255_run_freq_table;
+               }
+       }
+       if (cpu_is_pxa27x()) {
+               *pxa_freqs = pxa27x_freqs;
+               *freq_table = pxa27x_freq_table;
+       }
+}
+
+static void pxa27x_guess_max_freq(void)
+{
+       if (!pxa27x_maxfreq) {
+               pxa27x_maxfreq = 416000;
+               printk(KERN_INFO "PXA CPU 27x max frequency not defined "
+                      "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
+                      pxa27x_maxfreq);
+       } else {
+               pxa27x_maxfreq *= 1000;
+       }
+}
+
+static u32 mdrefr_dri(unsigned int freq)
+{
+       u32 dri = 0;
+
+       if (cpu_is_pxa25x())
+               dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32));
+       if (cpu_is_pxa27x())
+               dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32;
+       return dri;
+}
+
 /* find a valid frequency point */
 static int pxa_verify_policy(struct cpufreq_policy *policy)
 {
        struct cpufreq_frequency_table *pxa_freqs_table;
+       pxa_freqs_t *pxa_freqs;
        int ret;
 
-       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-               pxa_freqs_table = pxa255_run_freq_table;
-       } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-               pxa_freqs_table = pxa255_turbo_freq_table;
-       } else {
-               printk("CPU PXA: Unknown policy found. "
-                      "Using CPUFREQ_POLICY_PERFORMANCE\n");
-               pxa_freqs_table = pxa255_run_freq_table;
-       }
-
+       find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs);
        ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
 
        if (freq_debug)
                pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
-                      policy->min, policy->max);
+                        policy->min, policy->max);
 
        return ret;
 }
 
+static unsigned int pxa_cpufreq_get(unsigned int cpu)
+{
+       return get_clk_frequency_khz(0);
+}
+
 static int pxa_set_target(struct cpufreq_policy *policy,
-                          unsigned int target_freq,
-                          unsigned int relation)
+                         unsigned int target_freq,
+                         unsigned int relation)
 {
        struct cpufreq_frequency_table *pxa_freqs_table;
        pxa_freqs_t *pxa_freq_settings;
        struct cpufreq_freqs freqs;
        unsigned int idx;
        unsigned long flags;
-       unsigned int unused, preset_mdrefr, postset_mdrefr;
-       void *ramstart = phys_to_virt(0xa0000000);
+       unsigned int new_freq_cpu, new_freq_mem;
+       unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
 
        /* Get the current policy */
-       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-               pxa_freq_settings = pxa255_run_freqs;
-               pxa_freqs_table   = pxa255_run_freq_table;
-       } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-               pxa_freq_settings = pxa255_turbo_freqs;
-               pxa_freqs_table   = pxa255_turbo_freq_table;
-       } else {
-               printk("CPU PXA: Unknown policy found. "
-                      "Using CPUFREQ_POLICY_PERFORMANCE\n");
-               pxa_freq_settings = pxa255_run_freqs;
-               pxa_freqs_table   = pxa255_run_freq_table;
-       }
+       find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings);
 
        /* Lookup the next frequency */
        if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
-                                          target_freq, relation, &idx)) {
+                                          target_freq, relation, &idx)) {
                return -EINVAL;
        }
 
+       new_freq_cpu = pxa_freq_settings[idx].khz;
+       new_freq_mem = pxa_freq_settings[idx].membus;
        freqs.old = policy->cur;
-       freqs.new = pxa_freq_settings[idx].khz;
+       freqs.new = new_freq_cpu;
        freqs.cpu = policy->cpu;
 
        if (freq_debug)
-               pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
-                      freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
-                      (pxa_freq_settings[idx].membus / 2000) :
-                      (pxa_freq_settings[idx].membus / 1000));
+               pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
+                        "(SDRAM %d Mhz)\n",
+                        freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
+                        (new_freq_mem / 2000) : (new_freq_mem / 1000));
 
        /*
         * Tell everyone what we're about to do...
@@ -177,16 +268,16 @@ static int pxa_set_target(struct cpufreq_policy *policy,
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
        /* Calculate the next MDREFR.  If we're slowing down the SDRAM clock
-        * we need to preset the smaller DRI before the change.  If we're speeding
-        * up we need to set the larger DRI value after the change.
+        * we need to preset the smaller DRI before the change.  If we're
+        * speeding up we need to set the larger DRI value after the change.
         */
        preset_mdrefr = postset_mdrefr = MDREFR;
-       if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
-               preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
-                               MDREFR_DRI(pxa_freq_settings[idx].membus);
+       if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
+               preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
+               preset_mdrefr |= mdrefr_dri(new_freq_mem);
        }
-       postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
-                           MDREFR_DRI(pxa_freq_settings[idx].membus);
+       postset_mdrefr =
+               (postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem);
 
        /* If we're dividing the memory clock by two for the SDRAM clock, this
         * must be set prior to the change.  Clearing the divide must be done
@@ -201,26 +292,27 @@ static int pxa_set_target(struct cpufreq_policy *policy,
 
        local_irq_save(flags);
 
-       /* Set new the CCCR */
+       /* Set new the CCCR and prepare CCLKCFG */
        CCCR = pxa_freq_settings[idx].cccr;
+       cclkcfg = pxa_freq_settings[idx].cclkcfg;
 
        asm volatile("                                                  \n\
                ldr     r4, [%1]                /* load MDREFR */       \n\
                b       2f                                              \n\
-               .align  5                                               \n\
+               .align  5                                               \n\
 1:                                                                     \n\
-               str     %4, [%1]                /* preset the MDREFR */ \n\
+               str     %3, [%1]                /* preset the MDREFR */ \n\
                mcr     p14, 0, %2, c6, c0, 0   /* set CCLKCFG[FCS] */  \n\
-               str     %5, [%1]                /* postset the MDREFR */ \n\
+               str     %4, [%1]                /* postset the MDREFR */ \n\
                                                                        \n\
                b       3f                                              \n\
 2:             b       1b                                              \n\
 3:             nop                                                     \n\
          "
-         : "=&r" (unused)
-         : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
-           "r" (preset_mdrefr), "r" (postset_mdrefr)
-         : "r4", "r5");
+                    : "=&r" (unused)
+                    : "r" (&MDREFR), "r" (cclkcfg),
+                      "r" (preset_mdrefr), "r" (postset_mdrefr)
+                    : "r4", "r5");
        local_irq_restore(flags);
 
        /*
@@ -233,38 +325,57 @@ static int pxa_set_target(struct cpufreq_policy *policy,
        return 0;
 }
 
-static unsigned int pxa_cpufreq_get(unsigned int cpu)
-{
-       return get_clk_frequency_khz(0);
-}
-
-static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
 {
        int i;
+       unsigned int freq;
+
+       /* try to guess pxa27x cpu */
+       if (cpu_is_pxa27x())
+               pxa27x_guess_max_freq();
 
        /* set default policy and cpuinfo */
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-       policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
-       policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
+       if (cpu_is_pxa25x())
+               policy->policy = CPUFREQ_POLICY_PERFORMANCE;
        policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
-       policy->cur = get_clk_frequency_khz(0);    /* current freq */
+       policy->cur = get_clk_frequency_khz(0);    /* current freq */
        policy->min = policy->max = policy->cur;
 
-       /* Generate the run cpufreq_frequency_table struct */
-       for (i = 0; i < NUM_RUN_FREQS; i++) {
+       /* Generate pxa25x the run cpufreq_frequency_table struct */
+       for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
                pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
                pxa255_run_freq_table[i].index = i;
        }
-
        pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
-       /* Generate the turbo cpufreq_frequency_table struct */
-       for (i = 0; i < NUM_TURBO_FREQS; i++) {
-               pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
+
+       /* Generate pxa25x the turbo cpufreq_frequency_table struct */
+       for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
+               pxa255_turbo_freq_table[i].frequency =
+                       pxa255_turbo_freqs[i].khz;
                pxa255_turbo_freq_table[i].index = i;
        }
        pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
+       /* Generate the pxa27x cpufreq_frequency_table struct */
+       for (i = 0; i < NUM_PXA27x_FREQS; i++) {
+               freq = pxa27x_freqs[i].khz;
+               if (freq > pxa27x_maxfreq)
+                       break;
+               pxa27x_freq_table[i].frequency = freq;
+               pxa27x_freq_table[i].index = i;
+       }
+       pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+       /*
+        * Set the policy's minimum and maximum frequencies from the tables
+        * just constructed.  This sets cpuinfo.mxx_freq, min and max.
+        */
+       if (cpu_is_pxa25x())
+               cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table);
+       else if (cpu_is_pxa27x())
+               cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table);
+
        printk(KERN_INFO "PXA CPU frequency change support initialized\n");
 
        return 0;
@@ -275,26 +386,25 @@ static struct cpufreq_driver pxa_cpufreq_driver = {
        .target = pxa_set_target,
        .init   = pxa_cpufreq_init,
        .get    = pxa_cpufreq_get,
-       .name   = "PXA25x",
+       .name   = "PXA2xx",
 };
 
 static int __init pxa_cpu_init(void)
 {
        int ret = -ENODEV;
-       if (cpu_is_pxa25x())
+       if (cpu_is_pxa25x() || cpu_is_pxa27x())
                ret = cpufreq_register_driver(&pxa_cpufreq_driver);
        return ret;
 }
 
 static void __exit pxa_cpu_exit(void)
 {
-       if (cpu_is_pxa25x())
-               cpufreq_unregister_driver(&pxa_cpufreq_driver);
+       cpufreq_unregister_driver(&pxa_cpufreq_driver);
 }
 
 
-MODULE_AUTHOR ("Intrinsyc Software Inc.");
-MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
+MODULE_AUTHOR("Intrinsyc Software Inc.");
+MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
 MODULE_LICENSE("GPL");
 module_init(pxa_cpu_init);
 module_exit(pxa_cpu_exit);
index 0993f4d1a0bc71bba362a86a2c92aba54f56ee4f..7b9bdd0c66653b5a423b772d7f7e8152975e25ef 100644 (file)
@@ -396,7 +396,7 @@ static struct pxafb_mach_info sharp_lm8v31 = {
        .cmap_inverse   = 0,
        .cmap_static    = 0,
        .lcd_conn       = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
-                         LCD_AC_BIAS_FREQ(255);
+                         LCD_AC_BIAS_FREQ(255),
 };
 
 #define        MMC_POLL_RATE           msecs_to_jiffies(1000)
index ec1bbf333a3ad5a74c8c1cb06c2b0c6613fa277b..7d4debbdcca3feb1c9fa253f0441256d670c6a84 100644 (file)
@@ -42,20 +42,17 @@ int pxa_pm_enter(suspend_state_t state)
        if (state != PM_SUSPEND_STANDBY) {
                pxa_cpu_pm_fns->save(sleep_save);
                /* before sleeping, calculate and save a checksum */
-               for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+               for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
                        sleep_save_checksum += sleep_save[i];
        }
 
-       /* Clear reset status */
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        /* *** go zzz *** */
        pxa_cpu_pm_fns->enter(state);
        cpu_init();
 
        if (state != PM_SUSPEND_STANDBY) {
                /* after sleeping, validate the checksum */
-               for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+               for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
                        checksum += sleep_save[i];
 
                /* if invalid, display message and wait for a hardware reset */
@@ -101,7 +98,8 @@ static int __init pxa_pm_init(void)
                return -EINVAL;
        }
 
-       sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
+       sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
+                            GFP_KERNEL);
        if (!sleep_save) {
                printk(KERN_ERR "failed to alloc memory for pm save\n");
                return -ENOMEM;
index ca5ac196b47b71e3b011281ed5e77dc574df65b7..0b30f25cff3c15020d6363f1469b1c0e75977935 100644 (file)
@@ -326,13 +326,11 @@ static struct platform_device *devices[] __initdata = {
 
 static void poodle_poweroff(void)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
        arm_machine_restart('h');
 }
 
 static void poodle_restart(char mode)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
        arm_machine_restart('h');
 }
 
index d9b5450aee5b68e227e1fbf96ad24ad396a3ac88..e5b417d14bb04b772689b431631994c7985899d5 100644 (file)
@@ -150,9 +150,7 @@ static struct clk pxa25x_clks[] = {
  * 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_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
+enum { 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,
@@ -162,7 +160,7 @@ enum {      SLEEP_SAVE_START = 0,
 
        SLEEP_SAVE_CKEN,
 
-       SLEEP_SAVE_SIZE
+       SLEEP_SAVE_COUNT
 };
 
 
@@ -200,6 +198,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 
 static void pxa25x_cpu_pm_enter(suspend_state_t state)
 {
+       /* Clear reset status */
+       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
        switch (state) {
        case PM_SUSPEND_MEM:
                /* set resume return address */
@@ -210,7 +211,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
 }
 
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
-       .save_size      = SLEEP_SAVE_SIZE,
+       .save_count     = SLEEP_SAVE_COUNT,
        .valid          = suspend_valid_only_mem,
        .save           = pxa25x_cpu_pm_save,
        .restore        = pxa25x_cpu_pm_restore,
index 7a2449dd0fd4f19ebf7ac64c59290b7f4d8bd5b6..7e945836e12924e9e4a5b89a4edd3331f339710a 100644 (file)
@@ -181,9 +181,7 @@ static struct clk pxa27x_clks[] = {
  * 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_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+enum { 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,
@@ -198,7 +196,7 @@ enum {      SLEEP_SAVE_START = 0,
        SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
        SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
 
-       SLEEP_SAVE_SIZE
+       SLEEP_SAVE_COUNT
 };
 
 void pxa27x_cpu_pm_save(unsigned long *sleep_save)
@@ -251,6 +249,9 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
        /* Clear edge-detect status register. */
        PEDR = 0xDF12FE1B;
 
+       /* Clear reset status */
+       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
        switch (state) {
        case PM_SUSPEND_STANDBY:
                pxa_cpu_standby();
@@ -269,7 +270,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
 }
 
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
-       .save_size      = SLEEP_SAVE_SIZE,
+       .save_count     = SLEEP_SAVE_COUNT,
        .save           = pxa27x_cpu_pm_save,
        .restore        = pxa27x_cpu_pm_restore,
        .valid          = pxa27x_cpu_pm_valid,
index b6a6f5fcc77ad56158bbd01b061c973ca4700285..644550bfa330fb8607dc89e3f192f864f5adc95a 100644 (file)
@@ -256,12 +256,11 @@ static unsigned long wakeup_src;
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
 
-enum { SLEEP_SAVE_START = 0,
-       SLEEP_SAVE_CKENA,
+enum { SLEEP_SAVE_CKENA,
        SLEEP_SAVE_CKENB,
        SLEEP_SAVE_ACCR,
 
-       SLEEP_SAVE_SIZE,
+       SLEEP_SAVE_COUNT,
 };
 
 static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
@@ -376,7 +375,7 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state)
 }
 
 static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
-       .save_size      = SLEEP_SAVE_SIZE,
+       .save_count     = SLEEP_SAVE_COUNT,
        .save           = pxa3xx_cpu_pm_save,
        .restore        = pxa3xx_cpu_pm_restore,
        .valid          = pxa3xx_cpu_pm_valid,
index 62a02c3927c576e26d0dd016c3518882a5e0778f..e7d0fcd9b43ffbb2c749fe139b8649090e1e8ada 100644 (file)
@@ -529,8 +529,6 @@ static struct platform_device *devices[] __initdata = {
 
 static void spitz_poweroff(void)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
        GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
 
index 7a7f5f947cc557d2a5b4e81796ab92663a09e252..23f050feb2083d152640c43e9d47f6312235cf65 100644 (file)
@@ -119,9 +119,6 @@ static void spitz_presuspend(void)
        /* nRESET_OUT Disable */
        PSLR |= PSLR_SL_ROD;
 
-       /* Clear reset status */
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
        PCFR = PCFR_GPR_EN | PCFR_OPDE;
 }
index 6458f6d371d966e16399ce61c596df2835f75653..c2cbd66db8147e894b806c9c110996d0996700a6 100644 (file)
@@ -467,8 +467,6 @@ static struct platform_device *devices[] __initdata = {
 
 static void tosa_poweroff(void)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
        pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
        GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
 
index 246c573e7252dc0d833f1325222809bd1782e36d..1693d447a224b6eaf566ae649b9d65082f4656a0 100644 (file)
@@ -43,20 +43,18 @@ extern void sa1100_cpu_resume(void);
  * More ones like CP and general purpose register values are preserved
  * on the stack and then the stack pointer is stored last in sleep.S.
  */
-enum { SLEEP_SAVE_SP = 0,
-
-       SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
+enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
        SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
 
        SLEEP_SAVE_Ser1SDCR0,
 
-       SLEEP_SAVE_SIZE
+       SLEEP_SAVE_COUNT
 };
 
 
 static int sa11x0_pm_enter(suspend_state_t state)
 {
-       unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
+       unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
 
        gpio = GPLR;
 
index d84167fb33b1fa69df54602a925ffc2f573ed008..3ac8d8d781b3837f4ec47653e2b1ce4b98d25dfe 100644 (file)
@@ -411,7 +411,7 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
 
        clk->parent = parent;
 
-       if (clk == &s3c24xx_dclk0)
+       if (clk == &s3c24xx_clkout0)
                mask = S3C2410_MISCCR_CLK0_MASK;
        else {
                source <<= 4;
@@ -437,7 +437,7 @@ struct clk s3c24xx_dclk0 = {
 struct clk s3c24xx_dclk1 = {
        .name           = "dclk1",
        .id             = -1,
-       .ctrlbit        = S3C2410_DCLKCON_DCLK0EN,
+       .ctrlbit        = S3C2410_DCLKCON_DCLK1EN,
        .enable         = s3c24xx_dclk_enable,
        .set_parent     = s3c24xx_dclk_setparent,
        .set_rate       = s3c24xx_set_dclk_rate,
index 8deb6003ee626afb44c14f785c25eea3b239c9f2..8e8911e55c8f27a9a55acfa7025b1d6322aba6b1 100644 (file)
 #include <asm/mman.h>
 #include <asm/uaccess.h>
 
-asmlinkage int sys_pipe(unsigned long __user *filedes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(filedes, fd, sizeof(fd)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                          unsigned long prot, unsigned long flags,
                          unsigned long fd, off_t offset)
index 795d0ac67c2192a93c6fd0404bb3e9fed92c45d7..fd5708523f2e6c1469ae91d5e5acf0985a45f5ba 100644 (file)
@@ -832,6 +832,7 @@ config BANK_0
 config BANK_1
        hex "Bank 1"
        default 0x7BB0
+       default 0x5558 if BF54x
 
 config BANK_2
        hex "Bank 2"
@@ -963,21 +964,22 @@ endchoice
 
 endmenu
 
-if (BF537 || BF533 || BF54x)
-
 menu "CPU Frequency scaling"
 
 source "drivers/cpufreq/Kconfig"
 
-config CPU_FREQ
-       bool
+config CPU_VOLTAGE
+       bool "CPU Voltage scaling"
+       depends on EXPERIMENTAL 
+       depends on CPU_FREQ
        default n
        help
-         If you want to enable this option, you should select the
-         DPMC driver from Character Devices.
-endmenu
+         Say Y here if you want CPU voltage scaling according to the CPU frequency.
+         This option violates the PLL BYPASS recommendation in the Blackfin Processor
+         manuals. There is a theoretical risk that during VDDINT transitions 
+         the PLL may unlock.
 
-endif
+endmenu
 
 source "net/Kconfig"
 
index 721f15f3cebf1915d67f2b83ab46574697517155..881afe9082c76744bd9bdb01cc0bcd564a50f973 100644 (file)
@@ -56,9 +56,6 @@ int main(void)
        /* offsets into the thread struct */
        DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
        DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
-       DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
-       DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
-       DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
        DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
        DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
 
index 5ed47228a39075a284e99801d7c79165f6b7367f..4b03ba025488edd4ec55d0f2cc9c92d3d9c2313b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file contains sequences of code that will be copied to a
- * fixed location, defined in <asm/atomic_seq.h>.  The interrupt
+ * fixed location, defined in <asm/fixed_code.h>.  The interrupt
  * handlers ensure that these sequences appear to be atomic when
  * executed from userspace.
  * These are aligned to 16 bytes, so that we have some space to replace
index 8b9fe29d03f4f4a02c91f3a2585b703bfa7b3bc9..14a42848f37f70d453807bf3cbe7b1a3346e98e1 100644 (file)
@@ -160,6 +160,13 @@ int
 module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                          char *secstrings, struct module *mod)
 {
+       /*
+        * XXX: sechdrs are vmalloced in kernel/module.c
+        * and would be vfreed just after module is loaded,
+        * so we hack to keep the only information we needed
+        * in mod->arch to correctly free L1 I/D sram later.
+        * NOTE: this breaks the semantic of mod->arch structure.
+        */
        Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
        void *dest = NULL;
 
@@ -167,8 +174,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
                    ((strcmp(".text", secstrings + s->sh_name) == 0) &&
                     (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
-                       mod->arch.text_l1 = s;
                        dest = l1_inst_sram_alloc(s->sh_size);
+                       mod->arch.text_l1 = dest;
                        if (dest == NULL) {
                                printk(KERN_ERR
                                       "module %s: L1 instruction memory allocation failed\n",
@@ -182,8 +189,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
                    ((strcmp(".data", secstrings + s->sh_name) == 0) &&
                     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
-                       mod->arch.data_a_l1 = s;
                        dest = l1_data_sram_alloc(s->sh_size);
+                       mod->arch.data_a_l1 = dest;
                        if (dest == NULL) {
                                printk(KERN_ERR
                                        "module %s: L1 data memory allocation failed\n",
@@ -197,8 +204,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
                    ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
                     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
-                       mod->arch.bss_a_l1 = s;
                        dest = l1_data_sram_alloc(s->sh_size);
+                       mod->arch.bss_a_l1 = dest;
                        if (dest == NULL) {
                                printk(KERN_ERR
                                        "module %s: L1 data memory allocation failed\n",
@@ -210,8 +217,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                        s->sh_addr = (unsigned long)dest;
                }
                if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
-                       mod->arch.data_b_l1 = s;
                        dest = l1_data_B_sram_alloc(s->sh_size);
+                       mod->arch.data_b_l1 = dest;
                        if (dest == NULL) {
                                printk(KERN_ERR
                                        "module %s: L1 data memory allocation failed\n",
@@ -223,8 +230,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
                        s->sh_addr = (unsigned long)dest;
                }
                if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
-                       mod->arch.bss_b_l1 = s;
                        dest = l1_data_B_sram_alloc(s->sh_size);
+                       mod->arch.bss_b_l1 = dest;
                        if (dest == NULL) {
                                printk(KERN_ERR
                                        "module %s: L1 data memory allocation failed\n",
@@ -416,14 +423,14 @@ module_finalize(const Elf_Ehdr * hdr,
 
 void module_arch_cleanup(struct module *mod)
 {
-       if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
-               l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
-       if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
-               l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
-       if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
-               l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
-       if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
-               l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
-       if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
-               l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
+       if (mod->arch.text_l1)
+               l1_inst_sram_free((void *)mod->arch.text_l1);
+       if (mod->arch.data_a_l1)
+               l1_data_sram_free((void *)mod->arch.data_a_l1);
+       if (mod->arch.bss_a_l1)
+               l1_data_sram_free((void *)mod->arch.bss_a_l1);
+       if (mod->arch.data_b_l1)
+               l1_data_B_sram_free((void *)mod->arch.data_b_l1);
+       if (mod->arch.bss_b_l1)
+               l1_data_B_sram_free((void *)mod->arch.bss_b_l1);
 }
index be9fdd00d7cb2c55ef0dcd1d83a9c0bb9beb6c85..53c2cd255441ff5a23a55ce9cc8e5702ef1ec966 100644 (file)
@@ -245,7 +245,7 @@ unsigned long get_wchan(struct task_struct *p)
 
 void finish_atomic_sections (struct pt_regs *regs)
 {
-       int __user *up0 = (int __user *)&regs->p0;
+       int __user *up0 = (int __user *)regs->p0;
 
        if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
                return;
index b4f062c172c69042e192b73352c21805ef4a7abe..f51ab088098ec1e16162c2c4a62c4c20a42b4b17 100644 (file)
@@ -185,8 +185,8 @@ void ptrace_disable(struct task_struct *child)
 {
        unsigned long tmp;
        /* make sure the single step bit is not set. */
-       tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-       put_reg(child, PT_SR, tmp);
+       tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
+       put_reg(child, PT_SYSCFG, tmp);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
index cb9d883d493c4b3ad30dbefed9766de9980faf0e..dbc3bbf846be2f4cf7197644fa287c5e9f8ed070 100644 (file)
@@ -42,6 +42,9 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+/* Location of the trace bit in SYSCFG. */
+#define TRACE_BITS 0x0001
+
 struct fdpic_func_descriptor {
        unsigned long   text;
        unsigned long   GOT;
@@ -225,6 +228,16 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
        regs->r1 = (unsigned long)(&frame->info);
        regs->r2 = (unsigned long)(&frame->uc);
 
+       /*
+        * Clear the trace flag when entering the signal handler, but
+        * notify any tracer that was single-stepping it. The tracer
+        * may want to single-step inside the handler too.
+        */
+       if (regs->syscfg & TRACE_BITS) {
+               regs->syscfg &= ~TRACE_BITS;
+               ptrace_notify(SIGTRAP);
+       }
+
        return 0;
 
  give_sigsegv:
index efb7b25a2633be0c0c79971ec89ab3c9101153ed..fce49d7cf0017f0014304f8e715477cb29fa8f6b 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2 * sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 static inline long
 do_mmap2(unsigned long addr, unsigned long len,
index 4482c47c09e5c728891bd453c9a1bfeb8a8823c5..e887efc86c29e8215d544dcba262128b65343008 100644 (file)
@@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
 
 static cycle_t read_cycles(void)
 {
-       return get_cycles();
+       return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 }
 
 unsigned long long sched_clock(void)
@@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
                break;
        }
        case CLOCK_EVT_MODE_ONESHOT:
-               bfin_write_TSCALE(0);
+               bfin_write_TSCALE(TIME_SCALE - 1);
                bfin_write_TCOUNT(0);
                bfin_write_TCNTL(TMPWR | TMREN);
                CSYNC();
@@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
 
 static int __init bfin_clockevent_init(void)
 {
+       unsigned long timer_clk;
+
+       timer_clk = get_cclk() / TIME_SCALE;
+
        setup_irq(IRQ_CORETMR, &bfin_timer_irq);
        bfin_timer_init();
 
-       clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift);
+       clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
        clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
        clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
        clockevents_register_device(&clockevent_bfin);
index 583d53811f0364fb4ae28c3654c5736489e853dd..8aa49f8042289865568d22f4deeade8d18f67ed8 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
 #include <linux/ata_platform.h>
+#include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/sl811.h>
@@ -50,6 +52,7 @@
 #include <asm/reboot.h>
 #include <asm/nand.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -171,6 +174,46 @@ static struct platform_device bf52x_t350mcqb_device = {
 };
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ezkit_partitions[] = {
+       {
+               .name       = "Bootloader",
+               .size       = 0x40000,
+               .offset     = 0,
+       }, {
+               .name       = "Kernel",
+               .size       = 0x1C0000,
+               .offset     = MTDPART_OFS_APPEND,
+       }, {
+               .name       = "RootFS",
+               .size       = MTDPART_SIZ_FULL,
+               .offset     = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data ezkit_flash_data = {
+       .width      = 2,
+       .parts      = ezkit_partitions,
+       .nr_parts   = ARRAY_SIZE(ezkit_partitions),
+};
+
+static struct resource ezkit_flash_resource = {
+       .start = 0x20000000,
+       .end   = 0x203fffff,
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ezkit_flash_device = {
+       .name          = "physmap-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &ezkit_flash_data,
+       },
+       .num_resources = 1,
+       .resource      = &ezkit_flash_resource,
+};
+#endif
+
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
 static struct mtd_partition partition_info[] = {
        {
@@ -420,11 +463,7 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
                .offset = 0,
                .mask_flags = MTD_CAP_ROM
        }, {
-               .name = "kernel",
-               .size = 0xe0000,
-               .offset = MTDPART_OFS_APPEND,
-       }, {
-               .name = "file system",
+               .name = "linux kernel",
                .size = MTDPART_SIZ_FULL,
                .offset = MTDPART_OFS_APPEND,
        }
@@ -434,7 +473,7 @@ static struct flash_platform_data bfin_spi_flash_data = {
        .name = "m25p80",
        .parts = bfin_spi_flash_partitions,
        .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
-       .type = "m25p64",
+       .type = "m25p16",
 };
 
 /* SPI flash chip (m25p64) */
@@ -755,6 +794,24 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
+#ifdef CONFIG_I2C_BOARDINFO
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
+       {
+               I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+               .type = "pcf8574_lcd",
+       },
+#endif
+#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+       {
+               I2C_BOARD_INFO("pcf8574_keypad", 0x27),
+               .type = "pcf8574_keypad",
+               .irq = IRQ_PF8,
+       },
+#endif
+};
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
@@ -839,7 +896,32 @@ static struct platform_device bfin_gpios_device = {
        .resource = &bfin_gpios_resources,
 };
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_100, 400000000),
+       VRPAIR(VLEV_105, 426000000),
+       VRPAIR(VLEV_110, 500000000),
+       VRPAIR(VLEV_115, 533000000),
+       VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
        &bf5xx_nand_device,
 #endif
@@ -921,12 +1003,22 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_device_gpiokeys,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &ezkit_flash_device,
+#endif
+
        &bfin_gpios_device,
 };
 
 static int __init stamp_init(void)
 {
        printk(KERN_INFO "%s(): registering device resources\n", __func__);
+
+#ifdef CONFIG_I2C_BOARDINFO
+       i2c_register_board_info(0, bfin_i2c_board_info,
+                               ARRAY_SIZE(bfin_i2c_board_info));
+#endif
+
        platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        spi_register_board_info(bfin_spi_board_info,
index a03149c72681adb2fdf9e2f2c29c3ed005c59fc2..ed2b0b8f5dc93f4673accc7013329fa67baaf748 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -341,7 +344,37 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 600000000),
+       VRPAIR(VLEV_125, 600000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *cm_bf533_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
index 08a7943949aef477b5fb2820c6d70d059ded82b3..9d28415163ea67064a1085a0b5c9c63e005a4560 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -350,7 +351,37 @@ static struct platform_device i2c_gpio_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 600000000),
+       VRPAIR(VLEV_125, 600000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
        &smc91x_device,
 #endif
index 024f418ae5430b36951c67072ac312e5c139c58c..7fd35fb32fd52a0206e157893608eab0fd53766b 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -516,7 +517,37 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 600000000),
+       VRPAIR(VLEV_125, 600000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
 #endif
index d8a23cd9b9ed9f860ae22ccfba85ff1d2c4b175f..73f2142875e241d5257c92b860179b33b3207050 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -428,7 +431,37 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 500000000),
+       VRPAIR(VLEV_125, 533000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *cm_bf537_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
        &hitachi_fb_device,
 #endif
index d3727b7c2d7d94da933ec76834c2a2378764b407..9a756d1f3d73f19f52c0688b834952d2baa716f0 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -817,7 +818,37 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 376000000),
+       VRPAIR(VLEV_095, 426000000),
+       VRPAIR(VLEV_100, 426000000),
+       VRPAIR(VLEV_105, 476000000),
+       VRPAIR(VLEV_110, 476000000),
+       VRPAIR(VLEV_115, 476000000),
+       VRPAIR(VLEV_120, 500000000),
+       VRPAIR(VLEV_125, 533000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
        &bfin_pcmcia_cf_device,
 #endif
index e3e8479fffb5bf28731f2ba195ad0e640872a8c0..3b74f96d3590d04a728bf8970dd2199e2799e8d3 100644 (file)
@@ -36,7 +36,9 @@
 #include <linux/spi/flash.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 #include <linux/usb/musb.h>
+#endif
 #include <asm/bfin5xx_spi.h>
 #include <asm/cplb.h>
 #include <asm/dma.h>
@@ -44,6 +46,7 @@
 #include <asm/nand.h>
 #include <asm/portmux.h>
 #include <asm/mach/bf54x_keys.h>
+#include <asm/dpmc.h>
 #include <linux/input.h>
 #include <linux/spi/ad7877.h>
 
@@ -590,7 +593,38 @@ static struct platform_device bfin_device_gpiokeys = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+/*
+ * Internal VLEV BF54XSBBC1533
+ ****temporarily using these values until data sheet is updated
+ */
+       VRPAIR(VLEV_085, 150000000),
+       VRPAIR(VLEV_090, 250000000),
+       VRPAIR(VLEV_110, 276000000),
+       VRPAIR(VLEV_115, 301000000),
+       VRPAIR(VLEV_120, 525000000),
+       VRPAIR(VLEV_125, 550000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *cm_bf548_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
 #endif
index b00f68ac6bc991e972a765fe670bfff67bcc5ea8..d1682bb37509937646237df1bf6fa019995a5400 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/dma.h>
 #include <asm/gpio.h>
 #include <asm/nand.h>
+#include <asm/dpmc.h>
 #include <asm/portmux.h>
 #include <asm/mach/bf54x_keys.h>
 #include <linux/input.h>
@@ -689,7 +690,38 @@ static struct platform_device bfin_gpios_device = {
        .resource = &bfin_gpios_resources,
 };
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+/*
+ * Internal VLEV BF54XSBBC1533
+ ****temporarily using these values until data sheet is updated
+ */
+       VRPAIR(VLEV_085, 150000000),
+       VRPAIR(VLEV_090, 250000000),
+       VRPAIR(VLEV_110, 276000000),
+       VRPAIR(VLEV_115, 301000000),
+       VRPAIR(VLEV_120, 525000000),
+       VRPAIR(VLEV_125, 550000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
 #endif
index 9fd580952fd891cc0a64808f22fdf43fb154473b..466ef5929a254d76d62333fc198554d41245cfd7 100644 (file)
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -339,8 +342,37 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 300000000),
+       VRPAIR(VLEV_095, 313000000),
+       VRPAIR(VLEV_100, 350000000),
+       VRPAIR(VLEV_105, 400000000),
+       VRPAIR(VLEV_110, 444000000),
+       VRPAIR(VLEV_115, 450000000),
+       VRPAIR(VLEV_120, 475000000),
+       VRPAIR(VLEV_125, 500000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *cm_bf561_devices[] __initdata = {
 
+       &bfin_dpmc,
+
 #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
        &hitachi_fb_device,
 #endif
index 0d74b7d99209e7460c5af87f9926d9ea1c32c32e..61d8f7648b247da40f771d252ecfd759c20e29bf 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -443,7 +444,37 @@ static struct platform_device i2c_gpio_device = {
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_085, 250000000),
+       VRPAIR(VLEV_090, 300000000),
+       VRPAIR(VLEV_095, 313000000),
+       VRPAIR(VLEV_100, 350000000),
+       VRPAIR(VLEV_105, 400000000),
+       VRPAIR(VLEV_110, 444000000),
+       VRPAIR(VLEV_115, 450000000),
+       VRPAIR(VLEV_120, 475000000),
+       VRPAIR(VLEV_125, 500000000),
+       VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+       &bfin_dpmc,
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
        &smc91x_device,
 #endif
index 393081e9b6804316b4d61c6d4f25ef9fbe13bb3d..422bfee34adcec22b834a41a36b55f9e3337dffa 100644 (file)
@@ -6,5 +6,6 @@ obj-y := \
        cache.o cacheinit.o entry.o \
        interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o
 
-obj-$(CONFIG_PM)         += pm.o dpmc.o
-obj-$(CONFIG_CPU_FREQ)   += cpufreq.o
+obj-$(CONFIG_PM)          += pm.o dpmc_modes.o
+obj-$(CONFIG_CPU_FREQ)    += cpufreq.o
+obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
index ed81e00d20e172cd8c14e9966d77211fc00f2c49..75cdad291e889be2b3b1a761c6304d9308d46118 100644 (file)
@@ -62,6 +62,14 @@ static struct bfin_dpm_state {
        unsigned int tscale; /* change the divider on the core timer interrupt */
 } dpm_state_table[3];
 
+/*
+   normalized to maximum frequncy offset for CYCLES,
+   used in time-ts cycles clock source, but could be used
+   somewhere also.
+ */
+unsigned long long __bfin_cycles_off;
+unsigned int __bfin_cycles_mod;
+
 /**************************************************************************/
 
 static unsigned int bfin_getfreq(unsigned int cpu)
@@ -80,6 +88,7 @@ static int bfin_target(struct cpufreq_policy *policy,
        unsigned int index, plldiv, tscale;
        unsigned long flags, cclk_hz;
        struct cpufreq_freqs freqs;
+       cycles_t cycles;
 
        if (cpufreq_frequency_table_target(policy, bfin_freq_table,
                 target_freq, relation, &index))
@@ -101,8 +110,14 @@ static int bfin_target(struct cpufreq_policy *policy,
                bfin_write_PLL_DIV(plldiv);
                /* we have to adjust the core timer, because it is using cclk */
                bfin_write_TSCALE(tscale);
+               cycles = get_cycles();
                SSYNC();
+       cycles += 10; /* ~10 cycles we loose after get_cycles() */
+       __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
+       __bfin_cycles_mod = index;
        local_irq_restore(flags);
+       /* TODO: just test case for cycles clock source, remove later */
+       pr_debug("cpufreq: done\n");
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
        return 0;
@@ -119,22 +134,13 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
        unsigned long cclk, sclk, csel, min_cclk;
        int index;
 
-#ifdef CONFIG_CYCLES_CLOCKSOURCE
-/*
- * Clocksource CYCLES is still CONTINUOUS but not longer MONOTONIC in case we enable
- * CPU frequency scaling, since CYCLES runs off Core Clock.
- */
-       printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n"
-               return -ENODEV;
-#endif
-
        if (policy->cpu != 0)
                return -EINVAL;
 
        cclk = get_cclk();
        sclk = get_sclk();
 
-#if ANOMALY_05000273
+#if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE))
        min_cclk = sclk * 2;
 #else
        min_cclk = sclk;
diff --git a/arch/blackfin/mach-common/dpmc.c b/arch/blackfin/mach-common/dpmc.c
new file mode 100644 (file)
index 0000000..02c7efd
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+
+#include <asm/delay.h>
+#include <asm/dpmc.h>
+
+#define DRIVER_NAME "bfin dpmc"
+
+#define dprintk(msg...) \
+       cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg)
+
+struct bfin_dpmc_platform_data *pdata;
+
+/**
+ *     bfin_set_vlev - Update VLEV field in VR_CTL Reg.
+ *                     Avoid BYPASS sequence
+ */
+static void bfin_set_vlev(unsigned int vlev)
+{
+       unsigned pll_lcnt;
+
+       pll_lcnt = bfin_read_PLL_LOCKCNT();
+
+       bfin_write_PLL_LOCKCNT(1);
+       bfin_write_VR_CTL((bfin_read_VR_CTL() & ~VLEV) | vlev);
+       bfin_write_PLL_LOCKCNT(pll_lcnt);
+}
+
+/**
+ *     bfin_get_vlev - Get CPU specific VLEV from platform device data
+ */
+static unsigned int bfin_get_vlev(unsigned int freq)
+{
+       int i;
+
+       if (!pdata)
+               goto err_out;
+
+       freq >>= 16;
+
+       for (i = 0; i < pdata->tabsize; i++)
+               if (freq <= (pdata->tuple_tab[i] & 0xFFFF))
+                       return pdata->tuple_tab[i] >> 16;
+
+err_out:
+       printk(KERN_WARNING "DPMC: No suitable CCLK VDDINT voltage pair found\n");
+       return VLEV_120;
+}
+
+#ifdef CONFIG_CPU_FREQ
+static int
+vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+       struct cpufreq_freqs *freq = data;
+
+       if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) {
+               bfin_set_vlev(bfin_get_vlev(freq->new));
+               udelay(pdata->vr_settling_time); /* Wait until Volatge settled */
+
+       } else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)
+               bfin_set_vlev(bfin_get_vlev(freq->new));
+
+       return 0;
+}
+
+static struct notifier_block vreg_cpufreq_notifier_block = {
+       .notifier_call  = vreg_cpufreq_notifier
+};
+#endif /* CONFIG_CPU_FREQ */
+
+/**
+ *     bfin_dpmc_probe -
+ *
+ */
+static int __devinit bfin_dpmc_probe(struct platform_device *pdev)
+{
+       if (pdev->dev.platform_data)
+               pdata = pdev->dev.platform_data;
+       else
+               return -EINVAL;
+
+       return cpufreq_register_notifier(&vreg_cpufreq_notifier_block,
+                                        CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+/**
+ *     bfin_dpmc_remove -
+ */
+static int __devexit bfin_dpmc_remove(struct platform_device *pdev)
+{
+       pdata = NULL;
+       return cpufreq_unregister_notifier(&vreg_cpufreq_notifier_block,
+                                        CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+struct platform_driver bfin_dpmc_device_driver = {
+       .probe   = bfin_dpmc_probe,
+       .remove  = __devexit_p(bfin_dpmc_remove),
+       .driver  = {
+               .name = DRIVER_NAME,
+       }
+};
+
+/**
+ *     bfin_dpmc_init - Init driver
+ */
+static int __init bfin_dpmc_init(void)
+{
+       return platform_driver_register(&bfin_dpmc_device_driver);
+}
+module_init(bfin_dpmc_init);
+
+/**
+ *     bfin_dpmc_exit - break down driver
+ */
+static void __exit bfin_dpmc_exit(void)
+{
+       platform_driver_unregister(&bfin_dpmc_device_driver);
+}
+module_exit(bfin_dpmc_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("cpu power management driver for Blackfin");
+MODULE_LICENSE("GPL");
similarity index 82%
rename from arch/blackfin/mach-common/dpmc.S
rename to arch/blackfin/mach-common/dpmc_modes.S
index 9d45aa3265b19a399e403045c1cda8ad3cac5130..b7981d31c39212b42ea0d1ce56017e9a1867cb43 100644 (file)
@@ -1,30 +1,7 @@
 /*
- * File:         arch/blackfin/mach-common/dpmc.S
- * Based on:
- * Author:       LG Soft India
+ * Copyright 2004-2008 Analog Devices Inc.
  *
- * Created:      ?
- * Description:  Watchdog Timer APIs
- *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * 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, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/linkage.h>
index f2fb87e9a46e29edfb5f04f2190ff337717e35da..038f70e0be65cb4adcb1ada19b07f6d75eba7d8b 100644 (file)
@@ -151,26 +151,62 @@ ENTRY(_ex_soft_bp)
 ENDPROC(_ex_soft_bp)
 
 ENTRY(_ex_single_step)
+       /* If we just returned from an interrupt, the single step event is
+          for the RTI instruction.  */
        r7 = retx;
        r6 = reti;
        cc = r7 == r6;
-       if cc jump _bfin_return_from_exception
-       r7 = syscfg;
-       bitclr (r7, 0);
-       syscfg = R7;
+       if cc jump _bfin_return_from_exception;
 
+       /* If we were in user mode, do the single step normally.  */
        p5.l = lo(IPEND);
        p5.h = hi(IPEND);
        r6 = [p5];
-       cc = bittst(r6, 5);
-       if !cc jump _ex_trap_c;
-       p4.l = lo(EVT5);
-       p4.h = hi(EVT5);
-       r6.h = _exception_to_level5;
-       r6.l = _exception_to_level5;
-       r7 = [p4];
-       cc = r6 == r7;
-       if !cc jump _ex_trap_c;
+       r7 = 0xffe0 (z);
+       r7 = r7 & r6;
+       cc = r7 == 0;
+       if !cc jump 1f;
+
+       /* Single stepping only a single instruction, so clear the trace
+        * bit here.  */
+       r7 = syscfg;
+       bitclr (r7, 0);
+       syscfg = R7;
+       jump _ex_trap_c;
+
+1:
+       /*
+        * We were in an interrupt handler.  By convention, all of them save
+        * SYSCFG with their first instruction, so by checking whether our
+        * RETX points at the entry point, we can determine whether to allow
+        * a single step, or whether to clear SYSCFG.
+        *
+        * First, find out the interrupt level and the event vector for it.
+        */
+       p5.l = lo(EVT0);
+       p5.h = hi(EVT0);
+       p5 += -4;
+2:
+       r7 = rot r7 by -1;
+       p5 += 4;
+       if !cc jump 2b;
+
+       /* What we actually do is test for the _second_ instruction in the
+        * IRQ handler.  That way, if there are insns following the restore
+        * of SYSCFG after leaving the handler, we will not turn off SYSCFG
+        * for them.  */
+
+       r7 = [p5];
+       r7 += 2;
+       r6 = RETX;
+       cc = R7 == R6;
+       if !cc jump _bfin_return_from_exception;
+
+       r7 = syscfg;
+       bitclr (r7, 0);
+       syscfg = R7;
+
+       /* Fall through to _bfin_return_from_exception.  */
 ENDPROC(_ex_single_step)
 
 ENTRY(_bfin_return_from_exception)
@@ -234,20 +270,26 @@ ENTRY(_ex_trap_c)
        p5.l = _saved_icplb_fault_addr;
        [p5] = r7;
 
-       p4.l = __retx;
-       p4.h = __retx;
+       p4.l = _excpt_saved_stuff;
+       p4.h = _excpt_saved_stuff;
+
        r6 = retx;
        [p4] = r6;
-       p4.l = lo(SAFE_USER_INSTRUCTION);
-       p4.h = hi(SAFE_USER_INSTRUCTION);
-       retx = p4;
+
+       r6 = SYSCFG;
+       [p4 + 4] = r6;
+       BITCLR(r6, 0);
+       SYSCFG = r6;
 
        /* Disable all interrupts, but make sure level 5 is enabled so
         * we can switch to that level.  Save the old mask.  */
        cli r6;
-       p4.l = _excpt_saved_imask;
-       p4.h = _excpt_saved_imask;
-       [p4] = r6;
+       [p4 + 8] = r6;
+
+       p4.l = lo(SAFE_USER_INSTRUCTION);
+       p4.h = hi(SAFE_USER_INSTRUCTION);
+       retx = p4;
+
        r6 = 0x3f;
        sti r6;
 
@@ -295,6 +337,11 @@ ENTRY(_double_fault)
          */
         SAVE_ALL_SYS
 
+       /* The dumping functions expect the return address in the RETI
+        * slot.  */
+       r6 = retx;
+       [sp + PT_PC] = r6;
+
         r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
         SP += -12;
         call _double_fault_c;
@@ -307,16 +354,17 @@ ENDPROC(_double_fault)
 ENTRY(_exception_to_level5)
        SAVE_ALL_SYS
 
-       p4.l = __retx;
-       p4.h = __retx;
+       p4.l = _excpt_saved_stuff;
+       p4.h = _excpt_saved_stuff;
        r6 = [p4];
        [sp + PT_PC] = r6;
 
+       r6 = [p4 + 4];
+       [sp + PT_SYSCFG] = r6;
+
        /* Restore interrupt mask.  We haven't pushed RETI, so this
         * doesn't enable interrupts until we return from this handler.  */
-       p4.l = _excpt_saved_imask;
-       p4.h = _excpt_saved_imask;
-       r6 = [p4];
+       r6 = [p4 + 8];
        sti r6;
 
        /* Restore the hardware error vector.  */
@@ -1344,7 +1392,14 @@ ENTRY(_sys_call_table)
        .rept NR_syscalls-(.-_sys_call_table)/4
        .long _sys_ni_syscall
        .endr
-_excpt_saved_imask:
+
+       /*
+        * Used to save the real RETX, IMASK and SYSCFG when temporarily
+        * storing safe values across the transition from exception to IRQ5.
+        */
+_excpt_saved_stuff:
+       .long 0;
+       .long 0;
        .long 0;
 
 _exception_stack:
@@ -1358,7 +1413,3 @@ _exception_stack_top:
 _last_cplb_fault_retx:
        .long 0;
 #endif
-       /* Used to save the real RETX when temporarily storing a safe
-        * return address.  */
-__retx:
-       .long 0;
index 8b9984197edcc57878356a56848c237ea06aa109..a79fbd87021b02cf03663f7a06d680a58a24ceac 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user * fildes)
-{
-        int fd[2];
-        int error;
-
-        lock_kernel();
-        error = do_pipe(fd);
-        unlock_kernel();
-        if (!error) {
-                if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                        error = -EFAULT;
-        }
-        return error;
-}
-
 /* common code for old and new mmaps */
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
index 04c6b1677ccf7eb49d5eea003979c6c223e6d00d..49b2cf2c38f3d313e9136dfdeaf84ef675b7b53f 100644 (file)
 #include <asm/setup.h>
 #include <asm/uaccess.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage long sys_pipe(unsigned long __user * fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                          unsigned long prot, unsigned long flags,
                          unsigned long fd, unsigned long pgoff)
index fb8b1d860f46b1f71e60684534c38aa16f2812c6..1bca5ab8a6ab085aa35fdb1c14574b7dc2adb7a7 100644 (file)
@@ -6,4 +6,4 @@ obj-y := init.o kmap.o
 
 obj-$(CONFIG_MMU) += \
        pgalloc.o highmem.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \
-       mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o
+       mmu-context.o dma-alloc.o elf-fdpic.o
index 00608be6d56772cb0ece55d72b7ff5dab9440352..2745656dcc52c8ac6ad7f3c804e81c4fb3dd91ce 100644 (file)
 #include <asm/traps.h>
 #include <asm/unistd.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long * fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 static inline long do_mmap2(
        unsigned long addr, unsigned long len,
index 256a7faeda0787fc7ba6df9f48d0899dc0add99a..b763ca19ef173f26a642910124cbf30f30b3ad43 100644 (file)
@@ -463,7 +463,7 @@ sys32_sigsuspend (int history0, int history1, old_sigset_t mask)
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
-       set_thread_flag(TIF_RESTORE_SIGMASK);
+       set_restore_sigmask();
        return -ERESTARTNOHAND;
 }
 
index c7467f863c7af5c99312767f8f176628568ab96f..19709a0796351e408a30fcd74ebc3a6ac92ec279 100644 (file)
@@ -966,7 +966,7 @@ acpi_map_iosapics (void)
 fs_initcall(acpi_map_iosapics);
 #endif                         /* CONFIG_ACPI_NUMA */
 
-int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+int __ref acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
 {
        int err;
 
index 6dee579f205fc451bcffbcbaddd0c370b6d35104..7fd18f54c0568980238cc75a7810ea51de4a4308 100644 (file)
@@ -183,10 +183,10 @@ void fixup_irqs(void)
 {
        unsigned int irq;
        extern void ia64_process_pending_intr(void);
-       extern void ia64_disable_timer(void);
        extern volatile int time_keeper_id;
 
-       ia64_disable_timer();
+       /* Mask ITV to disable timer */
+       ia64_set_itv(1 << 16);
 
        /*
         * Find a new timesync master
index 396004e8cd1432af8fa1440ea0e2b93c385175bd..4547a2092af9d4717273883247b6e854749c819d 100644 (file)
@@ -1053,7 +1053,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb,
        return NOTIFY_OK;
 }
 
-static struct notifier_block palinfo_cpu_notifier __cpuinitdata =
+static struct notifier_block __refdata palinfo_cpu_notifier =
 {
        .notifier_call = palinfo_cpu_callback,
        .priority = 0,
index 7fbb51e10bbe04e70c2cc66570400f3569f3804c..c1ad27de2dd2080e0bdea8a845147fcc6f855dba 100644 (file)
@@ -867,7 +867,7 @@ pfm_rvfree(void *mem, unsigned long size)
 }
 
 static pfm_context_t *
-pfm_context_alloc(void)
+pfm_context_alloc(int ctx_flags)
 {
        pfm_context_t *ctx;
 
@@ -878,6 +878,46 @@ pfm_context_alloc(void)
        ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL);
        if (ctx) {
                DPRINT(("alloc ctx @%p\n", ctx));
+
+               /*
+                * init context protection lock
+                */
+               spin_lock_init(&ctx->ctx_lock);
+
+               /*
+                * context is unloaded
+                */
+               ctx->ctx_state = PFM_CTX_UNLOADED;
+
+               /*
+                * initialization of context's flags
+                */
+               ctx->ctx_fl_block       = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
+               ctx->ctx_fl_system      = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
+               ctx->ctx_fl_no_msg      = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
+               /*
+                * will move to set properties
+                * ctx->ctx_fl_excl_idle   = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
+                */
+
+               /*
+                * init restart semaphore to locked
+                */
+               init_completion(&ctx->ctx_restart_done);
+
+               /*
+                * activation is used in SMP only
+                */
+               ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+               SET_LAST_CPU(ctx, -1);
+
+               /*
+                * initialize notification message queue
+                */
+               ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
+               init_waitqueue_head(&ctx->ctx_msgq_wait);
+               init_waitqueue_head(&ctx->ctx_zombieq);
+
        }
        return ctx;
 }
@@ -2165,28 +2205,21 @@ static struct dentry_operations pfmfs_dentry_operations = {
 };
 
 
-static int
-pfm_alloc_fd(struct file **cfile)
+static struct file *
+pfm_alloc_file(pfm_context_t *ctx)
 {
-       int fd, ret = 0;
-       struct file *file = NULL;
-       struct inode * inode;
+       struct file *file;
+       struct inode *inode;
+       struct dentry *dentry;
        char name[32];
        struct qstr this;
 
-       fd = get_unused_fd();
-       if (fd < 0) return -ENFILE;
-
-       ret = -ENFILE;
-
-       file = get_empty_filp();
-       if (!file) goto out;
-
        /*
         * allocate a new inode
         */
        inode = new_inode(pfmfs_mnt->mnt_sb);
-       if (!inode) goto out;
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
 
        DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
 
@@ -2199,59 +2232,28 @@ pfm_alloc_fd(struct file **cfile)
        this.len  = strlen(name);
        this.hash = inode->i_ino;
 
-       ret = -ENOMEM;
-
        /*
         * allocate a new dcache entry
         */
-       file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
-       if (!file->f_path.dentry) goto out;
+       dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
+       if (!dentry) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
 
-       file->f_path.dentry->d_op = &pfmfs_dentry_operations;
+       dentry->d_op = &pfmfs_dentry_operations;
+       d_add(dentry, inode);
 
-       d_add(file->f_path.dentry, inode);
-       file->f_path.mnt = mntget(pfmfs_mnt);
-       file->f_mapping = inode->i_mapping;
+       file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops);
+       if (!file) {
+               dput(dentry);
+               return ERR_PTR(-ENFILE);
+       }
 
-       file->f_op    = &pfm_file_ops;
-       file->f_mode  = FMODE_READ;
        file->f_flags = O_RDONLY;
-       file->f_pos   = 0;
-
-       /*
-        * may have to delay until context is attached?
-        */
-       fd_install(fd, file);
-
-       /*
-        * the file structure we will use
-        */
-       *cfile = file;
-
-       return fd;
-out:
-       if (file) put_filp(file);
-       put_unused_fd(fd);
-       return ret;
-}
-
-static void
-pfm_free_fd(int fd, struct file *file)
-{
-       struct files_struct *files = current->files;
-       struct fdtable *fdt;
+       file->private_data = ctx;
 
-       /* 
-        * there ie no fd_uninstall(), so we do it here
-        */
-       spin_lock(&files->file_lock);
-       fdt = files_fdtable(files);
-       rcu_assign_pointer(fdt->fd[fd], NULL);
-       spin_unlock(&files->file_lock);
-
-       if (file)
-               put_filp(file);
-       put_unused_fd(fd);
+       return file;
 }
 
 static int
@@ -2475,6 +2477,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
 
        /* link buffer format and context */
        ctx->ctx_buf_fmt = fmt;
+       ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */
 
        /*
         * check if buffer format wants to use perfmon buffer allocation/mapping service
@@ -2669,78 +2672,45 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
 {
        pfarg_context_t *req = (pfarg_context_t *)arg;
        struct file *filp;
+       struct path path;
        int ctx_flags;
+       int fd;
        int ret;
 
        /* let's check the arguments first */
        ret = pfarg_is_sane(current, req);
-       if (ret < 0) return ret;
+       if (ret < 0)
+               return ret;
 
        ctx_flags = req->ctx_flags;
 
        ret = -ENOMEM;
 
-       ctx = pfm_context_alloc();
-       if (!ctx) goto error;
+       fd = get_unused_fd();
+       if (fd < 0)
+               return fd;
 
-       ret = pfm_alloc_fd(&filp);
-       if (ret < 0) goto error_file;
+       ctx = pfm_context_alloc(ctx_flags);
+       if (!ctx)
+               goto error;
 
-       req->ctx_fd = ctx->ctx_fd = ret;
+       filp = pfm_alloc_file(ctx);
+       if (IS_ERR(filp)) {
+               ret = PTR_ERR(filp);
+               goto error_file;
+       }
 
-       /*
-        * attach context to file
-        */
-       filp->private_data = ctx;
+       req->ctx_fd = ctx->ctx_fd = fd;
 
        /*
         * does the user want to sample?
         */
        if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) {
                ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req);
-               if (ret) goto buffer_error;
+               if (ret)
+                       goto buffer_error;
        }
 
-       /*
-        * init context protection lock
-        */
-       spin_lock_init(&ctx->ctx_lock);
-
-       /*
-        * context is unloaded
-        */
-       ctx->ctx_state = PFM_CTX_UNLOADED;
-
-       /*
-        * initialization of context's flags
-        */
-       ctx->ctx_fl_block       = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
-       ctx->ctx_fl_system      = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
-       ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */
-       ctx->ctx_fl_no_msg      = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
-       /*
-        * will move to set properties
-        * ctx->ctx_fl_excl_idle   = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
-        */
-
-       /*
-        * init restart semaphore to locked
-        */
-       init_completion(&ctx->ctx_restart_done);
-
-       /*
-        * activation is used in SMP only
-        */
-       ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
-       SET_LAST_CPU(ctx, -1);
-
-       /*
-        * initialize notification message queue
-        */
-       ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
-       init_waitqueue_head(&ctx->ctx_msgq_wait);
-       init_waitqueue_head(&ctx->ctx_zombieq);
-
        DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n",
                ctx,
                ctx_flags,
@@ -2755,10 +2725,14 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
         */
        pfm_reset_pmu_state(ctx);
 
+       fd_install(fd, filp);
+
        return 0;
 
 buffer_error:
-       pfm_free_fd(ctx->ctx_fd, filp);
+       path = filp->f_path;
+       put_filp(filp);
+       path_put(&path);
 
        if (ctx->ctx_buf_fmt) {
                pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs);
@@ -2767,6 +2741,7 @@ error_file:
        pfm_context_free(ctx);
 
 error:
+       put_unused_fd(fd);
        return ret;
 }
 
index 5740296c35afa3d597e8fd041db4385ff628f268..19c5a78636fc92fd78a38642063107da1895bd59 100644 (file)
@@ -464,7 +464,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
        if (!user_mode(&scr->pt))
                return;
 
-       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+       if (current_thread_info()->status & TS_RESTORE_SIGMASK)
                oldset = &current->saved_sigmask;
        else
                oldset = &current->blocked;
@@ -530,12 +530,13 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
                 * continue to iterate in this loop so we can deliver the SIGSEGV...
                 */
                if (handle_signal(signr, &ka, &info, oldset, scr)) {
-                       /* a signal was successfully delivered; the saved
+                       /*
+                        * A signal was successfully delivered; the saved
                         * sigmask will have been stored in the signal frame,
                         * and will be restored by sigreturn, so we can simply
-                        * clear the TIF_RESTORE_SIGMASK flag */
-                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+                        * clear the TS_RESTORE_SIGMASK flag.
+                        */
+                       current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
                        return;
                }
        }
@@ -566,8 +567,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 
        /* if there's no signal to deliver, we just put the saved sigmask
         * back */
-       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-               clear_thread_flag(TIF_RESTORE_SIGMASK);
+       if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+               current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
                sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
        }
 }
index 9a9d4c4893305848dc91ded242577d55ff3ef13a..983296f1c813a3baeb34435258b9ff8af737a172 100644 (file)
@@ -98,8 +98,33 @@ unlock_ipi_calllock(void)
        spin_unlock_irq(&call_lock);
 }
 
+static inline void
+handle_call_data(void)
+{
+       struct call_data_struct *data;
+       void (*func)(void *info);
+       void *info;
+       int wait;
+
+       /* release the 'pointer lock' */
+       data = (struct call_data_struct *)call_data;
+       func = data->func;
+       info = data->info;
+       wait = data->wait;
+
+       mb();
+       atomic_inc(&data->started);
+       /* At this point the structure may be gone unless wait is true. */
+       (*func)(info);
+
+       /* Notify the sending CPU that the task is done. */
+       mb();
+       if (wait)
+               atomic_inc(&data->finished);
+}
+
 static void
-stop_this_cpu (void)
+stop_this_cpu(void)
 {
        /*
         * Remove this CPU:
@@ -138,44 +163,21 @@ handle_IPI (int irq, void *dev_id)
                        ops &= ~(1 << which);
 
                        switch (which) {
-                             case IPI_CALL_FUNC:
-                             {
-                                     struct call_data_struct *data;
-                                     void (*func)(void *info);
-                                     void *info;
-                                     int wait;
-
-                                     /* release the 'pointer lock' */
-                                     data = (struct call_data_struct *) call_data;
-                                     func = data->func;
-                                     info = data->info;
-                                     wait = data->wait;
-
-                                     mb();
-                                     atomic_inc(&data->started);
-                                     /*
-                                      * At this point the structure may be gone unless
-                                      * wait is true.
-                                      */
-                                     (*func)(info);
-
-                                     /* Notify the sending CPU that the task is done.  */
-                                     mb();
-                                     if (wait)
-                                             atomic_inc(&data->finished);
-                             }
-                             break;
-
-                             case IPI_CPU_STOP:
+                       case IPI_CALL_FUNC:
+                               handle_call_data();
+                               break;
+
+                       case IPI_CPU_STOP:
                                stop_this_cpu();
                                break;
 #ifdef CONFIG_KEXEC
-                             case IPI_KDUMP_CPU_STOP:
+                       case IPI_KDUMP_CPU_STOP:
                                unw_init_running(kdump_cpu_freeze, NULL);
                                break;
 #endif
-                             default:
-                               printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
+                       default:
+                               printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n",
+                                               this_cpu, which);
                                break;
                        }
                } while (ops);
index 48e15a51782f617fae2c1fbc6f8964d70ccb870c..8c73643f2d664a5d9f8dd103ed67e5e5bbf037d4 100644 (file)
@@ -379,11 +379,6 @@ static struct irqaction timer_irqaction = {
        .name =         "timer"
 };
 
-void __devinit ia64_disable_timer(void)
-{
-       ia64_set_itv(1 << 16);
-}
-
 void __init
 time_init (void)
 {
index abb17a613b172f2feac86f38981c255d226864ac..26228e2d01ae472bcab1e5917b0c973d826f6f3a 100644 (file)
@@ -36,9 +36,11 @@ void arch_fix_phys_package_id(int num, u32 slot)
 }
 EXPORT_SYMBOL_GPL(arch_fix_phys_package_id);
 
-int arch_register_cpu(int num)
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __ref arch_register_cpu(int num)
 {
-#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
+#ifdef CONFIG_ACPI
        /*
         * If CPEI can be re-targetted or if this is not
         * CPEI target, then it is hotpluggable
@@ -47,19 +49,21 @@ int arch_register_cpu(int num)
                sysfs_cpus[num].cpu.hotpluggable = 1;
        map_cpu_to_node(num, node_cpuid[num].nid);
 #endif
-
        return register_cpu(&sysfs_cpus[num].cpu, num);
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
+EXPORT_SYMBOL(arch_register_cpu);
 
 void arch_unregister_cpu(int num)
 {
        unregister_cpu(&sysfs_cpus[num].cpu);
        unmap_cpu_from_node(num, cpu_to_node(num));
 }
-EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
+#else
+static int __init arch_register_cpu(int num)
+{
+       return register_cpu(&sysfs_cpus[num].cpu, num);
+}
 #endif /*CONFIG_HOTPLUG_CPU*/
 
 
index 6df0732401353f56524d1ee1d60ef2a9358bae8d..318b811006236fe08b7508e3a16f6ccaa326a28d 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * kvm_ia64.c: Basic KVM suppport On Itanium series processors
  *
@@ -431,7 +430,7 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
        if (itc_diff < 0)
                itc_diff = -itc_diff;
 
-       expires = div64_64(itc_diff, cyc_per_usec);
+       expires = div64_u64(itc_diff, cyc_per_usec);
        kt = ktime_set(0, 1000 * expires);
        vcpu->arch.ht_active = 1;
        hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS);
index 4072a07ebf8e301af8fa34fa788e5c5ece63eccb..469766b24e2286ca3495b39a9dbf194dd83ca423 100644 (file)
@@ -5,6 +5,8 @@
 # architecture-specific flags and dependencies.
 #
 
+KBUILD_DEFCONFIG := m32700ut.smp_defconfig
+
 LDFLAGS                :=
 OBJCOPYFLAGS   := -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux        :=
diff --git a/arch/m32r/defconfig b/arch/m32r/defconfig
deleted file mode 100644 (file)
index af3b981..0000000
+++ /dev/null
@@ -1,863 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc1
-# Wed Aug  1 17:22:35 2007
-#
-CONFIG_M32R=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_NO_IOPORT=y
-CONFIG_NO_DMA=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS 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=15
-# CONFIG_CPUSETS is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
-# CONFIG_EPOLL is not set
-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_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-# CONFIG_BLK_DEV_BSG is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-
-#
-# Processor type and features
-#
-# CONFIG_PLAT_MAPPI is not set
-# CONFIG_PLAT_USRV is not set
-CONFIG_PLAT_M32700UT=y
-# CONFIG_PLAT_OPSPUT is not set
-# CONFIG_PLAT_OAKS32R is not set
-# CONFIG_PLAT_MAPPI2 is not set
-# CONFIG_PLAT_MAPPI3 is not set
-# CONFIG_PLAT_M32104UT is not set
-CONFIG_CHIP_M32700=y
-# CONFIG_CHIP_M32102 is not set
-# CONFIG_CHIP_M32104 is not set
-# CONFIG_CHIP_VDEC2 is not set
-# CONFIG_CHIP_OPSP is not set
-CONFIG_MMU=y
-CONFIG_TLB_ENTRIES=32
-CONFIG_ISA_M32R2=y
-CONFIG_ISA_DSP_LEVEL2=y
-CONFIG_ISA_DUAL_ISSUE=y
-CONFIG_BUS_CLOCK=50000000
-CONFIG_TIMER_DIVIDE=128
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_MEMORY_START=0x08000000
-CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_NOHIGHMEM=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_FLATMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM_MANUAL=y
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_NEED_MULTIPLE_NODES=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_IRAM_START=0x00f00000
-CONFIG_IRAM_SIZE=0x00080000
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_PREEMPT=y
-CONFIG_SMP=y
-# CONFIG_CHIP_M32700_TS1 is not set
-CONFIG_NR_CPUS=2
-CONFIG_NODES_SHIFT=1
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_ISA is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# 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 is not set
-# 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 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 is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-# CONFIG_MTD_CHAR is not set
-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=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-# CONFIG_MTD_CFI_NOSWAP is not set
-CONFIG_MTD_CFI_BE_BYTE_SWAP=y
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-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 is not set
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_OTP is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=m
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=m
-# 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_PHYSMAP 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 is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-CONFIG_ATA_OVER_ETH=m
-CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-# 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_LIBSAS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
-# 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_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_SMC91X=y
-# CONFIG_NE2000 is not set
-CONFIG_NETDEV_1000=y
-CONFIG_NETDEV_10000=y
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 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
-# CONFIG_ISDN is not set
-# CONFIG_PHONE 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 is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-# 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_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_M32R_SIO=y
-CONFIG_SERIAL_M32R_SIO_CONSOLE=y
-CONFIG_SERIAL_M32R_PLDSIO=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_RTC is not set
-CONFIG_DS1302=y
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-CONFIG_VIDEO_V4L2=y
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_CPIA is not set
-CONFIG_VIDEO_M32R_AR=m
-CONFIG_VIDEO_M32R_AR_M64278=m
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
-
-#
-# Graphics support
-#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-# 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=y
-# 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_DETECT_PRIMARY is not set
-# 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
-CONFIG_LOGO_M32R_CLUT224=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-# CONFIG_MMC_UNSAFE_RESUME is not set
-
-#
-# MMC/SD Card Drivers
-#
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_BOUNCE=y
-
-#
-# MMC/SD Host Controller Drivers
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
-# CONFIG_UIO is not set
-
-#
-# 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=y
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR 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=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-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_KCORE=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 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 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
-
-#
-# 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 is not set
-# 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 is not set
-# 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 is not set
-
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_FRAME_POINTER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_CRYPTO is not set
-
-#
-# 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_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_HAS_IOMEM=y
index 6d7a80fdad488676b8e69c43b0db180e68baf823..305ac852bbed417dda77de7a9b100c6a401bc75d 100644 (file)
@@ -76,26 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
        return oldval;
 }
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int
-sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2,
-       unsigned long r3, unsigned long r4, unsigned long r5,
-       unsigned long r6, struct pt_regs regs)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user((void __user *)r0, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags,
        unsigned long fd, unsigned long pgoff)
index 41b07854fcc609c5d12c2254e1e09a807f1e9417..15a6f36c06db9c7c84db8d4698339f3f8d9ba413 100644 (file)
@@ -60,9 +60,6 @@ SECTIONS
   . = ALIGN(4096);
   __nosave_end = .;
 
-  . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
-
   . = ALIGN(32);
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
 
index e892f17ba3fac4984a84bbdd7d5e501cab80fe90..7f54efaf60bb12a0b980a0e05c3ae908f322e6d0 100644 (file)
 #include <asm/page.h>
 #include <asm/unistd.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user * fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 static inline long do_mmap2(
        unsigned long addr, unsigned long len,
index fd4858e2dd638d456636dee4dcdc9b9134c34b3c..75b8340b254be08caa07f9e29eac3cbb5e5f0161 100644 (file)
@@ -468,15 +468,26 @@ static inline void access_error040(struct frame *fp)
                         * (if do_page_fault didn't fix the mapping,
                          * the writeback won't do good)
                         */
+disable_wb:
 #ifdef DEBUG
                        printk(".. disabling wb2\n");
 #endif
                        if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
                                fp->un.fmt7.wb2s &= ~WBV_040;
+                       if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
+                               fp->un.fmt7.wb3s &= ~WBV_040;
                }
-       } else if (send_fault_sig(&fp->ptregs) > 0) {
-               printk("68040 access error, ssw=%x\n", ssw);
-               trap_c(fp);
+       } else {
+               /* In case of a bus error we either kill the process or expect
+                * the kernel to catch the fault, which then is also responsible
+                * for cleaning up the mess.
+                */
+               current->thread.signo = SIGBUS;
+               current->thread.faddr = fp->un.fmt7.faddr;
+               if (send_fault_sig(&fp->ptregs) >= 0)
+                       printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
+                              fp->un.fmt7.faddr);
+               goto disable_wb;
        }
 
        do_040writebacks(fp);
index 735a49b4b9366b0345db8cc954a824e4b0ff5cb1..ad3e3bacae39e6ee3960c2a492c8d532b2484f30 100644 (file)
@@ -48,9 +48,6 @@
 struct mac_booter_data mac_bi_data;
 int mac_bisize = sizeof mac_bi_data;
 
-struct mac_hw_present mac_hw_present;
-EXPORT_SYMBOL(mac_hw_present);
-
 /* New m68k bootinfo stuff and videobase */
 
 extern int m68k_num_memory;
@@ -817,27 +814,6 @@ void __init mac_identify(void)
                m68k_ramdisk.addr, m68k_ramdisk.size);
 #endif
 
-       /*
-        * TODO: set the various fields in macintosh_config->hw_present here!
-        */
-       switch (macintosh_config->scsi_type) {
-       case MAC_SCSI_OLD:
-               MACHW_SET(MAC_SCSI_80);
-               break;
-       case MAC_SCSI_QUADRA:
-       case MAC_SCSI_QUADRA2:
-       case MAC_SCSI_QUADRA3:
-               MACHW_SET(MAC_SCSI_96);
-               if ((macintosh_config->ident == MAC_MODEL_Q900) ||
-                   (macintosh_config->ident == MAC_MODEL_Q950))
-                       MACHW_SET(MAC_SCSI_96_2);
-               break;
-       default:
-               printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n");
-               MACHW_SET(MAC_SCSI_80);
-               break;
-       }
-
        iop_init();
        via_init();
        oss_init();
index 07eb4c4bab8243723ead643a13d6f5611a42d032..8e8441587c22bcb566976360ec34e53d6145fcd8 100644 (file)
@@ -671,6 +671,9 @@ config ROMKERNEL
 
 endchoice
 
+if COLDFIRE
+source "kernel/Kconfig.preempt"
+endif
 source "mm/Kconfig"
 
 endmenu
index fd0c685a7f11c13de748a5dc2551b4ee73651aa5..c785d07c02cc249ce8e537f13210b9b3edccdb35 100644 (file)
@@ -87,6 +87,7 @@ int main(void)
        DEFINE(TI_TASK, offsetof(struct thread_info, task));
        DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
        DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 
        return 0;
index 1e7ea6a3e1a146c9a092c33eba6073751f3c0d38..f4782d2dce8f7369fbdaeddd916dc61c57a2afa9 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/segment.h>
 #include <asm/asm-offsets.h>
 #include <asm/entry.h>
+#include <asm/unistd.h>
 
 .text
 
@@ -140,3 +141,11 @@ ENTRY(sys_rt_sigreturn)
        RESTORE_SWITCH_STACK
        rts
 
+ENTRY(ret_from_user_signal)
+       moveq #__NR_sigreturn,%d0
+       trap #0
+
+ENTRY(ret_from_user_rt_signal)
+       move #__NR_rt_sigreturn,%d0
+       trap #0
+
index d6f0200316febaa7f8f1fb76c09c0b96e91b0ad1..03f4fe6a2fc0e20e6e28f233cb8718a4799dd9b6 100644 (file)
@@ -162,7 +162,7 @@ void __init setup_arch(char **cmdline_p)
        printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
 #endif
 #ifdef CONFIG_M5235EVB
-       printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)");
+       printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
 #endif
 
 #ifdef DEBUG
index 70371378db868de2ce8cabf544993e44d4ef8aa2..bbfcae9e52b4b56ff76932e004e58916c8e12d64 100644 (file)
@@ -51,6 +51,8 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+void ret_from_user_signal(void);
+void ret_from_user_rt_signal(void);
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
 /*
@@ -539,10 +541,6 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
        return err;
 }
 
-static inline void push_cache (unsigned long vaddr)
-{
-}
-
 static inline void *
 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 {
@@ -586,16 +584,11 @@ static void setup_frame (int sig, struct k_sigaction *ka,
        err |= copy_to_user (&frame->sc, &context, sizeof(context));
 
        /* Set up to return from userspace.  */
-       err |= __put_user(frame->retcode, &frame->pretcode);
-       /* moveq #,d0; trap #0 */
-       err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
-                         (long *)(frame->retcode));
+       err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
 
        if (err)
                goto give_sigsegv;
 
-       push_cache ((unsigned long) &frame->retcode);
-
        /* Set up registers for signal handler */
        wrusp ((unsigned long) frame);
        regs->pc = (unsigned long) ka->sa.sa_handler;
@@ -655,17 +648,11 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
 
        /* Set up to return from userspace.  */
-       err |= __put_user(frame->retcode, &frame->pretcode);
-       /* moveq #,d0; notb d0; trap #0 */
-       err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
-                         (long *)(frame->retcode + 0));
-       err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+       err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
 
        if (err)
                goto give_sigsegv;
 
-       push_cache ((unsigned long) &frame->retcode);
-
        /* Set up registers for signal handler */
        wrusp ((unsigned long) frame);
        regs->pc = (unsigned long) ka->sa.sa_handler;
index 65f7a95f056e9726281521b792e5d12a9a9b6282..70028163862981e5ce0f7082a737b97f73f88163 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/unistd.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long * fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 static inline long do_mmap2(
        unsigned long addr, unsigned long len,
index 437a061d8b94a74745f0e7d55cc96c14d9276e08..ec9aea652e79d0665adcb36fe5e9cd49d9625a51 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
+#include <linux/kallsyms.h>
 
 #include <asm/setup.h>
 #include <asm/fpu.h>
@@ -102,56 +103,47 @@ asmlinkage void buserr_c(struct frame *fp)
        force_sig(SIGSEGV, current);
 }
 
-
 int kstack_depth_to_print = 48;
 
-void show_stack(struct task_struct *task, unsigned long *stack)
+static void __show_stack(struct task_struct *task, unsigned long *stack)
 {
        unsigned long *endstack, addr;
-       extern char _start, _etext;
+       unsigned long *last_stack;
        int i;
 
-       if (!stack) {
-               if (task)
-                       stack = (unsigned long *)task->thread.ksp;
-               else
-                       stack = (unsigned long *)&stack;
-       }
+       if (!stack)
+               stack = (unsigned long *)task->thread.ksp;
 
        addr = (unsigned long) stack;
        endstack = (unsigned long *) PAGE_ALIGN(addr);
 
        printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
        for (i = 0; i < kstack_depth_to_print; i++) {
-               if (stack + 1 > endstack)
+               if (stack + 1 + i > endstack)
                        break;
                if (i % 8 == 0)
                        printk("\n" KERN_EMERG "       ");
-               printk(" %08lx", *stack++);
+               printk(" %08lx", *(stack + i));
        }
        printk("\n");
 
-       printk(KERN_EMERG "Call Trace:");
-       i = 0;
-       while (stack + 1 <= endstack) {
-               addr = *stack++;
-               /*
-                * If the address is either in the text segment of the
-                * kernel, or in the region which contains vmalloc'ed
-                * memory, it *may* be the address of a calling
-                * routine; if so, print it so that someone tracing
-                * down the cause of the crash will be able to figure
-                * out the call path that was taken.
-                */
-               if (((addr >= (unsigned long) &_start) &&
-                    (addr <= (unsigned long) &_etext))) {
-                       if (i % 4 == 0)
-                               printk("\n" KERN_EMERG "       ");
-                       printk(" [<%08lx>]", addr);
-                       i++;
-               }
+#ifdef CONFIG_FRAME_POINTER
+       printk(KERN_EMERG "Call Trace:\n");
+
+       last_stack = stack - 1;
+       while (stack <= endstack && stack > last_stack) {
+
+               addr = *(stack + 1);
+               printk(KERN_EMERG " [%08lx] ", addr);
+               print_symbol(KERN_CONT "%s\n", addr);
+
+               last_stack = stack;
+               stack = (unsigned long *)*stack;
        }
        printk("\n");
+#else
+       printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic call trace\n");
+#endif
 }
 
 void bad_super_trap(struct frame *fp)
@@ -298,19 +290,47 @@ asmlinkage void set_esp0(unsigned long ssp)
        current->thread.esp0 = ssp;
 }
 
-
 /*
  * The architecture-independent backtrace generator
  */
 void dump_stack(void)
 {
-       unsigned long stack;
+       /*
+        * We need frame pointers for this little trick, which works as follows:
+        *
+        * +------------+ 0x00
+        * | Next SP    |       -> 0x0c
+        * +------------+ 0x04
+        * | Caller     |
+        * +------------+ 0x08
+        * | Local vars |       -> our stack var
+        * +------------+ 0x0c
+        * | Next SP    |       -> 0x18, that is what we pass to show_stack()
+        * +------------+ 0x10
+        * | Caller     |
+        * +------------+ 0x14
+        * | Local vars |
+        * +------------+ 0x18
+        * | ...        |
+        * +------------+
+        */
 
-       show_stack(current, &stack);
-}
+       unsigned long *stack;
 
+       stack = (unsigned long *)&stack;
+       stack++;
+       __show_stack(current, stack);
+}
 EXPORT_SYMBOL(dump_stack);
 
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+       if (!stack && !task)
+               dump_stack();
+       else
+               __show_stack(task, stack);
+}
+
 #ifdef CONFIG_M68KFPU_EMU
 asmlinkage void fpemu_signal(int signal, int code, void *addr)
 {
index b44edb08e21276f3dce89e8b938c4e6a5252596c..93e69236ed6f8bfd1b6b38408aa380fc43d247de 100644 (file)
@@ -64,6 +64,7 @@ SECTIONS {
                _stext = . ;
                TEXT_TEXT
                SCHED_TEXT
+               LOCK_TEXT
                *(.text.lock)
 
                . = ALIGN(16);          /* Exception table              */
@@ -73,6 +74,7 @@ SECTIONS {
 
                *(.rodata) *(.rodata.*)
                *(__vermagic)           /* Kernel version magic */
+               *(__markers_strings)
                *(.rodata1)
                *(.rodata.str1.1)
 
@@ -112,6 +114,16 @@ SECTIONS {
                *(__kcrctab_gpl)
                __stop___kcrctab_gpl = .;
 
+               /* Kernel symbol table: Normal unused symbols */
+               __start___kcrctab_unused = .;
+               *(__kcrctab_unused)
+               __stop___kcrctab_unused = .;
+
+               /* Kernel symbol table: GPL-only unused symbols */
+               __start___kcrctab_unused_gpl = .;
+               *(__kcrctab_unused_gpl)
+               __stop___kcrctab_unused_gpl = .;
+
                /* Kernel symbol table: GPL-future symbols */
                __start___kcrctab_gpl_future = .;
                *(__kcrctab_gpl_future)
@@ -182,6 +194,7 @@ SECTIONS {
                *(COMMON)
                . = ALIGN(4) ;
                _ebss = . ;
+               _end = . ;
        } > BSS
 
 }
index a6692e958f6b93265380bfe7631b57d2fae5fe01..d01a5d2b75579190df5babe0f162a9b1eb947041 100644 (file)
@@ -48,7 +48,7 @@ static struct platform_device *m5206e_devices[] __initdata = {
 
 /***************************************************************************/
 
-static void __init m5206_uart_init_line(int line, int irq)
+static void __init m5206e_uart_init_line(int line, int irq)
 {
        if (line == 0) {
                writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
index 2aca599a1ca714ae2b70ec3d6d89f2ce74dc631f..230bae691a7f4be9060b01397efd7cc20a045ace 100644 (file)
@@ -139,10 +139,6 @@ void __init config_BSP(char *commandp, int size)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0004000, size);
        commandp[size-1] = 0;
-#elif defined(CONFIG_MTD_KeyTechnology)
-       /* Copy command line from FLASH to local buffer... */
-       memcpy(commandp, (char *) 0xffe06000, size);
-       commandp[size-1] = 0;
 #elif defined(CONFIG_CANCam)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0010000, size);
index 036e1b73d94400b8619db75d71e271a5ce2592e3..dfdb5c2ed8e6d35a3ce45b0827c03b61833c2eaf 100644 (file)
 #include <asm/mcfuart.h>
 #include <asm/mcfqspi.h>
 
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
 /***************************************************************************/
 
 void coldfire_reset(void);
+static void coldfire_qspi_cs_control(u8 cs, u8 command);
+
+/***************************************************************************/
+
+#if defined(CONFIG_SPI)
+
+#if defined(CONFIG_WILDFIRE)
+#define SPI_NUM_CHIPSELECTS    0x02
+#define SPI_PAR_VAL            0x07  /* Enable DIN, DOUT, CLK */
+#define SPI_CS_MASK            0x18
+
+#define FLASH_BLOCKSIZE                (1024*64)
+#define FLASH_NUMBLOCKS                16
+#define FLASH_TYPE             "m25p80"
+
+#define M25P80_CS              0
+#define MMC_CS                 1
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition stm25p_partitions[] = {
+       /* sflash */
+       [0] = {
+               .name = "stm25p80",
+               .offset = 0x00000000,
+               .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS,
+               .mask_flags = 0
+       }
+};
+
+#endif
+
+#elif defined(CONFIG_WILDFIREMOD)
+
+#define SPI_NUM_CHIPSELECTS    0x08
+#define SPI_PAR_VAL            0x07  /* Enable DIN, DOUT, CLK */
+#define SPI_CS_MASK            0x78
+
+#define FLASH_BLOCKSIZE                (1024*64)
+#define FLASH_NUMBLOCKS                64
+#define FLASH_TYPE             "m25p32"
+/* Reserve 1M for the kernel parition */
+#define FLASH_KERNEL_SIZE   (1024 * 1024)
+
+#define M25P80_CS              5
+#define MMC_CS                 6
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition stm25p_partitions[] = {
+       /* sflash */
+       [0] = {
+               .name = "kernel",
+               .offset = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE,
+               .size = FLASH_KERNEL_SIZE,
+               .mask_flags = 0
+       },
+       [1] = {
+               .name = "image",
+               .offset = 0x00000000,
+               .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE,
+               .mask_flags = 0
+       },
+       [2] = {
+               .name = "all",
+               .offset = 0x00000000,
+               .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS,
+               .mask_flags = 0
+       }
+};
+#endif
+
+#else
+#define SPI_NUM_CHIPSELECTS    0x04
+#define SPI_PAR_VAL            0x7F  /* Enable DIN, DOUT, CLK, CS0 - CS4 */
+#endif
+
+#ifdef MMC_CS
+static struct coldfire_spi_chip flash_chip_info = {
+       .mode = SPI_MODE_0,
+       .bits_per_word = 16,
+       .del_cs_to_clk = 17,
+       .del_after_trans = 1,
+       .void_write_data = 0
+};
+
+static struct coldfire_spi_chip mmc_chip_info = {
+       .mode = SPI_MODE_0,
+       .bits_per_word = 16,
+       .del_cs_to_clk = 17,
+       .del_after_trans = 1,
+       .void_write_data = 0xFFFF
+};
+#endif
+
+#ifdef M25P80_CS
+static struct flash_platform_data stm25p80_platform_data = {
+       .name = "ST M25P80 SPI Flash chip",
+#ifdef CONFIG_MTD_PARTITIONS
+       .parts = stm25p_partitions,
+       .nr_parts = sizeof(stm25p_partitions) / sizeof(*stm25p_partitions),
+#endif
+       .type = FLASH_TYPE
+};
+#endif
+
+static struct spi_board_info spi_board_info[] __initdata = {
+#ifdef M25P80_CS
+       {
+               .modalias = "m25p80",
+               .max_speed_hz = 16000000,
+               .bus_num = 1,
+               .chip_select = M25P80_CS,
+               .platform_data = &stm25p80_platform_data,
+               .controller_data = &flash_chip_info
+       },
+#endif
+#ifdef MMC_CS
+       {
+               .modalias = "mmc_spi",
+               .max_speed_hz = 16000000,
+               .bus_num = 1,
+               .chip_select = MMC_CS,
+               .controller_data = &mmc_chip_info
+       }
+#endif
+};
+
+static struct coldfire_spi_master coldfire_master_info = {
+       .bus_num = 1,
+       .num_chipselect = SPI_NUM_CHIPSELECTS,
+       .irq_source = MCF5282_QSPI_IRQ_SOURCE,
+       .irq_vector = MCF5282_QSPI_IRQ_VECTOR,
+       .irq_mask = ((0x01 << MCF5282_QSPI_IRQ_SOURCE) | 0x01),
+       .irq_lp = 0x2B,  /* Level 5 and Priority 3 */
+       .par_val = SPI_PAR_VAL,
+       .cs_control = coldfire_qspi_cs_control,
+};
+
+static struct resource coldfire_spi_resources[] = {
+       [0] = {
+               .name = "qspi-par",
+               .start = MCF5282_QSPI_PAR,
+               .end = MCF5282_QSPI_PAR,
+               .flags = IORESOURCE_MEM
+       },
+
+       [1] = {
+               .name = "qspi-module",
+               .start = MCF5282_QSPI_QMR,
+               .end = MCF5282_QSPI_QMR + 0x18,
+               .flags = IORESOURCE_MEM
+       },
+
+       [2] = {
+               .name = "qspi-int-level",
+               .start = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE,
+               .end = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE,
+               .flags = IORESOURCE_MEM
+       },
+
+       [3] = {
+               .name = "qspi-int-mask",
+               .start = MCF5282_INTC0 + MCFINTC_IMRL,
+               .end = MCF5282_INTC0 + MCFINTC_IMRL,
+               .flags = IORESOURCE_MEM
+       }
+};
+
+static struct platform_device coldfire_spi = {
+       .name = "spi_coldfire",
+       .id = -1,
+       .resource = coldfire_spi_resources,
+       .num_resources = ARRAY_SIZE(coldfire_spi_resources),
+       .dev = {
+               .platform_data = &coldfire_master_info,
+       }
+};
+
+static void coldfire_qspi_cs_control(u8 cs, u8 command)
+{
+       u8 cs_bit = ((0x01 << cs) << 3) & SPI_CS_MASK;
+
+#if defined(CONFIG_WILDFIRE)
+       u8 cs_mask = ~(((0x01 << cs) << 3) & SPI_CS_MASK);
+#endif
+#if defined(CONFIG_WILDFIREMOD)
+       u8 cs_mask = (cs << 3) & SPI_CS_MASK;
+#endif
+
+       /*
+        * Don't do anything if the chip select is not
+        * one of the port qs pins.
+        */
+       if (command & QSPI_CS_INIT) {
+#if defined(CONFIG_WILDFIRE)
+               MCF5282_GPIO_DDRQS  |= cs_bit;
+               MCF5282_GPIO_PQSPAR &= ~cs_bit;
+#endif
+
+#if defined(CONFIG_WILDFIREMOD)
+               MCF5282_GPIO_DDRQS  |= SPI_CS_MASK;
+               MCF5282_GPIO_PQSPAR &= ~SPI_CS_MASK;
+#endif
+       }
+
+       if (command & QSPI_CS_ASSERT) {
+               MCF5282_GPIO_PORTQS &= ~SPI_CS_MASK;
+               MCF5282_GPIO_PORTQS |= cs_mask;
+       } else if (command & QSPI_CS_DROP) {
+               MCF5282_GPIO_PORTQS |= SPI_CS_MASK;
+       }
+}
+
+static int __init spi_dev_init(void)
+{
+       int retval;
+
+       retval = platform_device_register(&coldfire_spi);
+       if (retval < 0)
+               return retval;
+
+       if (ARRAY_SIZE(spi_board_info))
+               retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+       return retval;
+}
+
+#endif /* CONFIG_SPI */
 
 /***************************************************************************/
 
@@ -111,10 +342,43 @@ void mcf_autovector(unsigned int vec)
 
 /***************************************************************************/
 
+#ifdef CONFIG_WILDFIRE
+void wildfire_halt(void)
+{
+       writeb(0, 0x30000007);
+       writeb(0x2, 0x30000007);
+}
+#endif
+
+#ifdef CONFIG_WILDFIREMOD
+void wildfiremod_halt(void)
+{
+       printk(KERN_INFO "WildFireMod hibernating...\n");
+
+       /* Set portE.5 to Digital IO */
+       MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
+
+       /* Make portE.5 an output */
+       MCF5282_GPIO_DDRE |= (1 << 5);
+
+       /* Now toggle portE.5 from low to high */
+       MCF5282_GPIO_PORTE &= ~(1 << 5);
+       MCF5282_GPIO_PORTE |= (1 << 5);
+
+       printk(KERN_EMERG "Failed to hibernate. Halting!\n");
+}
+#endif
+
 void __init config_BSP(char *commandp, int size)
 {
        mcf_disableall();
-       mach_reset = coldfire_reset;
+
+#ifdef CONFIG_WILDFIRE
+       mach_halt = wildfire_halt;
+#endif
+#ifdef CONFIG_WILDFIREMOD
+       mach_halt = wildfiremod_halt;
+#endif
 }
 
 /***************************************************************************/
index 92dc862fa826edb5432875d585a99d266f2d80ca..11cff6625dcce8ae12b5e6d77abc2b17680edda5 100644 (file)
@@ -124,8 +124,7 @@ void __init config_BSP(char *commandp, int size)
        mcf_setimr(MCFSIM_IMR_MASKALL);
 
 #if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
-      defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
-      defined(CONFIG_CLEOPATRA)
+    defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
        /* Copy command line from FLASH to local buffer... */
        memcpy(commandp, (char *) 0xf0004000, size);
        commandp[size-1] = 0;
index 111b66dc737ba5f15e0d2af56b7a85e2db676050..1e3c0dcbd7acec7a1ac9070704d3109bd6d2980e 100644 (file)
@@ -103,9 +103,26 @@ ret_from_signal:
        addql   #4,%sp
 
 ret_from_exception:
+       move    #0x2700,%sr             /* disable intrs */
        btst    #5,%sp@(PT_SR)          /* check if returning to kernel */
        jeq     Luser_return            /* if so, skip resched, signals */
 
+#ifdef CONFIG_PREEMPT
+       movel   %sp,%d1                 /* get thread_info pointer */
+       andl    #-THREAD_SIZE,%d1       /* at base of kernel stack */
+       movel   %d1,%a0
+       movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
+       andl    #_TIF_NEED_RESCHED,%d1
+       jeq     Lkernel_return
+
+       movel   %a0@(TI_PREEMPTCOUNT),%d1
+       cmpl    #0,%d1
+       jne     Lkernel_return
+
+       pea     Lkernel_return
+       jmp     preempt_schedule_irq    /* preempt the kernel */
+#endif
+
 Lkernel_return:
        moveml  %sp@,%d1-%d5/%a0-%a2
        lea     %sp@(32),%sp            /* space for 8 regs */
@@ -140,6 +157,7 @@ Lreturn:
 
 Lwork_to_do:
        movel   %a0@(TI_FLAGS),%d1      /* get thread_info->flags */
+       move    #0x2000,%sr             /* enable intrs again */
        btst    #TIF_NEED_RESCHED,%d1
        jne     reschedule
 
index 90e2d7a46e8e2c7d96a86fb61500b11c9ddad4f5..dd0e19dacfcff444ab7b4ff07912ff8b0bcde082 100644 (file)
@@ -1,9 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Au1000 CPU, generic files.
+# Makefile for the Alchemy Au1xx0 CPUs, generic files.
 #
 
 obj-y += prom.o irq.o puts.o time.o reset.o \
index 37a10a01de9d30619c2a7c5feeabfac77cbb2c5f..c7ca1596394cc2a4e18c2f83c0f735ed7171d2b6 100644 (file)
 struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
 
 #if defined(CONFIG_SOC_AU1000)
-       { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+       { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -62,32 +62,32 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
        { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
        { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1500)
 
-       { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
        { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-       { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
        { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
-       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -100,26 +100,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
        { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
        { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1100)
 
-       { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+       { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -128,33 +128,33 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
        { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
        { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-       /*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
-       { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+       /* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
+       { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1550)
 
-       { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
        { AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-       { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
        { AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
        { AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
-       { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -163,26 +163,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
        { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
+       { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-       { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
 
 #elif defined(CONFIG_SOC_AU1200)
 
-       { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
-       { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
-       { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 },
        { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -191,10 +191,10 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
        { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-       { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
+       { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 },
        { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
-       { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
-       { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
+       { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
+       { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
 
 #else
 #error "Error: Unknown Alchemy SOC"
@@ -203,4 +203,3 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
 };
 
 int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);
-
index 3ce6cace0eb0d618294f0701228f0a9761c74e59..46f8ee0e265771be26b8833d54e19d949344ed3d 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Simple Au1000 clocks routines.
+ *     Simple Au1xx0 clocks routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -30,8 +29,8 @@
 #include <linux/module.h>
 #include <asm/mach-au1x00/au1000.h>
 
-static unsigned int au1x00_clock; // Hz
-static unsigned int lcd_clock;    // KHz
+static unsigned int au1x00_clock; /*  Hz */
+static unsigned int lcd_clock;    /* KHz */
 static unsigned long uart_baud_base;
 
 /*
@@ -47,8 +46,6 @@ unsigned int get_au1x00_speed(void)
        return au1x00_clock;
 }
 
-
-
 /*
  * The UART baud base is not known at compile time ... if
  * we want to be able to use the same code on different
@@ -73,24 +70,23 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
 void set_au1x00_lcd_clock(void)
 {
        unsigned int static_cfg0;
-       unsigned int sys_busclk =
-               (get_au1x00_speed()/1000) /
-               ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
+       unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
+                                 ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
 
        static_cfg0 = au_readl(MEM_STCFG0);
 
-       if (static_cfg0 & (1<<11))
+       if (static_cfg0 & (1 << 11))
                lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
        else
                lcd_clock = sys_busclk / 4;
 
        if (lcd_clock > 50000) /* Epson MAX */
-               printk("warning: LCD clock too high (%d KHz)\n", lcd_clock);
+               printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
+                                   lcd_clock);
 }
 
 unsigned int get_au1x00_lcd_clock(void)
 {
        return lcd_clock;
 }
-
 EXPORT_SYMBOL(get_au1x00_lcd_clock);
index 8c93a05d73826e804ff82781ae5f50d28ed35029..ba6430bc2d0300d78b9b66d3fa4870a12083eb82 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <asm/mach-au1x00/au1000.h>
 
-struct cpu_speccur_cpu_spec[NR_CPUS];
+struct cpu_spec *cur_cpu_spec[NR_CPUS];
 
 /* With some thought, we can probably use the mask to reduce the
  * size of the table.
@@ -39,8 +39,7 @@ struct cpu_spec cpu_specs[] = {
        { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
 };
 
-void
-set_cpuspec(void)
+void set_cpuspec(void)
 {
        struct  cpu_spec *sp;
        u32     prid;
index 53377dfc0640da33d85db3b7f47db242872ca5b1..42d555236de15bbd4bc731554fb54a8ab305d6d1 100644 (file)
  */
 static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
 
-/* I couldn't find a macro that did this......
-*/
+/* I couldn't find a macro that did this... */
 #define ALIGN_ADDR(x, a)       ((((u32)(x)) + (a-1)) & ~(a-1))
 
 static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
-static int dbdma_initialized=0;
+static int dbdma_initialized;
 static void au1xxx_dbdma_init(void);
 
 static dbdev_tab_t dbdev_tab[] = {
@@ -149,7 +148,7 @@ static dbdev_tab_t dbdev_tab[] = {
 
        { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
 
-#endif // CONFIG_SOC_AU1200
+#endif /* CONFIG_SOC_AU1200 */
 
        { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
        { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
@@ -177,8 +176,7 @@ static dbdev_tab_t dbdev_tab[] = {
 
 static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
 
-static dbdev_tab_t *
-find_dbdev_id(u32 id)
+static dbdev_tab_t *find_dbdev_id(u32 id)
 {
        int i;
        dbdev_tab_t *p;
@@ -190,29 +188,27 @@ find_dbdev_id(u32 id)
        return NULL;
 }
 
-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
 {
-        return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+       return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 }
 EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
 
-u32
-au1xxx_ddma_add_device(dbdev_tab_t *dev)
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev)
 {
        u32 ret = 0;
-       dbdev_tab_t *p=NULL;
-       static u16 new_id=0x1000;
+       dbdev_tab_t *p;
+       static u16 new_id = 0x1000;
 
        p = find_dbdev_id(~0);
-       if ( NULL != p )
-       {
+       if (NULL != p) {
                memcpy(p, dev, sizeof(dbdev_tab_t));
                p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id);
                ret = p->dev_id;
                new_id++;
 #if 0
-               printk("add_device: id:%x flags:%x padd:%x\n",
-                               p->dev_id, p->dev_flags, p->dev_physaddr );
+               printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n",
+                                 p->dev_id, p->dev_flags, p->dev_physaddr);
 #endif
        }
 
@@ -220,10 +216,8 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev)
 }
 EXPORT_SYMBOL(au1xxx_ddma_add_device);
 
-/* Allocate a channel and return a non-zero descriptor if successful.
-*/
-u32
-au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+/* Allocate a channel and return a non-zero descriptor if successful. */
+u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
        void (*callback)(int, void *), void *callparam)
 {
        unsigned long   flags;
@@ -234,7 +228,8 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
        chan_tab_t      *ctp;
        au1x_dma_chan_t *cp;
 
-       /* We do the intialization on the first channel allocation.
+       /*
+        * We do the intialization on the first channel allocation.
         * We have to wait because of the interrupt handler initialization
         * which can't be done successfully during board set up.
         */
@@ -242,16 +237,17 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
                au1xxx_dbdma_init();
        dbdma_initialized = 1;
 
-       if ((stp = find_dbdev_id(srcid)) == NULL)
+       stp = find_dbdev_id(srcid);
+       if (stp == NULL)
                return 0;
-       if ((dtp = find_dbdev_id(destid)) == NULL)
+       dtp = find_dbdev_id(destid);
+       if (dtp == NULL)
                return 0;
 
        used = 0;
        rv = 0;
 
-       /* Check to see if we can get both channels.
-       */
+       /* Check to see if we can get both channels. */
        spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
        if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
             (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
@@ -261,35 +257,30 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
                     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
                        /* Got destination */
                        dtp->dev_flags |= DEV_FLAGS_INUSE;
-               }
-               else {
-                       /* Can't get dest.  Release src.
-                       */
+               } else {
+                       /* Can't get dest.  Release src. */
                        stp->dev_flags &= ~DEV_FLAGS_INUSE;
                        used++;
                }
-       }
-       else {
+       } else
                used++;
-       }
        spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
 
        if (!used) {
-               /* Let's see if we can allocate a channel for it.
-               */
+               /* Let's see if we can allocate a channel for it. */
                ctp = NULL;
                chan = 0;
                spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
-               for (i=0; i<NUM_DBDMA_CHANS; i++) {
+               for (i = 0; i < NUM_DBDMA_CHANS; i++)
                        if (chan_tab_ptr[i] == NULL) {
-                               /* If kmalloc fails, it is caught below same
+                               /*
+                                * If kmalloc fails, it is caught below same
                                 * as a channel not available.
                                 */
                                ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
                                chan_tab_ptr[i] = ctp;
                                break;
                        }
-               }
                spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
 
                if (ctp != NULL) {
@@ -304,8 +295,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
                        ctp->chan_callback = callback;
                        ctp->chan_callparam = callparam;
 
-                       /* Initialize channel configuration.
-                       */
+                       /* Initialize channel configuration. */
                        i = 0;
                        if (stp->dev_intlevel)
                                i |= DDMA_CFG_SED;
@@ -326,8 +316,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
                         * operations.
                         */
                        rv = (u32)(&chan_tab_ptr[chan]);
-               }
-               else {
+               } else {
                        /* Release devices */
                        stp->dev_flags &= ~DEV_FLAGS_INUSE;
                        dtp->dev_flags &= ~DEV_FLAGS_INUSE;
@@ -337,11 +326,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
 }
 EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
 
-/* Set the device width if source or destination is a FIFO.
+/*
+ * Set the device width if source or destination is a FIFO.
  * Should be 8, 16, or 32 bits.
  */
-u32
-au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
 {
        u32             rv;
        chan_tab_t      *ctp;
@@ -365,10 +354,8 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
 }
 EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
 
-/* Allocate a descriptor ring, initializing as much as possible.
-*/
-u32
-au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+/* Allocate a descriptor ring, initializing as much as possible. */
+u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
 {
        int                     i;
        u32                     desc_base, srcid, destid;
@@ -378,43 +365,45 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
        dbdev_tab_t             *stp, *dtp;
        au1x_ddma_desc_t        *dp;
 
-       /* I guess we could check this to be within the
+       /*
+        * I guess we could check this to be within the
         * range of the table......
         */
        ctp = *((chan_tab_t **)chanid);
        stp = ctp->chan_src;
        dtp = ctp->chan_dest;
 
-       /* The descriptors must be 32-byte aligned.  There is a
+       /*
+        * The descriptors must be 32-byte aligned.  There is a
         * possibility the allocation will give us such an address,
         * and if we try that first we are likely to not waste larger
         * slabs of memory.
         */
        desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
-                       GFP_KERNEL|GFP_DMA);
+                                GFP_KERNEL|GFP_DMA);
        if (desc_base == 0)
                return 0;
 
        if (desc_base & 0x1f) {
-               /* Lost....do it again, allocate extra, and round
+               /*
+                * Lost....do it again, allocate extra, and round
                 * the address base.
                 */
                kfree((const void *)desc_base);
                i = entries * sizeof(au1x_ddma_desc_t);
                i += (sizeof(au1x_ddma_desc_t) - 1);
-               if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
+               desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA);
+               if (desc_base == 0)
                        return 0;
 
                desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
        }
        dp = (au1x_ddma_desc_t *)desc_base;
 
-       /* Keep track of the base descriptor.
-       */
+       /* Keep track of the base descriptor. */
        ctp->chan_desc_base = dp;
 
-       /* Initialize the rings with as much information as we know.
-        */
+       /* Initialize the rings with as much information as we know. */
        srcid = stp->dev_id;
        destid = dtp->dev_id;
 
@@ -426,11 +415,12 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
        cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
        cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
 
-        /* is it mem to mem transfer? */
-        if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
-           ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
-               cmd0 |= DSCR_CMD0_MEM;
-        }
+       /* Is it mem to mem transfer? */
+       if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) ||
+            (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+           ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) ||
+            (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS)))
+               cmd0 |= DSCR_CMD0_MEM;
 
        switch (stp->dev_devwidth) {
        case 8:
@@ -458,15 +448,17 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
                break;
        }
 
-       /* If the device is marked as an in/out FIFO, ensure it is
+       /*
+        * If the device is marked as an in/out FIFO, ensure it is
         * set non-coherent.
         */
        if (stp->dev_flags & DEV_FLAGS_IN)
-               cmd0 |= DSCR_CMD0_SN;           /* Source in fifo */
+               cmd0 |= DSCR_CMD0_SN;           /* Source in FIFO */
        if (dtp->dev_flags & DEV_FLAGS_OUT)
-               cmd0 |= DSCR_CMD0_DN;           /* Destination out fifo */
+               cmd0 |= DSCR_CMD0_DN;           /* Destination out FIFO */
 
-       /* Set up source1.  For now, assume no stride and increment.
+       /*
+        * Set up source1.  For now, assume no stride and increment.
         * A channel attribute update can change this later.
         */
        switch (stp->dev_tsize) {
@@ -485,19 +477,19 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
                break;
        }
 
-       /* If source input is fifo, set static address.
-       */
+       /* If source input is FIFO, set static address. */
        if (stp->dev_flags & DEV_FLAGS_IN) {
-               if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
+               if (stp->dev_flags & DEV_FLAGS_BURSTABLE)
                        src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
                else
-               src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
-
+                       src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
        }
+
        if (stp->dev_physaddr)
                src0 = stp->dev_physaddr;
 
-       /* Set up dest1.  For now, assume no stride and increment.
+       /*
+        * Set up dest1.  For now, assume no stride and increment.
         * A channel attribute update can change this later.
         */
        switch (dtp->dev_tsize) {
@@ -516,22 +508,24 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
                break;
        }
 
-       /* If destination output is fifo, set static address.
-       */
+       /* If destination output is FIFO, set static address. */
        if (dtp->dev_flags & DEV_FLAGS_OUT) {
-               if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
-                       dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
-                               else
-               dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+               if (dtp->dev_flags & DEV_FLAGS_BURSTABLE)
+                       dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+               else
+                       dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
        }
+
        if (dtp->dev_physaddr)
                dest0 = dtp->dev_physaddr;
 
 #if 0
-               printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
-                       dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
+               printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x "
+                                 "source1:%x dest0:%x dest1:%x\n",
+                                 dtp->dev_id, stp->dev_id, cmd0, cmd1, src0,
+                                 src1, dest0, dest1);
 #endif
-       for (i=0; i<entries; i++) {
+       for (i = 0; i < entries; i++) {
                dp->dscr_cmd0 = cmd0;
                dp->dscr_cmd1 = cmd1;
                dp->dscr_source0 = src0;
@@ -545,49 +539,49 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
                dp++;
        }
 
-       /* Make last descrptor point to the first.
-       */
+       /* Make last descrptor point to the first. */
        dp--;
        dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
        ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
 
-       return (u32)(ctp->chan_desc_base);
+       return (u32)ctp->chan_desc_base;
 }
 EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
 
-/* Put a source buffer into the DMA ring.
+/*
+ * Put a source buffer into the DMA ring.
  * This updates the source pointer and byte count.  Normally used
  * for memory to fifo transfers.
  */
-u32
-_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
 {
        chan_tab_t              *ctp;
        au1x_ddma_desc_t        *dp;
 
-       /* I guess we could check this to be within the
+       /*
+        * I guess we could check this to be within the
         * range of the table......
         */
-       ctp = *((chan_tab_t **)chanid);
+       ctp = *(chan_tab_t **)chanid;
 
-       /* We should have multiple callers for a particular channel,
+       /*
+        * We should have multiple callers for a particular channel,
         * an interrupt doesn't affect this pointer nor the descriptor,
         * so no locking should be needed.
         */
        dp = ctp->put_ptr;
 
-       /* If the descriptor is valid, we are way ahead of the DMA
+       /*
+        * If the descriptor is valid, we are way ahead of the DMA
         * engine, so just return an error condition.
         */
-       if (dp->dscr_cmd0 & DSCR_CMD0_V) {
+       if (dp->dscr_cmd0 & DSCR_CMD0_V)
                return 0;
-       }
 
-       /* Load up buffer address and byte count.
-       */
+       /* Load up buffer address and byte count. */
        dp->dscr_source0 = virt_to_phys(buf);
        dp->dscr_cmd1 = nbytes;
-       /* Check flags  */
+       /* Check flags */
        if (flags & DDMA_FLAGS_IE)
                dp->dscr_cmd0 |= DSCR_CMD0_IE;
        if (flags & DDMA_FLAGS_NOIE)
@@ -595,23 +589,21 @@ _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
 
        /*
         * There is an errata on the Au1200/Au1550 parts that could result
-        * in "stale" data being DMA'd. It has to do with the snoop logic on
-        * the dache eviction buffer.  NONCOHERENT_IO is on by default for
-        * these parts. If it is fixedin the future, these dma_cache_inv will
+        * in "stale" data being DMA'ed. It has to do with the snoop logic on
+        * the cache eviction buffer.  DMA_NONCOHERENT is on by default for
+        * these parts. If it is fixed in the future, these dma_cache_inv will
         * just be nothing more than empty macros. See io.h.
-        * */
+        */
        dma_cache_wback_inv((unsigned long)buf, nbytes);
-        dp->dscr_cmd0 |= DSCR_CMD0_V;        /* Let it rip */
+       dp->dscr_cmd0 |= DSCR_CMD0_V;   /* Let it rip */
        au_sync();
        dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
-        ctp->chan_ptr->ddma_dbell = 0;
+       ctp->chan_ptr->ddma_dbell = 0;
 
-       /* Get next descriptor pointer.
-       */
+       /* Get next descriptor pointer. */
        ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-       /* return something not zero.
-       */
+       /* Return something non-zero. */
        return nbytes;
 }
 EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
@@ -654,81 +646,77 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
        dp->dscr_dest0 = virt_to_phys(buf);
        dp->dscr_cmd1 = nbytes;
 #if 0
-       printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
-                       dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
-                       dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
+       printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+                         dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+                         dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
 #endif
        /*
         * There is an errata on the Au1200/Au1550 parts that could result in
-        * "stale" data being DMA'd. It has to do with the snoop logic on the
-        * dache eviction buffer. NONCOHERENT_IO is on by default for these
-        * parts. If it is fixedin the future, these dma_cache_inv will just
+        * "stale" data being DMA'ed. It has to do with the snoop logic on the
+        * cache eviction buffer.  DMA_NONCOHERENT is on by default for these
+        * parts. If it is fixed in the future, these dma_cache_inv will just
         * be nothing more than empty macros. See io.h.
-        * */
+        */
        dma_cache_inv((unsigned long)buf, nbytes);
        dp->dscr_cmd0 |= DSCR_CMD0_V;   /* Let it rip */
        au_sync();
        dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
-        ctp->chan_ptr->ddma_dbell = 0;
+       ctp->chan_ptr->ddma_dbell = 0;
 
-       /* Get next descriptor pointer.
-       */
+       /* Get next descriptor pointer. */
        ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-       /* return something not zero.
-       */
+       /* Return something non-zero. */
        return nbytes;
 }
 EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
 
-/* Get a destination buffer into the DMA ring.
+/*
+ * Get a destination buffer into the DMA ring.
  * Normally used to get a full buffer from the ring during fifo
  * to memory transfers.  This does not set the valid bit, you will
  * have to put another destination buffer to keep the DMA going.
  */
-u32
-au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
 {
        chan_tab_t              *ctp;
        au1x_ddma_desc_t        *dp;
        u32                     rv;
 
-       /* I guess we could check this to be within the
+       /*
+        * I guess we could check this to be within the
         * range of the table......
         */
        ctp = *((chan_tab_t **)chanid);
 
-       /* We should have multiple callers for a particular channel,
+       /*
+        * We should have multiple callers for a particular channel,
         * an interrupt doesn't affect this pointer nor the descriptor,
         * so no locking should be needed.
         */
        dp = ctp->get_ptr;
 
-       /* If the descriptor is valid, we are way ahead of the DMA
+       /*
+        * If the descriptor is valid, we are way ahead of the DMA
         * engine, so just return an error condition.
         */
        if (dp->dscr_cmd0 & DSCR_CMD0_V)
                return 0;
 
-       /* Return buffer address and byte count.
-       */
+       /* Return buffer address and byte count. */
        *buf = (void *)(phys_to_virt(dp->dscr_dest0));
        *nbytes = dp->dscr_cmd1;
        rv = dp->dscr_stat;
 
-       /* Get next descriptor pointer.
-       */
+       /* Get next descriptor pointer. */
        ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-       /* return something not zero.
-       */
+       /* Return something non-zero. */
        return rv;
 }
-
 EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest);
 
-void
-au1xxx_dbdma_stop(u32 chanid)
+void au1xxx_dbdma_stop(u32 chanid)
 {
        chan_tab_t      *ctp;
        au1x_dma_chan_t *cp;
@@ -743,7 +731,7 @@ au1xxx_dbdma_stop(u32 chanid)
                udelay(1);
                halt_timeout++;
                if (halt_timeout > 100) {
-                       printk("warning: DMA channel won't halt\n");
+                       printk(KERN_WARNING "warning: DMA channel won't halt\n");
                        break;
                }
        }
@@ -753,12 +741,12 @@ au1xxx_dbdma_stop(u32 chanid)
 }
 EXPORT_SYMBOL(au1xxx_dbdma_stop);
 
-/* Start using the current descriptor pointer.  If the dbdma encounters
- * a not valid descriptor, it will stop.  In this case, we can just
+/*
+ * Start using the current descriptor pointer.  If the DBDMA encounters
+ * a non-valid descriptor, it will stop.  In this case, we can just
  * continue by adding a buffer to the list and starting again.
  */
-void
-au1xxx_dbdma_start(u32 chanid)
+void au1xxx_dbdma_start(u32 chanid)
 {
        chan_tab_t      *ctp;
        au1x_dma_chan_t *cp;
@@ -773,8 +761,7 @@ au1xxx_dbdma_start(u32 chanid)
 }
 EXPORT_SYMBOL(au1xxx_dbdma_start);
 
-void
-au1xxx_dbdma_reset(u32 chanid)
+void au1xxx_dbdma_reset(u32 chanid)
 {
        chan_tab_t              *ctp;
        au1x_ddma_desc_t        *dp;
@@ -784,14 +771,14 @@ au1xxx_dbdma_reset(u32 chanid)
        ctp = *((chan_tab_t **)chanid);
        ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
 
-       /* Run through the descriptors and reset the valid indicator.
-       */
+       /* Run through the descriptors and reset the valid indicator. */
        dp = ctp->chan_desc_base;
 
        do {
                dp->dscr_cmd0 &= ~DSCR_CMD0_V;
-               /* reset our SW status -- this is used to determine
-                * if a descriptor is in use by upper level SW. Since
+               /*
+                * Reset our software status -- this is used to determine
+                * if a descriptor is in use by upper level software. Since
                 * posting can reset 'V' bit.
                 */
                dp->sw_status = 0;
@@ -800,8 +787,7 @@ au1xxx_dbdma_reset(u32 chanid)
 }
 EXPORT_SYMBOL(au1xxx_dbdma_reset);
 
-u32
-au1xxx_get_dma_residue(u32 chanid)
+u32 au1xxx_get_dma_residue(u32 chanid)
 {
        chan_tab_t      *ctp;
        au1x_dma_chan_t *cp;
@@ -810,18 +796,15 @@ au1xxx_get_dma_residue(u32 chanid)
        ctp = *((chan_tab_t **)chanid);
        cp = ctp->chan_ptr;
 
-       /* This is only valid if the channel is stopped.
-       */
+       /* This is only valid if the channel is stopped. */
        rv = cp->ddma_bytecnt;
        au_sync();
 
        return rv;
 }
-
 EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue);
 
-void
-au1xxx_dbdma_chan_free(u32 chanid)
+void au1xxx_dbdma_chan_free(u32 chanid)
 {
        chan_tab_t      *ctp;
        dbdev_tab_t     *stp, *dtp;
@@ -842,8 +825,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
 }
 EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
 
-static irqreturn_t
-dbdma_interrupt(int irq, void *dev_id)
+static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
 {
        u32 intstat;
        u32 chan_index;
@@ -859,13 +841,12 @@ dbdma_interrupt(int irq, void *dev_id)
        cp = ctp->chan_ptr;
        dp = ctp->cur_ptr;
 
-       /* Reset interrupt.
-       */
+       /* Reset interrupt. */
        cp->ddma_irq = 0;
        au_sync();
 
        if (ctp->chan_callback)
-               (ctp->chan_callback)(irq, ctp->chan_callparam);
+               ctp->chan_callback(irq, ctp->chan_callparam);
 
        ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
        return IRQ_RETVAL(1);
@@ -890,47 +871,47 @@ static void au1xxx_dbdma_init(void)
 
        if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
                        "Au1xxx dbdma", (void *)dbdma_gptr))
-               printk("Can't get 1550 dbdma irq");
+               printk(KERN_ERR "Can't get 1550 dbdma irq");
 }
 
-void
-au1xxx_dbdma_dump(u32 chanid)
+void au1xxx_dbdma_dump(u32 chanid)
 {
-       chan_tab_t              *ctp;
-       au1x_ddma_desc_t        *dp;
-       dbdev_tab_t             *stp, *dtp;
-       au1x_dma_chan_t *cp;
-               u32                     i = 0;
+       chan_tab_t       *ctp;
+       au1x_ddma_desc_t *dp;
+       dbdev_tab_t      *stp, *dtp;
+       au1x_dma_chan_t  *cp;
+       u32 i            = 0;
 
        ctp = *((chan_tab_t **)chanid);
        stp = ctp->chan_src;
        dtp = ctp->chan_dest;
        cp = ctp->chan_ptr;
 
-       printk("Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
-               (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
-       printk("desc base %x, get %x, put %x, cur %x\n",
-               (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
-               (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
-
-       printk("dbdma chan %x\n", (u32)cp);
-       printk("cfg %08x, desptr %08x, statptr %08x\n",
-               cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
-       printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
-               cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
-
-
-       /* Run through the descriptors
-       */
+       printk(KERN_DEBUG "Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+                         (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
+                         dtp - dbdev_tab);
+       printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
+                         (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+                         (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+
+       printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp);
+       printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n",
+                         cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+       printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+                         cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat,
+                         cp->ddma_bytecnt);
+
+       /* Run through the descriptors */
        dp = ctp->chan_desc_base;
 
        do {
-                printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
-                        i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
-                printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
-                        dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
-                printk("stat %08x, nxtptr %08x\n",
-                        dp->dscr_stat, dp->dscr_nxtptr);
+               printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+                                 i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+               printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+                                 dp->dscr_source0, dp->dscr_source1,
+                                 dp->dscr_dest0, dp->dscr_dest1);
+               printk(KERN_DEBUG "stat %08x, nxtptr %08x\n",
+                                 dp->dscr_stat, dp->dscr_nxtptr);
                dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
        } while (dp != ctp->chan_desc_base);
 }
@@ -938,32 +919,33 @@ au1xxx_dbdma_dump(u32 chanid)
 /* Put a descriptor into the DMA ring.
  * This updates the source/destination pointers and byte count.
  */
-u32
-au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
 {
        chan_tab_t *ctp;
        au1x_ddma_desc_t *dp;
-       u32 nbytes=0;
+       u32 nbytes = 0;
 
-       /* I guess we could check this to be within the
-       * range of the table......
-       */
+       /*
+        * I guess we could check this to be within the
+        * range of the table......
+        */
        ctp = *((chan_tab_t **)chanid);
 
-       /* We should have multiple callers for a particular channel,
-       * an interrupt doesn't affect this pointer nor the descriptor,
-       * so no locking should be needed.
-       */
+       /*
+        * We should have multiple callers for a particular channel,
+        * an interrupt doesn't affect this pointer nor the descriptor,
+        * so no locking should be needed.
+        */
        dp = ctp->put_ptr;
 
-       /* If the descriptor is valid, we are way ahead of the DMA
-       * engine, so just return an error condition.
-       */
+       /*
+        * If the descriptor is valid, we are way ahead of the DMA
+        * engine, so just return an error condition.
+        */
        if (dp->dscr_cmd0 & DSCR_CMD0_V)
                return 0;
 
-       /* Load up buffer addresses and byte count.
-       */
+       /* Load up buffer addresses and byte count. */
        dp->dscr_dest0 = dscr->dscr_dest0;
        dp->dscr_source0 = dscr->dscr_source0;
        dp->dscr_dest1 = dscr->dscr_dest1;
@@ -975,14 +957,11 @@ au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
        dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
        ctp->chan_ptr->ddma_dbell = 0;
 
-       /* Get next descriptor pointer.
-       */
+       /* Get next descriptor pointer. */
        ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-       /* return something not zero.
-       */
+       /* Return something non-zero. */
        return nbytes;
 }
 
 #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
-
index eae1bb2ca26e72ab115c35e97030fbe52a5d877a..af5be7df2f2a9f379d9c0a06125d20542479029b 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/types.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
@@ -8,12 +9,6 @@
  * uart to be used for debugging.
  */
 #define DEBUG_BASE  UART_DEBUG_BASE
-/**/
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef         unsigned char uint8;
-typedef         unsigned int  uint32;
 
 #define         UART16550_BAUD_2400             2400
 #define         UART16550_BAUD_4800             4800
@@ -51,17 +46,15 @@ typedef         unsigned int  uint32;
 #define UART_MOD_CNTRL 0x100   /* Module Control */
 
 /* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
+#define UART16550_READ(y)     (au_readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y, z) (au_writel(z & 0xff, DEBUG_BASE + y))
 
 extern unsigned long calc_clock(void);
 
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
 {
-
-       if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
+       if (UART16550_READ(UART_MOD_CNTRL) != 0x3)
                UART16550_WRITE(UART_MOD_CNTRL, 3);
-       }
        calc_clock();
 
        /* disable interrupts */
@@ -69,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
 
        /* set up baud rate */
        {
-               uint32 divisor;
+               u32 divisor;
 
                /* set divisor */
                divisor = get_au1x00_uart_baud_base() / baud;
@@ -80,9 +73,9 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
        UART16550_WRITE(UART_LCR, (data | parity | stop));
 }
 
-static int remoteDebugInitialized = 0;
+static int remoteDebugInitialized;
 
-uint8 getDebugChar(void)
+u8 getDebugChar(void)
 {
        if (!remoteDebugInitialized) {
                remoteDebugInitialized = 1;
@@ -92,15 +85,13 @@ uint8 getDebugChar(void)
                          UART16550_STOP_1BIT);
        }
 
-       while((UART16550_READ(UART_LSR) & 0x1) == 0);
+       while ((UART16550_READ(UART_LSR) & 0x1) == 0);
        return UART16550_READ(UART_RX);
 }
 
 
-int putDebugChar(uint8 byte)
+int putDebugChar(u8 byte)
 {
-//     int i;
-
        if (!remoteDebugInitialized) {
                remoteDebugInitialized = 1;
                debugInit(UART16550_BAUD_115200,
@@ -109,9 +100,8 @@ int putDebugChar(uint8 byte)
                          UART16550_STOP_1BIT);
        }
 
-       while ((UART16550_READ(UART_LSR)&0x40) == 0);
+       while ((UART16550_READ(UART_LSR) & 0x40) == 0);
        UART16550_WRITE(UART_TX, byte);
-       //for (i=0;i<0xfff;i++);
 
        return 1;
 }
index 95f69ea146e90a49d5ffdca4605af5fbb64df99e..d6fbda232e6ae5b8cdf92eee346dbdae091fe1f2 100644 (file)
@@ -1,12 +1,11 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *      A DMA channel allocator for Au1000. API is modeled loosely off of
+ *      A DMA channel allocator for Au1x00. API is modeled loosely off of
  *      linux/kernel/dma.c.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -39,7 +38,8 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1000_dma.h>
 
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+    defined(CONFIG_SOC_AU1100)
 /*
  * A note on resource allocation:
  *
@@ -56,7 +56,6 @@
  * returned from request_dma.
  */
 
-
 DEFINE_SPINLOCK(au1000_dma_spin_lock);
 
 struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
@@ -71,7 +70,7 @@ struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
 };
 EXPORT_SYMBOL(au1000_dma_table);
 
-// Device FIFO addresses and default DMA modes
+/* Device FIFO addresses and default DMA modes */
 static const struct dma_dev {
        unsigned int fifo_addr;
        unsigned int dma_mode;
@@ -80,8 +79,8 @@ static const struct dma_dev {
        {UART0_ADDR + UART_RX, 0},
        {0, 0},
        {0, 0},
-       {AC97C_DATA, DMA_DW16 },          // coherent
-       {AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
+       {AC97C_DATA, DMA_DW16 },          /* coherent */
+       {AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
        {UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
        {UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
        {USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
@@ -101,10 +100,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
        struct dma_chan *chan;
 
        for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
-               if ((chan = get_dma_chan(i)) != NULL) {
+               chan = get_dma_chan(i);
+               if (chan != NULL)
                        len += sprintf(buf + len, "%2d: %s\n",
                                       i, chan->dev_str);
-               }
        }
 
        if (fpos >= len) {
@@ -113,18 +112,19 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
                return 0;
        }
        *start = buf + fpos;
-       if ((len -= fpos) > length)
+       len -= fpos;
+       if (len > length)
                return length;
        *eof = 1;
        return len;
 }
 
-// Device FIFO addresses and default DMA modes - 2nd bank
+/* Device FIFO addresses and default DMA modes - 2nd bank */
 static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
-       {SD0_XMIT_FIFO, DMA_DS | DMA_DW8},              // coherent
-       {SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},     // coherent
-       {SD1_XMIT_FIFO, DMA_DS | DMA_DW8},              // coherent
-       {SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}      // coherent
+       { SD0_XMIT_FIFO, DMA_DS | DMA_DW8 },            /* coherent */
+       { SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 },   /* coherent */
+       { SD1_XMIT_FIFO, DMA_DS | DMA_DW8 },            /* coherent */
+       { SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }    /* coherent */
 };
 
 void dump_au1000_dma_channel(unsigned int dmanr)
@@ -150,7 +150,6 @@ void dump_au1000_dma_channel(unsigned int dmanr)
               au_readl(chan->io + DMA_BUFFER1_COUNT));
 }
 
-
 /*
  * Finds a free channel, and binds the requested device to it.
  * Returns the allocated channel number, or negative on error.
@@ -169,14 +168,14 @@ int request_au1000_dma(int dev_id, const char *dev_str,
        if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
                return -EINVAL;
 #else
-       if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+       if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
                return -EINVAL;
 #endif
 
-       for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+       for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
                if (au1000_dma_table[i].dev_id < 0)
                        break;
-       }
+
        if (i == NUM_AU1000_DMA_CHANNELS)
                return -ENODEV;
 
@@ -185,15 +184,15 @@ int request_au1000_dma(int dev_id, const char *dev_str,
        if (dev_id >= DMA_NUM_DEV) {
                dev_id -= DMA_NUM_DEV;
                dev = &dma_dev_table_bank2[dev_id];
-       } else {
+       } else
                dev = &dma_dev_table[dev_id];
-       }
 
        if (irqhandler) {
                chan->irq = AU1000_DMA_INT_BASE + i;
                chan->irq_dev = irq_dev_id;
-               if ((ret = request_irq(chan->irq, irqhandler, irqflags,
-                                      dev_str, chan->irq_dev))) {
+               ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
+                                 chan->irq_dev);
+               if (ret) {
                        chan->irq = 0;
                        chan->irq_dev = NULL;
                        return ret;
@@ -203,7 +202,7 @@ int request_au1000_dma(int dev_id, const char *dev_str,
                chan->irq_dev = NULL;
        }
 
-       // fill it in
+       /* fill it in */
        chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
        chan->dev_id = dev_id;
        chan->dev_str = dev_str;
@@ -220,8 +219,9 @@ EXPORT_SYMBOL(request_au1000_dma);
 void free_au1000_dma(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan) {
-               printk("Trying to free DMA%d\n", dmanr);
+               printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
                return;
        }
 
@@ -235,4 +235,4 @@ void free_au1000_dma(unsigned int dmanr)
 }
 EXPORT_SYMBOL(free_au1000_dma);
 
-#endif // AU1000 AU1500 AU1100
+#endif /* AU1000 AU1500 AU1100 */
index 52545258997157c5bd849f637ca7acef02a8a4fd..b485d94ce8a5055d4e28b35f8dec1c7fc3b2af9e 100644 (file)
@@ -69,7 +69,7 @@ static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
 
 static int au1xxx_gpio1_read(unsigned gpio)
 {
-       return ((gpio1->pinstaterd >> gpio) & 0x01);
+       return (gpio1->pinstaterd >> gpio) & 0x01;
 }
 
 static void au1xxx_gpio1_write(unsigned gpio, int value)
@@ -104,7 +104,6 @@ int au1xxx_gpio_get_value(unsigned gpio)
        else
                return au1xxx_gpio1_read(gpio);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_get_value);
 
 void au1xxx_gpio_set_value(unsigned gpio, int value)
@@ -118,7 +117,6 @@ void au1xxx_gpio_set_value(unsigned gpio, int value)
        else
                au1xxx_gpio1_write(gpio, value);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_set_value);
 
 int au1xxx_gpio_direction_input(unsigned gpio)
@@ -132,7 +130,6 @@ int au1xxx_gpio_direction_input(unsigned gpio)
 
        return au1xxx_gpio1_direction_input(gpio);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_direction_input);
 
 int au1xxx_gpio_direction_output(unsigned gpio, int value)
@@ -146,5 +143,4 @@ int au1xxx_gpio_direction_output(unsigned gpio, int value)
 
        return au1xxx_gpio1_direction_output(gpio, value);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_direction_output);
index f0626992fd75fce7b4f735d91c9db199ccdaba55..40c6ceceb5f9149f4f5a352c504cb6301b22a6fc 100644 (file)
@@ -210,10 +210,8 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
        au_sync();
 }
 
-
 static inline void mask_and_ack_level_irq(unsigned int irq_nr)
 {
-
        local_disable_irq(irq_nr);
        au_sync();
 #if defined(CONFIG_MIPS_PB1000)
@@ -263,14 +261,14 @@ void restore_local_and_enable(int controller, unsigned long mask)
        unsigned long flags, new_mask;
 
        spin_lock_irqsave(&irq_lock, flags);
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < 32; i++)
                if (mask & (1 << i)) {
                        if (controller)
                                local_enable_irq(i + 32);
                        else
                                local_enable_irq(i);
                }
-       }
+
        if (controller)
                new_mask = au_readl(IC1_MASKSET);
        else
index 7e966b31e3e1e2a383eaff451ba6b572aa2e2592..7866cf50cf99ce7ca5943a8f5a1a9217375d9ea4 100644 (file)
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *     Alchemy/AMD Au1x00 PCI support.
  *
- * Copyright 2001-2003, 2007 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
  *
@@ -86,9 +85,9 @@ static int __init au1x_pci_setup(void)
                u32 prid = read_c0_prid();
 
                if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
-                      au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
-                                Au1500_PCI_CFG);
-                      printk("Non-coherent PCI accesses enabled\n");
+                       au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
+                                 Au1500_PCI_CFG);
+                       printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
                }
        }
 #endif
index 31d2a2270878832354a02e4cd7f6b4b6eaf03516..8cae7753ef79931612eb5070e2236014df07fe78 100644 (file)
@@ -269,8 +269,8 @@ static struct platform_device au1x00_pcmcia_device = {
 #ifdef SMBUS_PSC_BASE
 static struct resource pbdb_smbus_resources[] = {
        {
-               .start  = SMBUS_PSC_BASE,
-               .end    = SMBUS_PSC_BASE + 0x24 - 1,
+               .start  = CPHYSADDR(SMBUS_PSC_BASE),
+               .end    = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
                .flags  = IORESOURCE_MEM,
        },
 };
@@ -302,16 +302,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
 #endif
 };
 
-int __init au1xxx_platform_init(void)
+static int __init au1xxx_platform_init(void)
 {
        unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
        int i;
 
        /* Fill up uartclk. */
-       for (i = 0; au1x00_uart_data[i].flags ; i++)
+       for (i = 0; au1x00_uart_data[i].flags; i++)
                au1x00_uart_data[i].uartclk = uartclk;
 
-       return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
+       return platform_add_devices(au1xxx_platform_devices,
+                                   ARRAY_SIZE(au1xxx_platform_devices));
 }
 
 arch_initcall(au1xxx_platform_init);
index a8cd2c1b9e1b59f313ae98a0c6e8579e0afc6dca..2166b9e1e80cf4fe1fe3452a4db5f8f852662005 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Au1000 Power Management routines.
+ *     Au1xx0 Power Management routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  *  Some of the routines are right out of init/main.c, whose
  *  copyrights apply here.
 #ifdef CONFIG_PM
 
 #define DEBUG 1
-#ifdef DEBUG
-#  define DPRINTK(fmt, args...)        printk("%s: " fmt, __func__, ## args)
+#ifdef DEBUG
+#define DPRINTK(fmt, args...)  printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
 #else
-#  define DPRINTK(fmt, args...)
+#define DPRINTK(fmt, args...)
 #endif
 
 static void au1000_calibrate_delay(void);
@@ -57,7 +56,8 @@ extern void local_enable_irq(unsigned int irq_nr);
 
 static DEFINE_SPINLOCK(pm_lock);
 
-/* We need to save/restore a bunch of core registers that are
+/*
+ * We need to save/restore a bunch of core registers that are
  * either volatile or reset to some state across a processor sleep.
  * If reading a register doesn't provide a proper result for a
  * later restore, we have to provide a function for loading that
@@ -78,24 +78,25 @@ static unsigned int sleep_usbhost_enable;
 static unsigned int    sleep_usbdev_enable;
 static unsigned int    sleep_static_memctlr[4][3];
 
-/* Define this to cause the value you write to /proc/sys/pm/sleep to
+/*
+ * Define this to cause the value you write to /proc/sys/pm/sleep to
  * set the TOY timer for the amount of time you want to sleep.
  * This is done mainly for testing, but may be useful in other cases.
  * The value is number of 32KHz ticks to sleep.
  */
 #define SLEEP_TEST_TIMEOUT 1
-#ifdef SLEEP_TEST_TIMEOUT
-static int     sleep_ticks;
+#ifdef SLEEP_TEST_TIMEOUT
+static int sleep_ticks;
 void wakeup_counter0_set(int ticks);
 #endif
 
-static void
-save_core_regs(void)
+static void save_core_regs(void)
 {
        extern void save_au1xxx_intctl(void);
        extern void pm_eth0_shutdown(void);
 
-       /* Do the serial ports.....these really should be a pm_*
+       /*
+        * Do the serial ports.....these really should be a pm_*
         * registered function by the driver......but of course the
         * standard serial driver doesn't understand our Au1xxx
         * unique registers.
@@ -106,27 +107,24 @@ save_core_regs(void)
        sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
        sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
 
-       /* Shutdown USB host/device.
-       */
+       /* Shutdown USB host/device. */
        sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
 
-       /* There appears to be some undocumented reset register....
-       */
+       /* There appears to be some undocumented reset register.... */
        au_writel(0, 0xb0100004); au_sync();
        au_writel(0, USB_HOST_CONFIG); au_sync();
 
        sleep_usbdev_enable = au_readl(USBD_ENABLE);
        au_writel(0, USBD_ENABLE); au_sync();
 
-       /* Save interrupt controller state.
-       */
+       /* Save interrupt controller state. */
        save_au1xxx_intctl();
 
-       /* Clocks and PLLs.
-       */
+       /* Clocks and PLLs. */
        sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
 
-       /* We don't really need to do this one, but unless we
+       /*
+        * We don't really need to do this one, but unless we
         * write it again it won't have a valid value if we
         * happen to read it.
         */
@@ -134,8 +132,7 @@ save_core_regs(void)
 
        sleep_pin_function = au_readl(SYS_PINFUNC);
 
-       /* Save the static memory controller configuration.
-       */
+       /* Save the static memory controller configuration. */
        sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
        sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
        sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
@@ -150,8 +147,7 @@ save_core_regs(void)
        sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
 }
 
-static void
-restore_core_regs(void)
+static void restore_core_regs(void)
 {
        extern void restore_au1xxx_intctl(void);
        extern void wakeup_counter0_adjust(void);
@@ -160,8 +156,7 @@ restore_core_regs(void)
        au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
        au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
 
-       /* Restore the static memory controller configuration.
-       */
+       /* Restore the static memory controller configuration. */
        au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
        au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
        au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
@@ -175,7 +170,8 @@ restore_core_regs(void)
        au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
        au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
 
-       /* Enable the UART if it was enabled before sleep.
+       /*
+        * Enable the UART if it was enabled before sleep.
         * I guess I should define module control bits........
         */
        if (sleep_uart0_enable & 0x02) {
@@ -202,7 +198,7 @@ void wakeup_from_suspend(void)
 int au_sleep(void)
 {
        unsigned long wakeup, flags;
-       extern  void    save_and_sleep(void);
+       extern void save_and_sleep(void);
 
        spin_lock_irqsave(&pm_lock, flags);
 
@@ -210,23 +206,22 @@ int au_sleep(void)
 
        flush_cache_all();
 
-       /** The code below is all system dependent and we should probably
+       /**
+        ** The code below is all system dependent and we should probably
         ** have a function call out of here to set this up.  You need
         ** to configure the GPIO or timer interrupts that will bring
         ** you out of sleep.
         ** For testing, the TOY counter wakeup is useful.
         **/
-
 #if 0
        au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
 
-       /* gpio 6 can cause a wake up event */
+       /* GPIO 6 can cause a wake up event */
        wakeup = au_readl(SYS_WAKEMSK);
        wakeup &= ~(1 << 8);    /* turn off match20 wakeup */
-       wakeup |= 1 << 6;       /* turn on gpio 6 wakeup   */
+       wakeup |= 1 << 6;       /* turn on  GPIO  6 wakeup */
 #else
-       /* For testing, allow match20 to wake us up.
-       */
+       /* For testing, allow match20 to wake us up. */
 #ifdef SLEEP_TEST_TIMEOUT
        wakeup_counter0_set(sleep_ticks);
 #endif
@@ -240,7 +235,8 @@ int au_sleep(void)
 
        save_and_sleep();
 
-       /* after a wakeup, the cpu vectors back to 0x1fc00000 so
+       /*
+        * After a wakeup, the cpu vectors back to 0x1fc00000, so
         * it's up to the boot code to get us back here.
         */
        restore_core_regs();
@@ -248,24 +244,22 @@ int au_sleep(void)
        return 0;
 }
 
-static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
-                      void __user *buffer, size_t * len, loff_t *ppos)
+static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
+                      void __user *buffer, size_t *len, loff_t *ppos)
 {
 #ifdef SLEEP_TEST_TIMEOUT
 #define TMPBUFLEN2 16
        char buf[TMPBUFLEN2], *p;
 #endif
 
-       if (!write) {
+       if (!write)
                *len = 0;
-       else {
+       else {
 #ifdef SLEEP_TEST_TIMEOUT
-               if (*len > TMPBUFLEN2 - 1) {
+               if (*len > TMPBUFLEN2 - 1)
                        return -EFAULT;
-               }
-               if (copy_from_user(buf, buffer, *len)) {
+               if (copy_from_user(buf, buffer, *len))
                        return -EFAULT;
-               }
                buf[*len] = 0;
                p = buf;
                sleep_ticks = simple_strtoul(p, &p, 0);
@@ -276,8 +270,8 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
        return 0;
 }
 
-static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
-                     void __user *buffer, size_t * len, loff_t *ppos)
+static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
+                     void __user *buffer, size_t *len, loff_t *ppos)
 {
        int retval = 0, i;
        unsigned long val, pll;
@@ -285,14 +279,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
 #define MAX_CPU_FREQ 396
        char buf[TMPBUFLEN], *p;
        unsigned long flags, intc0_mask, intc1_mask;
-       unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
-           old_refresh;
+       unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
        unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
+       unsigned long baud_rate;
 
        spin_lock_irqsave(&pm_lock, flags);
-       if (!write) {
+       if (!write)
                *len = 0;
-       else {
+       else {
                /* Parse the new frequency */
                if (*len > TMPBUFLEN - 1) {
                        spin_unlock_irqrestore(&pm_lock, flags);
@@ -312,7 +306,7 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
 
                pll = val / 12;
                if ((pll > 33) || (pll < 7)) {  /* 396 MHz max, 84 MHz min */
-                       /* revisit this for higher speed cpus */
+                       /* Revisit this for higher speed CPUs */
                        spin_unlock_irqrestore(&pm_lock, flags);
                        return -EFAULT;
                }
@@ -321,30 +315,28 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
                old_cpu_freq = get_au1x00_speed();
 
                new_cpu_freq = pll * 12 * 1000000;
-               new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
+               new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
+                                                           & 0x03) + 2) * 16));
                set_au1x00_speed(new_cpu_freq);
                set_au1x00_uart_baud_base(new_baud_base);
 
                old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
-               new_refresh =
-                   ((old_refresh * new_cpu_freq) /
-                    old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
+               new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
+                             (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
 
                au_writel(pll, SYS_CPUPLL);
                au_sync_delay(1);
                au_writel(new_refresh, MEM_SDREFCFG);
                au_sync_delay(1);
 
-               for (i = 0; i < 4; i++) {
-                       if (au_readl
-                           (UART_BASE + UART_MOD_CNTRL +
-                            i * 0x00100000) == 3) {
-                               old_clk =
-                                   au_readl(UART_BASE + UART_CLK +
-                                         i * 0x00100000);
-                               // baud_rate = baud_base/clk
+               for (i = 0; i < 4; i++)
+                       if (au_readl(UART_BASE + UART_MOD_CNTRL +
+                                    i * 0x00100000) == 3) {
+                               old_clk = au_readl(UART_BASE + UART_CLK +
+                                                  i * 0x00100000);
                                baud_rate = old_baud_base / old_clk;
-                               /* we won't get an exact baud rate and the error
+                               /*
+                                * We won't get an exact baud rate and the error
                                 * could be significant enough that our new
                                 * calculation will result in a clock that will
                                 * give us a baud rate that's too far off from
@@ -359,18 +351,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
                                else if (baud_rate > 17000)
                                        baud_rate = 19200;
                                else
-                                       (baud_rate = 9600);
-                               // new_clk = new_baud_base/baud_rate
+                                       baud_rate = 9600;
                                new_clk = new_baud_base / baud_rate;
-                               au_writel(new_clk,
-                                      UART_BASE + UART_CLK +
-                                      i * 0x00100000);
+                               au_writel(new_clk, UART_BASE + UART_CLK +
+                                         i * 0x00100000);
                                au_sync_delay(10);
                        }
-               }
        }
 
-
        /*
         * We don't want _any_ interrupts other than match20. Otherwise our
         * au1000_calibrate_delay() calculation will be off, potentially a lot.
@@ -428,14 +416,15 @@ static int __init pm_init(void)
 
 __initcall(pm_init);
 
-
 /*
  * This is right out of init/main.c
  */
 
-/* This is the number of bits of precision for the loops_per_jiffy.  Each
-   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
-   better than 1% */
+/*
+ * This is the number of bits of precision for the loops_per_jiffy.
+ * Each bit takes on average 1.5/HZ seconds.  This (like the original)
+ * is a little better than 1%.
+ */
 #define LPS_PREC 8
 
 static void au1000_calibrate_delay(void)
@@ -443,14 +432,14 @@ static void au1000_calibrate_delay(void)
        unsigned long ticks, loopbit;
        int lps_precision = LPS_PREC;
 
-       loops_per_jiffy = (1 << 12);
+       loops_per_jiffy = 1 << 12;
 
        while (loops_per_jiffy <<= 1) {
-               /* wait for "start of" clock tick */
+               /* Wait for "start of" clock tick */
                ticks = jiffies;
                while (ticks == jiffies)
                        /* nothing */ ;
-               /* Go .. */
+               /* Go ... */
                ticks = jiffies;
                __delay(loops_per_jiffy);
                ticks = jiffies - ticks;
@@ -458,8 +447,10 @@ static void au1000_calibrate_delay(void)
                        break;
        }
 
-/* Do a binary approximation to get loops_per_jiffy set to equal one clock
-   (up to lps_precision bits) */
+       /*
+        * Do a binary approximation to get loops_per_jiffy set to be equal
+        * one clock (up to lps_precision bits)
+        */
        loops_per_jiffy >>= 1;
        loopbit = loops_per_jiffy;
        while (lps_precision-- && (loopbit >>= 1)) {
@@ -472,4 +463,4 @@ static void au1000_calibrate_delay(void)
                        loops_per_jiffy &= ~loopbit;
        }
 }
-#endif                         /* CONFIG_PM */
+#endif /* CONFIG_PM */
index f10af829e4ec02b1292df103f6c98fca511ab258..18b310b475ca28195904f653637aedbd9bb57d7c 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *    PROM library initialisation code, supports YAMON and U-Boot.
  *
- * Copyright 2000, 2001, 2006 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/xx files.
@@ -57,7 +56,7 @@ void prom_init_cmdline(void)
        actr = 1; /* Always ignore argv[0] */
 
        cp = &(arcs_cmdline[0]);
-       while(actr < prom_argc) {
+       while (actr < prom_argc) {
                strcpy(cp, prom_argv[actr]);
                cp += strlen(prom_argv[actr]);
                *cp++ = ' ';
@@ -84,10 +83,8 @@ char *prom_getenv(char *envname)
                if (yamon) {
                        if (strcmp(envname, *env++) == 0)
                                return *env;
-               } else {
-                       if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
-                               return *env + i + 1;
-               }
+               } else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+                       return *env + i + 1;
                env++;
        }
 
@@ -110,13 +107,13 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 {
        int i;
 
-       for(i = 0; i < 6; i++) {
+       for (i = 0; i < 6; i++) {
                unsigned char num;
 
-               if((*str == '.') || (*str == ':'))
+               if ((*str == '.') || (*str == ':'))
                        str++;
-               num = str2hexnum(*str++) << 4;
-               num |= (str2hexnum(*str++));
+               num  = str2hexnum(*str++) << 4;
+               num |= str2hexnum(*str++);
                ea[i] = num;
        }
 }
index e34c67e892937527fe42f96bb9364c6d59f54475..55bbe24d45b6943e0689161525912171d669c630 100644 (file)
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *     Low level uart routines to directly access a 16550 uart.
+ *     Low level UART routines to directly access Alchemy UART.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
 
 static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
 
-
 #ifdef SLOW_DOWN
 static inline void slow_down(void)
 {
-    int k;
-    for (k=0; k<10000; k++);
+       int k;
+
+       for (k = 0; k < 10000; k++);
 }
 #else
 #define slow_down()
@@ -54,16 +53,16 @@ static inline void slow_down(void)
 void
 prom_putchar(const unsigned char c)
 {
-    unsigned char ch;
-    int i = 0;
+       unsigned char ch;
+       int i = 0;
+
+       do {
+               ch = com1[SER_CMD];
+               slow_down();
+               i++;
+               if (i > TIMEOUT)
+                       break;
+       } while (0 == (ch & TX_BUSY));
 
-    do {
-        ch = com1[SER_CMD];
-        slow_down();
-        i++;
-        if (i>TIMEOUT) {
-            break;
-        }
-    } while (0 == (ch & TX_BUSY));
-    com1[SER_DATA] = c;
+       com1[SER_DATA] = c;
 }
index 60cec537c7450cd4bb6d129f8dc83a16591f1044..d555429c8d6fff683fb8941cf872d83f3f022950 100644 (file)
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *     Au1000 reset routines.
+ *     Au1xx0 reset routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2006, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <asm/cacheflush.h>
+
 #include <asm/mach-au1x00/au1000.h>
 
 extern int au_sleep(void);
-extern void (*flush_cache_all)(void);
 
 void au1000_restart(char *command)
 {
@@ -40,8 +40,8 @@ void au1000_restart(char *command)
        u32 prid = read_c0_prid();
 
        printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
-       switch (prid & 0xFF000000)
-       {
+
+       switch (prid & 0xFF000000) {
        case 0x00000000: /* Au1000 */
                au_writel(0x02, 0xb0000010); /* ac97_enable */
                au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
@@ -138,9 +138,6 @@ void au1000_restart(char *command)
                au_writel(0x00, 0xb1900064); /* sys_auxpll */
                au_writel(0x00, 0xb1900100); /* sys_pininputen */
                break;
-
-       default:
-               break;
        }
 
        set_c0_status(ST0_BEV | ST0_ERL);
@@ -158,25 +155,25 @@ void au1000_restart(char *command)
 void au1000_halt(void)
 {
 #if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
-       /* power off system */
-       printk("\n** Powering off...\n");
-       au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
+       /* Power off system */
+       printk(KERN_NOTICE "\n** Powering off...\n");
+       au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
        au_sync();
-       while(1); /* should not get here */
+       while (1); /* should not get here */
 #else
        printk(KERN_NOTICE "\n** You can safely turn off the power\n");
 #ifdef CONFIG_MIPS_MIRAGE
        au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
 #endif
 #ifdef CONFIG_MIPS_DB1200
-       au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C);
+       au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
 #endif
 #ifdef CONFIG_PM
        au_sleep();
 
-       /* should not get here */
-       printk(KERN_ERR "Unable to put cpu in sleep mode\n");
-       while(1);
+       /* Should not get here */
+       printk(KERN_ERR "Unable to put CPU in sleep mode\n");
+       while (1);
 #else
        while (1)
                __asm__(".set\tmips3\n\t"
index 0e86f7a6b4a7f5ad60fa1a24cab5b14d7c815508..1ac6b06f42a369ef8e8d578bf33c72ef99eafe44 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com
  *
  * Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
  *
@@ -48,7 +47,7 @@ void __init plat_mem_setup(void)
 {
        struct  cpu_spec *sp;
        char *argptr;
-       unsigned long prid, cpufreq, bclk = 1;
+       unsigned long prid, cpufreq, bclk;
 
        set_cpuspec();
        sp = cur_cpu_spec[0];
@@ -66,42 +65,39 @@ void __init plat_mem_setup(void)
                cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
        printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
 
-       bclk = sp->cpu_bclk;
-       if (bclk)
-       {
+       if (sp->cpu_bclk) {
                /* Enable BCLK switching */
-               bclk = au_readl(0xB190003C);
-               au_writel(bclk | 0x60, 0xB190003C);
-               printk("BCLK switching enabled!\n");
+               bclk = au_readl(SYS_POWERCTRL);
+               au_writel(bclk | 0x60, SYS_POWERCTRL);
+               printk(KERN_INFO "BCLK switching enabled!\n");
        }
 
-       if (sp->cpu_od) {
-               /* Various early Au1000 Errata corrected by this */
-               set_c0_config(1<<19); /* Set Config[OD] */
-       }
-       else {
+       if (sp->cpu_od)
+               /* Various early Au1xx0 errata corrected by this */
+               set_c0_config(1 << 19); /* Set Config[OD] */
+       else
                /* Clear to obtain best system bus performance */
-               clear_c0_config(1<<19); /* Clear Config[OD] */
-       }
+               clear_c0_config(1 << 19); /* Clear Config[OD] */
 
        argptr = prom_getcmdline();
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
-       if ((argptr = strstr(argptr, "console=")) == NULL) {
+       argptr = strstr(argptr, "console=");
+       if (argptr == NULL) {
                argptr = prom_getcmdline();
                strcat(argptr, " console=ttyS0,115200");
        }
 #endif
 
 #ifdef CONFIG_FB_AU1100
-    if ((argptr = strstr(argptr, "video=")) == NULL) {
-        argptr = prom_getcmdline();
-        /* default panel */
-        /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-    }
+       argptr = strstr(argptr, "video=");
+       if (argptr == NULL) {
+               argptr = prom_getcmdline();
+               /* default panel */
+               /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+       }
 #endif
 
-
 #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
        /* au1000 does not support vra, au1500 and au1100 do */
        strcat(argptr, " au1000_audio=vra");
@@ -129,7 +125,7 @@ void __init plat_mem_setup(void)
 /* This routine should be valid for all Au1x based boards */
 phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 {
-       /* Don't fixup 36 bit addresses */
+       /* Don't fixup 36-bit addresses */
        if ((phys_addr >> 32) != 0)
                return phys_addr;
 
@@ -145,17 +141,17 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
        }
 #endif
 
-       /* All Au1x SOCs have a pcmcia controller */
-       /* We setup our 32 bit pseudo addresses to be equal to the
-        * 36 bit addr >> 4, to make it easier to check the address
+       /*
+        * All Au1xx0 SOCs have a PCMCIA controller.
+        * We setup our 32-bit pseudo addresses to be equal to the
+        * 36-bit addr >> 4, to make it easier to check the address
         * and fix it.
-        * The Au1x socket 0 phys attribute address is 0xF 4000 0000.
+        * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
         * The pseudo address we use is 0xF400 0000. Any address over
-        * 0xF400 0000 is a pcmcia pseudo address.
+        * 0xF400 0000 is a PCMCIA pseudo address.
         */
-       if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) {
+       if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
                return (phys_t)(phys_addr << 4);
-       }
 
        /* default nop */
        return phys_addr;
index bdb6d73b26fb19876ddff6da2da037946f144e10..563d9390a87269889e3dee6118fb8e4dd5f7e9c6 100644 (file)
  *
  * Setting up the clock on the MIPS boards.
  *
- * Update.  Always configure the kernel with CONFIG_NEW_TIME_C.  This
- * will use the user interface gettimeofday() functions from the
- * arch/mips/kernel/time.c, and we provide the clock interrupt processing
- * and the timer offset compute functions.  If CONFIG_PM is selected,
- * we also ensure the 32KHz timer is available.   -- Dan
+ * We provide the clock interrupt processing and the timer offset compute
+ * functions.  If CONFIG_PM is selected, we also ensure the 32KHz timer is
+ * available.  -- Dan
  */
 
 #include <linux/types.h>
@@ -47,8 +45,7 @@ extern int allow_au1k_wait; /* default off for CP0 Counter */
 #if HZ < 100 || HZ > 1000
 #error "unsupported HZ value! Must be in [100,1000]"
 #endif
-#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
-extern void startup_match20_interrupt(irq_handler_t handler);
+#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */
 static unsigned long last_pc0, last_match20;
 #endif
 
@@ -61,7 +58,7 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
 {
        unsigned long pc0;
        int time_elapsed;
-       static int jiffie_drift = 0;
+       static int jiffie_drift;
 
        if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
                /* should never happen! */
@@ -70,13 +67,11 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
        }
 
        pc0 = au_readl(SYS_TOYREAD);
-       if (pc0 < last_match20) {
+       if (pc0 < last_match20)
                /* counter overflowed */
                time_elapsed = (0xffffffff - last_match20) + pc0;
-       }
-       else {
+       else
                time_elapsed = pc0 - last_match20;
-       }
 
        while (time_elapsed > 0) {
                do_timer(1);
@@ -92,8 +87,9 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
        au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
        au_sync();
 
-       /* our counter ticks at 10.009765625 ms/tick, we we're running
-        * almost 10uS too slow per tick.
+       /*
+        * Our counter ticks at 10.009765625 ms/tick, we we're running
+        * almost 10 uS too slow per tick.
         */
 
        if (jiffie_drift >= 999) {
@@ -117,20 +113,17 @@ struct irqaction counter0_action = {
 /* When we wakeup from sleep, we have to "catch up" on all of the
  * timer ticks we have missed.
  */
-void
-wakeup_counter0_adjust(void)
+void wakeup_counter0_adjust(void)
 {
        unsigned long pc0;
        int time_elapsed;
 
        pc0 = au_readl(SYS_TOYREAD);
-       if (pc0 < last_match20) {
+       if (pc0 < last_match20)
                /* counter overflowed */
                time_elapsed = (0xffffffff - last_match20) + pc0;
-       }
-       else {
+       else
                time_elapsed = pc0 - last_match20;
-       }
 
        while (time_elapsed > 0) {
                time_elapsed -= MATCH20_INC;
@@ -143,10 +136,8 @@ wakeup_counter0_adjust(void)
 
 }
 
-/* This is just for debugging to set the timer for a sleep delay.
-*/
-void
-wakeup_counter0_set(int ticks)
+/* This is just for debugging to set the timer for a sleep delay. */
+void wakeup_counter0_set(int ticks)
 {
        unsigned long pc0;
 
@@ -157,21 +148,22 @@ wakeup_counter0_set(int ticks)
 }
 #endif
 
-/* I haven't found anyone that doesn't use a 12 MHz source clock,
+/*
+ * I haven't found anyone that doesn't use a 12 MHz source clock,
  * but just in case.....
  */
 #define AU1000_SRC_CLK 12000000
 
 /*
  * We read the real processor speed from the PLL.  This is important
- * because it is more accurate than computing it from the 32KHz
+ * because it is more accurate than computing it from the 32 KHz
  * counter, if it exists.  If we don't have an accurate processor
  * speed, all of the peripherals that derive their clocks based on
  * this advertised speed will introduce error and sometimes not work
  * properly.  This function is futher convoluted to still allow configurations
  * to do that in case they have really, really old silicon with a
- * write-only PLL register, that we need the 32KHz when power management
- * "wait" is enabled, and we need to detect if the 32KHz isn't present
+ * write-only PLL register, that we need the 32 KHz when power management
+ * "wait" is enabled, and we need to detect if the 32 KHz isn't present
  * but requested......got it? :-)              -- Dan
  */
 unsigned long calc_clock(void)
@@ -182,8 +174,7 @@ unsigned long calc_clock(void)
 
        spin_lock_irqsave(&time_lock, flags);
 
-       /* Power management cares if we don't have a 32KHz counter.
-       */
+       /* Power management cares if we don't have a 32 KHz counter. */
        no_au1xxx_32khz = 0;
        counter = au_readl(SYS_COUNTER_CNTRL);
        if (counter & SYS_CNTRL_E0) {
@@ -193,7 +184,7 @@ unsigned long calc_clock(void)
 
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
                /* RTC now ticks at 32.768/16 kHz */
-               au_writel(trim_divide-1, SYS_RTCTRIM);
+               au_writel(trim_divide - 1, SYS_RTCTRIM);
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
 
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
@@ -215,9 +206,11 @@ unsigned long calc_clock(void)
 #endif
        else
                cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
+       /* On Alchemy CPU:counter ratio is 1:1 */
        mips_hpt_frequency = cpu_speed;
-       // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
-       set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
+       /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
+       set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
+                                                         & 0x03) + 2) * 16));
        spin_unlock_irqrestore(&time_lock, flags);
        return cpu_speed;
 }
@@ -228,10 +221,10 @@ void __init plat_time_init(void)
 
        est_freq += 5000;    /* round */
        est_freq -= est_freq%10000;
-       printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-              (est_freq%1000000)*100/1000000);
-       set_au1x00_speed(est_freq);
-       set_au1x00_lcd_clock(); // program the LCD clock
+       printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
+              est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
+       set_au1x00_speed(est_freq);
+       set_au1x00_lcd_clock(); /* program the LCD clock */
 
 #ifdef CONFIG_PM
        /*
@@ -243,30 +236,29 @@ void __init plat_time_init(void)
         * counter 0 interrupt as a special irq and it doesn't show
         * up under /proc/interrupts.
         *
-        * Check to ensure we really have a 32KHz oscillator before
+        * Check to ensure we really have a 32 KHz oscillator before
         * we do this.
         */
        if (no_au1xxx_32khz)
-               printk("WARNING: no 32KHz clock found.\n");
+               printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
        else {
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
                au_writel(0, SYS_TOYWRITE);
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
 
-               au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+               au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
                au_writel(~0, SYS_WAKESRC);
                au_sync();
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 
-               /* setup match20 to interrupt once every HZ */
+               /* Setup match20 to interrupt once every HZ */
                last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
                au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
                au_sync();
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
                setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
 
-               /* We can use the real 'wait' instruction.
-               */
+               /* We can use the real 'wait' instruction. */
                allow_au1k_wait = 1;
        }
 
index 51d62bd5d900f93ad5408e71a3df031e027ea840..274db3b55d829f5d77336cfde244f3b3ab8dfdae 100644 (file)
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
 #
-# Makefile for the Alchemy Semiconductor Db1x00 board.
 
 lib-y := init.o board_setup.o irqmap.o
index b7dcbad5c5861070b267393f3f44e1fce1c036ff..9e5ccbbfcedd83dc8f11ab0a1b2ac86cf480d01b 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     Alchemy Db1x00 board setup.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -37,49 +36,49 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 
 void board_reset(void)
 {
-       /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+       /* Hit BCSR.SW_RESET[RESET] */
        bcsr->swreset = 0x0000;
 }
 
 void __init board_setup(void)
 {
-       u32 pin_func;
+       u32 pin_func = 0;
 
-       pin_func = 0;
-       /* not valid for 1550 */
-
-#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
-       /* set IRFIRSEL instead of GPIO15 */
-       pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
+       /* Not valid for Au1550 */
+#if defined(CONFIG_IRDA) && \
+   (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+       /* Set IRFIRSEL instead of GPIO15 */
+       pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
        au_writel(pin_func, SYS_PINFUNC);
-       /* power off until the driver is in use */
+       /* Power off until the driver is in use */
        bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
-       bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
+       bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
        au_sync();
 #endif
        bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
 
 #ifdef CONFIG_MIPS_MIRAGE
-       /* enable GPIO[31:0] inputs */
+       /* Enable GPIO[31:0] inputs */
        au_writel(0, SYS_PININPUTEN);
 
-       /* GPIO[20] is output, tristate the other input primary GPIO's */
-       au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
+       /* GPIO[20] is output, tristate the other input primary GPIOs */
+       au_writel(~(1 << 20), SYS_TRIOUTCLR);
 
-       /* set GPIO[210:208] instead of SSI_0 */
-       pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
+       /* Set GPIO[210:208] instead of SSI_0 */
+       pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
 
-       /* set GPIO[215:211] for LED's */
-       pin_func |= (u32)((5<<2));
+       /* Set GPIO[215:211] for LEDs */
+       pin_func |= 5 << 2;
 
-       /* set GPIO[214:213] for more LED's */
-       pin_func |= (u32)((5<<12));
+       /* Set GPIO[214:213] for more LEDs */
+       pin_func |= 5 << 12;
 
-       /* set GPIO[207:200] instead of PCMCIA/LCD */
-       pin_func |= (u32)((3<<17));
+       /* Set GPIO[207:200] instead of PCMCIA/LCD */
+       pin_func |= SYS_PF_LCD | SYS_PF_PC;
        au_writel(pin_func, SYS_PINFUNC);
 
-       /* Enable speaker amplifier.  This should
+       /*
+        * Enable speaker amplifier.  This should
         * be part of the audio driver.
         */
        au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
@@ -89,21 +88,21 @@ void __init board_setup(void)
        au_sync();
 
 #ifdef CONFIG_MIPS_DB1000
-    printk("AMD Alchemy Au1000/Db1000 Board\n");
+       printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1500
-    printk("AMD Alchemy Au1500/Db1500 Board\n");
+       printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1100
-    printk("AMD Alchemy Au1100/Db1100 Board\n");
+       printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
 #endif
 #ifdef CONFIG_MIPS_BOSPORUS
-    printk("AMD Alchemy Bosporus Board\n");
+       printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
 #endif
 #ifdef CONFIG_MIPS_MIRAGE
-    printk("AMD Alchemy Mirage Board\n");
+       printk(KERN_INFO "AMD Alchemy Mirage Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1550
-    printk("AMD Alchemy Au1550/Db1550 Board\n");
+       printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
 #endif
 }
index d3b967caf70c10729a7b1bb5a2681890c696a0a9..5ebe0de5e4590e404e8ba11c2a86730fd38bed16 100644 (file)
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *     PB1000 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -49,8 +48,8 @@ void __init prom_init(void)
        unsigned long memsize;
 
        prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
 
@@ -58,6 +57,6 @@ void __init prom_init(void)
        if (!memsize_str)
                memsize = 0x04000000;
        else
-               memsize = simple_strtol(memsize_str, NULL, 0);
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index eaa50c7b6341cdcf5407fbd58a69827accac7ef4..94c090e8bf7a61e29f04de475d00ef466933e49a 100644 (file)
 
 #ifdef CONFIG_MIPS_DB1500
 char irq_tab_alchemy[][5] __initdata = {
[12] =        { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
[13] =        { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
      [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371   */
      [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
 };
 #endif
 
 #ifdef CONFIG_MIPS_BOSPORUS
 char irq_tab_alchemy[][5] __initdata = {
[11] =        { -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
[12] =        { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
[13] =        { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
      [11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI  */
      [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741   */
      [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
 };
 #endif
 
 #ifdef CONFIG_MIPS_MIRAGE
 char irq_tab_alchemy[][5] __initdata = {
[11] =        { -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
[12] =        { -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
[13] =        { -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
      [11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
      [12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
      [13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
 };
 #endif
 
 #ifdef CONFIG_MIPS_DB1550
 char irq_tab_alchemy[][5] __initdata = {
[11] =        { -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
[12] =        { -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
[13] =        { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
      [11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
      [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
      [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
 };
 #endif
 
index 85a90941de4ff9c1b900fe52f44e3900e84ec5f2..7c67b3d33bec16a6b132b1e38a12f987d9eeb944 100644 (file)
@@ -1,7 +1,6 @@
 #
 #  Copyright 2003 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #       Bruno Randolf <bruno.randolf@4g-systems.biz>
 #
 # Makefile for 4G Systems MTX-1 board.
index 5736354829c6a2d4356cba3a978f29694981c720..3f8079186cf2bc62a1a9a5c595df2d3caa4bac47 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     4G Systems MTX-1 board setup.
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *         Bruno Randolf <bruno.randolf@4g-systems.biz>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -34,7 +33,7 @@
 #include <asm/mach-au1x00/au1000.h>
 
 extern int (*board_pci_idsel)(unsigned int devsel, int assert);
-int    mtx1_pci_idsel(unsigned int devsel, int assert);
+int mtx1_pci_idsel(unsigned int devsel, int assert);
 
 void board_reset(void)
 {
@@ -45,36 +44,36 @@ void board_reset(void)
 void __init board_setup(void)
 {
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-       // enable USB power switch
-       au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
-       au_writel( 0x100000, GPIO2_OUTPUT );
+       /* Enable USB power switch */
+       au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
+       au_writel(0x100000, GPIO2_OUTPUT);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
-       au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+       au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
        au_writel(0xf, Au1500_PCI_CFG);
 #endif
 #endif
 
-       // initialize sys_pinfunc:
-       au_writel( SYS_PF_NI2, SYS_PINFUNC );
+       /* Initialize sys_pinfunc */
+       au_writel(SYS_PF_NI2, SYS_PINFUNC);
 
-       // initialize GPIO
-       au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR );
-       au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF
-       au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF
-       au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
-       au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF
+       /* Initialize GPIO */
+       au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
+       au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */
+       au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */
+       au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
+       au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */
 
-       // enable LED and set it to green
-       au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR );
-       au_writel( 0x18000800, GPIO2_OUTPUT );
+       /* Enable LED and set it to green */
+       au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR);
+       au_writel(0x18000800, GPIO2_OUTPUT);
 
        board_pci_idsel = mtx1_pci_idsel;
 
-       printk("4G Systems MTX-1 Board\n");
+       printk(KERN_INFO "4G Systems MTX-1 Board\n");
 }
 
 int
@@ -82,20 +81,18 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
 {
 #define MTX_IDSEL_ONLY_0_AND_3 0
 #if MTX_IDSEL_ONLY_0_AND_3
-       if (devsel != 0 && devsel != 3) {
-               printk("*** not 0 or 3\n");
-               return 0;
-       }
+       if (devsel != 0 && devsel != 3) {
+               printk(KERN_ERR "*** not 0 or 3\n");
+               return 0;
+       }
 #endif
 
-       if (assert && devsel != 0) {
-               // suppress signal to cardbus
-               au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF
-       }
-       else {
-               au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
-       }
-       au_sync_udelay(1);
-       return 1;
+       if (assert && devsel != 0)
+               /* Suppress signal to Cardbus */
+               au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */
+       else
+               au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
+       au_sync_udelay(1);
+       return 1;
 }
 
index c015cbce1cca4b0c7b5063b39ffcc3362dd8bc4b..33a4aebe0cba37a33f3d89e918caaa03e1d40673 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     4G Systems MTX-1 board setup
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *         Bruno Randolf <bruno.randolf@4g-systems.biz>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -47,8 +46,8 @@ void __init prom_init(void)
        unsigned long memsize;
 
        prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
 
@@ -56,6 +55,6 @@ void __init prom_init(void)
        if (!memsize_str)
                memsize = 0x04000000;
        else
-               memsize = simple_strtol(memsize_str, NULL, 0);
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index 78d70c42c9dbc8265814f164bd51db83fb6741df..f2bf02951e9cb426ea92363963339eff6bcc08e4 100644 (file)
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, INTA, INTA, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
[1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
[3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
[5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
[7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
      [0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
      [1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
      [2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
      [3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
      [4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
      [5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
      [6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
      [7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
index a7edbf0829ac3b3ff13495421a738c26ef8fc9d7..9807be37c32f6fb61a00c90686599d80f3bf6bc9 100644 (file)
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 
-#include <asm/gpio.h>
-
 static struct gpio_keys_button mtx1_gpio_button[] = {
        {
                .gpio = 207,
index daa1a507e72f878e5af951bdf8f3e03998fd6963..99bbec0ca41bf9bcc6c8abe7cae650d1e6da5046 100644 (file)
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor Pb1000 board.
 #
-# Makefile for the Alchemy Semiconductor PB1000 board.
 
 lib-y := init.o board_setup.o irqmap.o
index 33f15acc1b17677bb6ae6b2191142aaec6267e01..25df167a95b3550a8b6599a8f7cc5aa0b464dc46 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -40,128 +39,126 @@ void __init board_setup(void)
        u32 sys_freqctrl, sys_clksrc;
        u32 prid = read_c0_prid();
 
-       // set AUX clock to 12MHz * 8 = 96 MHz
+       /* Set AUX clock to 12 MHz * 8 = 96 MHz */
        au_writel(8, SYS_AUXPLL);
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-       /* zero and disable FREQ2 */
+       /* Zero and disable FREQ2 */
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
        au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-       /* zero and disable USBH/USBD clocks */
+       /* Zero and disable USBH/USBD clocks */
        sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
+       sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+                       SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
        au_writel(sys_clksrc, SYS_CLKSRC);
 
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
 
        sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
+       sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+                       SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 
-       switch (prid & 0x000000FF)
-       {
+       switch (prid & 0x000000FF) {
        case 0x00: /* DA */
        case 0x01: /* HA */
        case 0x02: /* HB */
-       /* CPU core freq to 48MHz to slow it way down... */
-       au_writel(4, SYS_CPUPLL);
+               /* CPU core freq to 48 MHz to slow it way down... */
+               au_writel(4, SYS_CPUPLL);
 
-       /*
-        * Setup 48MHz FREQ2 from CPUPLL for USB Host
-        */
-       /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
-       sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
-       au_writel(sys_freqctrl, SYS_FREQCTRL0);
+               /*
+                * Setup 48 MHz FREQ2 from CPUPLL for USB Host
+                * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
+                */
+               sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-       /* CPU core freq to 384MHz */
-       au_writel(0x20, SYS_CPUPLL);
+               /* CPU core freq to 384 MHz */
+               au_writel(0x20, SYS_CPUPLL);
 
-       printk("Au1000: 48MHz OHCI workaround enabled\n");
+               printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
                break;
 
-       default:  /* HC and newer */
-       // FREQ2 = aux/2 = 48 MHz
-       sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-       au_writel(sys_freqctrl, SYS_FREQCTRL0);
+       default: /* HC and newer */
+               /* FREQ2 = aux / 2 = 48 MHz */
+               sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+                                SYS_FC_FE2 | SYS_FC_FS2;
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
                break;
        }
 
        /*
-        * Route 48MHz FREQ2 into USB Host and/or Device
+        * Route 48 MHz FREQ2 into USB Host and/or Device
         */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-       sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
+       sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
        au_writel(sys_clksrc, SYS_CLKSRC);
 
-       // configure pins GPIO[14:9] as GPIO
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
+       /* Configure pins GPIO[14:9] as GPIO */
+       pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
 
-       // 2nd USB port is USB host
-       pin_func |= 0x8000;
+       /* 2nd USB port is USB host */
+       pin_func |= SYS_PF_USB;
 
        au_writel(pin_func, SYS_PINFUNC);
        au_writel(0x2800, SYS_TRIOUTCLR);
        au_writel(0x0030, SYS_OUTPUTCLR);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
-       // make gpio 15 an input (for interrupt line)
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
-       // we don't need I2S, so make it available for GPIO[31:29]
-       pin_func |= (1<<5);
+       /* Make GPIO 15 an input (for interrupt line) */
+       pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
+       /* We don't need I2S, so make it available for GPIO[31:29] */
+       pin_func |= SYS_PF_I2S;
        au_writel(pin_func, SYS_PINFUNC);
 
        au_writel(0x8000, SYS_TRIOUTCLR);
 
-       static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
+       static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
        au_writel(static_cfg0, MEM_STCFG0);
 
-       // configure RCE2* for LCD
+       /* configure RCE2* for LCD */
        au_writel(0x00000004, MEM_STCFG2);
 
-       // MEM_STTIME2
+       /* MEM_STTIME2 */
        au_writel(0x09000000, MEM_STTIME2);
 
-       // Set 32-bit base address decoding for RCE2*
+       /* Set 32-bit base address decoding for RCE2* */
        au_writel(0x10003ff0, MEM_STADDR2);
 
-       // PCI CPLD setup
-       // expand CE0 to cover PCI
+       /*
+        * PCI CPLD setup
+        * Expand CE0 to cover PCI
+        */
        au_writel(0x11803e40, MEM_STADDR1);
 
-       // burst visibility on
+       /* Burst visibility on */
        au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
 
-       au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
-       au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+       au_writel(0x83, MEM_STCFG1);         /* ewait enabled, flash timing */
+       au_writel(0x33030a10, MEM_STTIME1);  /* slower timing for FPGA */
 
-       /* setup the static bus controller */
+       /* Setup the static bus controller */
        au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
        au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
        au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
-#ifdef CONFIG_PCI
-       au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
-       au_writel(0, SDRAM_MBAR);        // set mbar to 0
-       au_writel(0x2, SDRAM_CMD);       // enable memory accesses
-       au_sync_delay(1);
-#endif
-
-       /* Enable Au1000 BCLK switching - note: sed1356 must not use
-        * its BCLK (Au1000 LCLK) for any timings */
-       switch (prid & 0x000000FF)
-       {
+       /*
+        * Enable Au1000 BCLK switching - note: sed1356 must not use
+        * its BCLK (Au1000 LCLK) for any timings
+        */
+       switch (prid & 0x000000FF) {
        case 0x00: /* DA */
        case 0x01: /* HA */
        case 0x02: /* HB */
                break;
        default:  /* HC and newer */
-               /* Enable sys bus clock divider when IDLE state or no bus
-                  activity. */
+               /*
+                * Enable sys bus clock divider when IDLE state or no bus
+                * activity.
+                */
                au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
                break;
        }
index 549447df71d6f66d0c118a9860c4af7e8bb48857..3837365d613d54bf65b01acff016eb7e805e12e6 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     PB1000 board setup
+ *     Pb1000 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -44,16 +43,15 @@ void __init prom_init(void)
        unsigned char *memsize_str;
        unsigned long memsize;
 
-       prom_argc = (int) fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argc = (int)fw_arg0;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str) {
+       if (!memsize_str)
                memsize = 0x04000000;
-       } else {
-               memsize = simple_strtol(memsize_str, NULL, 0);
-       }
+       else
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index 996236df6375b2ddd53ce8361a59cf8e5ef65834..793e97c49e46d7f74871170be1e713d99d0894e9 100644 (file)
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000,2001 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for the Alchemy Semiconductor Pb1100 board.
+#
 
 lib-y := init.o board_setup.o irqmap.o
index 656164c8e9cafb4b4219c15b42fb0d63a8a9a174..c0bfd59a7a368f1dde18c428a5c9aa41df5a6087 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2002, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-    au_writel(0x00000000, 0xAE00001C);
+       /* Hit BCSR.RST_VDDI[SOFT_RESET] */
+       au_writel(0x00000000, PB1100_RST_VDDI);
 }
 
 void __init board_setup(void)
 {
-       volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;
+       volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
 
-       // set AUX clock to 12MHz * 8 = 96 MHz
+       /* Set AUX clock to 12 MHz * 8 = 96 MHz */
        au_writel(8, SYS_AUXPLL);
        au_writel(0, SYS_PININPUTEN);
        udelay(100);
@@ -49,44 +48,47 @@ void __init board_setup(void)
        {
                u32 pin_func, sys_freqctrl, sys_clksrc;
 
-               // configure pins GPIO[14:9] as GPIO
-               pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+               /* Configure pins GPIO[14:9] as GPIO */
+               pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
 
-               /* zero and disable FREQ2 */
+               /* Zero and disable FREQ2 */
                sys_freqctrl = au_readl(SYS_FREQCTRL0);
                sys_freqctrl &= ~0xFFF00000;
                au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-               /* zero and disable USBH/USBD/IrDA clock */
+               /* Zero and disable USBH/USBD/IrDA clock */
                sys_clksrc = au_readl(SYS_CLKSRC);
-               sys_clksrc &= ~0x0000001F;
+               sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
                au_writel(sys_clksrc, SYS_CLKSRC);
 
                sys_freqctrl = au_readl(SYS_FREQCTRL0);
                sys_freqctrl &= ~0xFFF00000;
 
                sys_clksrc = au_readl(SYS_CLKSRC);
-               sys_clksrc &= ~0x0000001F;
+               sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
 
-               // FREQ2 = aux/2 = 48 MHz
-               sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+               /* FREQ2 = aux / 2 = 48 MHz */
+               sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+                               SYS_FC_FE2 | SYS_FC_FS2;
                au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
                /*
-                * Route 48MHz FREQ2 into USBH/USBD/IrDA
+                * Route 48 MHz FREQ2 into USBH/USBD/IrDA
                 */
-               sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+               sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
                au_writel(sys_clksrc, SYS_CLKSRC);
 
-               /* setup the static bus controller */
+               /* Setup the static bus controller */
                au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
                au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
                au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
-               // get USB Functionality pin state (device vs host drive pins)
-               pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-               // 2nd USB port is USB host
-               pin_func |= 0x8000;
+               /*
+                * Get USB Functionality pin state (device vs host drive pins).
+                */
+               pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+               /* 2nd USB port is USB host. */
+               pin_func |= SYS_PF_USB;
                au_writel(pin_func, SYS_PINFUNC);
        }
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
@@ -94,12 +96,12 @@ void __init board_setup(void)
        /* Enable sys bus clock divider when IDLE state or no bus activity. */
        au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
 
-       // Enable the RTC if not already enabled
+       /* Enable the RTC if not already enabled. */
        if (!(readb(base + 0x28) & 0x20)) {
                writeb(readb(base + 0x28) | 0x20, base + 0x28);
                au_sync();
        }
-       // Put the clock in BCD mode
+       /* Put the clock in BCD mode. */
        if (readb(base + 0x2C) & 0x4) { /* reg B */
                writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
                au_sync();
index c91344648ed317f8fe5f160395a62c83fd1322b4..8355483f3de2a65503e60ac5801eada3679ee08b 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     Pb1100 board setup
  *
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2002, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -46,8 +45,8 @@ void __init prom_init(void)
        unsigned long memsize;
 
        prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg3;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg3;
 
        prom_init_cmdline();
 
@@ -55,7 +54,7 @@ void __init prom_init(void)
        if (!memsize_str)
                memsize = 0x04000000;
        else
-               memsize = simple_strtol(memsize_str, NULL, 0);
+               memsize = strict_strtol(memsize_str, 0, NULL);
 
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index b5021e3d477fcabd3b7db8222487380b14ee97f3..9b7dd8b41283c92e72ec8fa8cbce9ff64abc0c2f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Au1xxx irq map table
+ *     Au1xx0 IRQ map table
  *
  * Copyright 2003 Embedded Edge, LLC
  *             dan@embeddededge.com
 #include <asm/mach-au1x00/au1000.h>
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
-       { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
-       { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
-       { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
+       { AU1000_GPIO_9,  INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
+       { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
+       { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
+       { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
 };
 
 int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
index 4fe02ea65a60e13b20e5706532e95260492c044b..d678adf7ce85fada6e5e7f463b2d062482e559a6 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Makefile for the Alchemy Semiconductor PB1200 board.
+# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
 #
 
 lib-y := init.o board_setup.o irqmap.o
index 4493a792cc4c5a79d83b058c2066b3aac18a1437..6cb2115059adaf84a73ac6387037f276f625ecb5 100644 (file)
 #include <linux/init.h>
 #include <linux/sched.h>
 
-#include <au1000.h>
 #include <prom.h>
-
-#ifdef CONFIG_MIPS_PB1200
-#include <asm/mach-pb1x00/pb1200.h>
-#endif
-
-#ifdef CONFIG_MIPS_DB1200
-#include <asm/mach-db1x00/db1200.h>
-#endif
+#include <au1xxx.h>
 
 extern void _board_init_irq(void);
 extern void (*board_init_irq)(void);
@@ -53,56 +45,57 @@ void __init board_setup(void)
 
 #if 0
        {
-       u32 pin_func;
-
-       /* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
-        * but it is board specific code, so put it here.
-        */
-       pin_func = au_readl(SYS_PINFUNC);
-       au_sync();
-       pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
-       au_writel(pin_func, SYS_PINFUNC);
-
-       au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
-       au_sync();
+               u32 pin_func;
+
+               /*
+                * Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+                * but it is board specific code, so put it here.
+                */
+               pin_func = au_readl(SYS_PINFUNC);
+               au_sync();
+               pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+               au_writel(pin_func, SYS_PINFUNC);
+
+               au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
+               au_sync();
        }
 #endif
 
 #if defined(CONFIG_I2C_AU1550)
        {
-       u32 freq0, clksrc;
-       u32 pin_func;
-
-       /* Select SMBUS in CPLD */
-       bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
-
-       pin_func = au_readl(SYS_PINFUNC);
-       au_sync();
-       pin_func &= ~(3<<17 | 1<<4);
-       /* Set GPIOs correctly */
-       pin_func |= 2<<17;
-       au_writel(pin_func, SYS_PINFUNC);
-       au_sync();
-
-       /* The i2c driver depends on 50Mhz clock */
-       freq0 = au_readl(SYS_FREQCTRL0);
-       au_sync();
-       freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
-       freq0 |= (3<<SYS_FC_FRDIV1_BIT);
-       /* 396Mhz / (3+1)*2 == 49.5Mhz */
-       au_writel(freq0, SYS_FREQCTRL0);
-       au_sync();
-       freq0 |= SYS_FC_FE1;
-       au_writel(freq0, SYS_FREQCTRL0);
-       au_sync();
-
-       clksrc = au_readl(SYS_CLKSRC);
-       au_sync();
-       clksrc &= ~0x01f00000;
-       /* bit 22 is EXTCLK0 for PSC0 */
-       clksrc |= (0x3 << 22);
-       au_writel(clksrc, SYS_CLKSRC);
-       au_sync();
+               u32 freq0, clksrc;
+               u32 pin_func;
+
+               /* Select SMBus in CPLD */
+               bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
+
+               pin_func = au_readl(SYS_PINFUNC);
+               au_sync();
+               pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+               /* Set GPIOs correctly */
+               pin_func |= 2 << 17;
+               au_writel(pin_func, SYS_PINFUNC);
+               au_sync();
+
+               /* The I2C driver depends on 50 MHz clock */
+               freq0 = au_readl(SYS_FREQCTRL0);
+               au_sync();
+               freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+               freq0 |= 3 << SYS_FC_FRDIV1_BIT;
+               /* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
+               au_writel(freq0, SYS_FREQCTRL0);
+               au_sync();
+               freq0 |= SYS_FC_FE1;
+               au_writel(freq0, SYS_FREQCTRL0);
+               au_sync();
+
+               clksrc = au_readl(SYS_CLKSRC);
+               au_sync();
+               clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
+               /* Bit 22 is EXTCLK0 for PSC0 */
+               clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
+               au_writel(clksrc, SYS_CLKSRC);
+               au_sync();
        }
 #endif
 
@@ -116,27 +109,27 @@ void __init board_setup(void)
 #endif
 #endif
 
-       /* The Pb1200 development board uses external MUX for PSC0 to
-       support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
-       */
+       /*
+        * The Pb1200 development board uses external MUX for PSC0 to
+        * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+        */
 #ifdef CONFIG_I2C_AU1550
-       bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
+       bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
 #endif
        au_sync();
 
 #ifdef CONFIG_MIPS_PB1200
-       printk("AMD Alchemy Pb1200 Board\n");
+       printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1200
-       printk("AMD Alchemy Db1200 Board\n");
+       printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
 #endif
 
        /* Setup Pb1200 External Interrupt Controller */
        board_init_irq = _board_init_irq;
 }
 
-int
-board_au1200fb_panel(void)
+int board_au1200fb_panel(void)
 {
        BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
        int p;
@@ -147,23 +140,23 @@ board_au1200fb_panel(void)
        return p;
 }
 
-int
-board_au1200fb_panel_init(void)
+int board_au1200fb_panel_init(void)
 {
        /* Apply power */
-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-       bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
-       /*printk("board_au1200fb_panel_init()\n"); */
+       BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+       bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
+       /* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
        return 0;
 }
 
-int
-board_au1200fb_panel_shutdown(void)
+int board_au1200fb_panel_shutdown(void)
 {
        /* Remove power */
-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-       bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
-       /*printk("board_au1200fb_panel_shutdown()\n"); */
+       BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+       bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+                        BCSR_BOARD_LCDBL);
+       /* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
        return 0;
 }
-
index 72af5500660b0517c9f0fec4253da6fdabeaacaf..09fd63b86062060719490113a5ba9cfdee83c74e 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     PB1200 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@ void __init prom_init(void)
        unsigned char *memsize_str;
        unsigned long memsize;
 
-       prom_argc = (int) fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argc = (int)fw_arg0;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str) {
+       if (!memsize_str)
                memsize = 0x08000000;
-       } else {
-               memsize = simple_strtol(memsize_str, NULL, 0);
-       }
+       else
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index e61eb8e0b76bd96cccc2196a95ff9e86d83f9511..2a505ad8715b482b635a47e5ce4a28f88a59945b 100644 (file)
 #endif
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
+       /* This is external interrupt cascade */
+       { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 },
 };
 
 int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
 
 /*
- *     Support for External interrupts on the PbAu1200 Development platform.
+ * Support for External interrupts on the Pb1200 Development platform.
  */
-static volatile int pb1200_cascade_en=0;
+static volatile int pb1200_cascade_en;
 
-irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
+irqreturn_t pb1200_cascade_handler(int irq, void *dev_id)
 {
        unsigned short bisr = bcsr->int_status;
        int extirq_nr = 0;
 
-       /* Clear all the edge interrupts. This has no effect on level */
+       /* Clear all the edge interrupts. This has no effect on level. */
        bcsr->int_status = bisr;
-       for( ; bisr; bisr &= (bisr-1) )
-       {
+       for ( ; bisr; bisr &= bisr - 1) {
                extirq_nr = PB1200_INT_BEGIN + __ffs(bisr);
                /* Ack and dispatch IRQ */
                do_IRQ(extirq_nr);
@@ -68,26 +68,20 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
 
 inline void pb1200_enable_irq(unsigned int irq_nr)
 {
-       bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
-       bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
+       bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+       bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
 }
 
 inline void pb1200_disable_irq(unsigned int irq_nr)
 {
-       bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
-       bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
+       bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+       bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
 }
 
 static unsigned int pb1200_setup_cascade(void)
 {
-       int err;
-
-       err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
-                         0, "Pb1200 Cascade", &pb1200_cascade_handler);
-       if (err)
-               return err;
-
-       return 0;
+       return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
+                          0, "Pb1200 Cascade", &pb1200_cascade_handler);
 }
 
 static unsigned int pb1200_startup_irq(unsigned int irq)
@@ -132,23 +126,23 @@ void _board_init_irq(void)
        unsigned int irq;
 
 #ifdef CONFIG_MIPS_PB1200
-       /* We have a problem with CPLD rev3. Enable a workaround */
+       /* We have a problem with CPLD rev 3. */
        if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
-               printk("updated to latest revision. This software will not\n");
-               printk("work on anything less than CPLD rev4\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
-               printk("\nWARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
+               printk(KERN_ERR "updated to latest revision. This software will\n");
+               printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
+               printk(KERN_ERR "WARNING!!!\n");
                panic("Game over.  Your score is 0.");
        }
 #endif
@@ -161,6 +155,6 @@ void _board_init_irq(void)
 
        /*
         * GPIO_7 can not be hooked here, so it is hooked upon first
-        * request of any source attached to the cascade
+        * request of any source attached to the cascade.
         */
 }
index 97a730813cd37508ab20bf7f934a54e42f4b60da..602f38df20bbfe659e92bada6685637f2a2f0433 100644 (file)
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000,2001 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for the Alchemy Semiconductor Pb1500 board.
+#
 
 lib-y := init.o board_setup.o irqmap.o
index 24c652e8ec4b7f542b264430ed3e6b4ef4b61fab..035771c6e5b88f0faab9d99ca13a133157f2bdcd 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -32,8 +31,8 @@
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-    au_writel(0x00000000, 0xAE00001C);
+       /* Hit BCSR.RST_VDDI[SOFT_RESET] */
+       au_writel(0x00000000, PB1500_RST_VDDI);
 }
 
 void __init board_setup(void)
@@ -42,7 +41,7 @@ void __init board_setup(void)
        u32 sys_freqctrl, sys_clksrc;
 
        sys_clksrc = sys_freqctrl = pin_func = 0;
-       // set AUX clock to 12MHz * 8 = 96 MHz
+       /* Set AUX clock to 12 MHz * 8 = 96 MHz */
        au_writel(8, SYS_AUXPLL);
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
@@ -51,51 +50,48 @@ void __init board_setup(void)
 
        /* GPIO201 is input for PCMCIA card detect */
        /* GPIO203 is input for PCMCIA interrupt request */
-       au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);
+       au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR);
 
-       /* zero and disable FREQ2 */
+       /* Zero and disable FREQ2 */
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
        au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
        /* zero and disable USBH/USBD clocks */
        sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
+       sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+                       SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
        au_writel(sys_clksrc, SYS_CLKSRC);
 
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
 
        sys_clksrc = au_readl(SYS_CLKSRC);
-       sys_clksrc &= ~0x00007FE0;
+       sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+                       SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 
-       // FREQ2 = aux/2 = 48 MHz
-       sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+       /* FREQ2 = aux/2 = 48 MHz */
+       sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
        au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
        /*
         * Route 48MHz FREQ2 into USB Host and/or Device
         */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-       sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
+       sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
        au_writel(sys_clksrc, SYS_CLKSRC);
 
-
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-       // 2nd USB port is USB host
-       pin_func |= 0x8000;
+       pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+       /* 2nd USB port is USB host */
+       pin_func |= SYS_PF_USB;
        au_writel(pin_func, SYS_PINFUNC);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
-
-
 #ifdef CONFIG_PCI
-       // Setup PCI bus controller
+       /* Setup PCI bus controller */
        au_writel(0, Au1500_PCI_CMEM);
        au_writel(0x00003fff, Au1500_CFG_BASE);
 #if defined(__MIPSEB__)
-       au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+       au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
        au_writel(0xf, Au1500_PCI_CFG);
 #endif
@@ -112,11 +108,11 @@ void __init board_setup(void)
 
        /* Enable the RTC if not already enabled */
        if (!(au_readl(0xac000028) & 0x20)) {
-               printk("enabling clock ...\n");
+               printk(KERN_INFO "enabling clock ...\n");
                au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
        }
        /* Put the clock in BCD mode */
-       if (au_readl(0xac00002C) & 0x4) { /* reg B */
+       if (au_readl(0xac00002c) & 0x4) { /* reg B */
                au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
                au_sync();
        }
index 488507c07db929e40e5b99dd5d328c88b574b845..49f51e165863d40e004408b4a1199f16c59d29b1 100644 (file)
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *     PB1500 board setup
+ *     Pb1500 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@ void __init prom_init(void)
        unsigned char *memsize_str;
        unsigned long memsize;
 
-       prom_argc = (int) fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argc = (int)fw_arg0;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str) {
+       if (!memsize_str)
                memsize = 0x04000000;
-       } else {
-               memsize = simple_strtol(memsize_str, NULL, 0);
-       }
+       else
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index 4817ab44d07f660e7970703d2e37c0dca4389903..39c4682766a8ec1c696ef97ab4138badbb08443f 100644 (file)
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
[13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
      [12] = { -1, INTA, INTX, INTX, INTX },   /* IDSEL 12 - HPT370   */
      [13] = { -1, INTA, INTB, INTC, INTD },   /* IDSEL 13 - PCI slot */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
index aa35bc6cb8cf7b9da7569327ea3b2cc8bae50ed3..7d8beca87fa56f8eab2d40f6e26912ab20c9bfb0 100644 (file)
@@ -1,9 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Semiconductor PB1000 board.
+# Makefile for the Alchemy Semiconductor Pb1550 board.
 #
 
 lib-y := init.o board_setup.o irqmap.o
index 45d60872b5655b49905c3e300365c30cd2729ea5..0ed76b64b6ab9d1db957b98dfeb11ac8e37cbca9 100644 (file)
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *     Alchemy Pb1550 board setup.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-       au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C);
+       /* Hit BCSR.SYSTEM[RESET] */
+       au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
 }
 
 void __init board_setup(void)
 {
        u32 pin_func;
 
-       /* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+       /*
+        * Enable PSC1 SYNC for AC'97.  Normaly done in audio driver,
         * but it is board specific code, so put it here.
         */
        pin_func = au_readl(SYS_PINFUNC);
@@ -51,8 +51,8 @@ void __init board_setup(void)
        pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
        au_writel(pin_func, SYS_PINFUNC);
 
-       au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+       au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
        au_sync();
 
-       printk("AMD Alchemy Pb1550 Board\n");
+       printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
 }
index f6b2fc587980102a5f561609143ffb55b7651090..1b5f58434bb78390cad601c8b44bb4bf628a7d46 100644 (file)
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *     PB1550 board setup
+ *     Pb1550 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@ void __init prom_init(void)
        unsigned char *memsize_str;
        unsigned long memsize;
 
-       prom_argc = (int) fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argc = (int)fw_arg0;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str) {
+       if (!memsize_str)
                memsize = 0x08000000;
-       } else {
-               memsize = simple_strtol(memsize_str, NULL, 0);
-       }
+       else
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index e1dac37af08ac3ec426211b382c342e5bfd2afe7..a02a4d1fa899ce6d876ddc914e21e82bcaaf5af7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Au1xxx irq map table
+ *     Au1xx0 IRQ map table
  *
  * Copyright 2003 Embedded Edge, LLC
  *             dan@embeddededge.com
@@ -31,8 +31,8 @@
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
[12] =        { -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
[13] =        { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
      [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left)  */
      [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
index 44d7f7056ae76d2e7ece1e34510742b772c3f718..db3c526f64d8afd2d7eb39a329ad90d3da627410 100644 (file)
@@ -1,7 +1,6 @@
 #
 #  Copyright 2003 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#      ppopov@mvista.com or source@mvista.com
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for MyCable XXS1500 board.
 #
index 79d1798621bfede35ca23fbaa5bb80532222cfee..4c587acac5c3707a4a21e3ab28f96eb62dbf8b26 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000-2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2000-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -39,40 +38,40 @@ void __init board_setup(void)
 {
        u32 pin_func;
 
-       // set multiple use pins (UART3/GPIO) to UART (it's used as UART too)
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3);
+       /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
+       pin_func  = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
        pin_func |= SYS_PF_UR3;
        au_writel(pin_func, SYS_PINFUNC);
 
-       // enable UART
-       au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE)
+       /* Enable UART */
+       au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
        mdelay(10);
-       au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable"
+       au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
        mdelay(10);
 
-       // enable DTR = USB power up
-       au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01???
+       /* Enable DTR = USB power up */
+       au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
 
 #ifdef CONFIG_PCMCIA_XXS1500
-       /* setup pcmcia signals */
+       /* Setup PCMCIA signals */
        au_writel(0, SYS_PININPUTEN);
 
-       /* gpio 0, 1, and 4 are inputs */
-       au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR);
+       /* GPIO 0, 1, and 4 are inputs */
+       au_writel(1 | (1 << 1) | (1 << 4), SYS_TRIOUTCLR);
 
-       /* enable GPIO2 if not already enabled */
+       /* Enable GPIO2 if not already enabled */
        au_writel(1, GPIO2_ENABLE);
-       /* gpio2 208/9/10/11 are inputs */
-       au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR);
+       /* GPIO2 208/9/10/11 are inputs */
+       au_writel((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11), GPIO2_DIR);
 
-       /* turn off power */
-       au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT);
+       /* Turn off power */
+       au_writel((au_readl(GPIO2_PINSTATE) & ~(1 << 14)) | (1 << 30),
+                 GPIO2_OUTPUT);
 #endif
 
-
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
-       au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+       au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
        au_writel(0xf, Au1500_PCI_CFG);
 #endif
index 24fc6e132dc0276f7916856ee550321c8294e614..b849bf501c0423fb93d8cb82f3474324b971cca1 100644 (file)
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *     XXS1500 board setup
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,8 +44,8 @@ void __init prom_init(void)
        unsigned long memsize;
 
        prom_argc = fw_arg0;
-       prom_argv = (char **) fw_arg1;
-       prom_envp = (char **) fw_arg2;
+       prom_argv = (char **)fw_arg1;
+       prom_envp = (char **)fw_arg2;
 
        prom_init_cmdline();
 
@@ -54,6 +53,6 @@ void __init prom_init(void)
        if (!memsize_str)
                memsize = 0x04000000;
        else
-               memsize = simple_strtol(memsize_str, NULL, 0);
+               memsize = strict_strtol(memsize_str, 0, NULL);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
index dd6e3d1eb4d4da4cf09d531d420de4b4532ca9e2..edf06ed1187000ad3f04fe13f2ab297dc703d894 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/mach-au1x00/au1000.h>
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
index 82f9e9013e70c9ff38cab59fa9011c313b8af3ea..62bfb455d1b11c9edb89ab6d1683c0aaf6b20fef 100644 (file)
@@ -76,7 +76,9 @@ static void markeins_machine_power_off(void)
        while (1) ;
 }
 
-static unsigned long clock[4] = { 166500000, 187312500, 199800000, 210600000 };
+static unsigned long __initdata emma2rh_clock[4] = {
+       166500000, 187312500, 199800000, 210600000
+};
 
 static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
 {
@@ -85,7 +87,8 @@ static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
        /* detect from boot strap */
        reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
        reg = (reg >> 4) & 0x3;
-       return clock[reg];
+
+       return emma2rh_clock[reg];
 }
 
 void __init plat_time_init(void)
index 45545be3eb86ce015cabdc65059a32189d89595a..cc0244036aec793b9f45c983d346151bab3a4ed3 100644 (file)
@@ -56,9 +56,9 @@ obj-$(CONFIG_MIPS_MT_SMP)     += smp-mt.o
 obj-$(CONFIG_MIPS_CMP)         += smp-cmp.o
 obj-$(CONFIG_CPU_MIPSR2)       += spram.o
 
-obj-$(CONFIG_MIPS_APSP_KSPD)   += kspd.o
 obj-$(CONFIG_MIPS_VPE_LOADER)  += vpe.o
 obj-$(CONFIG_MIPS_VPE_APSP_API)        += rtlx.o
+obj-$(CONFIG_MIPS_APSP_KSPD)   += kspd.o
 
 obj-$(CONFIG_I8259)            += i8259.o
 obj-$(CONFIG_IRQ_CPU)          += irq_cpu.o
index 77db3473deabfc20c97acb99d89dbd77c96b9170..9fdd8bcdd21ef1785c90cc40b0579b6acb4dc1a0 100644 (file)
@@ -54,6 +54,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 #include <linux/module.h>
 #include <linux/elfcore.h>
 #include <linux/compat.h>
+#include <linux/math64.h>
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
@@ -102,8 +103,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
         * one divide.
         */
        u64 nsec = (u64)jiffies * TICK_NSEC;
-       long rem;
-       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
+       u32 rem;
+       value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
        value->tv_usec = rem / NSEC_PER_USEC;
 }
 
index 08f4cd781ee33cc5ac695fed9705a33e7e507e65..e1333d7319e275a065546490baa8401b87c9bf47 100644 (file)
@@ -56,6 +56,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 #include <linux/module.h>
 #include <linux/elfcore.h>
 #include <linux/compat.h>
+#include <linux/math64.h>
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
@@ -104,8 +105,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
         * one divide.
         */
        u64 nsec = (u64)jiffies * TICK_NSEC;
-       long rem;
-       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
+       u32 rem;
+       value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
        value->tv_usec = rem / NSEC_PER_USEC;
 }
 
index a1b48af0992ffb297c588c1a2cc5ae22de826871..02b7713cf71c3a8db4c89c98f0b61d9b31316473 100644 (file)
@@ -38,7 +38,7 @@ static inline void align_mod(const int align, const int mod)
                ".endr\n\t"
                ".set   pop"
                :
-               : GCC_IMM_ASM(align), GCC_IMM_ASM(mod));
+               : GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod));
 }
 
 static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
index 290d8e3a664d71bd71e2fb582dd004025a06b34d..469c7237e5baf4f3e7b1acc3b32bcde5fb319955 100644 (file)
@@ -578,7 +578,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
  * process and the system, here we map the page and fill the
  * structure
  */
-static void irix_map_prda_page(void)
+static int irix_map_prda_page(void)
 {
        unsigned long v;
        struct prda *pp;
@@ -587,8 +587,8 @@ static void irix_map_prda_page(void)
        v =  do_brk(PRDA_ADDRESS, PAGE_SIZE);
        up_write(&current->mm->mmap_sem);
 
-       if (v < 0)
-               return;
+       if (v != PRDA_ADDRESS)
+               return v;               /* v must be an error code */
 
        pp = (struct prda *) v;
        pp->prda_sys.t_pid  = task_pid_vnr(current);
@@ -596,6 +596,8 @@ static void irix_map_prda_page(void)
        pp->prda_sys.t_rpid = task_pid_vnr(current);
 
        /* We leave the rest set to zero */
+
+       return 0;
 }
 
 
@@ -781,7 +783,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
         * IRIX maps a page at 0x200000 which holds some system
         * information.  Programs depend on this.
         */
-       irix_map_prda_page();
+       if (irix_map_prda_page())
+               goto out_free_dentry;
 
        padzero(elf_bss);
 
index 2bde200d5ad0b6aa13371ada255dce2355eae4ca..b39bdba82e029294d1db4ed32df95c53bade32b3 100644 (file)
@@ -27,33 +27,6 @@ struct irix_termios {
        cc_t c_cc[NCCS];
 };
 
-extern void start_tty(struct tty_struct *tty);
-static struct tty_struct *get_tty(int fd)
-{
-       struct file *filp;
-       struct tty_struct *ttyp = NULL;
-
-       rcu_read_lock();
-       filp = fcheck(fd);
-       if(filp && filp->private_data) {
-               ttyp = (struct tty_struct *) filp->private_data;
-
-               if(ttyp->magic != TTY_MAGIC)
-                       ttyp =NULL;
-       }
-       rcu_read_unlock();
-       return ttyp;
-}
-
-static struct tty_struct *get_real_tty(struct tty_struct *tp)
-{
-       if (tp->driver->type == TTY_DRIVER_TYPE_PTY &&
-          tp->driver->subtype == PTY_TYPE_MASTER)
-               return tp->link;
-       else
-               return tp;
-}
-
 asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
 {
        struct tty_struct *tp, *rtp;
@@ -146,34 +119,24 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
                error = sys_ioctl(fd, TIOCNOTTY, arg);
                break;
 
-       case 0x00007416:
+       case 0x00007416: {
+               pid_t pid;
 #ifdef DEBUG_IOCTLS
                printk("TIOCGSID, %08lx) ", arg);
 #endif
-               tp = get_tty(fd);
-               if(!tp) {
-                       error = -EINVAL;
-                       break;
-               }
-               rtp = get_real_tty(tp);
-#ifdef DEBUG_IOCTLS
-               printk("rtp->session=%d ", rtp->session);
-#endif
-               error = put_user(rtp->session, (unsigned long __user *) arg);
+               old_fs = get_fs(); set_fs(get_ds());
+               error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid);
+               set_fs(old_fs);
+               if (!error)
+                       error = put_user(pid, (unsigned long __user *) arg);
                break;
-
+       }
        case 0x746e:
                /* TIOCSTART, same effect as hitting ^Q */
 #ifdef DEBUG_IOCTLS
                printk("TIOCSTART, %08lx) ", arg);
 #endif
-               tp = get_tty(fd);
-               if(!tp) {
-                       error = -EINVAL;
-                       break;
-               }
-               rtp = get_real_tty(tp);
-               start_tty(rtp);
+               error = sys_ioctl(fd, TCXONC, TCOON);
                break;
 
        case 0x20006968:
index 998c4efcce88df4acb15485d529badd73a0782eb..b0591ae0ce566456ed7c88eaa955d191a17bcaaa 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/unistd.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/syscalls.h>
 #include <linux/workqueue.h>
@@ -256,7 +257,7 @@ void sp_work_handle_request(void)
 
                vcwd = vpe_getcwd(tclimit);
 
-               /* change to the cwd of the process that loaded the SP program */
+               /* change to cwd of the process that loaded the SP program */
                old_fs = get_fs();
                set_fs(KERNEL_DS);
                sys_chdir(vcwd);
@@ -322,6 +323,9 @@ static void sp_cleanup(void)
                        set >>= 1;
                }
        }
+
+       /* Put daemon cwd back to root to avoid umount problems */
+       sys_chdir("/");
 }
 
 static int channel_open = 0;
index 0233798f71552c4c64b85e9a61e45f3aafc9fe6c..b88f1c18ff4dc2fe7b5877972ec39314e0d5639d 100644 (file)
@@ -72,6 +72,15 @@ static void rtlx_dispatch(void)
 static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
 {
        int i;
+       unsigned int flags, vpeflags;
+
+       /* Ought not to be strictly necessary for SMTC builds */
+       local_irq_save(flags);
+       vpeflags = dvpe();
+       set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
+       irq_enable_hazard();
+       evpe(vpeflags);
+       local_irq_restore(flags);
 
        for (i = 0; i < RTLX_CHANNELS; i++) {
                        wake_up(&channel_wqs[i].lx_queue);
@@ -108,7 +117,8 @@ static void __used dump_rtlx(void)
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
        if (rtlxi->id != RTLX_ID) {
-               printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id);
+               printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
+                       rtlxi, rtlxi->id);
                return -ENOEXEC;
        }
 
@@ -162,18 +172,17 @@ int rtlx_open(int index, int can_sleep)
 
        if (rtlx == NULL) {
                if( (p = vpe_get_shared(tclimit)) == NULL) {
-                       if (can_sleep) {
-                               __wait_event_interruptible(channel_wqs[index].lx_queue,
-                                                          (p = vpe_get_shared(tclimit)),
-                                                          ret);
-                               if (ret)
-                                       goto out_fail;
-                       } else {
-                               printk(KERN_DEBUG "No SP program loaded, and device "
-                                       "opened with O_NONBLOCK\n");
-                               ret = -ENOSYS;
+                   if (can_sleep) {
+                       __wait_event_interruptible(channel_wqs[index].lx_queue,
+                               (p = vpe_get_shared(tclimit)), ret);
+                       if (ret)
                                goto out_fail;
-                       }
+                   } else {
+                       printk(KERN_DEBUG "No SP program loaded, and device "
+                                       "opened with O_NONBLOCK\n");
+                       ret = -ENOSYS;
+                       goto out_fail;
+                   }
                }
 
                smp_rmb();
@@ -182,7 +191,9 @@ int rtlx_open(int index, int can_sleep)
                                DEFINE_WAIT(wait);
 
                                for (;;) {
-                                       prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE);
+                                       prepare_to_wait(
+                                               &channel_wqs[index].lx_queue,
+                                               &wait, TASK_INTERRUPTIBLE);
                                        smp_rmb();
                                        if (*p != NULL)
                                                break;
@@ -195,7 +206,7 @@ int rtlx_open(int index, int can_sleep)
                                }
                                finish_wait(&channel_wqs[index].lx_queue, &wait);
                        } else {
-                               printk(" *vpe_get_shared is NULL. "
+                               pr_err(" *vpe_get_shared is NULL. "
                                       "Has an SP program been loaded?\n");
                                ret = -ENOSYS;
                                goto out_fail;
@@ -203,8 +214,9 @@ int rtlx_open(int index, int can_sleep)
                }
 
                if ((unsigned int)*p < KSEG0) {
-                       printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
-                              "maybe an error code %d\n", (int)*p);
+                       printk(KERN_WARNING "vpe_get_shared returned an "
+                              "invalid pointer maybe an error code %d\n",
+                              (int)*p);
                        ret = -ENOSYS;
                        goto out_fail;
                }
@@ -232,6 +244,10 @@ out_ret:
 
 int rtlx_release(int index)
 {
+       if (rtlx == NULL) {
+               pr_err("rtlx_release() with null rtlx\n");
+               return 0;
+       }
        rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
        return 0;
 }
@@ -251,8 +267,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep)
                        int ret = 0;
 
                        __wait_event_interruptible(channel_wqs[index].lx_queue,
-                                                  chan->lx_read != chan->lx_write || sp_stopping,
-                                                  ret);
+                               (chan->lx_read != chan->lx_write) ||
+                               sp_stopping, ret);
                        if (ret)
                                return ret;
 
@@ -282,7 +298,9 @@ static inline int write_spacefree(int read, int write, int size)
 unsigned int rtlx_write_poll(int index)
 {
        struct rtlx_channel *chan = &rtlx->channel[index];
-       return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
+
+       return write_spacefree(chan->rt_read, chan->rt_write,
+                               chan->buffer_size);
 }
 
 ssize_t rtlx_read(int index, void __user *buff, size_t count)
@@ -344,8 +362,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
        rt_read = rt->rt_read;
 
        /* total number of bytes to copy */
-       count = min(count,
-                   (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
+       count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
+                                                       rt->buffer_size));
 
        /* first bit from write pointer to the end of the buffer, or count */
        fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
@@ -514,6 +532,11 @@ static int __init rtlx_module_init(void)
 
        if (cpu_has_vint)
                set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
+       else {
+               pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
+               err = -ENODEV;
+               goto out_chrdev;
+       }
 
        rtlx_irq.dev_id = rtlx;
        setup_irq(rtlx_irq_num, &rtlx_irq);
index 39f3dfe134fb9cb619c3c49d48de00be105a9490..c6a063b2a0d9fcc9a7296a580f8c4ee65b0b89f3 100644 (file)
@@ -331,6 +331,7 @@ static void __init bootmem_init(void)
        /*
         * Determine low and high memory ranges
         */
+       max_pfn = max_low_pfn;
        if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
 #ifdef CONFIG_HIGHMEM
                highstart_pfn = PFN_DOWN(HIGHMEM_START);
index 33780cc61ce902e80a289410d46bded866e582f2..63370cdd3c90f83f4ed04fcb926148fa8f4d061f 100644 (file)
@@ -87,8 +87,8 @@ struct plat_smp_ops *mp_ops;
 
 __cpuinit void register_smp_ops(struct plat_smp_ops *ops)
 {
-       if (ops)
-               printk(KERN_WARNING "Overriding previous set SMP ops\n");
+       if (mp_ops)
+               printk(KERN_WARNING "Overriding previously set SMP ops\n");
 
        mp_ops = ops;
 }
index 39804c584eddbaf794a3eda5526bd8122f3bb817..2794501ff302923b38afe00c3e90531379307bf2 100644 (file)
@@ -269,7 +269,7 @@ static void *alloc_progmem(unsigned long len)
         * This means you must tell Linux to use less memory than you
         * physically have, for example by passing a mem= boot argument.
         */
-       addr = pfn_to_kaddr(max_pfn);
+       addr = pfn_to_kaddr(max_low_pfn);
        memset(addr, 0, len);
 #else
        /* simple grab some mem for now */
@@ -781,10 +781,15 @@ static int vpe_run(struct vpe * v)
        /* take system out of configuration state */
        clear_c0_mvpcontrol(MVPCONTROL_VPC);
 
+       /*
+        * SMTC/SMVP kernels manage VPE enable independently,
+        * but uniprocessor kernels need to turn it on, even
+        * if that wasn't the pre-dvpe() state.
+        */
 #ifdef CONFIG_SMP
-       evpe(EVPE_ENABLE);
-#else
        evpe(vpeflags);
+#else
+       evpe(EVPE_ENABLE);
 #endif
        emt(dmt_flag);
        local_irq_restore(flags);
@@ -840,7 +845,7 @@ static int vpe_elfload(struct vpe * v)
 
        /* Sanity checks against insmoding binaries or wrong arch,
           weird elf version */
-       if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+       if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
            || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
            || !elf_check_arch(hdr)
            || hdr->e_shentsize != sizeof(*sechdrs)) {
@@ -947,12 +952,14 @@ static int vpe_elfload(struct vpe * v)
                struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
 
                for (i = 0; i < hdr->e_phnum; i++) {
-                       if (phdr->p_type != PT_LOAD)
-                               continue;
-
-                       memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
-                       memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
-                       phdr++;
+                       if (phdr->p_type == PT_LOAD) {
+                               memcpy((void *)phdr->p_paddr,
+                                      (char *)hdr + phdr->p_offset,
+                                      phdr->p_filesz);
+                               memset((void *)phdr->p_paddr + phdr->p_filesz,
+                                      0, phdr->p_memsz - phdr->p_filesz);
+                   }
+                   phdr++;
                }
 
                for (i = 0; i < hdr->e_shnum; i++) {
@@ -1107,7 +1114,7 @@ static int vpe_release(struct inode *inode, struct file *filp)
                return -ENODEV;
 
        hdr = (Elf_Ehdr *) v->pbuffer;
-       if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
+       if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
                if (vpe_elfload(v) >= 0) {
                        vpe_run(v);
                } else {
index 10dd2af2343bfa791a9f63657869fa4b9641272c..8f2cd8eda7415c37d0a2ff2da7a8c3e1d587ebd0 100644 (file)
@@ -116,4 +116,3 @@ EXPORT_SYMBOL(__kmap);
 EXPORT_SYMBOL(__kunmap);
 EXPORT_SYMBOL(__kmap_atomic);
 EXPORT_SYMBOL(__kunmap_atomic);
-EXPORT_SYMBOL(__kmap_atomic_to_page);
index da8cbb6899dcde8cb439fd53766f0281dad78c1d..b40df7d2cf4465858abb998497d384a46af32cb2 100644 (file)
@@ -281,7 +281,7 @@ static inline int n_counters(void)
 
 static void reset_counters(void *arg)
 {
-       int counters = (int)arg;
+       int counters = (int)(long)arg;
        switch (counters) {
        case 4:
                w_c0_perfctrl3(0);
@@ -313,7 +313,7 @@ static int __init mipsxx_init(void)
        if (!cpu_has_mipsmt_pertccounters)
                counters = counters_total_to_per_cpu(counters);
 #endif
-       on_each_cpu(reset_counters, (void *)counters, 0, 1);
+       on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
 
        op_model_mipsxx_ops.num_counters = counters;
        switch (current_cpu_type()) {
@@ -382,7 +382,7 @@ static void mipsxx_exit(void)
        int counters = op_model_mipsxx_ops.num_counters;
 
        counters = counters_per_cpu_to_total(counters);
-       on_each_cpu(reset_counters, (void *)counters, 0, 1);
+       on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
 
        perf_irq = save_perf_irq;
 }
index 00c36c9dbe0e9ccd3ddc2429d22fe5e69701ed40..e2ddfc49237c5d9f54e6f3b87a5f3fc8ce75ed01 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Board specific pci fixups.
+ *     Board specific PCI fixups.
  *
- * Copyright 2001-2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
index 1314bd58f0365415a4553a8282d981e36ff54c73..9a57c5ab91dd515fdd83319f918e2ac7ce1922b5 100644 (file)
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Alchemy/AMD Au1x00 PCI support.
+ *     Alchemy/AMD Au1xx0 PCI support.
  *
- * Copyright 2001-2003, 2007 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  *  Support for all devices (greater than 16) added by David Gathright.
  *
@@ -28,6 +27,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -36,9 +36,9 @@
 
 #include <asm/mach-au1x00/au1000.h>
 
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
 #else
 #define DBG(x...)
 #endif
@@ -46,7 +46,6 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-
 int (*board_pci_idsel)(unsigned int devsel, int assert);
 
 void mod_wired_entry(int entry, unsigned long entrylo0,
@@ -92,10 +91,9 @@ void __init au1x_pci_cfg_init(void)
 }
 
 static int config_access(unsigned char access_type, struct pci_bus *bus,
-                        unsigned int dev_fn, unsigned char where,
-                        u32 * data)
+                        unsigned int dev_fn, unsigned char where, u32 *data)
 {
-#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
        unsigned int device = PCI_SLOT(dev_fn);
        unsigned int function = PCI_FUNC(dev_fn);
        unsigned long offset, status;
@@ -114,38 +112,36 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
                        Au1500_PCI_STATCMD);
        au_sync_udelay(1);
 
-       /* Allow board vendors to implement their own off-chip idsel.
+       /*
+        * Allow board vendors to implement their own off-chip IDSEL.
         * If it doesn't succeed, may as well bail out at this point.
         */
-       if (board_pci_idsel) {
-               if (board_pci_idsel(device, 1) == 0) {
-                       *data = 0xffffffff;
-                       local_irq_restore(flags);
-                       return -1;
-               }
+       if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
+               *data = 0xffffffff;
+               local_irq_restore(flags);
+               return -1;
        }
 
-        /* setup the config window */
-        if (bus->number == 0) {
-                cfg_base = ((1<<device)<<11);
-        } else {
-                cfg_base = 0x80000000 | (bus->number<<16) | (device<<11);
-        }
+       /* Setup the config window */
+       if (bus->number == 0)
+               cfg_base = (1 << device) << 11;
+       else
+               cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
 
-        /* setup the lower bits of the 36 bit address */
-        offset = (function << 8) | (where & ~0x3);
-       /* pick up any address that falls below the page mask */
+       /* Setup the lower bits of the 36-bit address */
+       offset = (function << 8) | (where & ~0x3);
+       /* Pick up any address that falls below the page mask */
        offset |= cfg_base & ~PAGE_MASK;
 
-       /* page boundary */
+       /* Page boundary */
        cfg_base = cfg_base & PAGE_MASK;
 
        /*
         * To improve performance, if the current device is the same as
         * the last device accessed, we don't touch the TLB.
         */
-       entryLo0 = (6 << 26)  | (cfg_base >> 6) | (2 << 3) | 7;
-       entryLo1 = (6 << 26)  | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
+       entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
+       entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
        if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
                mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
                                (unsigned long)pci_cfg_vm->addr, PM_4K);
@@ -153,38 +149,37 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
                last_entryLo1 = entryLo1;
        }
 
-       if (access_type == PCI_ACCESS_WRITE) {
+       if (access_type == PCI_ACCESS_WRITE)
                au_writel(*data, (int)(pci_cfg_vm->addr + offset));
-       } else {
+       else
                *data = au_readl((int)(pci_cfg_vm->addr + offset));
-       }
+
        au_sync_udelay(2);
 
-       DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n",
-                       access_type, bus->number, device, where, *data, offset);
+       DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
+           access_type, bus->number, device, where, *data, offset);
 
-       /* check master abort */
+       /* Check master abort */
        status = au_readl(Au1500_PCI_STATCMD);
 
-       if (status & (1<<29)) {
+       if (status & (1 << 29)) {
                *data = 0xffffffff;
                error = -1;
                DBG("Au1x Master Abort\n");
        } else if ((status >> 28) & 0xf) {
-               DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf));
+               DBG("PCI ERR detected: device %u, status %lx\n",
+                   device, (status >> 28) & 0xf);
 
-               /* clear errors */
+               /* Clear errors */
                au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
 
                *data = 0xffffffff;
                error = -1;
        }
 
-       /* Take away the idsel.
-       */
-       if (board_pci_idsel) {
+       /* Take away the IDSEL. */
+       if (board_pci_idsel)
                (void)board_pci_idsel(device, 0);
-       }
 
        local_irq_restore(flags);
        return error;
@@ -192,7 +187,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
 }
 
 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
-                           int where, u8 * val)
+                           int where,  u8 *val)
 {
        u32 data;
        int ret;
@@ -206,9 +201,8 @@ static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
        return ret;
 }
 
-
 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
-                           int where, u16 * val)
+                           int where, u16 *val)
 {
        u32 data;
        int ret;
@@ -221,7 +215,7 @@ static int read_config_word(struct pci_bus *bus, unsigned int devfn,
 }
 
 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
-                            int where, u32 * val)
+                            int where, u32 *val)
 {
        int ret;
 
@@ -229,9 +223,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
        return ret;
 }
 
-static int
-write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
-                 u8 val)
+static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
+                            int where, u8 val)
 {
        u32 data = 0;
 
@@ -239,7 +232,7 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
                return -1;
 
        data = (data & ~(0xff << ((where & 3) << 3))) |
-           (val << ((where & 3) << 3));
+              (val << ((where & 3) << 3));
 
        if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
                return -1;
@@ -247,9 +240,8 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
-                 u16 val)
+static int write_config_word(struct pci_bus *bus, unsigned int devfn,
+                            int where, u16 val)
 {
        u32 data = 0;
 
@@ -257,18 +249,16 @@ write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
                return -1;
 
        data = (data & ~(0xffff << ((where & 3) << 3))) |
-           (val << ((where & 3) << 3));
+              (val << ((where & 3) << 3));
 
        if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
                return -1;
 
-
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
-                  u32 val)
+static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
+                             int where, u32 val)
 {
        if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
                return -1;
@@ -277,18 +267,20 @@ write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
 }
 
 static int config_read(struct pci_bus *bus, unsigned int devfn,
-                      int where, int size, u32 * val)
+                      int where, int size, u32 *val)
 {
        switch (size) {
        case 1: {
                        u8 _val;
                        int rc = read_config_byte(bus, devfn, where, &_val);
+
                        *val = _val;
                        return rc;
                }
-       case 2: {
+       case 2: {
                        u16 _val;
                        int rc = read_config_word(bus, devfn, where, &_val);
+
                        *val = _val;
                        return rc;
                }
@@ -310,7 +302,6 @@ static int config_write(struct pci_bus *bus, unsigned int devfn,
        }
 }
 
-
 struct pci_ops au1x_pci_ops = {
        config_read,
        config_write
index ab96a2d7f4c4fc63c0c7594918342e0f98b4e489..11769b55438c27da2c113da9d21c39e21affa31e 100644 (file)
@@ -126,9 +126,6 @@ static irqreturn_t hwbutton_handler(int irq, void *data)
        struct hwbutton_interrupt *hirq = data;
        unsigned long cic_ext = *CIC_EXT_CFG_REG;
 
-       if (irq != hirq->irq)
-               return IRQ_NONE;
-
        if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
                /* Interrupt: pin is now HI */
                CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
@@ -164,7 +161,7 @@ static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
        *CIC_EXT_CFG_REG = cic_ext;
 
        return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
-                               hirq->name, (void *)hirq);
+                          hirq->name, hirq);
 }
 
 static int __init msp_hwbutton_setup(void)
index 25d3baf0ebc4362a8c6cb02fa11468759c0f0b28..9cebc9e7da63ad4c926fbd142f39da54313d8594 100644 (file)
@@ -158,7 +158,7 @@ static void rt_set_mode(enum clock_event_mode mode,
        }
 }
 
-unsigned int rt_timer_irq;
+int rt_timer_irq;
 
 static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
 {
@@ -219,7 +219,7 @@ static void __cpuinit hub_rt_clock_event_init(void)
 
 static void __init hub_rt_clock_event_global_init(void)
 {
-       unsigned int irq;
+       int irq;
 
        do {
                smp_wmb();
index 6a6409adc56403c34ced10eee3d51c638c8314e2..e856218da90d36098e719602be9ffaa78c28f606 100644 (file)
@@ -186,17 +186,6 @@ config PREEMPT
          Say Y here if you are building a kernel for a desktop, embedded
          or real-time system.  Say N if you are unsure.
 
-config PREEMPT_BKL
-       bool "Preempt The Big Kernel Lock"
-       depends on PREEMPT
-       default y
-       help
-         This option reduces the latency of the kernel by making the
-         big kernel lock preemptible.
-
-         Say Y here if you are building a kernel for a desktop system.
-         Say N if you are unsure.
-
 config MN10300_CURRENT_IN_E2
        bool "Hold current task address in E2 register"
        default y
index 072951c83976a22f41adf2098b5df95b8761ce2b..abba30971191bd900808b2e47bd356b6cbac713e 100644 (file)
@@ -26,42 +26,42 @@ rm -fr $4/../usr/include/linux $4/../usr/include/asm
 install -c -m 0755 $2 $4/vmlinuz
 install -c -m 0755 $5 $4/boot.rom
 install -c -m 0755 -d $4/../usr/include/linux
-cd $TOPDIR/include/linux
+cd ${srctree}/include/linux
 for i in `find . -maxdepth 1 -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux
 done
 install -c -m 0755 -d $4/../usr/include/linux/byteorder
-cd $TOPDIR/include/linux/byteorder
+cd ${srctree}/include/linux/byteorder
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/byteorder
 done
 install -c -m 0755 -d $4/../usr/include/linux/lockd
-cd $TOPDIR/include/linux/lockd
+cd ${srctree}/include/linux/lockd
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/lockd
 done
 install -c -m 0755 -d $4/../usr/include/linux/netfilter_ipv4
-cd $TOPDIR/include/linux/netfilter_ipv4
+cd ${srctree}/include/linux/netfilter_ipv4
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/netfilter_ipv4
 done
 install -c -m 0755 -d $4/../usr/include/linux/nfsd
-cd $TOPDIR/include/linux/nfsd
+cd ${srctree}/include/linux/nfsd
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/nfsd/$i
 done
 install -c -m 0755 -d $4/../usr/include/linux/raid
-cd $TOPDIR/include/linux/raid
+cd ${srctree}/include/linux/raid
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/raid
 done
 install -c -m 0755 -d $4/../usr/include/linux/sunrpc
-cd $TOPDIR/include/linux/sunrpc
+cd ${srctree}/include/linux/sunrpc
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/sunrpc
 done
 install -c -m 0755 -d $4/../usr/include/asm
-cd $TOPDIR/include/asm
+cd ${srctree}/include/asm
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/asm
 done
index 5f17a1ebc8253e658e49b173e11c8efaeedcd3ac..bca5a84dc72cced1e6c597a02ec725181a651cfb 100644 (file)
 
 #define MIN_MAP_ADDR   PAGE_SIZE       /* minimum fixed mmap address */
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage long sys_pipe(unsigned long __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2 * sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /*
  * memory mapping syscall
  */
index 4f589216b39e2a47864ea83ca897a859e2a8f3cb..71b31957c8f13805c5a8da1c93c6061bf562f2a7 100644 (file)
 #include <linux/utsname.h>
 #include <linux/personality.h>
 
-int sys_pipe(int __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 static unsigned long get_unshared_area(unsigned long addr, unsigned long len)
 {
        struct vm_area_struct *vma;
index 1f012843150fbd83b801c11b8a6a58ddcaa099b5..b0ed709d5743adef26b50516743c51949052d8a6 100644 (file)
@@ -606,7 +606,7 @@ void show_mem(void)
                int i, j;
 
                for (i = 0; i < npmem_ranges; i++) {
-                       zl = node_zonelist(i);
+                       zl = node_zonelist(i, 0);
                        for (j = 0; j < MAX_NR_ZONES; j++) {
                                struct zoneref *z;
                                struct zone *zone;
index 1f2f1e0a55714ffbbaea58c1b1216b6cab67adb1..bba234eb14a92a12c9896ecb7936a240d96fb4bb 100644 (file)
@@ -21,6 +21,7 @@
                serial1 = &serial1;
                pci0 = &pci0;
                pci1 = &pci1;
+               pci2 = &pci2;
        };
 
        cpus {
                        compatible = "ns16550";
                        reg = <0x4600 0x100>;
                        clock-frequency = <0>;
-                       interrupts = <28 2>;
+                       interrupts = <42 2>;
                        interrupt-parent = <&mpic>;
                };
 
                        };
                };
        };
+
+       pci2: pcie@e0009000 {
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+               device_type = "pci";
+               compatible = "fsl,mpc8641-pcie";
+               reg = <0xe0009000 0x00001000>;
+               ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000
+                         0x01000000 0 0x00000000 0xe2000000 0 0x00100000>;
+               bus-range = <0 255>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <0x0000 0 0 1 &mpic 4 1
+                                0x0000 0 0 2 &mpic 5 1
+                                0x0000 0 0 3 &mpic 6 1
+                                0x0000 0 0 4 &mpic 7 1>;
+               interrupt-parent = <&mpic>;
+               interrupts = <25 2>;
+               clock-frequency = <33333333>;
+       };
 };
index a1ae4d6ec9908c3a86dc1900b39086ec8d08c995..72d67564bdfc6302a3d48185761aa5abeadd67ce 100644 (file)
                        /* Outbound ranges, one memory and one IO,
                         * later cannot be changed. Chip supports a second
                         * IO range but we don't use it for now
+                        * From the 440EPx user manual:
+                        * PCI 1 Memory     1 8000 0000     1 BFFF FFFF     1GB
+                        * I/O              1 E800 0000     1 E800 FFFF     64KB
+                        * I/O              1 E880 0000     1 EBFF FFFF     56MB
                         */
-                       ranges = <02000000 0 80000000 1 80000000 0 10000000
-                               01000000 0 00000000 1 e8000000 0 00100000>;
+                       ranges = <02000000 0 80000000 1 80000000 0 40000000
+                               01000000 0 00000000 1 e8000000 0 00010000
+                               01000000 0 00000000 1 e8800000 0 03800000>;
 
                        /* Inbound 2GB range starting at 0 */
                        dma-ranges = <42000000 0 0 0 0 0 80000000>;
index 7a64c564f6e636f0fc7a61c70c168a5a666f3290..71d79e428d20ccabd786a0e7a880ff17c2bf2903 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc6
-# Thu Mar 20 11:07:04 2008
+# Linux kernel version: 2.6.25
+# Mon Apr 28 12:39:10 2008
 #
 CONFIG_PPC64=y
 
@@ -30,6 +30,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_ARCH_HAS_ILOG2_U64=y
@@ -73,8 +76,6 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
-# CONFIG_USER_SCHED is not set
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -161,7 +162,6 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 # CONFIG_PPC_PASEMI is not set
-# CONFIG_PPC_CELLEB is not set
 CONFIG_PPC_PS3=y
 
 #
@@ -181,6 +181,7 @@ CONFIG_PS3_LPM=m
 CONFIG_PPC_CELL=y
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_IBM_CELL_BLADE is not set
+# CONFIG_PPC_CELLEB is not set
 
 #
 # Cell Broadband Engine options
@@ -205,9 +206,9 @@ CONFIG_SPU_BASE=y
 #
 # Kernel options
 #
-# CONFIG_TICK_ONESHOT is not set
+CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -221,7 +222,6 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 CONFIG_COMPAT_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
-CONFIG_FORCE_MAX_ZONEORDER=13
 # CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -255,6 +255,7 @@ CONFIG_BOUNCE=y
 CONFIG_ARCH_MEMORY_PROBE=y
 # CONFIG_PPC_HAS_HASH_64K is not set
 # CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -272,7 +273,9 @@ CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCCARD is not set
+CONFIG_PAGE_OFFSET=0xc000000000000000
 CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_PHYSICAL_START=0x00000000
 
 #
 # Networking
@@ -292,7 +295,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
@@ -301,6 +304,7 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
@@ -332,8 +336,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -392,8 +398,6 @@ CONFIG_IEEE80211=m
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
 CONFIG_IEEE80211_CRYPT_TKIP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -507,6 +511,7 @@ CONFIG_WLAN_80211=y
 # CONFIG_LIBERTAS is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_HOSTAP is not set
 
 #
@@ -578,6 +583,7 @@ CONFIG_INPUT_JOYSTICK=y
 # CONFIG_JOYSTICK_SPACEBALL is not set
 # CONFIG_JOYSTICK_STINGER is not set
 # CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_ZHENHUA is not set
 # CONFIG_JOYSTICK_JOYDUMP is not set
 # CONFIG_JOYSTICK_XPAD is not set
 # CONFIG_INPUT_TABLET is not set
@@ -641,6 +647,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
 
 #
 # Multimedia devices
@@ -760,10 +767,6 @@ CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
 #
 # CONFIG_SND_SOC is not set
 
-#
-# SoC Audio support for SuperH
-#
-
 #
 # ALSA SoC audio for Freescale SOCs
 #
@@ -849,6 +852,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -893,10 +897,6 @@ CONFIG_USB_MON=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
-
-#
-# Userspace I/O
-#
 # CONFIG_UIO is not set
 
 #
@@ -986,7 +986,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
@@ -1059,9 +1058,10 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
@@ -1071,6 +1071,7 @@ CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
 
 #
 # Kernel hacking
@@ -1078,6 +1079,7 @@ CONFIG_HAS_DMA=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
@@ -1093,12 +1095,16 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
@@ -1121,51 +1127,81 @@ CONFIG_IRQSTACKS=y
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_AEAD=m
 CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_SEQIV=m
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=m
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
 # 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=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-CONFIG_CRYPTO_CTR=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_CCM=m
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# 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_WP512 is not set
+
+#
+# Ciphers
+#
 CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_SALSA20=m
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
 # CONFIG_CRYPTO_DEFLATE is not set
-CONFIG_CRYPTO_MICHAEL_MIC=m
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index d14cebf62bb03e42732c174a67d5f2134dffe13e..2346d271fbfdbc5bb8323a588de5124e3237cabf 100644 (file)
@@ -105,6 +105,9 @@ PHONY += systbl_chk
 systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
        $(call cmd,systbl_chk)
 
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+
 $(obj)/built-in.o:             prom_init_check
 
 quiet_cmd_prom_init_check = CALL    $<
@@ -114,4 +117,7 @@ PHONY += prom_init_check
 prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o
        $(call cmd,prom_init_check)
 
+endif
+
+
 clean-files := vmlinux.lds
index 9f9377745490d966ff434f728bc1e15581c3dace..d8f0329b13444b73be463ea06c71169a193d180f 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/udbg.h>
 
index 36080d4d1922ba1d47621916f84fa528fe615816..e44d5530f0a6d5ea0457d137d1856fac559a7b82 100644 (file)
@@ -1208,6 +1208,18 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_4xx,
                .platform               = "ppc405",
        },
+       {       /* default match */
+               .pvr_mask               = 0x00000000,
+               .pvr_value              = 0x00000000,
+               .cpu_name               = "(generic 40x PPC)",
+               .cpu_features           = CPU_FTRS_40X,
+               .cpu_user_features      = PPC_FEATURE_32 |
+                       PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .machine_check          = machine_check_4xx,
+               .platform               = "ppc405",
+       }
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
@@ -1421,8 +1433,18 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_440A,
                .platform               = "ppc440",
        },
+       {       /* default match */
+               .pvr_mask               = 0x00000000,
+               .pvr_value              = 0x00000000,
+               .cpu_name               = "(generic 44x PPC)",
+               .cpu_features           = CPU_FTRS_44X,
+               .cpu_user_features      = COMMON_USER_BOOKE,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+               .machine_check          = machine_check_4xx,
+               .platform               = "ppc440",
+       }
 #endif /* CONFIG_44x */
-#ifdef CONFIG_FSL_BOOKE
 #ifdef CONFIG_E200
        {       /* e200z5 */
                .pvr_mask               = 0xfff00000,
@@ -1451,7 +1473,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_e200,
                .platform               = "ppc5554",
        },
-#elif defined(CONFIG_E500)
+       {       /* default match */
+               .pvr_mask               = 0x00000000,
+               .pvr_value              = 0x00000000,
+               .cpu_name               = "(generic E200 PPC)",
+               .cpu_features           = CPU_FTRS_E200,
+               .cpu_user_features      = COMMON_USER_BOOKE |
+                       PPC_FEATURE_HAS_EFP_SINGLE |
+                       PPC_FEATURE_UNIFIED_CACHE,
+               .dcache_bsize           = 32,
+               .machine_check          = machine_check_e200,
+               .platform               = "ppc5554",
+       }
+#endif /* CONFIG_E200 */
+#ifdef CONFIG_E500
        {       /* e500 */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x80200000,
@@ -1487,20 +1522,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_e500,
                .platform               = "ppc8548",
        },
-#endif
-#endif
-#if !CLASSIC_PPC
        {       /* default match */
                .pvr_mask               = 0x00000000,
                .pvr_value              = 0x00000000,
-               .cpu_name               = "(generic PPC)",
-               .cpu_features           = CPU_FTRS_GENERIC_32,
-               .cpu_user_features      = PPC_FEATURE_32,
+               .cpu_name               = "(generic E500 PPC)",
+               .cpu_features           = CPU_FTRS_E500,
+               .cpu_user_features      = COMMON_USER_BOOKE |
+                       PPC_FEATURE_HAS_SPE_COMP |
+                       PPC_FEATURE_HAS_EFP_SINGLE_COMP,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
+               .machine_check          = machine_check_e500,
                .platform               = "powerpc",
        }
-#endif /* !CLASSIC_PPC */
+#endif /* CONFIG_E500 */
 #endif /* CONFIG_PPC32 */
 };
 
index b84ec6a2fc94c06a4374647344e0c4ce6c87e01c..c2b9dc4fce5d24a4021972f5337d66828faca918 100644 (file)
@@ -653,7 +653,14 @@ finish_tlb_load:
        rlwimi  r10, r11, 0, 26, 26             /* UX = HWEXEC & USER */
 
        rlwimi  r12, r10, 0, 26, 31             /* Insert static perms */
-       rlwinm  r12, r12, 0, 20, 15             /* Clear U0-U3 */
+
+       /*
+        * Clear U0-U3 and WL1 IL1I IL1D IL2I IL2D bits which are added
+        * on newer 440 cores like the 440x6 used on AMCC 460EX/460GT (see
+        * include/asm-powerpc/pgtable-ppc32.h for details).
+        */
+       rlwinm  r12, r12, 0, 20, 10
+
        tlbwe   r12, r13, PPC44x_TLB_ATTRIB     /* Write ATTRIB */
 
        /* Done...restore registers and get out of here.
index 024805e1747df86a9c1e58f71b581932b70ddae7..25e84c0e116695e37d416296e34eb6f8cfc28ba6 100644 (file)
@@ -1517,10 +1517,6 @@ _INIT_STATIC(start_here_multiplatform)
        addi    r2,r2,0x4000
        add     r2,r2,r26
 
-       /* Set initial ptr to current */
-       LOAD_REG_IMMEDIATE(r4, init_task)
-       std     r4,PACACURRENT(r13)
-
        /* Do very early kernel initializations, including initial hash table,
         * stab and slb setup before we turn on relocation.     */
 
index 289af348978dac142638703e630bdaf367001068..4d5731b2429aa605f6776a8674d6c7e4a40d5520 100644 (file)
@@ -108,9 +108,6 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
        if (size > 0x10000)
                size = 0x10000;
 
-       printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
-              "mapping 64k\n");
-
        __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
                     size, _PAGE_NO_CACHE|_PAGE_GUARDED);
        return;
index 25e3fd8606ab589ebae8ee51143e39a517d32505..098fd96a394aa4df6947a2cad11146458de2b29f 100644 (file)
@@ -170,6 +170,8 @@ void __init setup_paca(int cpu)
 
 void __init early_setup(unsigned long dt_ptr)
 {
+       /* -------- printk is _NOT_ safe to use here ! ------- */
+
        /* Fill in any unititialised pacas */
        initialise_pacas();
 
@@ -179,12 +181,14 @@ void __init early_setup(unsigned long dt_ptr)
        /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
        setup_paca(0);
 
-       /* Enable early debugging if any specified (see udbg.h) */
-       udbg_early_init();
-
        /* Initialize lockdep early or else spinlocks will blow */
        lockdep_init();
 
+       /* -------- printk is now safe to use ------- */
+
+       /* Enable early debugging if any specified (see udbg.h) */
+       udbg_early_init();
+
        DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
 
        /*
index be35ffae10f0726b5e2ac3746b80f464f976222c..1457aa0a08f136355347adcbe122a3d2c1692ba2 100644 (file)
@@ -386,6 +386,8 @@ static void __init smp_create_idle(unsigned int cpu)
                panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
 #ifdef CONFIG_PPC64
        paca[cpu].__current = p;
+       paca[cpu].kstack = (unsigned long) task_thread_info(p)
+               + THREAD_SIZE - STACK_FRAME_OVERHEAD;
 #endif
        current_set[cpu] = task_thread_info(p);
        task_thread_info(p)->cpu = cpu;
index e722a4eeb5d0fc4a0a8150900b378fe38969e2bb..4fe69ca244818e78fb86c37c2091a023b4e77b0b 100644 (file)
@@ -136,23 +136,6 @@ int sys_ipc(uint call, int first, unsigned long second, long third,
        return ret;
 }
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-int sys_pipe(int __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 static inline unsigned long do_mmap2(unsigned long addr, size_t len,
                        unsigned long prot, unsigned long flags,
                        unsigned long fd, unsigned long off, int shift)
index 3b26fbd6bec9ee4978ff6430ce1ef27a55723089..73401e83739a09b4dcefdaecc84451c018607ca5 100644 (file)
@@ -149,7 +149,7 @@ EXPORT_SYMBOL(tb_ticks_per_sec);    /* for cputime_t conversions */
 u64 tb_to_xs;
 unsigned tb_to_us;
 
-#define TICKLEN_SCALE  TICK_LENGTH_SHIFT
+#define TICKLEN_SCALE  NTP_SCALE_SHIFT
 u64 last_tick_len;     /* units are ns / 2^TICKLEN_SCALE */
 u64 ticklen_to_xs;     /* 0.64 fraction */
 
@@ -1007,8 +1007,6 @@ void __init time_init(void)
        vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
        vdso_data->tb_to_xs = tb_to_xs;
 
-       time_freq = 0;
-
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
        /* Register the clocksource, if we're not running on iSeries */
index 6d9884a6884aa2379f68992738ec40baf141e0bc..712d89a28c46205f0f7fbfebfc4df03daf148192 100644 (file)
@@ -49,6 +49,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "inst_emu",   VCPU_STAT(emulated_inst_exits) },
        { "dec",        VCPU_STAT(dec_exits) },
        { "ext_intr",   VCPU_STAT(ext_intr_exits) },
+       { "halt_wakeup", VCPU_STAT(halt_wakeup) },
        { NULL }
 };
 
@@ -338,6 +339,11 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                }
                break;
 
+       case BOOKE_INTERRUPT_FP_UNAVAIL:
+               kvmppc_queue_exception(vcpu, exit_nr);
+               r = RESUME_GUEST;
+               break;
+
        case BOOKE_INTERRUPT_DATA_STORAGE:
                vcpu->arch.dear = vcpu->arch.fault_dear;
                vcpu->arch.esr = vcpu->arch.fault_esr;
index bad40bd2d3ac5e966926487cb10df89513e2acc6..777e0f34e0ea12d60e643a47f0b68af5a6bdc930 100644 (file)
@@ -36,13 +36,12 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 
 int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
 {
-       /* XXX implement me */
-       return 0;
+       return !!(v->arch.pending_exceptions);
 }
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
-       return 1;
+       return !(v->arch.msr & MSR_WE);
 }
 
 
@@ -214,6 +213,11 @@ static void kvmppc_decrementer_func(unsigned long data)
        struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;
 
        kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER);
+
+       if (waitqueue_active(&vcpu->wq)) {
+               wake_up_interruptible(&vcpu->wq);
+               vcpu->stat.halt_wakeup++;
+       }
 }
 
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
@@ -339,6 +343,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
        int r;
        sigset_t sigsaved;
 
+       vcpu_load(vcpu);
+
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
@@ -363,12 +369,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
+       vcpu_put(vcpu);
+
        return r;
 }
 
 int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
 {
        kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL);
+
+       if (waitqueue_active(&vcpu->wq)) {
+               wake_up_interruptible(&vcpu->wq);
+               vcpu->stat.halt_wakeup++;
+       }
+
        return 0;
 }
 
index 4bb023f4c8690f332152eb00706f4f7cfa85f3e8..c71d37dc6a88220d41b14480cbdf2a6ae692dcd8 100644 (file)
@@ -10,6 +10,7 @@ ifeq ($(CONFIG_PPC_MERGE),y)
 obj-y                  := string.o alloc.o \
                           checksum_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC32)    += div64.o copy_32.o
+obj-$(CONFIG_HAS_IOMEM)        += devres.o
 endif
 
 obj-$(CONFIG_PPC64)    += copypage_64.o copyuser_64.o \
diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
new file mode 100644 (file)
index 0000000..292115d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>      /* devres_*(), devm_ioremap_release() */
+#include <linux/io.h>          /* ioremap_flags() */
+#include <linux/module.h>      /* EXPORT_SYMBOL() */
+
+/**
+ * devm_ioremap_prot - Managed ioremap_flags()
+ * @dev: Generic device to remap IO address for
+ * @offset: BUS offset to map
+ * @size: Size of map
+ * @flags: Page flags
+ *
+ * Managed ioremap_prot().  Map is automatically unmapped on driver
+ * detach.
+ */
+void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
+                                size_t size, unsigned long flags)
+{
+       void __iomem **ptr, *addr;
+
+       ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return NULL;
+
+       addr = ioremap_flags(offset, size, flags);
+       if (addr) {
+               *ptr = addr;
+               devres_add(dev, ptr);
+       } else
+               devres_free(ptr);
+
+       return addr;
+}
+EXPORT_SYMBOL(devm_ioremap_prot);
index 906daeda59a8ff431d6bee026af51f55e4318512..cf8705e32d607b9692d0213f543ac84e092afe7b 100644 (file)
@@ -30,7 +30,7 @@
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
 #else
-#define DBG(fmt...)
+#define DBG pr_debug
 #endif
 
 extern void slb_allocate_realmode(unsigned long ea);
@@ -44,13 +44,13 @@ static void slb_allocate(unsigned long ea)
        slb_allocate_realmode(ea);
 }
 
+#define slb_esid_mask(ssize)   \
+       (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T)
+
 static inline unsigned long mk_esid_data(unsigned long ea, int ssize,
                                         unsigned long slot)
 {
-       unsigned long mask;
-
-       mask = (ssize == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T;
-       return (ea & mask) | SLB_ESID_V | slot;
+       return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot;
 }
 
 #define slb_vsid_shift(ssize)  \
@@ -279,8 +279,8 @@ void slb_initialize(void)
                patch_slb_encoding(slb_compare_rr_to_size,
                                   mmu_slb_size);
 
-               DBG("SLB: linear  LLP = %04x\n", linear_llp);
-               DBG("SLB: io      LLP = %04x\n", io_llp);
+               DBG("SLB: linear  LLP = %04lx\n", linear_llp);
+               DBG("SLB: io      LLP = %04lx\n", io_llp);
        }
 
        get_paca()->stab_rr = SLB_NUM_BOLTED;
@@ -301,11 +301,16 @@ void slb_initialize(void)
 
        create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1);
 
+       /* For the boot cpu, we're running on the stack in init_thread_union,
+        * which is in the first segment of the linear mapping, and also
+        * get_paca()->kstack hasn't been initialized yet.
+        * For secondary cpus, we need to bolt the kernel stack entry now.
+        */
        slb_shadow_clear(2);
+       if (raw_smp_processor_id() != boot_cpuid &&
+           (get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET)
+               create_shadowed_slbe(get_paca()->kstack,
+                                    mmu_kernel_ssize, lflags, 2);
 
-       /* We don't bolt the stack for the time being - we're in boot,
-        * so the stack is in the bolted segment.  By the time it goes
-        * elsewhere, we'll call _switch() which will bolt in the new
-        * one. */
        asm volatile("isync":::"memory");
 }
index 04f74f9f9ab67dcae27a706a7c3de449bab22ac6..5bf7df14602288b1d4daafb79e1116ac92066864 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/percpu.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
+#include <linux/kernel_stat.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -231,6 +232,54 @@ static int iic_host_match(struct irq_host *h, struct device_node *node)
                                    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
+extern int noirqdebug;
+
+static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
+{
+       const unsigned int cpu = smp_processor_id();
+
+       spin_lock(&desc->lock);
+
+       desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+       /*
+        * If we're currently running this IRQ, or its disabled,
+        * we shouldn't process the IRQ. Mark it pending, handle
+        * the necessary masking and go out
+        */
+       if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
+                   !desc->action)) {
+               desc->status |= IRQ_PENDING;
+               goto out_eoi;
+       }
+
+       kstat_cpu(cpu).irqs[irq]++;
+
+       /* Mark the IRQ currently in progress.*/
+       desc->status |= IRQ_INPROGRESS;
+
+       do {
+               struct irqaction *action = desc->action;
+               irqreturn_t action_ret;
+
+               if (unlikely(!action))
+                       goto out_eoi;
+
+               desc->status &= ~IRQ_PENDING;
+               spin_unlock(&desc->lock);
+               action_ret = handle_IRQ_event(irq, action);
+               if (!noirqdebug)
+                       note_interrupt(irq, desc, action_ret);
+               spin_lock(&desc->lock);
+
+       } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
+
+       desc->status &= ~IRQ_INPROGRESS;
+out_eoi:
+       desc->chip->eoi(irq);
+       spin_unlock(&desc->lock);
+}
+
 static int iic_host_map(struct irq_host *h, unsigned int virq,
                        irq_hw_number_t hw)
 {
@@ -240,10 +289,10 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
                break;
        case IIC_IRQ_TYPE_IOEXC:
                set_irq_chip_and_handler(virq, &iic_ioexc_chip,
-                                        handle_fasteoi_irq);
+                                        handle_iic_irq);
                break;
        default:
-               set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
+               set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq);
        }
        return 0;
 }
index 6bab44b7716b2d525bff0720c0c6a0f436a55acb..70c660121ec4d0d2da4a36071d851a1acd3e7870 100644 (file)
@@ -141,6 +141,10 @@ static void spu_restart_dma(struct spu *spu)
 
        if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
                out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
+       else {
+               set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
+               mb();
+       }
 }
 
 static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
@@ -226,11 +230,13 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
                return 0;
        }
 
-       spu->class_0_pending = 0;
-       spu->dar = ea;
-       spu->dsisr = dsisr;
+       spu->class_1_dar = ea;
+       spu->class_1_dsisr = dsisr;
+
+       spu->stop_callback(spu, 1);
 
-       spu->stop_callback(spu);
+       spu->class_1_dar = 0;
+       spu->class_1_dsisr = 0;
 
        return 0;
 }
@@ -318,11 +324,15 @@ spu_irq_class_0(int irq, void *data)
        stat = spu_int_stat_get(spu, 0) & mask;
 
        spu->class_0_pending |= stat;
-       spu->dsisr = spu_mfc_dsisr_get(spu);
-       spu->dar = spu_mfc_dar_get(spu);
+       spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
+       spu->class_0_dar = spu_mfc_dar_get(spu);
        spin_unlock(&spu->register_lock);
 
-       spu->stop_callback(spu);
+       spu->stop_callback(spu, 0);
+
+       spu->class_0_pending = 0;
+       spu->class_0_dsisr = 0;
+       spu->class_0_dar = 0;
 
        spu_int_stat_clear(spu, 0, stat);
 
@@ -363,6 +373,9 @@ spu_irq_class_1(int irq, void *data)
        if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
                ;
 
+       spu->class_1_dsisr = 0;
+       spu->class_1_dar = 0;
+
        return stat ? IRQ_HANDLED : IRQ_NONE;
 }
 
@@ -396,10 +409,10 @@ spu_irq_class_2(int irq, void *data)
                spu->ibox_callback(spu);
 
        if (stat & CLASS2_SPU_STOP_INTR)
-               spu->stop_callback(spu);
+               spu->stop_callback(spu, 2);
 
        if (stat & CLASS2_SPU_HALT_INTR)
-               spu->stop_callback(spu);
+               spu->stop_callback(spu, 2);
 
        if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
                spu->mfc_callback(spu);
index 67fa7247b80a4e0dac21d6702c2fcc0c1d6b1867..906a0a2a9fe18fc4273be7916f18df118c824dc1 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/sched.h>
 
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
@@ -75,8 +76,19 @@ static u64 int_stat_get(struct spu *spu, int class)
 
 static void cpu_affinity_set(struct spu *spu, int cpu)
 {
-       u64 target = iic_get_target_id(cpu);
-       u64 route = target << 48 | target << 32 | target << 16;
+       u64 target;
+       u64 route;
+
+       if (nr_cpus_node(spu->node)) {
+               cpumask_t spumask = node_to_cpumask(spu->node);
+               cpumask_t cpumask = node_to_cpumask(cpu_to_node(cpu));
+
+               if (!cpus_intersects(spumask, cpumask))
+                       return;
+       }
+
+       target = iic_get_target_id(cpu);
+       route = target << 48 | target << 32 | target << 16;
        out_be64(&spu->priv1->int_route_RW, route);
 }
 
index b962c3ab470cbe01f2f5a5d6e510866bd8a60e5a..af116aadba105674617cb97e514996797501dc5c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/elf.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/module.h>
index e46d300e21a5e18cf3b612b214a11af5f9562805..f093a581ac7410792a9126b2b0bbc87f665e9fdc 100644 (file)
@@ -83,13 +83,18 @@ int spufs_handle_class0(struct spu_context *ctx)
                return 0;
 
        if (stat & CLASS0_DMA_ALIGNMENT_INTR)
-               spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT);
+               spufs_handle_event(ctx, ctx->csa.class_0_dar,
+                       SPE_EVENT_DMA_ALIGNMENT);
 
        if (stat & CLASS0_INVALID_DMA_COMMAND_INTR)
-               spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA);
+               spufs_handle_event(ctx, ctx->csa.class_0_dar,
+                       SPE_EVENT_INVALID_DMA);
 
        if (stat & CLASS0_SPU_ERROR_INTR)
-               spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR);
+               spufs_handle_event(ctx, ctx->csa.class_0_dar,
+                       SPE_EVENT_SPE_ERROR);
+
+       ctx->csa.class_0_pending = 0;
 
        return -EIO;
 }
@@ -119,8 +124,8 @@ int spufs_handle_class1(struct spu_context *ctx)
         * in time, we can still expect to get the same fault
         * the immediately after the context restore.
         */
-       ea = ctx->csa.dar;
-       dsisr = ctx->csa.dsisr;
+       ea = ctx->csa.class_1_dar;
+       dsisr = ctx->csa.class_1_dsisr;
 
        if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
                return 0;
@@ -158,7 +163,7 @@ int spufs_handle_class1(struct spu_context *ctx)
         * time slicing will not preempt the context while the page fault
         * handler is running. Context switch code removes mappings.
         */
-       ctx->csa.dar = ctx->csa.dsisr = 0;
+       ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0;
 
        /*
         * If we handled the fault successfully and are in runnable
index 0c32a05ab068a1487485d8871ce26a847d50a784..f407b24718554f474a153dc9a66e93d88518739f 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/fsnotify.h>
 #include <linux/backing-dev.h>
 #include <linux/init.h>
 #include <linux/ioctl.h>
@@ -223,7 +224,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
        parent = dir->d_parent->d_inode;
        ctx = SPUFS_I(dir->d_inode)->i_ctx;
 
-       mutex_lock(&parent->i_mutex);
+       mutex_lock_nested(&parent->i_mutex, I_MUTEX_PARENT);
        ret = spufs_rmdir(parent, dir);
        mutex_unlock(&parent->i_mutex);
        WARN_ON(ret);
@@ -618,12 +619,15 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
        mode &= ~current->fs->umask;
 
        if (flags & SPU_CREATE_GANG)
-               return spufs_create_gang(nd->path.dentry->d_inode,
+               ret = spufs_create_gang(nd->path.dentry->d_inode,
                                         dentry, nd->path.mnt, mode);
        else
-               return spufs_create_context(nd->path.dentry->d_inode,
+               ret = spufs_create_context(nd->path.dentry->d_inode,
                                            dentry, nd->path.mnt, flags, mode,
                                            filp);
+       if (ret >= 0)
+               fsnotify_mkdir(nd->path.dentry->d_inode, dentry);
+       return ret;
 
 out_dput:
        dput(dentry);
index a9c35b7b719fda3bd3850dc1dfdaa74d2e5acc6b..b7493b86581228d0edf8b0c0b691582e706bac58 100644 (file)
@@ -11,7 +11,7 @@
 #include "spufs.h"
 
 /* interrupt-level stop callback function. */
-void spufs_stop_callback(struct spu *spu)
+void spufs_stop_callback(struct spu *spu, int irq)
 {
        struct spu_context *ctx = spu->ctx;
 
@@ -24,9 +24,19 @@ void spufs_stop_callback(struct spu *spu)
         */
        if (ctx) {
                /* Copy exception arguments into module specific structure */
-               ctx->csa.class_0_pending = spu->class_0_pending;
-               ctx->csa.dsisr = spu->dsisr;
-               ctx->csa.dar = spu->dar;
+               switch(irq) {
+               case 0 :
+                       ctx->csa.class_0_pending = spu->class_0_pending;
+                       ctx->csa.class_0_dsisr = spu->class_0_dsisr;
+                       ctx->csa.class_0_dar = spu->class_0_dar;
+                       break;
+               case 1 :
+                       ctx->csa.class_1_dsisr = spu->class_1_dsisr;
+                       ctx->csa.class_1_dar = spu->class_1_dar;
+                       break;
+               case 2 :
+                       break;
+               }
 
                /* ensure that the exception status has hit memory before a
                 * thread waiting on the context's stop queue is woken */
@@ -34,11 +44,6 @@ void spufs_stop_callback(struct spu *spu)
 
                wake_up_all(&ctx->stop_wq);
        }
-
-       /* Clear callback arguments from spu structure */
-       spu->class_0_pending = 0;
-       spu->dsisr = 0;
-       spu->dar = 0;
 }
 
 int spu_stopped(struct spu_context *ctx, u32 *stat)
@@ -56,7 +61,11 @@ int spu_stopped(struct spu_context *ctx, u32 *stat)
        if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped))
                return 1;
 
-       dsisr = ctx->csa.dsisr;
+       dsisr = ctx->csa.class_0_dsisr;
+       if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
+               return 1;
+
+       dsisr = ctx->csa.class_1_dsisr;
        if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
                return 1;
 
@@ -294,7 +303,7 @@ static int spu_process_callback(struct spu_context *ctx)
        u32 ls_pointer, npc;
        void __iomem *ls;
        long spu_ret;
-       int ret, ret2;
+       int ret;
 
        /* get syscall block from local store */
        npc = ctx->ops->npc_read(ctx) & ~3;
@@ -316,11 +325,9 @@ static int spu_process_callback(struct spu_context *ctx)
                if (spu_ret <= -ERESTARTSYS) {
                        ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
                }
-               ret2 = spu_acquire(ctx);
+               mutex_lock(&ctx->state_mutex);
                if (ret == -ERESTARTSYS)
                        return ret;
-               if (ret2)
-                       return -EINTR;
        }
 
        /* need to re-get the ls, as it may have changed when we released the
@@ -343,13 +350,14 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
        if (mutex_lock_interruptible(&ctx->run_mutex))
                return -ERESTARTSYS;
 
-       spu_enable_spu(ctx);
        ctx->event_return = 0;
 
        ret = spu_acquire(ctx);
        if (ret)
                goto out_unlock;
 
+       spu_enable_spu(ctx);
+
        spu_update_sched_info(ctx);
 
        ret = spu_run_init(ctx, npc);
index 7298e7db2c8365cf83f8519350f917a01a35c8c3..2e411f23462b47417e50f965905a62f947c73f8f 100644 (file)
@@ -140,6 +140,9 @@ void __spu_update_sched_info(struct spu_context *ctx)
         * if it is timesliced or preempted.
         */
        ctx->cpus_allowed = current->cpus_allowed;
+
+       /* Save the current cpu id for spu interrupt routing. */
+       ctx->last_ran = raw_smp_processor_id();
 }
 
 void spu_update_sched_info(struct spu_context *ctx)
@@ -243,7 +246,6 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
        spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0);
        spu_restore(&ctx->csa, spu);
        spu->timestamp = jiffies;
-       spu_cpu_affinity_set(spu, raw_smp_processor_id());
        spu_switch_notify(spu, ctx);
        ctx->state = SPU_STATE_RUNNABLE;
 
@@ -657,7 +659,8 @@ static struct spu *find_victim(struct spu_context *ctx)
 
                        victim->stats.invol_ctx_switch++;
                        spu->stats.invol_ctx_switch++;
-                       spu_add_to_rq(victim);
+                       if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
+                               spu_add_to_rq(victim);
 
                        mutex_unlock(&victim->state_mutex);
 
index 7312745b7540d4586fd72c7e4b57e9b5a9abd641..454c277c1457deaf4034b084cf95e438241c295c 100644 (file)
@@ -121,6 +121,7 @@ struct spu_context {
        cpumask_t cpus_allowed;
        int policy;
        int prio;
+       int last_ran;
 
        /* statistics */
        struct {
@@ -331,7 +332,7 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
 /* irq callback funcs. */
 void spufs_ibox_callback(struct spu *spu);
 void spufs_wbox_callback(struct spu *spu);
-void spufs_stop_callback(struct spu *spu);
+void spufs_stop_callback(struct spu *spu, int irq);
 void spufs_mfc_callback(struct spu *spu);
 void spufs_dma_callback(struct spu *spu, int type);
 
index d2a1249d36dd2a7bc018727e09c3b7c57b88cf1c..3df9a36eb2f58efe6bcda41f7d27cf5861ac4e5b 100644 (file)
@@ -132,6 +132,14 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
        spu_int_mask_set(spu, 2, 0ul);
        eieio();
        spin_unlock_irq(&spu->register_lock);
+
+       /*
+        * This flag needs to be set before calling synchronize_irq so
+        * that the update will be visible to the relevant handlers
+        * via a simple load.
+        */
+       set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
+       clear_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
        synchronize_irq(spu->irqs[0]);
        synchronize_irq(spu->irqs[1]);
        synchronize_irq(spu->irqs[2]);
@@ -166,9 +174,8 @@ static inline void set_switch_pending(struct spu_state *csa, struct spu *spu)
        /* Save, Step 7:
         * Restore, Step 5:
         *     Set a software context switch pending flag.
+        *     Done above in Step 3 - disable_interrupts().
         */
-       set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
-       mb();
 }
 
 static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu)
@@ -186,20 +193,21 @@ static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu)
                                 MFC_CNTL_SUSPEND_COMPLETE);
                /* fall through */
        case MFC_CNTL_SUSPEND_COMPLETE:
-               if (csa) {
+               if (csa)
                        csa->priv2.mfc_control_RW =
-                               MFC_CNTL_SUSPEND_MASK |
+                               in_be64(&priv2->mfc_control_RW) |
                                MFC_CNTL_SUSPEND_DMA_QUEUE;
-               }
                break;
        case MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION:
                out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE);
                POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) &
                                  MFC_CNTL_SUSPEND_DMA_STATUS_MASK) ==
                                 MFC_CNTL_SUSPEND_COMPLETE);
-               if (csa) {
-                       csa->priv2.mfc_control_RW = 0;
-               }
+               if (csa)
+                       csa->priv2.mfc_control_RW =
+                               in_be64(&priv2->mfc_control_RW) &
+                               ~MFC_CNTL_SUSPEND_DMA_QUEUE &
+                               ~MFC_CNTL_SUSPEND_MASK;
                break;
        }
 }
@@ -249,16 +257,21 @@ static inline void save_spu_status(struct spu_state *csa, struct spu *spu)
        }
 }
 
-static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu)
+static inline void save_mfc_stopped_status(struct spu_state *csa,
+               struct spu *spu)
 {
        struct spu_priv2 __iomem *priv2 = spu->priv2;
+       const u64 mask = MFC_CNTL_DECREMENTER_RUNNING |
+                       MFC_CNTL_DMA_QUEUES_EMPTY;
 
        /* Save, Step 12:
         *     Read MFC_CNTL[Ds].  Update saved copy of
         *     CSA.MFC_CNTL[Ds].
+        *
+        * update: do the same with MFC_CNTL[Q].
         */
-       csa->priv2.mfc_control_RW |=
-               in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING;
+       csa->priv2.mfc_control_RW &= ~mask;
+       csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask;
 }
 
 static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu)
@@ -462,7 +475,9 @@ static inline void purge_mfc_queue(struct spu_state *csa, struct spu *spu)
         * Restore, Step 14.
         *     Write MFC_CNTL[Pc]=1 (purge queue).
         */
-       out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST);
+       out_be64(&priv2->mfc_control_RW,
+                       MFC_CNTL_PURGE_DMA_REQUEST |
+                       MFC_CNTL_SUSPEND_MASK);
        eieio();
 }
 
@@ -725,10 +740,14 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
        /* Save, Step 48:
         * Restore, Step 23.
         *     Change the software context switch pending flag
-        *     to context switch active.
+        *     to context switch active.  This implementation does
+        *     not uses a switch active flag.
         *
-        *     This implementation does not uses a switch active flag.
+        * Now that we have saved the mfc in the csa, we can add in the
+        * restart command if an exception occurred.
         */
+       if (test_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags))
+               csa->priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
        clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
        mb();
 }
@@ -1690,6 +1709,13 @@ static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu)
        eieio();
 }
 
+static inline void set_int_route(struct spu_state *csa, struct spu *spu)
+{
+       struct spu_context *ctx = spu->ctx;
+
+       spu_cpu_affinity_set(spu, ctx->last_ran);
+}
+
 static inline void restore_other_spu_access(struct spu_state *csa,
                                            struct spu *spu)
 {
@@ -1721,15 +1747,15 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu)
         */
        out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW);
        eieio();
+
        /*
-        * FIXME: this is to restart a DMA that we were processing
-        *        before the save. better remember the fault information
-        *        in the csa instead.
+        * The queue is put back into the same state that was evident prior to
+        * the context switch. The suspend flag is added to the saved state in
+        * the csa, if the operational state was suspending or suspended. In
+        * this case, the code that suspended the mfc is responsible for
+        * continuing it. Note that SPE faults do not change the operational
+        * state of the spu.
         */
-       if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) {
-               out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
-               eieio();
-       }
 }
 
 static inline void enable_user_access(struct spu_state *csa, struct spu *spu)
@@ -1788,7 +1814,7 @@ static int quiece_spu(struct spu_state *prev, struct spu *spu)
        save_spu_runcntl(prev, spu);            /* Step 9. */
        save_mfc_sr1(prev, spu);                /* Step 10. */
        save_spu_status(prev, spu);             /* Step 11. */
-       save_mfc_decr(prev, spu);               /* Step 12. */
+       save_mfc_stopped_status(prev, spu);     /* Step 12. */
        halt_mfc_decr(prev, spu);               /* Step 13. */
        save_timebase(prev, spu);               /* Step 14. */
        remove_other_spu_access(prev, spu);     /* Step 15. */
@@ -2000,6 +2026,7 @@ static void restore_csa(struct spu_state *next, struct spu *spu)
        check_ppuint_mb_stat(next, spu);        /* Step 67. */
        spu_invalidate_slbs(spu);               /* Modified Step 68. */
        restore_mfc_sr1(next, spu);             /* Step 69. */
+       set_int_route(next, spu);               /* NEW      */
        restore_other_spu_access(next, spu);    /* Step 70. */
        restore_spu_runcntl(next, spu);         /* Step 71. */
        restore_mfc_cntl(next, spu);            /* Step 72. */
index a14e5cdc2fed758862ef2e5de522831955b16810..e59634f7af9637d29bca47505508bb30cf624953 100644 (file)
@@ -167,8 +167,8 @@ static struct irq_chip ps3_irq_chip = {
  * ps3_private data.
  */
 
-int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
-       unsigned int *virq)
+static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
+                         unsigned int *virq)
 {
        int result;
        struct ps3_private *pd;
@@ -217,7 +217,7 @@ fail_create:
  * Clears chip data and calls irq_dispose_mapping() for the virq.
  */
 
-int ps3_virq_destroy(unsigned int virq)
+static int ps3_virq_destroy(unsigned int virq)
 {
        const struct ps3_private *pd = get_irq_chip_data(virq);
 
index bec3803f0618ec9486a98668b39e7145f0c21b6f..417eca79df697ed35eb9b29d41ef15cd1a1891b2 100644 (file)
@@ -55,11 +55,6 @@ static ssize_t scanlog_read(struct file *file, char __user *buf,
         dp = PDE(inode);
        data = (unsigned int *)dp->data;
 
-       if (!data) {
-               printk(KERN_ERR "scanlog: read failed no data\n");
-               return -EIO;
-       }
-
        if (count > RTAS_DATA_BUF_SIZE)
                count = RTAS_DATA_BUF_SIZE;
 
@@ -146,11 +141,6 @@ static int scanlog_open(struct inode * inode, struct file * file)
        struct proc_dir_entry *dp = PDE(inode);
        unsigned int *data = (unsigned int *)dp->data;
 
-       if (!data) {
-               printk(KERN_ERR "scanlog: open failed no data\n");
-               return -EIO;
-       }
-
        if (data[0] != 0) {
                /* This imperfect test stops a second copy of the
                 * data (or a reset while data is being copied)
@@ -168,10 +158,6 @@ static int scanlog_release(struct inode * inode, struct file * file)
        struct proc_dir_entry *dp = PDE(inode);
        unsigned int *data = (unsigned int *)dp->data;
 
-       if (!data) {
-               printk(KERN_ERR "scanlog: release failed no data\n");
-               return -EIO;
-       }
        data[0] = 0;
 
        return 0;
@@ -200,12 +186,11 @@ static int __init scanlog_init(void)
        if (!data)
                goto err;
 
-       ent = proc_create("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
-                         &scanlog_fops);
+       ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
+                              &scanlog_fops, data);
        if (!ent)
                goto err;
 
-       ent->data = data;
        proc_ppc64_scan_log_dump = ent;
 
        return 0;
index 3d920376f58e8b2a6bfd5746196136424be7ad1c..a0fa4ebb39c62b2b2a569bcf03204cde7db0e1b6 100644 (file)
@@ -176,6 +176,7 @@ struct rio_priv {
 
 /**
  * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
+ * @mport: RapidIO master port info
  * @index: ID of RapidIO interface
  * @destid: Destination ID of target device
  * @data: 16-bit info field of RapidIO doorbell message
@@ -211,6 +212,7 @@ static int fsl_rio_doorbell_send(struct rio_mport *mport,
 
 /**
  * fsl_local_config_read - Generate a MPC85xx local config space read
+ * @mport: RapidIO master port info
  * @index: ID of RapdiIO interface
  * @offset: Offset into configuration space
  * @len: Length (in bytes) of the maintenance transaction
@@ -232,6 +234,7 @@ static int fsl_local_config_read(struct rio_mport *mport,
 
 /**
  * fsl_local_config_write - Generate a MPC85xx local config space write
+ * @mport: RapidIO master port info
  * @index: ID of RapdiIO interface
  * @offset: Offset into configuration space
  * @len: Length (in bytes) of the maintenance transaction
@@ -254,6 +257,7 @@ static int fsl_local_config_write(struct rio_mport *mport,
 
 /**
  * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * @mport: RapidIO master port info
  * @index: ID of RapdiIO interface
  * @destid: Destination ID of transaction
  * @hopcount: Number of hops to target device
@@ -295,6 +299,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
 
 /**
  * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * @mport: RapidIO master port info
  * @index: ID of RapdiIO interface
  * @destid: Destination ID of transaction
  * @hopcount: Number of hops to target device
@@ -985,8 +990,8 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr)
 }
 
 /**
- * fsl_rio_setup - Setup MPC85xx RapidIO interface
- * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
+ * fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
+ * @dev: of_device pointer
  *
  * Initializes MPC85xx RapidIO hardware interface, configures
  * master port with system-specific info, and registers the
index 324c01b70dddfc14701210dc1547c3dfd9a65fab..3a7054e2bb75722a731632af377da31f6420496b 100644 (file)
@@ -389,8 +389,8 @@ static int __init gfar_of_init(void)
                        }
 
                        gfar_data.phy_id = *id;
-                       snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%x",
-                                       res.start);
+                       snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx",
+                                (unsigned long long)res.start);
 
                        of_node_put(phy);
                        of_node_put(mdio);
index 1814adbd22363c13f79f8e2744f41cf9f14e1f5d..b4a54c52e8805cac1fb32af31d85d0168ff41bda 100644 (file)
@@ -1387,28 +1387,59 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
        resource_size_t size = res->end - res->start + 1;
        u64 sa;
 
-       /* Calculate window size */
-       sa = (0xffffffffffffffffull << ilog2(size));;
-       if (res->flags & IORESOURCE_PREFETCH)
-               sa |= 0x8;
+       if (port->endpoint) {
+               resource_size_t ep_addr = 0;
+               resource_size_t ep_size = 32 << 20;
+
+               /* Currently we map a fixed 64MByte window to PLB address
+                * 0 (SDRAM). This should probably be configurable via a dts
+                * property.
+                */
+
+               /* Calculate window size */
+               sa = (0xffffffffffffffffull << ilog2(ep_size));;
+
+               /* Setup BAR0 */
+               out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
+               out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa) |
+                        PCI_BASE_ADDRESS_MEM_TYPE_64);
 
-       out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
-       out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
+               /* Disable BAR1 & BAR2 */
+               out_le32(mbase + PECFG_BAR1MPA, 0);
+               out_le32(mbase + PECFG_BAR2HMPA, 0);
+               out_le32(mbase + PECFG_BAR2LMPA, 0);
 
-       /* The setup of the split looks weird to me ... let's see if it works */
-       out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
-       out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
-       out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
-       out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
-       out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
-       out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+               out_le32(mbase + PECFG_PIM01SAH, RES_TO_U32_HIGH(sa));
+               out_le32(mbase + PECFG_PIM01SAL, RES_TO_U32_LOW(sa));
+
+               out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(ep_addr));
+               out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr));
+       } else {
+               /* Calculate window size */
+               sa = (0xffffffffffffffffull << ilog2(size));;
+               if (res->flags & IORESOURCE_PREFETCH)
+                       sa |= 0x8;
+
+               out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
+               out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
+
+               /* The setup of the split looks weird to me ... let's see
+                * if it works
+                */
+               out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
+               out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
+               out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+               out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
+               out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
+               out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+
+               out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
+               out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
+       }
 
        /* Enable inbound mapping */
        out_le32(mbase + PECFG_PIMEN, 0x1);
 
-       out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
-       out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
-
        /* Enable I/O, Mem, and Busmaster cycles */
        out_le16(mbase + PCI_COMMAND,
                 in_le16(mbase + PCI_COMMAND) |
@@ -1422,13 +1453,8 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
        const int *bus_range;
        int primary = 0, busses;
        void __iomem *mbase = NULL, *cfg_data = NULL;
-
-       /* XXX FIXME: Handle endpoint mode properly */
-       if (port->endpoint) {
-               printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n",
-                      port->index);
-               return;
-       }
+       const u32 *pval;
+       u32 val;
 
        /* Check if primary bridge */
        if (of_get_property(port->node, "primary", NULL))
@@ -1462,21 +1488,30 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
                hose->last_busno = hose->first_busno + busses;
        }
 
-       /* We map the external config space in cfg_data and the host config
-        * space in cfg_addr. External space is 1M per bus, internal space
-        * is 4K
+       if (!port->endpoint) {
+               /* Only map the external config space in cfg_data for
+                * PCIe root-complexes. External space is 1M per bus
+                */
+               cfg_data = ioremap(port->cfg_space.start +
+                                  (hose->first_busno + 1) * 0x100000,
+                                  busses * 0x100000);
+               if (cfg_data == NULL) {
+                       printk(KERN_ERR "%s: Can't map external config space !",
+                              port->node->full_name);
+                       goto fail;
+               }
+               hose->cfg_data = cfg_data;
+       }
+
+       /* Always map the host config space in cfg_addr.
+        * Internal space is 4K
         */
-       cfg_data = ioremap(port->cfg_space.start +
-                                (hose->first_busno + 1) * 0x100000,
-                                busses * 0x100000);
        mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
-       if (cfg_data == NULL || mbase == NULL) {
-               printk(KERN_ERR "%s: Can't map config space !",
+       if (mbase == NULL) {
+               printk(KERN_ERR "%s: Can't map internal config space !",
                       port->node->full_name);
                goto fail;
        }
-
-       hose->cfg_data = cfg_data;
        hose->cfg_addr = mbase;
 
        pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name,
@@ -1489,12 +1524,14 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
        port->hose = hose;
        mbase = (void __iomem *)hose->cfg_addr;
 
-       /*
-        * Set bus numbers on our root port
-        */
-       out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
-       out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
-       out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
+       if (!port->endpoint) {
+               /*
+                * Set bus numbers on our root port
+                */
+               out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
+               out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
+               out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
+       }
 
        /*
         * OMRs are already reset, also disable PIMs
@@ -1515,17 +1552,49 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
        ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window);
 
        /* The root complex doesn't show up if we don't set some vendor
-        * and device IDs into it. Those are the same bogus one that the
-        * initial code in arch/ppc add. We might want to change that.
+        * and device IDs into it. The defaults below are the same bogus
+        * one that the initial code in arch/ppc had. This can be
+        * overwritten by setting the "vendor-id/device-id" properties
+        * in the pciex node.
         */
-       out_le16(mbase + 0x200, 0xaaa0 + port->index);
-       out_le16(mbase + 0x202, 0xbed0 + port->index);
 
-       /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
-       out_le32(mbase + 0x208, 0x06040001);
+       /* Get the (optional) vendor-/device-id from the device-tree */
+       pval = of_get_property(port->node, "vendor-id", NULL);
+       if (pval) {
+               val = *pval;
+       } else {
+               if (!port->endpoint)
+                       val = 0xaaa0 + port->index;
+               else
+                       val = 0xeee0 + port->index;
+       }
+       out_le16(mbase + 0x200, val);
+
+       pval = of_get_property(port->node, "device-id", NULL);
+       if (pval) {
+               val = *pval;
+       } else {
+               if (!port->endpoint)
+                       val = 0xbed0 + port->index;
+               else
+                       val = 0xfed0 + port->index;
+       }
+       out_le16(mbase + 0x202, val);
+
+       if (!port->endpoint) {
+               /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
+               out_le32(mbase + 0x208, 0x06040001);
+
+               printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
+                      port->index);
+       } else {
+               /* Set Class Code to Processor/PPC */
+               out_le32(mbase + 0x208, 0x0b200001);
+
+               printk(KERN_INFO "PCIE%d: successfully set as endpoint\n",
+                      port->index);
+       }
 
-       printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
-              port->index);
        return;
  fail:
        if (hose)
@@ -1542,6 +1611,7 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
        const u32 *pval;
        int portno;
        unsigned int dcrs;
+       const char *val;
 
        /* First, proceed to core initialization as we assume there's
         * only one PCIe core in the system
@@ -1573,8 +1643,20 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
        }
        port->sdr_base = *pval;
 
-       /* XXX Currently, we only support root complex mode */
-       port->endpoint = 0;
+       /* Check if device_type property is set to "pci" or "pci-endpoint".
+        * Resulting from this setup this PCIe port will be configured
+        * as root-complex or as endpoint.
+        */
+       val = of_get_property(port->node, "device_type", NULL);
+       if (!strcmp(val, "pci-endpoint")) {
+               port->endpoint = 1;
+       } else if (!strcmp(val, "pci")) {
+               port->endpoint = 0;
+       } else {
+               printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n",
+                      np->full_name);
+               return;
+       }
 
        /* Fetch config space registers address */
        if (of_address_to_resource(np, 0, &port->cfg_space)) {
index ba8eea2bcce0460f833adf4a968be19a209c75d7..b7aefd0d45cb20204d7e95b81240564e0cc1ba69 100644 (file)
@@ -107,7 +107,7 @@ xilinx_intc_init(struct device_node *np)
        }
        regs = ioremap(res.start, 32);
 
-       printk(KERN_INFO "Xilinx intc at 0x%08X mapped to 0x%p\n",
+       printk(KERN_INFO "Xilinx intc at 0x%08LX mapped to 0x%p\n",
                res.start, regs);
 
        /* Setup interrupt controller */
index 52c74780f403c420c47bbcf13640173b6992852e..1702de9395eeee96b02d686e20550dbc98b8d63d 100644 (file)
@@ -2842,9 +2842,11 @@ static void dump_spu_fields(struct spu *spu)
        DUMP_FIELD(spu, "0x%lx", ls_size);
        DUMP_FIELD(spu, "0x%x", node);
        DUMP_FIELD(spu, "0x%lx", flags);
-       DUMP_FIELD(spu, "0x%lx", dar);
-       DUMP_FIELD(spu, "0x%lx", dsisr);
        DUMP_FIELD(spu, "%d", class_0_pending);
+       DUMP_FIELD(spu, "0x%lx", class_0_dar);
+       DUMP_FIELD(spu, "0x%lx", class_0_dsisr);
+       DUMP_FIELD(spu, "0x%lx", class_1_dar);
+       DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
        DUMP_FIELD(spu, "0x%lx", irqs[0]);
        DUMP_FIELD(spu, "0x%lx", irqs[1]);
        DUMP_FIELD(spu, "0x%lx", irqs[2]);
index 8df7f0e4c3a62ee245ca120355c3545d944d793f..2352d139b262bd378434987782bf1c5b0592404c 100644 (file)
@@ -43,7 +43,7 @@ KBUILD_AFLAGS += $(cpu-as-y)
 KBUILD_CFLAGS += $(cpu-as-y)
 
 # Default to the common case.
-KBUILD_DEFCONFIG := common_defconfig
+KBUILD_DEFCONFIG := ebony_defconfig
 
 head-y                         := arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)             := arch/ppc/kernel/head_8xx.o
index 16ac11ca7ba0feb0b022fc8093a21bcf6cae4f61..602c268fc8a2875ae55f5c51ddbbf59f510d4838 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <linux/pmu.h>
index bfddfdee0b6592867d3801b8c3500c55e76f3d33..51e8094f52d6e9f46f5ff71a806de653db578a4a 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/nvram.h>
 #include <asm/xmon.h>
 #include <asm/ocp.h>
+#include <asm/irq.h>
 
 #define USES_PPC_SYS (defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
                      defined(CONFIG_PPC_MPC52xx))
index 18495e754e3086be415af6e69f86f927fd4ce978..d687b0f8763b20750b1f2de574836c87db968376 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sections.h>
 #include <asm/mmu.h>
index 29a7940f284f62fa1f9e27508bc7d55f9b50aca4..1d035082e78eb15fc73f8f3b7b939af19eaa23ba 100644 (file)
@@ -430,6 +430,13 @@ config CMM_IUCV
          Select this option to enable the special message interface to
          the cooperative memory management.
 
+config PAGE_STATES
+       bool "Unused page notification"
+       help
+         This enables the notification of unused pages to the
+         hypervisor. The ESSA instruction is used to do the states
+         changes between a page that has content and the unused state.
+
 config VIRT_TIMER
        bool "Virtual CPU timer support"
        help
index 743d54f0b8dbb01e93c17f51be274bece0005f48..d003a6e16afb807df2ecbbcc6066de49f0784c33 100644 (file)
@@ -121,7 +121,7 @@ sys32_ptrace_wrapper:
        lgfr    %r3,%r3                 # long
        llgtr   %r4,%r4                 # long
        llgfr   %r5,%r5                 # long
-       jg      sys_ptrace              # branch to system call
+       jg      compat_sys_ptrace       # branch to system call
 
        .globl  sys32_alarm_wrapper
 sys32_alarm_wrapper:
index bdbb3bcd78a5d7088ed4cfd39f7fb444e2f15814..708cf9cf9a355e175d5b1cf4fbdc2b96732e7084 100644 (file)
@@ -279,8 +279,6 @@ sysc_do_restart:
        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
 
 sysc_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-       bno     BASED(sysc_restore)
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_restore:
@@ -312,6 +310,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       bno     BASED(sysc_restore)
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(sysc_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -602,12 +602,6 @@ io_no_vtime:
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        basr    %r14,%r1                # branch to standard irq handler
 io_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifdef CONFIG_PREEMPT
-       bno     BASED(io_preempt)       # no -> check for preemptive scheduling
-#else
-       bno     BASED(io_restore)       # no-> skip resched & signal
-#endif
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
        bnz     BASED(io_work)          # there is work to do (signals etc.)
 io_restore:
@@ -629,10 +623,18 @@ io_restore_trace_psw:
        .long   0, io_restore_trace + 0x80000000
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# switch to kernel stack, then check the TIF bits
+#
+io_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+#ifndef CONFIG_PREEMPT
+       bno     BASED(io_restore)       # no-> skip resched & signal
+#else
+       bnz     BASED(io_work_user)     # no -> check for preemptive scheduling
+       # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
-       bnz     BASED(io_restore)
+       bnz     BASED(io_restore)       # preemption disabled
        l       %r1,SP_R15(%r15)
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -646,10 +648,7 @@ io_resume_loop:
        br      %r1                     # call schedule
 #endif
 
-#
-# switch to kernel stack, then check the TIF bits
-#
-io_work:
+io_work_user:
        l       %r1,__LC_KERNEL_STACK
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
index 5a4a7bcd2bbad8e92e95eb529fb11559977c0dd9..fee10177dbfcf67a175c7d82f1839886ef509ff4 100644 (file)
@@ -271,8 +271,6 @@ sysc_noemu:
        stg     %r2,SP_R2(%r15) # store return value (change R2 on stack)
 
 sysc_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-       jno     sysc_restore
        tm      __TI_flags+7(%r9),_TIF_WORK_SVC
        jnz     sysc_work       # there is work to do (signals etc.)
 sysc_restore:
@@ -304,6 +302,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       jno     sysc_restore
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jo      sysc_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -585,12 +585,6 @@ io_no_vtime:
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        brasl   %r14,do_IRQ             # call standard irq handler
 io_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifdef CONFIG_PREEMPT
-       jno     io_preempt              # no -> check for preemptive scheduling
-#else
-       jno     io_restore              # no-> skip resched & signal
-#endif
        tm      __TI_flags+7(%r9),_TIF_WORK_INT
        jnz     io_work                 # there is work to do (signals etc.)
 io_restore:
@@ -612,10 +606,41 @@ io_restore_trace_psw:
        .quad   0, io_restore_trace
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# There is work todo, we need to check if we return to userspace, then
+# check, if we are in SIE, if yes leave it
+#
+io_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+#ifndef CONFIG_PREEMPT
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+       jnz     io_work_user            # yes -> no need to check for SIE
+       la      %r1, BASED(sie_opcode)  # we return to kernel here
+       lg      %r2, SP_PSW+8(%r15)
+       clc     0(2,%r1), 0(%r2)        # is current instruction = SIE?
+       jne     io_restore              # no-> return to kernel
+       lg      %r1, SP_PSW+8(%r15)     # yes-> add 4 bytes to leave SIE
+       aghi    %r1, 4
+       stg     %r1, SP_PSW+8(%r15)
+       j       io_restore              # return to kernel
+#else
+       jno     io_restore              # no-> skip resched & signal
+#endif
+#else
+       jnz     io_work_user            # yes -> do resched & signal
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+       la      %r1, BASED(sie_opcode)
+       lg      %r2, SP_PSW+8(%r15)
+       clc     0(2,%r1), 0(%r2)        # is current instruction = SIE?
+       jne     0f                      # no -> leave PSW alone
+       lg      %r1, SP_PSW+8(%r15)     # yes-> add 4 bytes to leave SIE
+       aghi    %r1, 4
+       stg     %r1, SP_PSW+8(%r15)
+0:
+#endif
+       # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
-       jnz     io_restore
+       jnz     io_restore              # preemption is disabled
        # switch to kernel stack
        lg      %r1,SP_R15(%r15)
        aghi    %r1,-SP_SIZE
@@ -629,10 +654,7 @@ io_resume_loop:
        jg      preempt_schedule_irq
 #endif
 
-#
-# switch to kernel stack, then check TIF bits
-#
-io_work:
+io_work_user:
        lg      %r1,__LC_KERNEL_STACK
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -653,6 +675,11 @@ io_work_loop:
        j       io_restore
 io_work_done:
 
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+sie_opcode:
+       .long 0xb2140000
+#endif
+
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
index 7f4270163744b1ea5af37b6a68ca69e2cef89437..35827b9bd4d1827f102f79f3e999bbb69c52f5ab 100644 (file)
@@ -292,8 +292,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
        return 0;
 }
 
-static int
-do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        ptrace_area parea; 
        int copied, ret;
@@ -529,35 +528,19 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
        return 0;
 }
 
-static int
-do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+                       compat_ulong_t caddr, compat_ulong_t cdata)
 {
-       unsigned int tmp;  /* 4 bytes !! */
+       unsigned long addr = caddr;
+       unsigned long data = cdata;
        ptrace_area_emu31 parea; 
        int copied, ret;
 
        switch (request) {
-       case PTRACE_PEEKTEXT:
-       case PTRACE_PEEKDATA:
-               /* read word at location addr. */
-               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-               if (copied != sizeof(tmp))
-                       return -EIO;
-               return put_user(tmp, (unsigned int __force __user *) data);
-
        case PTRACE_PEEKUSR:
                /* read the word at location addr in the USER area. */
                return peek_user_emu31(child, addr, data);
 
-       case PTRACE_POKETEXT:
-       case PTRACE_POKEDATA:
-               /* write the word at location addr. */
-               tmp = data;
-               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
-               if (copied != sizeof(tmp))
-                       return -EIO;
-               return 0;
-
        case PTRACE_POKEUSR:
                /* write the word at location addr in the USER area */
                return poke_user_emu31(child, addr, data);
@@ -587,82 +570,11 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
                        copied += sizeof(unsigned int);
                }
                return 0;
-       case PTRACE_GETEVENTMSG:
-               return put_user((__u32) child->ptrace_message,
-                               (unsigned int __force __user *) data);
-       case PTRACE_GETSIGINFO:
-               if (child->last_siginfo == NULL)
-                       return -EINVAL;
-               return copy_siginfo_to_user32((compat_siginfo_t
-                                              __force __user *) data,
-                                             child->last_siginfo);
-       case PTRACE_SETSIGINFO:
-               if (child->last_siginfo == NULL)
-                       return -EINVAL;
-               return copy_siginfo_from_user32(child->last_siginfo,
-                                               (compat_siginfo_t
-                                                __force __user *) data);
        }
-       return ptrace_request(child, request, addr, data);
+       return compat_ptrace_request(child, request, addr, data);
 }
 #endif
 
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
-{
-       switch (request) {
-       case PTRACE_SYSCALL:
-               /* continue and stop at next (return from) syscall */
-       case PTRACE_CONT:
-               /* restart after signal. */
-               if (!valid_signal(data))
-                       return -EIO;
-               if (request == PTRACE_SYSCALL)
-                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               else
-                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->exit_code = data;
-               /* make sure the single step bit is not set. */
-               user_disable_single_step(child);
-               wake_up_process(child);
-               return 0;
-
-       case PTRACE_KILL:
-               /*
-                * make the child exit.  Best I can do is send it a sigkill. 
-                * perhaps it should be put in the status that it wants to 
-                * exit.
-                */
-               if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-                       return 0;
-               child->exit_code = SIGKILL;
-               /* make sure the single step bit is not set. */
-               user_disable_single_step(child);
-               wake_up_process(child);
-               return 0;
-
-       case PTRACE_SINGLESTEP:
-               /* set the trap flag. */
-               if (!valid_signal(data))
-                       return -EIO;
-               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->exit_code = data;
-               user_enable_single_step(child);
-               /* give it a chance to run. */
-               wake_up_process(child);
-               return 0;
-
-       /* Do requests that differ for 31/64 bit */
-       default:
-#ifdef CONFIG_COMPAT
-               if (test_thread_flag(TIF_31BIT))
-                       return do_ptrace_emu31(child, request, addr, data);
-#endif
-               return do_ptrace_normal(child, request, addr, data);
-       }
-       /* Not reached.  */
-       return -EIO;
-}
-
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
index 988d0d64c2c898f154278b8accfa5d935efe0ad8..5fdb799062b7abfa1471488fd2582660cd56b08a 100644 (file)
 #include <asm/uaccess.h>
 #include "entry.h"
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage long sys_pipe(unsigned long __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 /* common code for old and new mmaps */
 static inline long do_mmap2(
        unsigned long addr, unsigned long len,
index 1761b74d639be88e3fbc870cda7a4942c7b50ac9..e051cad1f1e09d9f880b91f0d23b7738e10a5a57 100644 (file)
@@ -22,7 +22,6 @@ config KVM
        select PREEMPT_NOTIFIERS
        select ANON_INODES
        select S390_SWITCH_AMODE
-       select PREEMPT
        ---help---
          Support hosting paravirtualized guest machines using the SIE
          virtualization capability on the mainframe. This should work
index 349581a2610344f23c1af6873dc57d6c23761b47..47a0b642174c1ef807ca5d16774f9d10c6584197 100644 (file)
@@ -105,6 +105,9 @@ static intercept_handler_t instruction_handlers[256] = {
 static int handle_noop(struct kvm_vcpu *vcpu)
 {
        switch (vcpu->arch.sie_block->icptcode) {
+       case 0x0:
+               vcpu->stat.exit_null++;
+               break;
        case 0x10:
                vcpu->stat.exit_external_request++;
                break;
index 98d1e73e01f11f31cdac4d693f54c1bfddedc871..0ac36a649eba9a2823189d3bb31dcb68b0ec6055 100644 (file)
@@ -31,6 +31,7 @@
 
 struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "userspace_handled", VCPU_STAT(exit_userspace) },
+       { "exit_null", VCPU_STAT(exit_null) },
        { "exit_validity", VCPU_STAT(exit_validity) },
        { "exit_stop_request", VCPU_STAT(exit_stop_request) },
        { "exit_external_request", VCPU_STAT(exit_external_request) },
@@ -221,10 +222,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
        restore_fp_regs(&vcpu->arch.guest_fpregs);
        restore_access_regs(vcpu->arch.guest_acrs);
-
-       if (signal_pending(current))
-               atomic_set_mask(CPUSTAT_STOP_INT,
-                       &vcpu->arch.sie_block->cpuflags);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
index fb988a48a754ff541d161ba341a108e10a2a15e1..2a745813454410cb35ff525e837efc9f29c0dd95 100644 (file)
@@ -5,3 +5,4 @@
 obj-y   := init.o fault.o extmem.o mmap.o vmem.o pgtable.o
 obj-$(CONFIG_CMM) += cmm.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_PAGE_STATES) += page-states.o
index fa31de6ae97aef1577b99d0f9afb04cf257334ce..29f3a63806b976ee8847dd3efd84292697ba53db 100644 (file)
@@ -126,6 +126,9 @@ void __init mem_init(void)
         /* clear the zero-page */
         memset(empty_zero_page, 0, PAGE_SIZE);
 
+       /* Setup guest page hinting */
+       cmma_init();
+
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem();
 
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
new file mode 100644 (file)
index 0000000..fc0ad73
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * arch/s390/mm/page-states.c
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Guest page hinting for unused pages.
+ *
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#define ESSA_SET_STABLE                1
+#define ESSA_SET_UNUSED                2
+
+static int cmma_flag;
+
+static int __init cmma(char *str)
+{
+       char *parm;
+       parm = strstrip(str);
+       if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) {
+               cmma_flag = 1;
+               return 1;
+       }
+       cmma_flag = 0;
+       if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0)
+               return 1;
+       return 0;
+}
+
+__setup("cmma=", cmma);
+
+void __init cmma_init(void)
+{
+       register unsigned long tmp asm("0") = 0;
+       register int rc asm("1") = -EOPNOTSUPP;
+
+       if (!cmma_flag)
+               return;
+       asm volatile(
+               "       .insn rrf,0xb9ab0000,%1,%1,0,0\n"
+               "0:     la      %0,0\n"
+               "1:\n"
+               EX_TABLE(0b,1b)
+               : "+&d" (rc), "+&d" (tmp));
+       if (rc)
+               cmma_flag = 0;
+}
+
+void arch_free_page(struct page *page, int order)
+{
+       int i, rc;
+
+       if (!cmma_flag)
+               return;
+       for (i = 0; i < (1 << order); i++)
+               asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
+                            : "=&d" (rc)
+                            : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
+                              "i" (ESSA_SET_UNUSED));
+}
+
+void arch_alloc_page(struct page *page, int order)
+{
+       int i, rc;
+
+       if (!cmma_flag)
+               return;
+       for (i = 0; i < (1 << order); i++)
+               asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
+                            : "=&d" (rc)
+                            : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
+                              "i" (ESSA_SET_STABLE));
+}
index 6a679c3e15e817d14adcee8d6771c9e3c89e5b30..8a68160079a90cb5c77411f410960d59899abd5a 100644 (file)
@@ -448,14 +448,6 @@ config SH_DREAMCAST
          Select Dreamcast if configuring for a SEGA Dreamcast.
          More information at <http://www.linux-sh.org>
 
-config SH_MPC1211
-       bool "Interface MPC1211"
-       depends on CPU_SUBTYPE_SH7751 && BROKEN
-       help
-         CTP/PCI-SH02 is a CPU module computer that is produced
-         by Interface Corporation.
-         More information at <http://www.interface.co.jp>
-
 config SH_SH03
        bool "Interface CTP/PCI-SH03"
        depends on CPU_SUBTYPE_SH7751
@@ -657,8 +649,7 @@ source "arch/sh/drivers/Kconfig"
 endmenu
 
 config ISA_DMA_API
-       def_bool y
-       depends on SH_MPC1211
+       bool
 
 menu "Kernel features"
 
@@ -666,7 +657,7 @@ source kernel/Kconfig.hz
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on SUPERH32 && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
@@ -683,7 +674,7 @@ config KEXEC
 
 config CRASH_DUMP
        bool "kernel crash dumps (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on SUPERH32 && EXPERIMENTAL
        help
          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
@@ -763,7 +754,7 @@ menu "Boot options"
 
 config ZERO_PAGE_OFFSET
        hex "Zero page offset"
-       default "0x00004000" if SH_MPC1211 || SH_SH03
+       default "0x00004000" if SH_SH03
        default "0x00010000" if PAGE_SIZE_64KB
        default "0x00002000" if PAGE_SIZE_8KB
        default "0x00001000"
index d9d28f9dd0db5fbd990a1262d07898017e73cc04..0d2ef1e9a6fdd45cf483f61b33ccc96d2e71ce04 100644 (file)
@@ -7,6 +7,7 @@ source "lib/Kconfig.debug"
 
 config SH_STANDARD_BIOS
        bool "Use LinuxSH standard BIOS"
+       depends on SUPERH32
        help
          Say Y here if your target has the gdb-sh-stub
          package from www.m17n.org (or any conforming standard LinuxSH BIOS)
index bb06f83e6239c648e138a1d820f0d3e6dab7fa51..8050b03d51fca42823063b2c31cf12984572728b 100644 (file)
@@ -110,7 +110,6 @@ machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE)   += se/7343
 machdir-$(CONFIG_SH_7721_SOLUTION_ENGINE)      += se/7721
 machdir-$(CONFIG_SH_HP6XX)                     += hp6xx
 machdir-$(CONFIG_SH_DREAMCAST)                 += dreamcast
-machdir-$(CONFIG_SH_MPC1211)                   += mpc1211
 machdir-$(CONFIG_SH_SH03)                      += sh03
 machdir-$(CONFIG_SH_SECUREEDGE5410)            += snapgear
 machdir-$(CONFIG_SH_RTS7751R2D)                        += renesas/rts7751r2d
diff --git a/arch/sh/boards/mpc1211/Makefile b/arch/sh/boards/mpc1211/Makefile
deleted file mode 100644 (file)
index 8cd31b5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
-#
-
-obj-y   := setup.o rtc.o
-
-obj-$(CONFIG_PCI) += pci.o
-
diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c
deleted file mode 100644 (file)
index 23849f7..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *     Low-Level PCI Support for the MPC-1211(CTP/PCI/MPC-SH02)
- *
- *  (c) 2002-2003 Saito.K & Jeanne
- *
- *  Dustin McIntire (dustin@sensoria.com)
- *     Derived from arch/i386/kernel/pci-*.c which bore the message:
- *     (c) 1999--2000 Martin Mares <mj@ucw.cz>
- *     
- *  May be copied or modified under the terms of the GNU General Public
- *  License.  See linux/COPYING for more information.
- *
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-
-#include <asm/machvec.h>
-#include <asm/io.h>
-#include <asm/mpc1211/pci.h>
-
-static struct resource mpcpci_io_resource = {
-       "MPCPCI IO",
-       0x00000000,
-       0xffffffff,
-       IORESOURCE_IO
-};
-
-static struct resource mpcpci_mem_resource = {
-       "MPCPCI mem",
-       0x00000000,
-       0xffffffff,
-       IORESOURCE_MEM
-};
-
-static struct pci_ops pci_direct_conf1;
-struct pci_channel board_pci_channels[] = {
-       {&pci_direct_conf1, &mpcpci_io_resource, &mpcpci_mem_resource, 0, 256},
-       {NULL, NULL, NULL, 0, 0},
-};
-
-/*
- * Direct access to PCI hardware...
- */
-
-
-#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-
-/*
- * Functions for accessing PCI configuration space with type 1 accesses
- */
-static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-       u32 word;
-       unsigned long flags;
-
-       /* 
-        * PCIPDR may only be accessed as 32 bit words, 
-        * so we must do byte alignment by hand 
-        */
-       local_irq_save(flags);
-       writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
-       word = readl(PCIPDR);
-       local_irq_restore(flags);
-
-       switch (size) {
-       case 1:
-               switch (where & 0x3) {
-               case 3:
-                       *value = (u8)(word >> 24);
-                       break;
-               case 2:
-                       *value = (u8)(word >> 16);
-                       break;
-               case 1:
-                       *value = (u8)(word >> 8);
-                       break;
-               default:
-                       *value = (u8)word;
-                       break;
-               }
-               break;
-       case 2:
-               switch (where & 0x3) {
-               case 3:
-                       *value = (u16)(word >> 24);
-                       local_irq_save(flags);
-                       writel(CONFIG_CMD(bus,devfn,(where+1)), PCIPAR);
-                       word = readl(PCIPDR);
-                       local_irq_restore(flags);
-                       *value |= ((word & 0xff) << 8);
-                       break;
-               case 2:
-                       *value = (u16)(word >> 16);
-                       break;
-               case 1:
-                       *value = (u16)(word >> 8);
-                       break;
-               default:
-                       *value = (u16)word;
-                       break;
-               }
-               break;
-       case 4:
-               *value = word;
-               break;
-       }
-       PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value); 
-       return PCIBIOS_SUCCESSFUL;    
-}
-
-/* 
- * Since MPC-1211 only does 32bit access we'll have to do a read,mask,write operation.  
- * We'll allow an odd byte offset, though it should be illegal.
- */ 
-static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
-       u32 word,mask = 0;
-       unsigned long flags;
-       u32 shift = (where & 3) * 8;
-
-       if(size == 1) {
-               mask = ((1 << 8) - 1) << shift;  // create the byte mask
-       } else if(size == 2){
-               if(shift == 24)
-                       return PCIBIOS_BAD_REGISTER_NUMBER;           
-               mask = ((1 << 16) - 1) << shift;  // create the word mask
-       }
-       local_irq_save(flags);
-       writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
-       if(size == 4){
-               writel(value, PCIPDR);
-               local_irq_restore(flags);
-               PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
-               return PCIBIOS_SUCCESSFUL;
-       }
-       word = readl(PCIPDR);
-       word &= ~mask;
-       word |= ((value << shift) & mask);
-       writel(word, PCIPDR);
-       local_irq_restore(flags);
-       PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-#undef CONFIG_CMD
-
-static struct pci_ops pci_direct_conf1 = {
-       .read =         pci_conf1_read,
-       .write =        pci_conf1_write,
-};
-
-static void __devinit quirk_ali_ide_ports(struct pci_dev *dev)
-{
-        dev->resource[0].start = 0x1f0;
-       dev->resource[0].end   = 0x1f7;
-       dev->resource[0].flags = IORESOURCE_IO;
-        dev->resource[1].start = 0x3f6;
-       dev->resource[1].end   = 0x3f6;
-       dev->resource[1].flags = IORESOURCE_IO;
-        dev->resource[2].start = 0x170;
-       dev->resource[2].end   = 0x177;
-       dev->resource[2].flags = IORESOURCE_IO;
-        dev->resource[3].start = 0x376;
-       dev->resource[3].end   = 0x376;
-       dev->resource[3].flags = IORESOURCE_IO;
-        dev->resource[4].start = 0xf000;
-       dev->resource[4].end   = 0xf00f;
-       dev->resource[4].flags = IORESOURCE_IO;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports);
-
-char * __devinit pcibios_setup(char *str)
-{
-       return str;
-}
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-
-void __devinit pcibios_fixup_bus(struct pci_bus *b)
-{
-       pci_read_bridge_bases(b);
-}
-
-/* 
- *     IRQ functions 
- */
-static inline u8 bridge_swizzle(u8 pin, u8 slot)
-{
-        return (((pin-1) + slot) % 4) + 1;
-}
-
-static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot)
-{
-        return (((pin-1) - slot) & 3) + 1;
-}
-
-static u8 __init mpc1211_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-       unsigned long flags;
-        u8 pin = *pinp;
-       u32 word;
-
-       for ( ; dev->bus->self; dev = dev->bus->self) {
-               if (!pin)
-                       continue;
-
-               if (dev->bus->number == 1) {
-                       local_irq_save(flags);
-                       writel(0x80000000 | 0x2c, PCIPAR);
-                       word = readl(PCIPDR);
-                       local_irq_restore(flags);
-                       word >>= 16;
-
-                       if (word == 0x0001)
-                               pin = bridge_swizzle_pci_1(pin, PCI_SLOT(dev->devfn));
-                       else
-                               pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-               } else
-                       pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-       }
-
-       *pinp = pin;
-
-       return PCI_SLOT(dev->devfn);
-}
-
-static int __init map_mpc1211_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq = -1;
-
-       /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
-       if (dev->bus->number == 0) {
-               switch (slot) {
-               case 13:   irq =  9; break;   /* USB */
-               case 22:   irq = 10; break;   /* LAN */
-               default:   irq =  0; break;
-               }
-       } else {
-               switch (pin) {
-               case 0:   irq =  0; break;
-               case 1:   irq =  7; break;
-               case 2:   irq =  9; break;
-               case 3:   irq = 10; break;
-               case 4:   irq = 11; break;
-               }
-       }
-
-       if( irq < 0 ) {
-               PCIDBG(3, "PCI: Error mapping IRQ on device %s\n", pci_name(dev));
-               return irq;
-       }
-       
-       PCIDBG(2, "Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
-
-       return irq;
-}
-
-void __init pcibios_fixup_irqs(void)
-{
-       pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq);
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
-                           resource_size_t size, resource_size_t align)
-{
-       resource_size_t start = res->start;
-
-       if (res->flags & IORESOURCE_IO) {
-               if (start >= 0x10000UL) {
-                       if ((start & 0xffffUL) < 0x4000UL) {
-                               start = (start & 0xffff0000UL) + 0x4000UL;
-                       } else if ((start & 0xffffUL) >= 0xf000UL) {
-                               start = (start & 0xffff0000UL) + 0x10000UL;
-                       }
-                       res->start = start;
-               } else {
-                       if (start & 0x300) {
-                               start = (start + 0x3ff) & ~0x3ff;
-                               res->start = start;
-                       }
-               }
-       }
-}
-
diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c
deleted file mode 100644 (file)
index 03b123a..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * linux/arch/sh/kernel/rtc-mpc1211.c -- MPC-1211 on-chip RTC support
- *
- *  Copyright (C) 2002  Saito.K & Jeanne
- *
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/bcd.h>
-#include <linux/mc146818rtc.h>
-
-unsigned long get_cmos_time(void)
-{
-       unsigned int year, mon, day, hour, min, sec;
-
-       spin_lock(&rtc_lock);
-
-       do {
-               sec = CMOS_READ(RTC_SECONDS);
-               min = CMOS_READ(RTC_MINUTES);
-               hour = CMOS_READ(RTC_HOURS);
-               day = CMOS_READ(RTC_DAY_OF_MONTH);
-               mon = CMOS_READ(RTC_MONTH);
-               year = CMOS_READ(RTC_YEAR);
-       } while (sec != CMOS_READ(RTC_SECONDS));
-
-       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(sec);
-               BCD_TO_BIN(min);
-               BCD_TO_BIN(hour);
-               BCD_TO_BIN(day);
-               BCD_TO_BIN(mon);
-               BCD_TO_BIN(year);
-       }
-
-       spin_unlock(&rtc_lock);
-
-       year += 1900;
-       if (year < 1970)
-               year += 100;
-
-       return mktime(year, mon, day, hour, min, sec);
-}
-
-void mpc1211_rtc_gettimeofday(struct timeval *tv)
-{
-
-       tv->tv_sec = get_cmos_time();
-       tv->tv_usec = 0;
-}
-
-/* arc/i386/kernel/time.c */
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-       int retval = 0;
-       int real_seconds, real_minutes, cmos_minutes;
-       unsigned char save_control, save_freq_select;
-
-       /* gets recalled with irq locally disabled */
-       spin_lock(&rtc_lock);
-       save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-       CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-       save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-       CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-       cmos_minutes = CMOS_READ(RTC_MINUTES);
-       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-               BCD_TO_BIN(cmos_minutes);
-
-       /*
-        * since we're only adjusting minutes and seconds,
-        * don't interfere with hour overflow. This avoids
-        * messing with unknown time zones but requires your
-        * RTC not to be off by more than 15 minutes
-        */
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-               real_minutes += 30;             /* correct for half hour time zone */
-       real_minutes %= 60;
-
-       if (abs(real_minutes - cmos_minutes) < 30) {
-               if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-                       BIN_TO_BCD(real_seconds);
-                       BIN_TO_BCD(real_minutes);
-               }
-               CMOS_WRITE(real_seconds,RTC_SECONDS);
-               CMOS_WRITE(real_minutes,RTC_MINUTES);
-       } else {
-               printk(KERN_WARNING
-                      "set_rtc_mmss: can't update from %d to %d\n",
-                      cmos_minutes, real_minutes);
-               retval = -1;
-       }
-
-       /* The following flags have to be released exactly in this order,
-        * otherwise the DS12887 (popular MC146818A clone with integrated
-        * battery and quartz) will not reset the oscillator and will not
-        * update precisely 500 ms later. You won't find this mentioned in
-        * the Dallas Semiconductor data sheets, but who believes data
-        * sheets anyway ...                           -- Markus Kuhn
-        */
-       CMOS_WRITE(save_control, RTC_CONTROL);
-       CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-       spin_unlock(&rtc_lock);
-
-       return retval;
-}
-
-int mpc1211_rtc_settimeofday(const struct timeval *tv)
-{
-       unsigned long nowtime = tv->tv_sec;
-
-       return set_rtc_mmss(nowtime);
-}
-
-void mpc1211_time_init(void)
-{
-       rtc_sh_get_time = mpc1211_rtc_gettimeofday;
-       rtc_sh_set_time = mpc1211_rtc_settimeofday;
-}
-
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
deleted file mode 100644 (file)
index fede363..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * linux/arch/sh/boards/mpc1211/setup.c
- *
- * Copyright (C) 2002  Saito.K & Jeanne,  Fujii.Y
- *
- */
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-#include <asm/mpc1211/mpc1211.h>
-#include <asm/mpc1211/pci.h>
-#include <asm/mpc1211/m1543c.h>
-
-/* ALI15X3 SMBus address offsets */
-#define SMBHSTSTS   (0 + 0x3100)
-#define SMBHSTCNT   (1 + 0x3100)
-#define SMBHSTSTART (2 + 0x3100)
-#define SMBHSTCMD   (7 + 0x3100)
-#define SMBHSTADD   (3 + 0x3100)
-#define SMBHSTDAT0  (4 + 0x3100)
-#define SMBHSTDAT1  (5 + 0x3100)
-#define SMBBLKDAT   (6 + 0x3100)
-
-/* Other settings */
-#define MAX_TIMEOUT 500                /* times 1/100 sec */
-
-/* ALI15X3 command constants */
-#define ALI15X3_ABORT      0x04
-#define ALI15X3_T_OUT      0x08
-#define ALI15X3_QUICK      0x00
-#define ALI15X3_BYTE       0x10
-#define ALI15X3_BYTE_DATA  0x20
-#define ALI15X3_WORD_DATA  0x30
-#define ALI15X3_BLOCK_DATA 0x40
-#define ALI15X3_BLOCK_CLR  0x80
-
-/* ALI15X3 status register bits */
-#define ALI15X3_STS_IDLE       0x04
-#define ALI15X3_STS_BUSY       0x08
-#define ALI15X3_STS_DONE       0x10
-#define ALI15X3_STS_DEV                0x20    /* device error */
-#define ALI15X3_STS_COLL       0x40    /* collision or no response */
-#define ALI15X3_STS_TERM       0x80    /* terminated by abort */
-#define ALI15X3_STS_ERR                0xE0    /* all the bad error bits */
-
-static void __init pci_write_config(unsigned long busNo,
-                                   unsigned long devNo,
-                                   unsigned long fncNo,
-                                   unsigned long cnfAdd,
-                                   unsigned long cnfData)
-{
-       ctrl_outl((0x80000000 
-                + ((busNo & 0xff) << 16) 
-                + ((devNo & 0x1f) << 11) 
-                + ((fncNo & 0x07) <<  8) 
-               + (cnfAdd & 0xfc)), PCIPAR);
-
-        ctrl_outl(cnfData, PCIPDR);
-}
-
-/*
-  Initialize IRQ setting
-*/
-
-static unsigned char m_irq_mask = 0xfb;
-static unsigned char s_irq_mask = 0xff;
-
-static void disable_mpc1211_irq(unsigned int irq)
-{
-       if( irq < 8) {
-               m_irq_mask |= (1 << irq);
-               outb(m_irq_mask,I8259_M_MR);
-       } else {
-               s_irq_mask |= (1 << (irq - 8));
-               outb(s_irq_mask,I8259_S_MR);
-       }
-
-}
-
-static void enable_mpc1211_irq(unsigned int irq)
-{
-       if( irq < 8) {
-               m_irq_mask &= ~(1 << irq);
-               outb(m_irq_mask,I8259_M_MR);
-       } else {
-               s_irq_mask &= ~(1 << (irq - 8));
-               outb(s_irq_mask,I8259_S_MR);
-       }
-}
-
-static inline int mpc1211_irq_real(unsigned int irq)
-{
-       int value;
-       int irqmask;
-
-       if ( irq < 8) {
-               irqmask = 1<<irq;
-               outb(0x0b,I8259_M_CR);          /* ISR register */
-               value = inb(I8259_M_CR) & irqmask;
-               outb(0x0a,I8259_M_CR);          /* back ro the IPR reg */
-               return value;
-       }
-       irqmask = 1<<(irq - 8);
-       outb(0x0b,I8259_S_CR);          /* ISR register */
-       value = inb(I8259_S_CR) & irqmask;
-       outb(0x0a,I8259_S_CR);          /* back ro the IPR reg */
-       return value;
-}
-
-static void mask_and_ack_mpc1211(unsigned int irq)
-{
-       if(irq < 8) {
-               if(m_irq_mask & (1<<irq)){
-                 if(!mpc1211_irq_real(irq)){
-                   atomic_inc(&irq_err_count)
-                   printk("spurious 8259A interrupt: IRQ %x\n",irq);
-                  }
-               } else {
-                       m_irq_mask |= (1<<irq);
-               }
-               inb(I8259_M_MR);                /* DUMMY */
-               outb(m_irq_mask,I8259_M_MR);    /* disable */
-               outb(0x60+irq,I8259_M_CR);      /* EOI */
-               
-       } else {
-               if(s_irq_mask & (1<<(irq - 8))){
-                 if(!mpc1211_irq_real(irq)){
-                   atomic_inc(&irq_err_count);
-                   printk("spurious 8259A interrupt: IRQ %x\n",irq);
-                 }
-               } else {
-                       s_irq_mask |= (1<<(irq - 8));
-               }
-               inb(I8259_S_MR);                /* DUMMY */
-               outb(s_irq_mask,I8259_S_MR);    /* disable */
-               outb(0x60+(irq-8),I8259_S_CR);  /* EOI */
-               outb(0x60+2,I8259_M_CR);
-       }
-}
-
-static void end_mpc1211_irq(unsigned int irq)
-{
-       enable_mpc1211_irq(irq);
-}
-
-static unsigned int startup_mpc1211_irq(unsigned int irq)
-{
-       enable_mpc1211_irq(irq);
-       return 0;
-}
-
-static void shutdown_mpc1211_irq(unsigned int irq)
-{
-       disable_mpc1211_irq(irq);
-}
-
-static struct hw_interrupt_type mpc1211_irq_type = {
-       .typename       = "MPC1211-IRQ",
-       .startup        = startup_mpc1211_irq,
-       .shutdown       = shutdown_mpc1211_irq,
-       .enable         = enable_mpc1211_irq,
-       .disable        = disable_mpc1211_irq,
-       .ack            = mask_and_ack_mpc1211,
-       .end            = end_mpc1211_irq
-};
-
-static void make_mpc1211_irq(unsigned int irq)
-{
-       irq_desc[irq].chip = &mpc1211_irq_type;
-       irq_desc[irq].status  = IRQ_DISABLED;
-       irq_desc[irq].action  = 0;
-       irq_desc[irq].depth   = 1;
-       disable_mpc1211_irq(irq);
-}
-
-int mpc1211_irq_demux(int irq)
-{
-       unsigned int poll;
-
-       if( irq == 2 ) {
-               outb(0x0c,I8259_M_CR);
-               poll = inb(I8259_M_CR);
-               if(poll & 0x80) {
-                       irq = (poll & 0x07);
-               }
-               if( irq == 2) {
-                       outb(0x0c,I8259_S_CR);
-                       poll = inb(I8259_S_CR);
-                       irq = (poll & 0x07) + 8;
-               }
-       }
-       return irq;
-}
-
-static void __init init_mpc1211_IRQ(void)
-{
-       int i;
-       /*
-        * Super I/O (Just mimic PC):
-        *  1: keyboard
-        *  3: serial 1
-        *  4: serial 0
-        *  5: printer
-        *  6: floppy
-        *  8: rtc
-        * 10: lan
-        * 12: mouse
-        * 14: ide0
-        * 15: ide1
-        */
-
-       pci_write_config(0,0,0,0x54, 0xb0b0002d);
-       outb(0x11, I8259_M_CR);         /* mater icw1 edge trigger  */
-       outb(0x11, I8259_S_CR);         /* slave icw1 edge trigger  */
-       outb(0x20, I8259_M_MR);         /* m icw2 base vec 0x08     */
-       outb(0x28, I8259_S_MR);         /* s icw2 base vec 0x70     */
-       outb(0x04, I8259_M_MR);         /* m icw3 slave irq2        */
-       outb(0x02, I8259_S_MR);         /* s icw3 slave id          */
-       outb(0x01, I8259_M_MR);         /* m icw4 non buf normal eoi*/
-       outb(0x01, I8259_S_MR);         /* s icw4 non buf normal eo1*/
-       outb(0xfb, I8259_M_MR);         /* disable irq0--irq7  */
-       outb(0xff, I8259_S_MR);         /* disable irq8--irq15 */
-
-       for ( i=0; i < 16; i++) {
-               if(i != 2) {
-                       make_mpc1211_irq(i);
-               }
-       }
-}
-
-static void delay1000(void)
-{
-       int i;
-
-       for (i=0; i<1000; i++)
-               ctrl_delay();
-}
-
-static int put_smb_blk(unsigned char *p, int address, int command, int no)
-{
-       int temp;
-       int timeout;
-       int i;
-
-       outb(0xff, SMBHSTSTS);
-       temp = inb(SMBHSTSTS);
-       for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
-               delay1000();
-               temp = inb(SMBHSTSTS);
-       }
-       if (timeout >= MAX_TIMEOUT){
-               return -1;
-       }
-
-       outb(((address & 0x7f) << 1), SMBHSTADD);
-       outb(0xc0, SMBHSTCNT);
-       outb(command & 0xff, SMBHSTCMD);
-       outb(no & 0x1f, SMBHSTDAT0);
-
-       for(i = 1; i <= no; i++) {
-               outb(*p++, SMBBLKDAT);
-       }
-       outb(0xff, SMBHSTSTART);
-
-       temp = inb(SMBHSTSTS);
-       for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
-               delay1000();
-               temp = inb(SMBHSTSTS);
-       }
-       if (timeout >= MAX_TIMEOUT) {
-               return -2;
-       }
-       if ( temp & ALI15X3_STS_ERR ){
-               return -3;
-       }
-       return 0;
-}
-
-static struct resource heartbeat_resources[] = {
-       [0] = {
-               .start  = 0xa2000000,
-               .end    = 0xa2000000,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device heartbeat_device = {
-       .name           = "heartbeat",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(heartbeat_resources),
-       .resource       = heartbeat_resources,
-};
-
-static struct platform_device *mpc1211_devices[] __initdata = {
-       &heartbeat_device,
-};
-
-static int __init mpc1211_devices_setup(void)
-{
-       return platform_add_devices(mpc1211_devices,
-                                   ARRAY_SIZE(mpc1211_devices));
-}
-__initcall(mpc1211_devices_setup);
-
-/* arch/sh/boards/mpc1211/rtc.c */
-void mpc1211_time_init(void);
-
-static void __init mpc1211_setup(char **cmdline_p)
-{
-       unsigned char spd_buf[128];
-
-       __set_io_port_base(PA_PCI_IO);
-
-       pci_write_config(0,0,0,0x54, 0xb0b00000);
-
-       do {
-               outb(ALI15X3_ABORT, SMBHSTCNT);
-               spd_buf[0] = 0x0c;
-               spd_buf[1] = 0x43;
-               spd_buf[2] = 0x7f;
-               spd_buf[3] = 0x03;
-               spd_buf[4] = 0x00;
-               spd_buf[5] = 0x03;
-               spd_buf[6] = 0x00;
-       } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);
-
-       board_time_init = mpc1211_time_init;
-
-       return 0;
-}
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_mpc1211 __initmv = {
-       .mv_name                = "Interface MPC-1211(CTP/PCI/MPC-SH02)",
-       .mv_setup               = mpc1211_setup,
-       .mv_nr_irqs             = 48,
-       .mv_irq_demux           = mpc1211_irq_demux,
-       .mv_init_irq            = init_mpc1211_IRQ,
-};
index e7c150d4970297629be13c17fefa543f5cfe9ac5..01af44245b57761c5f4f5004d3b438a93e7fcc07 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
+#include <linux/smc91x.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/sh_keysc.h>
  * 0x18000000       8GB    8   NAND Flash (K9K8G08U0A)
  */
 
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT,
+       .irq_flags = IRQF_TRIGGER_HIGH,
+};
+
 static struct resource smc91x_eth_resources[] = {
        [0] = {
                .name   = "SMC91C111" ,
@@ -36,7 +42,7 @@ static struct resource smc91x_eth_resources[] = {
        },
        [1] = {
                .start  = 32, /* IRQ0 */
-               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+               .flags  = IORESOURCE_IRQ,
        },
 };
 
@@ -44,6 +50,9 @@ static struct platform_device smc91x_eth_device = {
        .name           = "smc91x",
        .num_resources  = ARRAY_SIZE(smc91x_eth_resources),
        .resource       = smc91x_eth_resources,
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
 };
 
 static struct sh_keysc_info sh_keysc_info = {
index 68f0ad1b637dd3335243e7e101761fe34cd08688..ae1cfcb297008f76f8cb003872cf2ba87c6a8aa0 100644 (file)
@@ -62,7 +62,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
                         NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7780mp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
        if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) {
                printk(KERN_INFO "Using r7780mp interrupt controller.\n");
index bd34048ed0e1f95c6b042a77d7a17486d13663e0..9d3921fe27c0b4506322ad5a3a0837c652a63c02 100644 (file)
@@ -55,7 +55,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
                         NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7780rp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
        if (ctrl_inw(0xa5000600)) {
                printk(KERN_INFO "Using r7780rp interrupt controller.\n");
index bf7ec107fbc63b4515e871a7858e6dfb7086e176..896c045aa39d63ab66ebc4eceed0b38f00911b59 100644 (file)
@@ -64,7 +64,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
                         NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7785rp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
        if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000)
                return NULL;
index ac0a96522e45e3f9387ae578149fe9ec05e34578..bc79afb6fc4c04c7c13335b9ae03e4938ec51939 100644 (file)
@@ -316,7 +316,7 @@ static void __init highlander_setup(char **cmdline_p)
 
 static unsigned char irl2irq[HL_NR_IRL];
 
-int highlander_irq_demux(int irq)
+static int highlander_irq_demux(int irq)
 {
        if (irq >= HL_NR_IRL || !irl2irq[irq])
                return irq;
@@ -324,27 +324,9 @@ int highlander_irq_demux(int irq)
        return irl2irq[irq];
 }
 
-void __init highlander_init_irq(void)
+static void __init highlander_init_irq(void)
 {
-       unsigned char *ucp = NULL;
-
-       do {
-#ifdef CONFIG_SH_R7780MP
-               ucp = highlander_init_irq_r7780mp();
-               if (ucp)
-                       break;
-#endif
-#ifdef CONFIG_SH_R7785RP
-               ucp = highlander_init_irq_r7785rp();
-               if (ucp)
-                       break;
-#endif
-#ifdef CONFIG_SH_R7780RP
-               ucp = highlander_init_irq_r7780rp();
-               if (ucp)
-                       break;
-#endif
-       } while (0);
+       unsigned char *ucp = highlander_plat_irq_setup();
 
        if (ucp) {
                plat_irq_setup_pins(IRQ_MODE_IRL3210);
index f21ee49ef3a5c842c540c8e4a0780b113d666c2a..452d0d6459a40ee0da3a1f1050d8525ac66367ee 100644 (file)
@@ -109,7 +109,6 @@ static struct platform_device heartbeat_device = {
        .resource       = heartbeat_resources,
 };
 
-#ifdef CONFIG_MFD_SM501
 static struct plat_serial8250_port uart_platform_data[] = {
        {
                .membase        = (void __iomem *)0xb3e30000,
@@ -208,13 +207,9 @@ static struct platform_device sm501_device = {
        .resource       = sm501_resources,
 };
 
-#endif /* CONFIG_MFD_SM501 */
-
 static struct platform_device *rts7751r2d_devices[] __initdata = {
-#ifdef CONFIG_MFD_SM501
        &uart_device,
        &sm501_device,
-#endif
        &heartbeat_device,
        &spi_sh_sci_device,
 };
@@ -234,7 +229,9 @@ static int __init rts7751r2d_devices_setup(void)
 {
        if (register_trapped_io(&cf_trapped_io) == 0)
                platform_device_register(&cf_ide_device);
+
        spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
+
        return platform_add_devices(rts7751r2d_devices,
                                    ARRAY_SIZE(rts7751r2d_devices));
 }
index 5b3ee089d91de3acc943cc3ef142dac056072b60..4fe84cc0840679fa3ad0ca83aa09fc7975def7b0 100644 (file)
@@ -3,12 +3,13 @@
  * linux/arch/sh/boards/se/7206/setup.c
  *
  * Copyright (C) 2006  Yoshinori Sato
- * Copyright (C) 2007  Paul Mundt
+ * Copyright (C) 2007 - 2008  Paul Mundt
  *
  * Hitachi 7206 SolutionEngine Support.
  */
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/smc91x.h>
 #include <asm/se7206.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -16,8 +17,9 @@
 
 static struct resource smc91x_resources[] = {
        [0] = {
-               .start          = 0x300,
-               .end            = 0x300 + 0x020 - 1,
+               .name           = "smc91x-regs",
+               .start          = PA_SMSC + 0x300,
+               .end            = PA_SMSC + 0x300 + 0x020 - 1,
                .flags          = IORESOURCE_MEM,
        },
        [1] = {
@@ -27,9 +29,18 @@ static struct resource smc91x_resources[] = {
        },
 };
 
+static struct smc91x_platdata smc91x_info = {
+       .flags  = SMC91X_USE_16BIT,
+};
+
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
        .id             = -1,
+       .dev            = {
+               .dma_mask               = NULL,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &smc91x_info,
+       },
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
 };
index 33f6ee71f8483f9c58dd736ed93c9237d54f2e33..ede3957fc14afa676eb8f609c06f97d651cc6949 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/input.h>
+#include <linux/smc91x.h>
 #include <asm/machvec.h>
 #include <asm/se7722.h>
 #include <asm/io.h>
@@ -44,6 +45,10 @@ static struct platform_device heartbeat_device = {
 };
 
 /* SMC91x */
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT,
+};
+
 static struct resource smc91x_eth_resources[] = {
        [0] = {
                .name   = "smc91x-regs" ,
@@ -64,6 +69,7 @@ static struct platform_device smc91x_eth_device = {
        .dev = {
                .dma_mask               = NULL,         /* don't use dma */
                .coherent_dma_mask      = 0xffffffff,
+               .platform_data  = &smc91x_info,
        },
        .num_resources  = ARRAY_SIZE(smc91x_eth_resources),
        .resource       = smc91x_eth_resources,
index 6ac8d4a4ed1d87986b8a3debb9caa6ce2df31237..c0d25fb1aa608bb4829294d0907bde736a02f82c 100644 (file)
@@ -6,7 +6,6 @@
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz \
                   head_32.o misc_32.o piggy.o
-EXTRA_AFLAGS   := -traditional
 
 OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o
 
index 4334f2b86d8f2e109750e34a29014cc4feae680c..912f3e205a0d38678c532cff4a884f80fd541d77 100644 (file)
@@ -13,7 +13,6 @@
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz \
                   head_64.o misc_64.o cache.o piggy.o
-EXTRA_AFLAGS   := -traditional
 
 OBJECTS                := $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \
                   $(obj)/cache.o
index d6e0e2bdaad5b62858a1e045537eea75389bd5df..de45c6a3e33be98285b04aaa39e927535375f8ee 100644 (file)
@@ -184,9 +184,8 @@ int intc_irq_describe(char* p, int irq)
 
 void __init plat_irq_setup(void)
 {
-        unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
+       unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
        unsigned long reg;
-       unsigned long data;
        int i;
 
        intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
@@ -196,11 +195,8 @@ void __init plat_irq_setup(void)
 
 
        /* Set default: per-line enable/disable, priority driven ack/eoi */
-       for (i = 0; i < NR_INTC_IRQS; i++) {
-               if (platform_int_priority[i] != NO_PRIORITY) {
-                       irq_desc[i].chip = &intc_irq_type;
-               }
-       }
+       for (i = 0; i < NR_INTC_IRQS; i++)
+               irq_desc[i].chip = &intc_irq_type;
 
 
        /* Disable all interrupts and set all priorities to 0 to avoid trouble */
@@ -211,35 +207,42 @@ void __init plat_irq_setup(void)
                ctrl_outl( NO_PRIORITY, reg);
 
 
-       /* Set IRLM */
-       /* If all the priorities are set to 'no priority', then
-        * assume we are using encoded mode.
-        */
-       irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
-               platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
-
-       if (irlm == NO_PRIORITY) {
-               /* IRLM = 0 */
-               reg = INTC_ICR_CLEAR;
-               i = IRQ_INTA;
-               printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
-       } else {
-               /* IRLM = 1 */
-               reg = INTC_ICR_SET;
-               i = IRQ_IRL0;
-       }
-       ctrl_outl(INTC_ICR_IRLM, reg);
-
-       /* Set interrupt priorities according to platform description */
-       for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
-               data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
-               if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
-                       /* Upon the 7th, set Priority Register */
-                       ctrl_outl(data, reg);
-                       data = 0;
-                       reg += 8;
+#ifdef CONFIG_SH_CAYMAN
+       {
+               unsigned long data;
+
+               /* Set IRLM */
+               /* If all the priorities are set to 'no priority', then
+                * assume we are using encoded mode.
+                */
+               irlm = platform_int_priority[IRQ_IRL0] +
+                      platform_int_priority[IRQ_IRL1] +
+                      platform_int_priority[IRQ_IRL2] +
+                      platform_int_priority[IRQ_IRL3];
+               if (irlm == NO_PRIORITY) {
+                       /* IRLM = 0 */
+                       reg = INTC_ICR_CLEAR;
+                       i = IRQ_INTA;
+                       printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
+               } else {
+                       /* IRLM = 1 */
+                       reg = INTC_ICR_SET;
+                       i = IRQ_IRL0;
                }
-       }
+               ctrl_outl(INTC_ICR_IRLM, reg);
+
+               /* Set interrupt priorities according to platform description */
+               for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
+                       data |= platform_int_priority[i] <<
+                               ((i % INTC_INTPRI_PPREG) * 4);
+                       if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
+                               /* Upon the 7th, set Priority Register */
+                               ctrl_outl(data, reg);
+                               data = 0;
+                               reg += 8;
+                       }
+               }
+#endif
 
        /*
         * And now let interrupts come in.
index 84806b2027f85525fee1b8569cc898dd1f94ca59..da5dae787888fe104fb78000290b4a0427d6b862 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Shared interrupt handling code for IPR and INTC2 types of IRQs.
  *
- * Copyright (C) 2007 Magnus Damm
+ * Copyright (C) 2007, 2008 Magnus Damm
  *
  * Based on intc2.c and ipr.c
  *
@@ -62,6 +62,9 @@ struct intc_desc_int {
 #endif
 
 static unsigned int intc_prio_level[NR_IRQS]; /* for now */
+#ifdef CONFIG_CPU_SH3
+static unsigned long ack_handle[NR_IRQS];
+#endif
 
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
@@ -98,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data)
 
 static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
 {
+       unsigned long flags;
+       local_irq_save(flags);
        ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
+       local_irq_restore(flags);
 }
 
 enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
@@ -219,6 +231,25 @@ static void intc_disable(unsigned int irq)
        }
 }
 
+#ifdef CONFIG_CPU_SH3
+static void intc_mask_ack(unsigned int irq)
+{
+       struct intc_desc_int *d = get_intc_desc(irq);
+       unsigned long handle = ack_handle[irq];
+       unsigned long addr;
+
+       intc_disable(irq);
+
+       /* read register and write zero only to the assocaited bit */
+
+       if (handle) {
+               addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+               ctrl_inb(addr);
+               ctrl_outb(0x3f ^ set_field(0, 1, handle), addr);
+       }
+}
+#endif
+
 static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
                                             unsigned int nr_hp,
                                             unsigned int irq)
@@ -280,7 +311,12 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
        [IRQ_TYPE_EDGE_FALLING] = VALID(0),
        [IRQ_TYPE_EDGE_RISING] = VALID(1),
        [IRQ_TYPE_LEVEL_LOW] = VALID(2),
+       /* SH7706, SH7707 and SH7709 do not support high level triggered */
+#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7707) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7709)
        [IRQ_TYPE_LEVEL_HIGH] = VALID(3),
+#endif
 };
 
 static int intc_set_sense(unsigned int irq, unsigned int type)
@@ -430,6 +466,40 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
        return 0;
 }
 
+#ifdef CONFIG_CPU_SH3
+static unsigned int __init intc_ack_data(struct intc_desc *desc,
+                                         struct intc_desc_int *d,
+                                         intc_enum enum_id)
+{
+       struct intc_mask_reg *mr = desc->ack_regs;
+       unsigned int i, j, fn, mode;
+       unsigned long reg_e, reg_d;
+
+       for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
+               mr = desc->ack_regs + i;
+
+               for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+                       if (mr->enum_ids[j] != enum_id)
+                               continue;
+
+                       fn = REG_FN_MODIFY_BASE;
+                       mode = MODE_ENABLE_REG;
+                       reg_e = mr->set_reg;
+                       reg_d = mr->set_reg;
+
+                       fn += (mr->reg_width >> 3) - 1;
+                       return _INTC_MK(fn, mode,
+                                       intc_get_reg(d, reg_e),
+                                       intc_get_reg(d, reg_d),
+                                       1,
+                                       (mr->reg_width - 1) - j);
+               }
+       }
+
+       return 0;
+}
+#endif
+
 static unsigned int __init intc_sense_data(struct intc_desc *desc,
                                           struct intc_desc_int *d,
                                           intc_enum enum_id)
@@ -530,6 +600,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
 
        /* irq should be disabled by default */
        d->chip.mask(irq);
+
+#ifdef CONFIG_CPU_SH3
+       if (desc->ack_regs)
+               ack_handle[irq] = intc_ack_data(desc, d, enum_id);
+#endif
 }
 
 static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -560,6 +635,9 @@ void __init register_intc_controller(struct intc_desc *desc)
        d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
        d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
 
+#ifdef CONFIG_CPU_SH3
+       d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
+#endif
        d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
 #ifdef CONFIG_SMP
        d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
@@ -592,14 +670,23 @@ void __init register_intc_controller(struct intc_desc *desc)
                }
        }
 
-       BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
-
        d->chip.name = desc->name;
        d->chip.mask = intc_disable;
        d->chip.unmask = intc_enable;
        d->chip.mask_ack = intc_disable;
        d->chip.set_type = intc_set_sense;
 
+#ifdef CONFIG_CPU_SH3
+       if (desc->ack_regs) {
+               for (i = 0; i < desc->nr_ack_regs; i++)
+                       k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
+
+               d->chip.mask_ack = intc_mask_ack;
+       }
+#endif
+
+       BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+
        for (i = 0; i < desc->nr_vectors; i++) {
                struct intc_vect *vect = desc->vectors + i;
 
index 5627c0b3ffa82e2c9496fec63eeeb2861eade897..6df2fb98eb30edb905c248290c0d64d754ed33cb 100644 (file)
@@ -300,7 +300,7 @@ static int denormal_addf(int hx, int hy)
                iy = hy & 0x7fffffff;
                if (iy < 0x00800000) {
                        ix = denormal_subf1(ix, iy);
-                       if (ix < 0) {
+                       if ((int) ix < 0) {
                                ix = -ix;
                                sign ^= 0x80000000;
                        }
@@ -385,7 +385,7 @@ static long long denormal_addd(long long hx, long long hy)
                iy = hy & 0x7fffffffffffffffLL;
                if (iy < 0x0010000000000000LL) {
                        ix = denormal_subd1(ix, iy);
-                       if (ix < 0) {
+                       if ((int) ix < 0) {
                                ix = -ix;
                                sign ^= 0x8000000000000000LL;
                        }
index 3ae4d9111f19e7cecc33463da2d5a93767713faf..511de55af8321c0d982d827d7987a6c85c45c0c6 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the Linux/SuperH SH-3 backends.
 #
 
-obj-y  := ex.o probe.o entry.o
+obj-y  := ex.o probe.o entry.o setup-sh3.o
 
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7705)       += setup-sh7705.o
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
new file mode 100644 (file)
index 0000000..c988468
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Shared SH3 Setup code
+ *
+ *  Copyright (C) 2008  Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */
+
+enum {
+       UNUSED = 0,
+
+       /* interrupt sources */
+       IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
+};
+
+static struct intc_vect vectors_irq0123[] __initdata = {
+       INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
+       INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
+};
+
+static struct intc_vect vectors_irq45[] __initdata = {
+       INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+       { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
+       { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+       { 0xa4000004, 0, 8, /* IRR0 */
+         { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+       { 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh3-irq0123",
+                            vectors_irq0123, NULL, NULL,
+                            prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45",
+                            vectors_irq45, NULL, NULL,
+                            prio_registers, sense_registers, ack_registers);
+
+#define INTC_ICR1              0xa4000010UL
+#define INTC_ICR1_IRQLVL       (1<<14)
+
+void __init plat_irq_setup_pins(int mode)
+{
+       if (mode == IRQ_MODE_IRQ) {
+               ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
+               register_intc_controller(&intc_desc_irq0123);
+               return;
+       }
+       BUG();
+}
+
+void __init plat_irq_setup_sh3(void)
+{
+       register_intc_controller(&intc_desc_irq45);
+}
index f581534cb732c08163b274dc452745e957d924d5..6468ae86b9443fd53bf0310fc3e97092f641786e 100644 (file)
@@ -37,7 +37,7 @@ enum {
 };
 
 static struct intc_vect vectors[] __initdata = {
-       INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+       /* IRQ0->5 are handled in setup-sh3.c */
        INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
        INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
        INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
@@ -48,7 +48,7 @@ static struct intc_vect vectors[] __initdata = {
        INTC_VECT(ADC_ADI, 0x980),
        INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
        INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
-       INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0),
+       INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0),
        INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
        INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
        INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
@@ -81,14 +81,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
                         NULL, prio_registers, NULL);
 
-static struct intc_vect vectors_irq[] __initdata = {
-       INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-       INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
-                        NULL, prio_registers, NULL);
-
 static struct plat_sci_port sci_platform_data[] = {
        {
                .mapbase        = 0xa4410000,
@@ -159,16 +151,8 @@ static int __init sh7705_devices_setup(void)
 }
 __initcall(sh7705_devices_setup);
 
-void __init plat_irq_setup_pins(int mode)
-{
-       if (mode == IRQ_MODE_IRQ) {
-               register_intc_controller(&intc_desc_irq);
-               return;
-       }
-       BUG();
-}
-
 void __init plat_irq_setup(void)
 {
        register_intc_controller(&intc_desc);
+       plat_irq_setup_sh3();
 }
index d3733b13ea5298194020ee43114ce3bafe8420c4..93c55e2ed952484fead5128b91509a851c28a887 100644 (file)
@@ -52,7 +52,7 @@ static struct intc_vect vectors[] __initdata = {
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
-       INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+       /* IRQ0->5 are handled in setup-sh3.c */
        INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
        INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
        INTC_VECT(ADC_ADI, 0x980),
@@ -104,18 +104,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
                         NULL, prio_registers, NULL);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-static struct intc_vect vectors_irq[] __initdata = {
-       INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-       INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
-                        NULL, prio_registers, NULL);
-#endif
-
 static struct resource rtc_resources[] = {
        [0] =   {
                .start  = 0xfffffec0,
@@ -194,24 +182,12 @@ static int __init sh770x_devices_setup(void)
 }
 __initcall(sh770x_devices_setup);
 
-#define INTC_ICR1              0xa4000010UL
-#define INTC_ICR1_IRQLVL       (1<<14)
-
-void __init plat_irq_setup_pins(int mode)
+void __init plat_irq_setup(void)
 {
-       if (mode == IRQ_MODE_IRQ) {
+       register_intc_controller(&intc_desc);
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
-               ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
-               register_intc_controller(&intc_desc_irq);
-               return;
+       plat_irq_setup_sh3();
 #endif
-       }
-       BUG();
-}
-
-void __init plat_irq_setup(void)
-{
-       register_intc_controller(&intc_desc);
 }
index 7406c9ad92597c758cab7cecdf3102e48e72f078..77eee481de474fc23d2c2d7b387ff29758d8ba59 100644 (file)
@@ -38,7 +38,7 @@ enum {
 };
 
 static struct intc_vect vectors[] __initdata = {
-       INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+       /* IRQ0->5 are handled in setup-sh3.c */
        INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
        INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
        INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
@@ -79,10 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
        { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
        { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
        { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } },
-       { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } },
-#ifdef CONFIG_CPU_SUBTYPE_SH7710
-       { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } },
-#endif
+       { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC, DMAC2 } },
        { 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } },
        { 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } },
        { 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
@@ -91,14 +88,6 @@ static struct intc_prio_reg prio_registers[] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
                         NULL, prio_registers, NULL);
 
-static struct intc_vect vectors_irq[] __initdata = {
-       INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-       INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
-                        NULL, prio_registers, NULL);
-
 static struct resource rtc_resources[] = {
        [0] =   {
                .start  = 0xa413fec0,
@@ -170,16 +159,8 @@ static int __init sh7710_devices_setup(void)
 }
 __initcall(sh7710_devices_setup);
 
-void __init plat_irq_setup_pins(int mode)
-{
-       if (mode == IRQ_MODE_IRQ) {
-               register_intc_controller(&intc_desc_irq);
-               return;
-       }
-       BUG();
-}
-
 void __init plat_irq_setup(void)
 {
        register_intc_controller(&intc_desc);
+       plat_irq_setup_sh3();
 }
index 8028082527c55a82d835fc32f800a4262dc1bf06..f807a21b066c629e8e4ea636aa3021ffeddccae1 100644 (file)
 #include <linux/serial_sci.h>
 #include <asm/rtc.h>
 
-#define INTC_ICR1      0xA4140010UL
-#define INTC_ICR_IRLM   0x4000
-#define INTC_ICR_IRQ   (~INTC_ICR_IRLM)
-
 static struct resource rtc_resources[] = {
        [0] = {
                .start  = 0xa413fec0,
@@ -170,6 +166,7 @@ enum {
 };
 
 static struct intc_vect vectors[] __initdata = {
+       /* IRQ0->5 are handled in setup-sh3.c */
        INTC_VECT(TMU0, 0x400),       INTC_VECT(TMU1, 0x420),
        INTC_VECT(TMU2, 0x440),       INTC_VECT(RTC_ATI, 0x480),
        INTC_VECT(RTC_PRI, 0x4a0),    INTC_VECT(RTC_CUI, 0x4c0),
@@ -214,11 +211,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
        { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
        { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
        { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
-#if defined(CONFIG_CPU_SUBTYPE_SH7720)
        { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
-#else
-       { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } },
-#endif
        { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
        { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
        { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
@@ -229,32 +222,8 @@ static struct intc_prio_reg prio_registers[] __initdata = {
 static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
                NULL, prio_registers, NULL);
 
-static struct intc_sense_reg sense_registers[] __initdata = {
-       { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
-};
-
-static struct intc_vect vectors_irq[] __initdata = {
-       INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-       INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-       INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
-};
-
-static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
-               NULL, NULL, prio_registers, sense_registers);
-
-void __init plat_irq_setup_pins(int mode)
-{
-       switch (mode) {
-       case IRQ_MODE_IRQ:
-               ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1);
-               register_intc_controller(&intc_irq_desc);
-               break;
-       default:
-               BUG();
-       }
-}
-
 void __init plat_irq_setup(void)
 {
        register_intc_controller(&intc_desc);
+       plat_irq_setup_sh3();
 }
index ba8750176d9172113c49ec538de4a83066b57ad5..05372ed6c5686c0dd346853eefb131d9848bbf6a 100644 (file)
@@ -143,12 +143,22 @@ resvec_save_area:
 trap_jtable:
        .long   do_exception_error              /* 0x000 */
        .long   do_exception_error              /* 0x020 */
+#ifdef CONFIG_MMU
        .long   tlb_miss_load                           /* 0x040 */
        .long   tlb_miss_store                          /* 0x060 */
+#else
+       .long   do_exception_error
+       .long   do_exception_error
+#endif
        ! ARTIFICIAL pseudo-EXPEVT setting
        .long   do_debug_interrupt              /* 0x080 */
+#ifdef CONFIG_MMU
        .long   tlb_miss_load                           /* 0x0A0 */
        .long   tlb_miss_store                          /* 0x0C0 */
+#else
+       .long   do_exception_error
+       .long   do_exception_error
+#endif
        .long   do_address_error_load   /* 0x0E0 */
        .long   do_address_error_store  /* 0x100 */
 #ifdef CONFIG_SH_FPU
@@ -185,10 +195,18 @@ trap_jtable:
        .endr
        .long   do_IRQ                  /* 0xA00 */
        .long   do_IRQ                  /* 0xA20 */
+#ifdef CONFIG_MMU
        .long   itlb_miss_or_IRQ                        /* 0xA40 */
+#else
+       .long   do_IRQ
+#endif
        .long   do_IRQ                  /* 0xA60 */
        .long   do_IRQ                  /* 0xA80 */
+#ifdef CONFIG_MMU
        .long   itlb_miss_or_IRQ                        /* 0xAA0 */
+#else
+       .long   do_IRQ
+#endif
        .long   do_exception_error              /* 0xAC0 */
        .long   do_address_error_exec   /* 0xAE0 */
        .rept 8
@@ -274,6 +292,7 @@ not_a_tlb_miss:
         * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
         * block making sure the final alignment is correct.
         */
+#ifdef CONFIG_MMU
 tlb_miss:
        synco   /* TAKum03020 (but probably a good idea anyway.) */
        putcon  SP, KCR1
@@ -377,6 +396,9 @@ fixup_to_invoke_general_handler:
        getcon  KCR1, SP
        pta     handle_exception, tr0
        blink   tr0, ZERO
+#else /* CONFIG_MMU */
+       .balign 256
+#endif
 
 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
    DOES END UP AT VBR+0x600 */
@@ -1103,6 +1125,7 @@ restore_all:
  * fpu_error_or_IRQ? is a helper to deflect to the right cause.
  *
  */
+#ifdef CONFIG_MMU
 tlb_miss_load:
        or      SP, ZERO, r2
        or      ZERO, ZERO, r3          /* Read */
@@ -1132,6 +1155,7 @@ call_do_page_fault:
        movi    do_page_fault, r6
         ptabs  r6, tr0
         blink  tr0, ZERO
+#endif /* CONFIG_MMU */
 
 fpu_error_or_IRQA:
        pta     its_IRQ, tr0
@@ -1481,6 +1505,7 @@ poke_real_address_q:
        ptabs   LINK, tr0
        blink   tr0, r63
 
+#ifdef CONFIG_MMU
 /*
  * --- User Access Handling Section
  */
@@ -1604,6 +1629,7 @@ ___clear_user_exit:
        ptabs   LINK, tr0
        blink   tr0, ZERO
 
+#endif /* CONFIG_MMU */
 
 /*
  * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
@@ -2014,9 +2040,11 @@ sa_default_restorer:
        .global asm_uaccess_start       /* Just a marker */
 asm_uaccess_start:
 
+#ifdef CONFIG_MMU
        .long   ___copy_user1, ___copy_user_exit
        .long   ___copy_user2, ___copy_user_exit
        .long   ___clear_user1, ___clear_user_exit
+#endif
        .long   ___strncpy_from_user1, ___strncpy_from_user_exit
        .long   ___strnlen_user1, ___strnlen_user_exit
        .long   ___get_user_asm_b1, ___get_user_asm_b_exit
index 31f8cb0f6374ac71d517fb04c058a99b3a7f0642..92ad844b5c1220a349944f474d881767715aab1a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
+#include <asm/tlb.h>
 
 int __init detect_cpu_and_cache_system(void)
 {
@@ -67,5 +68,8 @@ int __init detect_cpu_and_cache_system(void)
        set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags));
 #endif
 
+       /* Setup some I/D TLB defaults */
+       sh64_tlb_init();
+
        return 0;
 }
index 957f256115434fa866ba16cd2f2bccc80664c23c..6b7d166694e28fecc3f949b66cb94ae8c2e53950 100644 (file)
@@ -141,7 +141,9 @@ static void scif_sercon_init(char *s)
  */
 static void scif_sercon_init(char *s)
 {
+       struct uart_port *port = &scif_port;
        unsigned baud = DEFAULT_BAUD;
+       unsigned int status;
        char *e;
 
        if (*s == ',')
@@ -160,19 +162,25 @@ static void scif_sercon_init(char *s)
                        baud = DEFAULT_BAUD;
        }
 
-       ctrl_outw(0, scif_port.mapbase + 8);
-       ctrl_outw(0, scif_port.mapbase);
+       do {
+               status = sci_in(port, SCxSR);
+       } while (!(status & SCxSR_TEND(port)));
+
+       sci_out(port, SCSCR, 0);         /* TE=0, RE=0 */
+       sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+       sci_out(port, SCSMR, 0);
 
        /* Set baud rate */
-       ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
-                 (32 * baud) - 1, scif_port.mapbase + 4);
-
-       ctrl_outw(12, scif_port.mapbase + 24);
-       ctrl_outw(8, scif_port.mapbase + 24);
-       ctrl_outw(0, scif_port.mapbase + 32);
-       ctrl_outw(0x60, scif_port.mapbase + 16);
-       ctrl_outw(0, scif_port.mapbase + 36);
-       ctrl_outw(0x30, scif_port.mapbase + 8);
+       sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) /
+               (32 * baud) - 1);
+       udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
+
+       sci_out(port, SCSPTR, 0);
+       sci_out(port, SCxSR, 0x60);
+       sci_out(port, SCLSR, 0);
+
+       sci_out(port, SCFCR, 0);
+       sci_out(port, SCSCR, 0x30);      /* TE=1, RE=1 */
 }
 #endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
 #endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
index 284f66f1ebbeb812be6623c7111d820ccaa4ad01..516bde9c50fad25bbebbf7b00e9dcd3cc23577f2 100644 (file)
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(cpu_data);
  * sh_mv= on the command line, prior to .machvec.init teardown.
  */
 struct sh_machine_vector sh_mv = { .mv_name = "generic", };
+EXPORT_SYMBOL(sh_mv);
 
 #ifdef CONFIG_VT
 struct screen_info screen_info;
@@ -76,11 +77,18 @@ static struct resource data_resource = {
        .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
 };
 
+static struct resource bss_resource = {
+       .name   = "Kernel bss",
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM,
+};
+
 unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end = 0;
 EXPORT_SYMBOL(memory_end);
 
+static struct resource mem_resources[MAX_NUMNODES];
+
 int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
 
 static int __init early_parse_mem(char *p)
@@ -169,6 +177,40 @@ static inline void __init reserve_crashkernel(void)
 {}
 #endif
 
+void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
+                                               unsigned long end_pfn)
+{
+       struct resource *res = &mem_resources[nid];
+
+       WARN_ON(res->name); /* max one active range per node for now */
+
+       res->name = "System RAM";
+       res->start = start_pfn << PAGE_SHIFT;
+       res->end = (end_pfn << PAGE_SHIFT) - 1;
+       res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+       if (request_resource(&iomem_resource, res)) {
+               pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
+                      start_pfn, end_pfn);
+               return;
+       }
+
+       /*
+        *  We don't know which RAM region contains kernel data,
+        *  so we try it repeatedly and let the resource manager
+        *  test it.
+        */
+       request_resource(res, &code_resource);
+       request_resource(res, &data_resource);
+       request_resource(res, &bss_resource);
+
+#ifdef CONFIG_KEXEC
+       if (crashk_res.start != crashk_res.end)
+               request_resource(res, &crashk_res);
+#endif
+
+       add_active_range(nid, start_pfn, end_pfn);
+}
+
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
        unsigned long bootmap_size;
@@ -181,7 +223,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
        bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
                                         min_low_pfn, max_low_pfn);
 
-       add_active_range(0, min_low_pfn, max_low_pfn);
+       __add_active_range(0, min_low_pfn, max_low_pfn);
        register_bootmem_low_pages();
 
        node_set_online(0);
@@ -267,6 +309,8 @@ void __init setup_arch(char **cmdline_p)
        code_resource.end = virt_to_phys(_etext)-1;
        data_resource.start = virt_to_phys(_etext);
        data_resource.end = virt_to_phys(_edata)-1;
+       bss_resource.start = virt_to_phys(__bss_start);
+       bss_resource.end = virt_to_phys(_ebss)-1;
 
        memory_start = (unsigned long)__va(__MEMORY_START);
        if (!memory_end)
index 6d405462cee84774939382483436e8c69c0445fd..8f916536719c81261b443225d85e618baff4bd50 100644 (file)
@@ -20,8 +20,6 @@
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 extern struct hw_interrupt_type no_irq_type;
 
-EXPORT_SYMBOL(sh_mv);
-
 /* platform dependent support */
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
index a310c9707f03266400cbeafa6c37545584d1bd4d..9324d32adacc669c6159a39f6752f59cf286c394 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/in6.h>
 #include <linux/interrupt.h>
 #include <linux/screen_info.h>
+#include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
@@ -29,25 +30,50 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
 
+#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU)
+EXPORT_SYMBOL(clear_user_page);
+#endif
+
+#ifndef CONFIG_CACHE_OFF
+EXPORT_SYMBOL(flush_dcache_page);
+#endif
+
 /* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_nocheck);
+#ifdef CONFIG_IPV6
+EXPORT_SYMBOL(csum_ipv6_magic);
+#endif
 
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
 
+EXPORT_SYMBOL(__put_user_asm_b);
+EXPORT_SYMBOL(__put_user_asm_w);
 EXPORT_SYMBOL(__put_user_asm_l);
+EXPORT_SYMBOL(__put_user_asm_q);
+EXPORT_SYMBOL(__get_user_asm_b);
+EXPORT_SYMBOL(__get_user_asm_w);
 EXPORT_SYMBOL(__get_user_asm_l);
+EXPORT_SYMBOL(__get_user_asm_q);
+EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
+EXPORT_SYMBOL(__const_udelay);
 
 /* Ugh.  These come in from libgcc.a at link time. */
 #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
 
 DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__sdivsi3_2);
 DECLARE_EXPORT(__muldi3);
 DECLARE_EXPORT(__udivsi3);
+DECLARE_EXPORT(__div_table);
index 578004d71e02dbe68d1c74b769803fa8aa45e9dd..91fb8445a5a094ac8c5f2191b9bca308b5e1b8e4 100644 (file)
 #include <asm/ptrace.h>
 #include <asm/unistd.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long * fildes)
-{
-        int fd[2];
-        int error;
-
-        error = do_pipe(fd);
-        if (!error) {
-                if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                        error = -EFAULT;
-        }
-        return error;
-}
-
 /*
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
index 898977ee2030d99ca792425f22e58464b9ee8a0d..022a55f1c1d46b510c1efa784d1376d342104372 100644 (file)
@@ -172,6 +172,7 @@ void do_gettimeofday(struct timeval *tv)
        tv->tv_sec = sec;
        tv->tv_usec = usec;
 }
+EXPORT_SYMBOL(do_gettimeofday);
 
 int do_settimeofday(struct timespec *tv)
 {
@@ -240,7 +241,7 @@ static inline void do_timer_interrupt(void)
         * the irq version of write_lock because as just said we have irq
         * locally disabled. -arca
         */
-       write_lock(&xtime_lock);
+       write_seqlock(&xtime_lock);
        asm ("getcon cr62, %0" : "=r" (current_ctc));
        ctc_last_interrupt = (unsigned long) current_ctc;
 
@@ -266,7 +267,7 @@ static inline void do_timer_interrupt(void)
                        /* do it again in 60 s */
                        last_rtc_update = xtime.tv_sec - 600;
        }
-       write_unlock(&xtime_lock);
+       write_sequnlock(&xtime_lock);
 
 #ifndef CONFIG_SMP
        update_process_times(user_mode(get_irq_regs()));
index 75825ef6e0846443be7a549a1671961d64607de9..2fb8eaf6de60a01c6bbaae80d7839b0a2d1778bc 100644 (file)
@@ -186,8 +186,8 @@ void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs)
        rr->pc = regs->pc;
 
        if (sp < stack_bottom + 3092) {
-               printk("evt_debug : stack underflow report\n");
                int i, j;
+               printk("evt_debug : stack underflow report\n");
                for (j=0, i = event_ptr; j<16; j++) {
                        rr = event_ring + i;
                        printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n",
index cbd6aa33c5ac108720c1e83db535a54b995976b6..0d92a8a3ac9a1e312870740b7d982e1eafebb021 100644 (file)
@@ -2,10 +2,11 @@
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
 
-obj-y                  := init.o extable_64.o consistent.o
+obj-y                  := init.o consistent.o
 
-mmu-y                  := tlb-nommu.o pg-nommu.o
-mmu-$(CONFIG_MMU)      := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o
+mmu-y                  := tlb-nommu.o pg-nommu.o extable_32.o
+mmu-$(CONFIG_MMU)      := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \
+                          extable_64.o
 
 ifndef CONFIG_CACHE_OFF
 obj-y                  += cache-sh5.o
index 3877321fcede375cd8698cf98c2e9884798ac209..9e277ec7d5360e1b46e0a7ee0b934e9e8a75c08c 100644 (file)
@@ -714,6 +714,7 @@ void flush_cache_sigtramp(unsigned long vaddr)
        sh64_icache_inv_current_user_range(vaddr, end);
 }
 
+#ifdef CONFIG_MMU
 /*
  * These *MUST* lie in an area of virtual address space that's otherwise
  * unused.
@@ -830,3 +831,4 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
        else
                sh64_clear_user_page_coloured(to, address);
 }
+#endif
index cea224c3e49b6049b54edd6d5a6e782a02728dc2..6e0be24d26e2c3cd9168ff3ac7203d4f0466b298 100644 (file)
@@ -343,6 +343,7 @@ unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *n
 
        return shmedia_alloc_io(phys, size, name);
 }
+EXPORT_SYMBOL(onchip_remap);
 
 void onchip_unmap(unsigned long vaddr)
 {
@@ -370,6 +371,7 @@ void onchip_unmap(unsigned long vaddr)
                kfree(res);
        }
 }
+EXPORT_SYMBOL(onchip_unmap);
 
 #ifdef CONFIG_PROC_FS
 static int
index 2de7302724fc188cd6a8bf9680470bc55fad2dc7..1663199ce888649a6ecd0368f2c114ae7866a38e 100644 (file)
@@ -59,7 +59,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
        free_pfn = start_pfn = start >> PAGE_SHIFT;
        end_pfn = end >> PAGE_SHIFT;
 
-       add_active_range(nid, start_pfn, end_pfn);
+       __add_active_range(nid, start_pfn, end_pfn);
 
        /* Node-local pgdat */
        NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
index 987c6682bf9906a51f120dc73cc478b00a07d8d8..1bba7d36be9067de687cbb2d28065393b2e1369a 100644 (file)
@@ -28,7 +28,6 @@ HD64465                       HD64465
 7751SYSTEMH            SH_7751_SYSTEMH
 HP6XX                  SH_HP6XX
 DREAMCAST              SH_DREAMCAST
-MPC1211                        SH_MPC1211
 SNAPGEAR               SH_SECUREEDGE5410
 EDOSK7705              SH_EDOSK7705
 SH4202_MICRODEV                SH_SH4202_MICRODEV
index 57d1bbdd0bd2aa5f996b9df420ff50415d64573e..4bcfe54f878d3250c98ed613cdc899770aaaa850 100644 (file)
@@ -1306,6 +1306,8 @@ ret_from_fork:
        .align  4
        .globl  linux_sparc_syscall
 linux_sparc_syscall:
+       sethi   %hi(PSR_SYSCALL), %l4
+       or      %l0, %l4, %l0
        /* Direct access to user regs, must faster. */
        cmp     %g1, NR_SYSCALLS
        bgeu    linux_sparc_ni_syscall
index e7f35198ae34943f5adfeeedd7223014dfe146ff..da48d248cc17d6d9da5f9cb4faf96d1cb41e17e2 100644 (file)
@@ -419,14 +419,26 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
                              unsigned long stack_size)
 {
        unsigned long parent_tid_ptr, child_tid_ptr;
+       unsigned long orig_i1 = regs->u_regs[UREG_I1];
+       long ret;
 
        parent_tid_ptr = regs->u_regs[UREG_I2];
        child_tid_ptr = regs->u_regs[UREG_I4];
 
-       return do_fork(clone_flags, stack_start,
-                      regs, stack_size,
-                      (int __user *) parent_tid_ptr,
-                      (int __user *) child_tid_ptr);
+       ret = do_fork(clone_flags, stack_start,
+                     regs, stack_size,
+                     (int __user *) parent_tid_ptr,
+                     (int __user *) child_tid_ptr);
+
+       /* If we get an error and potentially restart the system
+        * call, we're screwed because copy_thread() clobbered
+        * the parent's %o1.  So detect that case and restore it
+        * here.
+        */
+       if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+               regs->u_regs[UREG_I1] = orig_i1;
+
+       return ret;
 }
 
 /* Copy a Sparc thread.  The fork() return value conventions
@@ -626,11 +638,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
                          (char __user * __user *)regs->u_regs[base + UREG_I2],
                          regs);
        putname(filename);
-       if (error == 0) {
-               task_lock(current);
-               current->ptrace &= ~PT_DTRACE;
-               task_unlock(current);
-       }
 out:
        return error;
 }
index 7f44ae69b29e52dd2ae7ff0a647d7ace053211fc..81f3b929743f12c17ec44642acb58f6526d4319c 100644 (file)
@@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target,
                switch (pos) {
                case 32: /* PSR */
                        psr = regs->psr;
-                       psr &= ~PSR_ICC;
-                       psr |= (reg & PSR_ICC);
+                       psr &= ~(PSR_ICC | PSR_SYSCALL);
+                       psr |= (reg & (PSR_ICC | PSR_SYSCALL));
                        regs->psr = psr;
                        break;
                case 33: /* PC */
@@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 
        default:
+               if (request == PTRACE_SPARC_DETACH)
+                       request = PTRACE_DETACH;
                ret = ptrace_request(child, request, addr, data);
                break;
        }
index 77ca6fd812538b2c2dae9b2c40c29f2303b6bdde..ab818cdc4cc0da412da435093b5cce37c30da0b1 100644 (file)
@@ -50,8 +50,9 @@ rtrap_7win_patch5:    and     %g1, 0x7f, %g1
 ret_trap_entry:
 ret_trap_lockless_ipi:
        andcc   %t_psr, PSR_PS, %g0
+       sethi   %hi(PSR_SYSCALL), %g1
        be      1f
-        nop
+        andn   %t_psr, %g1, %t_psr
 
        wr      %t_psr, 0x0, %psr
        b       ret_trap_kernel
@@ -73,7 +74,6 @@ signal_p:
         ld     [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
 
        mov     %l5, %o1
-       mov     %l6, %o2
        call    do_signal
         add    %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
 
@@ -81,6 +81,8 @@ signal_p:
        ld      [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
        clr     %l6
 ret_trap_continue:
+       sethi   %hi(PSR_SYSCALL), %g1
+       andn    %t_psr, %g1, %t_psr
        wr      %t_psr, 0x0, %psr
        WRITE_PAUSE
 
@@ -137,8 +139,9 @@ ret_trap_userwins_ok:
        LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
        or      %t_pc, %t_npc, %g2
        andcc   %g2, 0x3, %g0
+       sethi   %hi(PSR_SYSCALL), %g2
        be      1f
-        nop
+        andn   %t_psr, %g2, %t_psr
 
        b       ret_trap_unaligned_pc
         add    %sp, STACKFRAME_SZ, %o0
@@ -201,6 +204,8 @@ rtrap_patch5:       and     %g1, 0xff, %g1
 1:
        LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
 2:
+       sethi   %hi(PSR_SYSCALL), %twin_tmp1
+       andn    %t_psr, %twin_tmp1, %t_psr
        wr      %t_psr, 0x0, %psr
        WRITE_PAUSE
 
index 3c13137685da8a281adee5bccf44c5f5f4438654..8a55c4f0df8483b11d3b1a6ac67c74a1ca0f034d 100644 (file)
@@ -180,11 +180,9 @@ static void __init boot_flags_init(char *commands)
 
 /* This routine will in the future do all the nasty prom stuff
  * to probe for the mmu type and its parameters, etc. This will
- * also be where SMP things happen plus the Sparc specific memory
- * physical memory probe as on the alpha.
+ * also be where SMP things happen.
  */
 
-extern int prom_probe_memory(void);
 extern void sun4c_probe_vac(void);
 extern char cputypval;
 extern unsigned long start, end;
@@ -268,7 +266,6 @@ void __init setup_arch(char **cmdline_p)
        if (ARCH_SUN4C_SUN4)
                sun4c_probe_vac();
        load_mmu();
-       (void) prom_probe_memory();
 
        phys_base = 0xffffffffUL;
        highest_paddr = 0UL;
index 3c312290c3c288eda469d5272e71c3ae46226321..3fd1df9f9ba7e849609f5018d443378a301fb2e4 100644 (file)
@@ -145,6 +145,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
        regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
                  | (regs->psr & (PSR_ICC | PSR_EF));
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_syscall(regs);
+
        err |= __get_user(fpu_save, &sf->fpu_save);
 
        if (fpu_save)
@@ -199,6 +202,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
 
        regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_syscall(regs);
+
        err |= __get_user(fpu_save, &sf->fpu_save);
 
        if (fpu_save)
@@ -245,15 +251,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
 
 static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
 {
-       unsigned long sp;
+       unsigned long sp = regs->u_regs[UREG_FP];
 
-       sp = regs->u_regs[UREG_FP];
+       /*
+        * If we are on the alternate signal stack and would overflow it, don't.
+        * Return an always-bogus address instead so we will die with SIGSEGV.
+        */
+       if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+               return (void __user *) -1L;
 
        /* This is the X/Open sanctioned signal stack switching.  */
        if (sa->sa_flags & SA_ONSTACK) {
-               if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
+               if (sas_ss_flags(sp) == 0)
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
+
+       /* Always align the stack frame.  This handles two cases.  First,
+        * sigaltstack need not be mindful of platform specific stack
+        * alignment.  Second, if we took this signal because the stack
+        * is not aligned properly, we'd like to take the signal cleanly
+        * and report that.
+        */
+       sp &= ~7UL;
+
        return (void __user *)(sp - framesize);
 }
 
@@ -493,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
+asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
 {
-       siginfo_t info;
-       struct sparc_deliver_cookie cookie;
        struct k_sigaction ka;
-       int signr;
+       int restart_syscall;
        sigset_t *oldset;
+       siginfo_t info;
+       int signr;
 
-       cookie.restart_syscall = restart_syscall;
-       cookie.orig_i0 = orig_i0;
+       if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
+               restart_syscall = 1;
+       else
+               restart_syscall = 0;
 
        if (test_thread_flag(TIF_RESTORE_SIGMASK))
                oldset = &current->saved_sigmask;
        else
                oldset = &current->blocked;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+       /* If the debugger messes with the program counter, it clears
+        * the software "in syscall" bit, directing us to not perform
+        * a syscall restart.
+        */
+       if (restart_syscall && !pt_regs_is_syscall(regs))
+               restart_syscall = 0;
+
        if (signr > 0) {
-               if (cookie.restart_syscall)
-                       syscall_restart(cookie.orig_i0, regs, &ka.sa);
+               if (restart_syscall)
+                       syscall_restart(orig_i0, regs, &ka.sa);
                handle_signal(signr, &ka, &info, oldset, regs);
 
                /* a signal was successfully delivered; the saved
@@ -524,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
                        clear_thread_flag(TIF_RESTORE_SIGMASK);
                return;
        }
-       if (cookie.restart_syscall &&
+       if (restart_syscall &&
            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
             regs->u_regs[UREG_I0] == ERESTARTSYS ||
             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
                /* replay the system call when we are done */
-               regs->u_regs[UREG_I0] = cookie.orig_i0;
+               regs->u_regs[UREG_I0] = orig_i0;
                regs->pc -= 4;
                regs->npc -= 4;
        }
-       if (cookie.restart_syscall &&
+       if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->pc -= 4;
@@ -585,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
 out:
        return ret;
 }
-
-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
-{
-       struct sparc_deliver_cookie *cp = cookie;
-
-       if (cp->restart_syscall &&
-           (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-            regs->u_regs[UREG_I0] == ERESTARTSYS ||
-            regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-               /* replay the system call when we are done */
-               regs->u_regs[UREG_I0] = cp->orig_i0;
-               regs->pc -= 4;
-               regs->npc -= 4;
-               cp->restart_syscall = 0;
-       }
-
-       if (cp->restart_syscall &&
-           regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-               regs->u_regs[UREG_G1] = __NR_restart_syscall;
-               regs->pc -= 4;
-               regs->npc -= 4;
-               cp->restart_syscall = 0;
-       }
-}
index f188b5dc9fd001bec3691b03401408b5af655ce4..e995491c443627d5e0e1b5f363990608b946685f 100644 (file)
@@ -223,8 +223,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
 {
        if (ARCH_SUN4C_SUN4 &&
            (len > 0x20000000 ||
-            ((flags & MAP_FIXED) &&
-             addr < 0xe0000000 && addr + len > 0x20000000)))
+            (addr < 0xe0000000 && addr + len > 0x20000000)))
                return -EINVAL;
 
        /* See asm-sparc/uaccess.h */
index e4d9c8e19df5d1e70c3de848898cba9fe977eda4..abd50795a7b614a408c1ef950f2de9213b76d2c0 100644 (file)
@@ -47,64 +47,15 @@ int vac_size, vac_linesize, vac_do_hw_vac_flushes;
 int vac_entries_per_context, vac_entries_per_segment;
 int vac_entries_per_page;
 
-/* Nice, simple, prom library does all the sweating for us. ;) */
-int prom_probe_memory (void)
+/* Return how much physical memory we have.  */
+unsigned long probe_memory(void)
 {
-       register struct linux_mlist_v0 *mlist;
-       register unsigned long bytes, base_paddr, tally;
-       register int i;
-
-       i = 0;
-       mlist= *prom_meminfo()->v0_available;
-       bytes = tally = mlist->num_bytes;
-       base_paddr = (unsigned long) mlist->start_adr;
-  
-       sp_banks[0].base_addr = base_paddr;
-       sp_banks[0].num_bytes = bytes;
-
-       while (mlist->theres_more != (void *) 0){
-               i++;
-               mlist = mlist->theres_more;
-               bytes = mlist->num_bytes;
-               tally += bytes;
-               if (i > SPARC_PHYS_BANKS-1) {
-                       printk ("The machine has more banks than "
-                               "this kernel can support\n"
-                               "Increase the SPARC_PHYS_BANKS "
-                               "setting (currently %d)\n",
-                               SPARC_PHYS_BANKS);
-                       i = SPARC_PHYS_BANKS-1;
-                       break;
-               }
-    
-               sp_banks[i].base_addr = (unsigned long) mlist->start_adr;
-               sp_banks[i].num_bytes = mlist->num_bytes;
-       }
-
-       i++;
-       sp_banks[i].base_addr = 0xdeadbeef;
-       sp_banks[i].num_bytes = 0;
-
-       /* Now mask all bank sizes on a page boundary, it is all we can
-        * use anyways.
-        */
-       for(i=0; sp_banks[i].num_bytes != 0; i++)
-               sp_banks[i].num_bytes &= PAGE_MASK;
-
-       return tally;
-}
-
-/* Traverse the memory lists in the prom to see how much physical we
- * have.
- */
-unsigned long
-probe_memory(void)
-{
-       int total;
+       unsigned long total = 0;
+       int i;
 
-       total = prom_probe_memory();
+       for (i = 0; sp_banks[i].num_bytes; i++)
+               total += sp_banks[i].num_bytes;
 
-       /* Oh man, much nicer, keep the dirt in promlib. */
        return total;
 }
 
index 50abfb1b880eba9b29d891a018625f070faa055a..2fa3a474e3a251a4bdee596a2f9369952d27f520 100644 (file)
@@ -21,8 +21,6 @@ linux_sun4_romvec *sun4_romvec;
 /* The root node of the prom device tree. */
 int prom_root_node;
 
-int prom_stdin, prom_stdout;
-
 /* Pointer to the device tree operations structure. */
 struct linux_nodeops *prom_nodeops;
 
@@ -74,11 +72,6 @@ void __init prom_init(struct linux_romvec *rp)
           (((unsigned long) prom_nodeops) == -1))
                prom_halt();
 
-       if(prom_vers == PROM_V2 || prom_vers == PROM_V3) {
-               prom_stdout = *romvec->pv_v2bootargs.fd_stdout;
-               prom_stdin  = *romvec->pv_v2bootargs.fd_stdin;
-       }
-       
        prom_meminit();
 
        prom_ranges_init();
index b0c0f9c4fc14bc36f4bd67090d2a576a2f5f5bd4..947f047dc95a67173d0072653052f92187b74325 100644 (file)
-/* $Id: memory.c,v 1.15 2000/01/29 01:09:12 anton Exp $
- * memory.c: Prom routine for acquiring various bits of information
+/* memory.c: Prom routine for acquiring various bits of information
  *           about RAM on the machine, both virtual and physical.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
  */
 
 #include <linux/kernel.h>
+#include <linux/sort.h>
 #include <linux/init.h>
 
 #include <asm/openprom.h>
 #include <asm/sun4prom.h>
 #include <asm/oplib.h>
+#include <asm/page.h>
 
-/* This routine, for consistency, returns the ram parameters in the
- * V0 prom memory descriptor format.  I choose this format because I
- * think it was the easiest to work with.  I feel the religious
- * arguments now... ;)  Also, I return the linked lists sorted to
- * prevent paging_init() upset stomach as I have not yet written
- * the pepto-bismol kernel module yet.
- */
+static int __init prom_meminit_v0(void)
+{
+       struct linux_mlist_v0 *p;
+       int index;
+
+       index = 0;
+       for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) {
+               sp_banks[index].base_addr = (unsigned long) p->start_adr;
+               sp_banks[index].num_bytes = p->num_bytes;
+               index++;
+       }
 
-struct linux_prom_registers prom_reg_memlist[64];
-struct linux_prom_registers prom_reg_tmp[64];
+       return index;
+}
 
-struct linux_mlist_v0 prom_phys_total[64];
-struct linux_mlist_v0 prom_prom_taken[64];
-struct linux_mlist_v0 prom_phys_avail[64];
+static int __init prom_meminit_v2(void)
+{
+       struct linux_prom_registers reg[64];
+       int node, size, num_ents, i;
 
-struct linux_mlist_v0 *prom_ptot_ptr = prom_phys_total;
-struct linux_mlist_v0 *prom_ptak_ptr = prom_prom_taken;
-struct linux_mlist_v0 *prom_pavl_ptr = prom_phys_avail;
+       node = prom_searchsiblings(prom_getchild(prom_root_node), "memory");
+       size = prom_getproperty(node, "available", (char *) reg, sizeof(reg));
+       num_ents = size / sizeof(struct linux_prom_registers);
 
-struct linux_mem_v0 prom_memlist;
+       for (i = 0; i < num_ents; i++) {
+               sp_banks[i].base_addr = reg[i].phys_addr;
+               sp_banks[i].num_bytes = reg[i].reg_size;
+       }
 
+       return num_ents;
+}
 
-/* Internal Prom library routine to sort a linux_mlist_v0 memory
- * list.  Used below in initialization.
- */
-static void __init
-prom_sortmemlist(struct linux_mlist_v0 *thislist)
+static int __init prom_meminit_sun4(void)
 {
-       int swapi = 0;
-       int i, mitr, tmpsize;
-       char *tmpaddr;
-       char *lowest;
-
-       for(i=0; thislist[i].theres_more; i++) {
-               lowest = thislist[i].start_adr;
-               for(mitr = i+1; thislist[mitr-1].theres_more; mitr++)
-                       if(thislist[mitr].start_adr < lowest) {
-                               lowest = thislist[mitr].start_adr;
-                               swapi = mitr;
-                       }
-               if(lowest == thislist[i].start_adr) continue;
-               tmpaddr = thislist[swapi].start_adr;
-               tmpsize = thislist[swapi].num_bytes;
-               for(mitr = swapi; mitr > i; mitr--) {
-                       thislist[mitr].start_adr = thislist[mitr-1].start_adr;
-                       thislist[mitr].num_bytes = thislist[mitr-1].num_bytes;
-               }
-               thislist[i].start_adr = tmpaddr;
-               thislist[i].num_bytes = tmpsize;
-       }
+#ifdef CONFIG_SUN4
+       sp_banks[0].base_addr = 0;
+       sp_banks[0].num_bytes = *(sun4_romvec->memoryavail);
+#endif
+       return 1;
+}
+
+static int sp_banks_cmp(const void *a, const void *b)
+{
+       const struct sparc_phys_banks *x = a, *y = b;
 
-       return;
+       if (x->base_addr > y->base_addr)
+               return 1;
+       if (x->base_addr < y->base_addr)
+               return -1;
+       return 0;
 }
 
 /* Initialize the memory lists based upon the prom version. */
 void __init prom_meminit(void)
 {
-       int node = 0;
-       unsigned int iter, num_regs;
-       struct linux_mlist_v0 *mptr;  /* ptr for traversal */
+       int i, num_ents = 0;
 
-       switch(prom_vers) {
+       switch (prom_vers) {
        case PROM_V0:
-               /* Nice, kind of easier to do in this case. */
-               /* First, the total physical descriptors. */
-               for(mptr = (*(romvec->pv_v0mem.v0_totphys)), iter=0;
-                   mptr; mptr=mptr->theres_more, iter++) {
-                       prom_phys_total[iter].start_adr = mptr->start_adr;
-                       prom_phys_total[iter].num_bytes = mptr->num_bytes;
-                       prom_phys_total[iter].theres_more = &prom_phys_total[iter+1];
-               }
-               prom_phys_total[iter-1].theres_more = NULL;
-               /* Second, the total prom taken descriptors. */
-               for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0;
-                   mptr; mptr=mptr->theres_more, iter++) {
-                       prom_prom_taken[iter].start_adr = mptr->start_adr;
-                       prom_prom_taken[iter].num_bytes = mptr->num_bytes;
-                       prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1];
-               }
-               prom_prom_taken[iter-1].theres_more = NULL;
-               /* Last, the available physical descriptors. */
-               for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0;
-                   mptr; mptr=mptr->theres_more, iter++) {
-                       prom_phys_avail[iter].start_adr = mptr->start_adr;
-                       prom_phys_avail[iter].num_bytes = mptr->num_bytes;
-                       prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1];
-               }
-               prom_phys_avail[iter-1].theres_more = NULL;
-               /* Sort all the lists. */
-               prom_sortmemlist(prom_phys_total);
-               prom_sortmemlist(prom_prom_taken);
-               prom_sortmemlist(prom_phys_avail);
+               num_ents = prom_meminit_v0();
                break;
+
        case PROM_V2:
        case PROM_V3:
-               /* Grrr, have to traverse the prom device tree ;( */
-               node = prom_getchild(prom_root_node);
-               node = prom_searchsiblings(node, "memory");
-               num_regs = prom_getproperty(node, "available",
-                                           (char *) prom_reg_memlist,
-                                           sizeof(prom_reg_memlist));
-               num_regs = (num_regs/sizeof(struct linux_prom_registers));
-               for(iter=0; iter<num_regs; iter++) {
-                       prom_phys_avail[iter].start_adr =
-                               (char *) prom_reg_memlist[iter].phys_addr;
-                       prom_phys_avail[iter].num_bytes =
-                               (unsigned long) prom_reg_memlist[iter].reg_size;
-                       prom_phys_avail[iter].theres_more =
-                               &prom_phys_avail[iter+1];
-               }
-               prom_phys_avail[iter-1].theres_more = NULL;
-
-               num_regs = prom_getproperty(node, "reg",
-                                           (char *) prom_reg_memlist,
-                                           sizeof(prom_reg_memlist));
-               num_regs = (num_regs/sizeof(struct linux_prom_registers));
-               for(iter=0; iter<num_regs; iter++) {
-                       prom_phys_total[iter].start_adr =
-                               (char *) prom_reg_memlist[iter].phys_addr;
-                       prom_phys_total[iter].num_bytes =
-                               (unsigned long) prom_reg_memlist[iter].reg_size;
-                       prom_phys_total[iter].theres_more =
-                               &prom_phys_total[iter+1];
-               }
-               prom_phys_total[iter-1].theres_more = NULL;
-
-               node = prom_getchild(prom_root_node);
-               node = prom_searchsiblings(node, "virtual-memory");
-               num_regs = prom_getproperty(node, "available",
-                                           (char *) prom_reg_memlist,
-                                           sizeof(prom_reg_memlist));
-               num_regs = (num_regs/sizeof(struct linux_prom_registers));
-
-               /* Convert available virtual areas to taken virtual
-                * areas.  First sort, then convert.
-                */
-               for(iter=0; iter<num_regs; iter++) {
-                       prom_prom_taken[iter].start_adr =
-                               (char *) prom_reg_memlist[iter].phys_addr;
-                       prom_prom_taken[iter].num_bytes =
-                               (unsigned long) prom_reg_memlist[iter].reg_size;
-                       prom_prom_taken[iter].theres_more =
-                               &prom_prom_taken[iter+1];
-               }
-               prom_prom_taken[iter-1].theres_more = NULL;
-
-               prom_sortmemlist(prom_prom_taken);
-
-               /* Finally, convert. */
-               for(iter=0; iter<num_regs; iter++) {
-                       prom_prom_taken[iter].start_adr =
-                               prom_prom_taken[iter].start_adr +
-                                       prom_prom_taken[iter].num_bytes;
-                       prom_prom_taken[iter].num_bytes =
-                               prom_prom_taken[iter+1].start_adr -
-                                       prom_prom_taken[iter].start_adr;
-               }
-               prom_prom_taken[iter-1].num_bytes =
-                       0xffffffff - (unsigned long) prom_prom_taken[iter-1].start_adr;
-
-               /* Sort the other two lists. */
-               prom_sortmemlist(prom_phys_total);
-               prom_sortmemlist(prom_phys_avail);
+               num_ents = prom_meminit_v2();
                break;
 
        case PROM_SUN4:
-#ifdef CONFIG_SUN4     
-               /* how simple :) */
-               prom_phys_total[0].start_adr = NULL;
-               prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize);
-               prom_phys_total[0].theres_more = NULL;
-               prom_prom_taken[0].start_adr = NULL; 
-               prom_prom_taken[0].num_bytes = 0x0;
-               prom_prom_taken[0].theres_more = NULL;
-               prom_phys_avail[0].start_adr = NULL;
-               prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail);
-               prom_phys_avail[0].theres_more = NULL;
-#endif
+               num_ents = prom_meminit_sun4();
                break;
 
        default:
                break;
-       };
-
-       /* Link all the lists into the top-level descriptor. */
-       prom_memlist.v0_totphys=&prom_ptot_ptr;
-       prom_memlist.v0_prommap=&prom_ptak_ptr;
-       prom_memlist.v0_available=&prom_pavl_ptr;
+       }
+       sort(sp_banks, num_ents, sizeof(struct sparc_phys_banks),
+            sp_banks_cmp, NULL);
 
-       return;
-}
+       /* Sentinel.  */
+       sp_banks[num_ents].base_addr = 0xdeadbeef;
+       sp_banks[num_ents].num_bytes = 0;
 
-/* This returns a pointer to our libraries internal v0 format
- * memory descriptor.
- */
-struct linux_mem_v0 *
-prom_meminfo(void)
-{
-       return &prom_memlist;
+       for (i = 0; i < num_ents; i++)
+               sp_banks[i].num_bytes &= PAGE_MASK;
 }
index b49d3b60bc0ca267cb79a61dc293c29d7faae83b..f25e1da3fd0307992d1f80c9b4ee5d5e466cbc3c 100644 (file)
 
                .text           
                .align  64
-               .globl  etrap, etrap_irq, etraptl1
+               .globl  etrap_syscall, etrap, etrap_irq, etraptl1
 etrap:         rdpr    %pil, %g2
-etrap_irq:
-               TRAP_LOAD_THREAD_REG(%g6, %g1)
+etrap_irq:     clr     %g3
+etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1)
                rdpr    %tstate, %g1
+               or      %g1, %g3, %g1
                sllx    %g2, 20, %g3
                andcc   %g1, TSTATE_PRIV, %g0
                or      %g1, %g3, %g1
index dbf2fc2f4d8713a83b5481e2b8f211a6f7c5866c..112b09f16f367ffe788e2623a91debb118454c16 100644 (file)
@@ -350,8 +350,7 @@ static void pci_parse_of_addrs(struct of_device *op,
 
 struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
                                  struct device_node *node,
-                                 struct pci_bus *bus, int devfn,
-                                 int host_controller)
+                                 struct pci_bus *bus, int devfn)
 {
        struct dev_archdata *sd;
        struct pci_dev *dev;
@@ -390,43 +389,28 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->devfn = devfn;
        dev->multifunction = 0;         /* maybe a lie? */
 
-       if (host_controller) {
-               if (tlb_type != hypervisor) {
-                       pci_read_config_word(dev, PCI_VENDOR_ID,
-                                            &dev->vendor);
-                       pci_read_config_word(dev, PCI_DEVICE_ID,
-                                            &dev->device);
-               } else {
-                       dev->vendor = PCI_VENDOR_ID_SUN;
-                       dev->device = 0x80f0;
-               }
-               dev->cfg_size = 256;
-               dev->class = PCI_CLASS_BRIDGE_HOST << 8;
-               sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
-                       0x00, PCI_SLOT(devfn), PCI_FUNC(devfn));
-       } else {
-               dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
-               dev->device = of_getintprop_default(node, "device-id", 0xffff);
-               dev->subsystem_vendor =
-                       of_getintprop_default(node, "subsystem-vendor-id", 0);
-               dev->subsystem_device =
-                       of_getintprop_default(node, "subsystem-id", 0);
-
-               dev->cfg_size = pci_cfg_space_size(dev);
-
-               /* We can't actually use the firmware value, we have
-                * to read what is in the register right now.  One
-                * reason is that in the case of IDE interfaces the
-                * firmware can sample the value before the the IDE
-                * interface is programmed into native mode.
-                */
-               pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
-               dev->class = class >> 8;
-               dev->revision = class & 0xff;
+       dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
+       dev->device = of_getintprop_default(node, "device-id", 0xffff);
+       dev->subsystem_vendor =
+               of_getintprop_default(node, "subsystem-vendor-id", 0);
+       dev->subsystem_device =
+               of_getintprop_default(node, "subsystem-id", 0);
+
+       dev->cfg_size = pci_cfg_space_size(dev);
+
+       /* We can't actually use the firmware value, we have
+        * to read what is in the register right now.  One
+        * reason is that in the case of IDE interfaces the
+        * firmware can sample the value before the the IDE
+        * interface is programmed into native mode.
+        */
+       pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
+       dev->class = class >> 8;
+       dev->revision = class & 0xff;
+
+       sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+               dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
-               sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
-                       dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
-       }
        if (ofpci_verbose)
                printk("    class: 0x%x device name: %s\n",
                       dev->class, pci_name(dev));
@@ -441,26 +425,21 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->current_state = 4;         /* unknown power state */
        dev->error_state = pci_channel_io_normal;
 
-       if (host_controller) {
+       if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+               /* a PCI-PCI bridge */
                dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
                dev->rom_base_reg = PCI_ROM_ADDRESS1;
-               dev->irq = PCI_IRQ_NONE;
+       } else if (!strcmp(type, "cardbus")) {
+               dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
        } else {
-               if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
-                       /* a PCI-PCI bridge */
-                       dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
-                       dev->rom_base_reg = PCI_ROM_ADDRESS1;
-               } else if (!strcmp(type, "cardbus")) {
-                       dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
-               } else {
-                       dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
-                       dev->rom_base_reg = PCI_ROM_ADDRESS;
+               dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+               dev->rom_base_reg = PCI_ROM_ADDRESS;
 
-                       dev->irq = sd->op->irqs[0];
-                       if (dev->irq == 0xffffffff)
-                               dev->irq = PCI_IRQ_NONE;
-               }
+               dev->irq = sd->op->irqs[0];
+               if (dev->irq == 0xffffffff)
+                       dev->irq = PCI_IRQ_NONE;
        }
+
        pci_parse_of_addrs(sd->op, node, dev);
 
        if (ofpci_verbose)
@@ -749,7 +728,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
                prev_devfn = devfn;
 
                /* create a new pci_dev for this device */
-               dev = of_create_pci_dev(pbm, child, bus, devfn, 0);
+               dev = of_create_pci_dev(pbm, child, bus, devfn);
                if (!dev)
                        continue;
                if (ofpci_verbose)
@@ -796,48 +775,9 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus)
                pci_bus_register_of_sysfs(child_bus);
 }
 
-int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
-                                unsigned int devfn,
-                                int where, int size,
-                                u32 *value)
-{
-       static u8 fake_pci_config[] = {
-               0x8e, 0x10, /* Vendor: 0x108e (Sun) */
-               0xf0, 0x80, /* Device: 0x80f0 (Fire) */
-               0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */
-               0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */
-               0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */
-               0x00, /* Cacheline: 0x00 */
-               0x40, /* Latency: 0x40 */
-               0x00, /* Header-Type: 0x00 normal */
-       };
-
-       *value = 0;
-       if (where >= 0 && where < sizeof(fake_pci_config) &&
-           (where + size) >= 0 &&
-           (where + size) < sizeof(fake_pci_config) &&
-           size <= sizeof(u32)) {
-               while (size--) {
-                       *value <<= 8;
-                       *value |= fake_pci_config[where + size];
-               }
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
-                                 unsigned int devfn,
-                                 int where, int size,
-                                 u32 value)
-{
-       return PCIBIOS_SUCCESSFUL;
-}
-
 struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm)
 {
        struct device_node *node = pbm->prom_node;
-       struct pci_dev *host_pdev;
        struct pci_bus *bus;
 
        printk("PCI: Scanning PBM %s\n", node->full_name);
@@ -855,10 +795,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm)
        bus->resource[0] = &pbm->io_space;
        bus->resource[1] = &pbm->mem_space;
 
-       /* Create the dummy host bridge and link it in.  */
-       host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1);
-       bus->self = host_pdev;
-
        pci_of_scan_bus(pbm, node, bus);
        pci_bus_add_devices(bus);
        pci_bus_register_of_sysfs(bus);
index 923e0bcc3bfdb0e65cdb6b957324957aa886040a..19fa621d6a60b0bb12fd8356fdc6933945bd5656 100644 (file)
@@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
        unsigned int func = PCI_FUNC(devfn);
        unsigned long ret;
 
-       if (!bus && devfn == 0x00)
-               return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
-                                                   size, value);
        if (config_out_of_range(pbm, bus, devfn, where)) {
                ret = ~0UL;
        } else {
@@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
        unsigned int func = PCI_FUNC(devfn);
        unsigned long ret;
 
-       if (!bus && devfn == 0x00)
-               return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
-                                                    size, value);
        if (config_out_of_range(pbm, bus, devfn, where)) {
                /* Do nothing. */
        } else {
index 218bac4ff79bdaf18fae0acb0d54e64e8ceae703..c385d126be1185240f3613e60cdf30f0d6365351 100644 (file)
@@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm);
 extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
 extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
 
-extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
-                                       unsigned int devfn,
-                                       int where, int size,
-                                       u32 *value);
-extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
-                                        unsigned int devfn,
-                                        int where, int size,
-                                        u32 value);
-
 /* Error reporting support. */
 extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
 extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *);
index 0560137491578b25b7aba3d1ce321d46ce0e8209..4129c0449856bbe61a34e670ec87996cd71bd19a 100644 (file)
@@ -503,6 +503,8 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
                              unsigned long stack_size)
 {
        int __user *parent_tid_ptr, *child_tid_ptr;
+       unsigned long orig_i1 = regs->u_regs[UREG_I1];
+       long ret;
 
 #ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
@@ -515,9 +517,19 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
                child_tid_ptr = (int __user *) regs->u_regs[UREG_I4];
        }
 
-       return do_fork(clone_flags, stack_start,
-                      regs, stack_size,
-                      parent_tid_ptr, child_tid_ptr);
+       ret = do_fork(clone_flags, stack_start,
+                     regs, stack_size,
+                     parent_tid_ptr, child_tid_ptr);
+
+       /* If we get an error and potentially restart the system
+        * call, we're screwed because copy_thread() clobbered
+        * the parent's %o1.  So detect that case and restore it
+        * here.
+        */
+       if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+               regs->u_regs[UREG_I1] = orig_i1;
+
+       return ret;
 }
 
 /* Copy a Sparc thread.  The fork() return value conventions
@@ -591,12 +603,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
        if (clone_flags & CLONE_SETTLS)
                t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3];
 
-       /* We do not want to accidently trigger system call restart
-        * handling in the new thread.  Therefore, clear out the trap
-        * type, which will make pt_regs_regs_is_syscall() return false.
-        */
-       pt_regs_clear_trap_type(t->kregs);
-
        return 0;
 }
 
index e9fc0aa2da386e8161a7a4badedb8f77b8ce7789..f6c9fc92921d4405693f6f23ab2817bdee3993fa 100644 (file)
@@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target,
                                         32 * sizeof(u64),
                                         33 * sizeof(u64));
                if (!ret) {
-                       /* Only the condition codes can be modified
-                        * in the %tstate register.
+                       /* Only the condition codes and the "in syscall"
+                        * state can be modified in the %tstate register.
                         */
-                       tstate &= (TSTATE_ICC | TSTATE_XCC);
-                       regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+                       tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+                       regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
                        regs->tstate |= tstate;
                }
        }
@@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target,
                switch (pos) {
                case 32: /* PSR */
                        tstate = regs->tstate;
-                       tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+                       tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
                        tstate |= psr_to_tstate_icc(reg);
+                       if (reg & PSR_SYSCALL)
+                               tstate |= TSTATE_SYSCALL;
                        regs->tstate = tstate;
                        break;
                case 33: /* PC */
@@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                break;
 
        default:
+               if (request == PTRACE_SPARC_DETACH)
+                       request = PTRACE_DETACH;
                ret = compat_ptrace_request(child, request, addr, data);
                break;
        }
@@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 
        default:
+               if (request == PTRACE_SPARC_DETACH)
+                       request = PTRACE_DETACH;
                ret = ptrace_request(child, request, addr, data);
                break;
        }
index ecf6753b204a07d2da8b5a9c1bad0bbc35995218..b9b785fd8b46d93be55c08042ce23155d8b9458f 100644 (file)
@@ -257,6 +257,7 @@ rt_continue:        ldx                     [%sp + PTREGS_OFF + PT_V9_G1], %g1
                wr                      %o3, %g0, %y
                wrpr                    %l4, 0x0, %pil
                wrpr                    %g0, 0x1, %tl
+               andn                    %l1, TSTATE_SYSCALL, %l1
                wrpr                    %l1, %g0, %tstate
                wrpr                    %l2, %g0, %tpc
                wrpr                    %o2, %g0, %tnpc
index f2d88d8f7a427e4ff01d2d3da5d0afbd0ed802ba..2378482c2aaba0299c1d61c0d44dc613c77aaa8b 100644 (file)
@@ -332,6 +332,9 @@ void do_rt_sigreturn(struct pt_regs *regs)
        regs->tpc = tpc;
        regs->tnpc = tnpc;
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_syscall(regs);
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sighand->siglock);
        current->blocked = set;
@@ -373,16 +376,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 
 static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
 {
-       unsigned long sp;
+       unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
 
-       sp = regs->u_regs[UREG_FP] + STACK_BIAS;
+       /*
+        * If we are on the alternate signal stack and would overflow it, don't.
+        * Return an always-bogus address instead so we will die with SIGSEGV.
+        */
+       if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+               return (void __user *) -1L;
 
        /* This is the X/Open sanctioned signal stack switching.  */
        if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (!on_sig_stack(sp) &&
-                   !((current->sas_ss_sp + current->sas_ss_size) & 7))
+               if (sas_ss_flags(sp) == 0)
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
+
+       /* Always align the stack frame.  This handles two cases.  First,
+        * sigaltstack need not be mindful of platform specific stack
+        * alignment.  Second, if we took this signal because the stack
+        * is not aligned properly, we'd like to take the signal cleanly
+        * and report that.
+        */
+       sp &= ~7UL;
+
        return (void __user *)(sp - framesize);
 }
 
@@ -483,7 +499,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
-                                    struct sigaction *sa)
+                                  struct sigaction *sa)
 {
        switch (regs->u_regs[UREG_I0]) {
        case ERESTART_RESTARTBLOCK:
@@ -509,18 +525,17 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
  */
 static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 {
-       struct signal_deliver_cookie cookie;
        struct k_sigaction ka;
+       int restart_syscall;
        sigset_t *oldset;
        siginfo_t info;
        int signr;
        
-       if (pt_regs_is_syscall(regs)) {
-               pt_regs_clear_trap_type(regs);
-               cookie.restart_syscall = 1;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               restart_syscall = 1;
        } else
-               cookie.restart_syscall = 0;
-       cookie.orig_i0 = orig_i0;
+               restart_syscall = 0;
 
        if (test_thread_flag(TIF_RESTORE_SIGMASK))
                oldset = &current->saved_sigmask;
@@ -530,16 +545,25 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 #ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
                extern void do_signal32(sigset_t *, struct pt_regs *,
-                                       struct signal_deliver_cookie *);
-               do_signal32(oldset, regs, &cookie);
+                                       int restart_syscall,
+                                       unsigned long orig_i0);
+               do_signal32(oldset, regs, restart_syscall, orig_i0);
                return;
        }
 #endif 
 
-       signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+       /* If the debugger messes with the program counter, it clears
+        * the software "in syscall" bit, directing us to not perform
+        * a syscall restart.
+        */
+       if (restart_syscall && !pt_regs_is_syscall(regs))
+               restart_syscall = 0;
+
        if (signr > 0) {
-               if (cookie.restart_syscall)
-                       syscall_restart(cookie.orig_i0, regs, &ka.sa);
+               if (restart_syscall)
+                       syscall_restart(orig_i0, regs, &ka.sa);
                handle_signal(signr, &ka, &info, oldset, regs);
 
                /* a signal was successfully delivered; the saved
@@ -551,16 +575,16 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
                        clear_thread_flag(TIF_RESTORE_SIGMASK);
                return;
        }
-       if (cookie.restart_syscall &&
+       if (restart_syscall &&
            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
             regs->u_regs[UREG_I0] == ERESTARTSYS ||
             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
                /* replay the system call when we are done */
-               regs->u_regs[UREG_I0] = cookie.orig_i0;
+               regs->u_regs[UREG_I0] = orig_i0;
                regs->tpc -= 4;
                regs->tnpc -= 4;
        }
-       if (cookie.restart_syscall &&
+       if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->tpc -= 4;
@@ -581,26 +605,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
        if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
                do_signal(regs, orig_i0);
 }
-
-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
-{
-       struct signal_deliver_cookie *cp = cookie;
-
-       if (cp->restart_syscall &&
-           (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-            regs->u_regs[UREG_I0] == ERESTARTSYS ||
-            regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-               /* replay the system call when we are done */
-               regs->u_regs[UREG_I0] = cp->orig_i0;
-               regs->tpc -= 4;
-               regs->tnpc -= 4;
-               cp->restart_syscall = 0;
-       }
-       if (cp->restart_syscall &&
-           regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-               regs->u_regs[UREG_G1] = __NR_restart_syscall;
-               regs->tpc -= 4;
-               regs->tnpc -= 4;
-               cp->restart_syscall = 0;
-       }
-}
index 91f8d0826db1084b0abb8c7206431406c9108f23..3f19e9af3d1bf9d02a90c967ad38d9cad418703f 100644 (file)
@@ -268,6 +268,9 @@ void do_sigreturn32(struct pt_regs *regs)
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
        regs->tstate |= psr_to_tstate_icc(psr);
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_syscall(regs);
+
        err |= __get_user(fpu_save, &sf->fpu_save);
        if (fpu_save)
                err |= restore_fpu_state32(regs, &sf->fpu_state);
@@ -351,6 +354,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
        regs->tstate |= psr_to_tstate_icc(psr);
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_syscall(regs);
+
        err |= __get_user(fpu_save, &sf->fpu_save);
        if (fpu_save)
                err |= restore_fpu_state32(regs, &sf->fpu_state);
@@ -400,11 +406,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
        sp = regs->u_regs[UREG_FP];
        
+       /*
+        * If we are on the alternate signal stack and would overflow it, don't.
+        * Return an always-bogus address instead so we will die with SIGSEGV.
+        */
+       if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+               return (void __user *) -1L;
+
        /* This is the X/Open sanctioned signal stack switching.  */
        if (sa->sa_flags & SA_ONSTACK) {
-               if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
+               if (sas_ss_flags(sp) == 0)
                        sp = current->sas_ss_sp + current->sas_ss_size;
        }
+
+       /* Always align the stack frame.  This handles two cases.  First,
+        * sigaltstack need not be mindful of platform specific stack
+        * alignment.  Second, if we took this signal because the stack
+        * is not aligned properly, we'd like to take the signal cleanly
+        * and report that.
+        */
+       sp &= ~7UL;
+
        return (void __user *)(sp - framesize);
 }
 
@@ -746,16 +768,24 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
  * mistake.
  */
 void do_signal32(sigset_t *oldset, struct pt_regs * regs,
-                struct signal_deliver_cookie *cookie)
+                int restart_syscall, unsigned long orig_i0)
 {
        struct k_sigaction ka;
        siginfo_t info;
        int signr;
        
-       signr = get_signal_to_deliver(&info, &ka, regs, cookie);
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+       /* If the debugger messes with the program counter, it clears
+        * the "in syscall" bit, directing us to not perform a syscall
+        * restart.
+        */
+       if (restart_syscall && !pt_regs_is_syscall(regs))
+               restart_syscall = 0;
+
        if (signr > 0) {
-               if (cookie->restart_syscall)
-                       syscall_restart32(cookie->orig_i0, regs, &ka.sa);
+               if (restart_syscall)
+                       syscall_restart32(orig_i0, regs, &ka.sa);
                handle_signal32(signr, &ka, &info, oldset, regs);
 
                /* a signal was successfully delivered; the saved
@@ -767,16 +797,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
                        clear_thread_flag(TIF_RESTORE_SIGMASK);
                return;
        }
-       if (cookie->restart_syscall &&
+       if (restart_syscall &&
            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
             regs->u_regs[UREG_I0] == ERESTARTSYS ||
             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
                /* replay the system call when we are done */
-               regs->u_regs[UREG_I0] = cookie->orig_i0;
+               regs->u_regs[UREG_I0] = orig_i0;
                regs->tpc -= 4;
                regs->tnpc -= 4;
        }
-       if (cookie->restart_syscall &&
+       if (restart_syscall &&
            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
                regs->u_regs[UREG_G1] = __NR_restart_syscall;
                regs->tpc -= 4;
index 3aba47624df45aa0e773c169fe6498b5bb5e377e..0d6403a630acd1f4c2e22201755d67de04a83cc1 100644 (file)
@@ -865,21 +865,14 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
        void *info = call_data->info;
 
        clear_softint(1 << irq);
-
-       irq_enter();
-
-       if (!call_data->wait) {
-               /* let initiator proceed after getting data */
-               atomic_inc(&call_data->finished);
-       }
-
-       func(info);
-
-       irq_exit();
-
        if (call_data->wait) {
                /* let initiator proceed only after completion */
+               func(info);
                atomic_inc(&call_data->finished);
+       } else {
+               /* let initiator proceed after getting data */
+               atomic_inc(&call_data->finished);
+               func(info);
        }
 }
 
@@ -1041,9 +1034,7 @@ void smp_receive_signal(int cpu)
 
 void smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
-       irq_enter();
        clear_softint(1 << irq);
-       irq_exit();
 }
 
 void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
@@ -1051,8 +1042,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
        struct mm_struct *mm;
        unsigned long flags;
 
-       irq_enter();
-
        clear_softint(1 << irq);
 
        /* See if we need to allocate a new TLB context because
@@ -1072,8 +1061,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
        load_secondary_context(mm);
        __flush_tlb_mm(CTX_HWBITS(mm->context),
                       SECONDARY_CONTEXT);
-
-       irq_exit();
 }
 
 void smp_new_mmu_context_version(void)
@@ -1239,8 +1226,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 
-       irq_enter();
-
        preempt_disable();
 
        __asm__ __volatile__("flushw");
@@ -1253,8 +1238,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
        prom_world(0);
 
        preempt_enable();
-
-       irq_exit();
 }
 
 /* /proc/profile writes can call this, don't __init it please. */
index 8d4761f15fa932cdede6dc4dc4336fdaa2b1cc88..0dbc941f130e6f8163422b0e42306bc68d226162 100644 (file)
@@ -549,13 +549,13 @@ int sparc64_mmap_check(unsigned long addr, unsigned long len,
                if (len >= STACK_TOP32)
                        return -EINVAL;
 
-               if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
+               if (addr > STACK_TOP32 - len)
                        return -EINVAL;
        } else {
                if (len >= VA_EXCLUDE_START)
                        return -EINVAL;
 
-               if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
+               if (invalid_64bit_range(addr, len))
                        return -EINVAL;
        }
 
index 161ce4710fe76143326905011db732358de7c891..1aa4288125f25906eb5fddea19ddeff3c6bac493 100644 (file)
@@ -236,13 +236,6 @@ asmlinkage long sys32_getegid16(void)
 
 /* 32-bit timeval and related flotsam.  */
 
-static long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-       return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-               (__get_user(o->tv_sec, &i->tv_sec) |
-                __get_user(o->tv_usec, &i->tv_usec)));
-}
-
 static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
        return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
@@ -757,30 +750,6 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
        return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
-asmlinkage long sys32_utimes(char __user *filename,
-                            struct compat_timeval __user *tvs)
-{
-       struct timespec tv[2];
-
-       if (tvs) {
-               struct timeval ktvs[2];
-               if (get_tv32(&ktvs[0], tvs) ||
-                   get_tv32(&ktvs[1], 1+tvs))
-                       return -EFAULT;
-
-               if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
-                   ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
-                       return -EINVAL;
-
-               tv[0].tv_sec = ktvs[0].tv_sec;
-               tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
-               tv[1].tv_sec = ktvs[1].tv_sec;
-               tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
-       }
-
-       return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);
-}
-
 /* These are here just in case some old sparc32 binary calls it. */
 asmlinkage long sys32_pause(void)
 {
index a4fef2ba1ae162848d801034f7cf18008b10b8de..8b5282d433c44b6c1d04ebaf525cda6470b9a9f2 100644 (file)
@@ -45,7 +45,7 @@ sys_call_table32:
 /*120*/        .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
        .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
 /*130*/        .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
-       .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64
+       .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
 /*140*/        .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
        .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
 /*150*/        .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
index 4cad0b32b0afcd5256dce395a1ce6e682c50715c..a9828d748e2c1e9db4772497e63465ed82e94fe6 100644 (file)
@@ -610,8 +610,6 @@ static void __init remap_kernel(void)
 
 static void __init inherit_prom_mappings(void)
 {
-       read_obp_translations();
-
        /* Now fixup OBP's idea about where we really are mapped. */
        printk("Remapping the kernel... ");
        remap_kernel();
@@ -771,6 +769,9 @@ static void __init find_ramdisk(unsigned long phys_base)
                initrd_end = ramdisk_image + sparc_ramdisk_size;
 
                lmb_reserve(initrd_start, initrd_end);
+
+               initrd_start += PAGE_OFFSET;
+               initrd_end += PAGE_OFFSET;
        }
 #endif
 }
@@ -1744,7 +1745,17 @@ void __init paging_init(void)
 
        lmb_init();
 
-       /* Find available physical memory... */
+       /* Find available physical memory...
+        *
+        * Read it twice in order to work around a bug in openfirmware.
+        * The call to grab this table itself can cause openfirmware to
+        * allocate memory, which in turn can take away some space from
+        * the list of available memory.  Reading it twice makes sure
+        * we really do get the final value.
+        */
+       read_obp_translations();
+       read_obp_memory("reg", &pall[0], &pall_ents);
+       read_obp_memory("available", &pavail[0], &pavail_ents);
        read_obp_memory("available", &pavail[0], &pavail_ents);
 
        phys_base = 0xffffffffffffffffUL;
@@ -1785,8 +1796,6 @@ void __init paging_init(void)
        
        inherit_prom_mappings();
        
-       read_obp_memory("reg", &pall[0], &pall_ents);
-
        init_kpte_bitmap();
 
        /* Ok, we can use our TLB miss and window trap handlers safely.  */
@@ -2362,16 +2371,3 @@ void __flush_tlb_all(void)
        __asm__ __volatile__("wrpr      %0, 0, %%pstate"
                             : : "r" (pstate));
 }
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-
-void online_page(struct page *page)
-{
-       ClearPageReserved(page);
-       init_page_count(page);
-       __free_page(page);
-       totalram_pages++;
-       num_physpages++;
-}
-
-#endif /* CONFIG_MEMORY_HOTPLUG */
index 3a4b396d7979916177b30d5689b759d277eafe35..1b238ebae6b39973cbf7d57b0d7dbe8a40f49a06 100644 (file)
@@ -145,14 +145,14 @@ config LEGACY_PTYS
          systems, it is safe to say N.
 
 config RAW_DRIVER
-        tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+        tristate "RAW driver (/dev/raw/rawN)"
+       depends on BLOCK
         help
           The raw driver permits block devices to be bound to /dev/raw/rawN.
           Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
           See the raw(8) manpage for more details.
 
-          The raw driver is deprecated and will be removed soon.
-          Applications should simply open the device (eg /dev/hda1)
+          Applications should preferably open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
 config MAX_RAW_DEVS
index 025764089ac8ea7b739652c827fbe88b3a400324..cfeb3f4a44afc0ef9cb6a5edf5e08d0d81ec32a1 100644 (file)
@@ -11,6 +11,7 @@
 #include <termios.h>
 #include <sys/ioctl.h>
 #include "chan_user.h"
+#include "kern_constants.h"
 #include "os.h"
 #include "um_malloc.h"
 #include "user.h"
index ca8c9e11a39b9f94361b10c6739e8712ec3a932c..f5701fd2ef90b2d8d1964c3222ebb155c2594ec1 100644 (file)
@@ -8,7 +8,7 @@
 
 static inline void *cow_malloc(int size)
 {
-       return kmalloc(size, UM_GFP_KERNEL);
+       return uml_kmalloc(size, UM_GFP_KERNEL);
 }
 
 static inline void cow_free(void *ptr)
index f23c109a055c865e9e5aac0337a2afed17c96888..f8e85e0bdace20fddc82ca805e6101bcc9c76a8d 100644 (file)
@@ -34,7 +34,7 @@ static struct sockaddr_un *new_addr(void *name, int len)
 {
        struct sockaddr_un *sun;
 
-       sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+       sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
        if (sun == NULL) {
                printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
                       "failed\n");
@@ -83,7 +83,7 @@ static int connect_to_switch(struct daemon_data *pri)
                goto out_close;
        }
 
-       sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+       sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
        if (sun == NULL) {
                printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
                       "failed\n");
index 0a2bb5b64b82e8ca5bc66c0d76e06cab0e818ed6..f5a981a16240e4d8dd92afca3fb710d9d4d84588 100644 (file)
@@ -40,7 +40,7 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
                return NULL;
        }
 
-       data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+       data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
        if (data == NULL)
                return NULL;
 
index ff1b22b69e9c73fb56f842ba367c814c423508af..368219cc2366d666ca92e0ac38497f111d888501 100644 (file)
@@ -154,7 +154,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
        case SNDCTL_DSP_SUBDIVIDE:
        case SNDCTL_DSP_SETFRAGMENT:
                if (get_user(data, (int __user *) arg))
-                       return EFAULT;
+                       return -EFAULT;
                break;
        default:
                break;
index 10b86e1cc659ee8ca02bee67c2e931067eef8de2..5047490fc299aa69ae999b348760277767684569 100644 (file)
@@ -191,9 +191,9 @@ void line_flush_chars(struct tty_struct *tty)
        line_flush_buffer(tty);
 }
 
-void line_put_char(struct tty_struct *tty, unsigned char ch)
+int line_put_char(struct tty_struct *tty, unsigned char ch)
 {
-       line_write(tty, &ch, sizeof(ch));
+       return line_write(tty, &ch, sizeof(ch));
 }
 
 int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
index 5f647d7a7292946dfdd36fecf0759198802c35a7..ee19e91568a2585765127970fc9d1ba821bcc613 100644 (file)
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <netinet/in.h>
+#include "kern_constants.h"
 #include "mcast.h"
 #include "net_user.h"
 #include "um_malloc.h"
@@ -24,7 +25,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
 {
        struct sockaddr_in *sin;
 
-       sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+       sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
        if (sin == NULL) {
                printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
                       "failed\n");
index abf2653f5517cbf6f65b851dd10455e7bc8e27e2..9415dd9e63ef1e98c15505733c3ba1c1eff02029 100644 (file)
@@ -222,7 +222,7 @@ static void change(char *dev, char *what, unsigned char *addr,
                netmask[2], netmask[3]);
 
        output_len = UM_KERN_PAGE_SIZE;
-       output = kmalloc(output_len, UM_GFP_KERNEL);
+       output = uml_kmalloc(output_len, UM_GFP_KERNEL);
        if (output == NULL)
                printk(UM_KERN_ERR "change : failed to allocate output "
                       "buffer\n");
index d269ca387f108de63595a5bf46085864668537e6..b49bf56a56aa4a7b0b94a2b3709c972a144302f4 100644 (file)
@@ -47,7 +47,7 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
        if (kern_data == NULL)
                return NULL;
 
-       data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+       data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
        if (data == NULL)
                goto err;
 
index 49c79dda6046492fc936c4c921a04d71d7584c2b..1113911dcb2bfb70696785ac194089705c9c8693 100644 (file)
@@ -29,7 +29,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
 {
        struct pty_chan *data;
 
-       data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+       data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
        if (data == NULL)
                return NULL;
 
index 71f0959c15357b4587cd10c816d3eca1db1fbe92..4949044773ba78b93797d43701ab751b0a1bce23 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Copyright (C) 2005 - 2008 Jeff Dike <jdike@{linux.intel,addtoit}.com> */
+
 /* Much of this ripped from drivers/char/hw_random.c, see there for other
  * copyright.
  *
@@ -8,16 +9,18 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/interrupt.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
+#include "irq_kern.h"
 #include "os.h"
 
 /*
  * core module and version information
  */
 #define RNG_VERSION "1.0.0"
-#define RNG_MODULE_NAME "random"
+#define RNG_MODULE_NAME "hw_random"
 
 #define RNG_MISCDEV_MINOR              183 /* official */
 
  * protects against a module being loaded twice at the same time.
  */
 static int random_fd = -1;
+static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
 {
        /* enforce read-only access to this chrdev */
        if ((filp->f_mode & FMODE_READ) == 0)
                return -EINVAL;
-       if (filp->f_mode & FMODE_WRITE)
+       if ((filp->f_mode & FMODE_WRITE) != 0)
                return -EINVAL;
 
        return 0;
 }
 
+static atomic_t host_sleep_count = ATOMIC_INIT(0);
+
 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
-                             loff_t * offp)
+                            loff_t *offp)
 {
-        u32 data;
-        int n, ret = 0, have_data;
-
-        while(size){
-                n = os_read_file(random_fd, &data, sizeof(data));
-                if(n > 0){
-                        have_data = n;
-                        while (have_data && size) {
-                                if (put_user((u8)data, buf++)) {
-                                        ret = ret ? : -EFAULT;
-                                        break;
-                                }
-                                size--;
-                                ret++;
-                                have_data--;
-                                data>>=8;
-                        }
-                }
-                else if(n == -EAGAIN){
-                        if (filp->f_flags & O_NONBLOCK)
-                                return ret ? : -EAGAIN;
-
-                        if(need_resched())
-                                schedule_timeout_interruptible(1);
-                }
-                else return n;
+       u32 data;
+       int n, ret = 0, have_data;
+
+       while (size) {
+               n = os_read_file(random_fd, &data, sizeof(data));
+               if (n > 0) {
+                       have_data = n;
+                       while (have_data && size) {
+                               if (put_user((u8) data, buf++)) {
+                                       ret = ret ? : -EFAULT;
+                                       break;
+                               }
+                               size--;
+                               ret++;
+                               have_data--;
+                               data >>= 8;
+                       }
+               }
+               else if (n == -EAGAIN) {
+                       DECLARE_WAITQUEUE(wait, current);
+
+                       if (filp->f_flags & O_NONBLOCK)
+                               return ret ? : -EAGAIN;
+
+                       atomic_inc(&host_sleep_count);
+                       reactivate_fd(random_fd, RANDOM_IRQ);
+                       add_sigio_fd(random_fd);
+
+                       add_wait_queue(&host_read_wait, &wait);
+                       set_task_state(current, TASK_INTERRUPTIBLE);
+
+                       schedule();
+                       set_task_state(current, TASK_RUNNING);
+                       remove_wait_queue(&host_read_wait, &wait);
+
+                       if (atomic_dec_and_test(&host_sleep_count)) {
+                               ignore_sigio_fd(random_fd);
+                               deactivate_fd(random_fd, RANDOM_IRQ);
+                       }
+               }
+               else
+                       return n;
+
                if (signal_pending (current))
                        return ret ? : -ERESTARTSYS;
        }
@@ -86,6 +109,13 @@ static struct miscdevice rng_miscdev = {
        &rng_chrdev_ops,
 };
 
+static irqreturn_t random_interrupt(int irq, void *data)
+{
+       wake_up(&host_read_wait);
+
+       return IRQ_HANDLED;
+}
+
 /*
  * rng_init - initialize RNG module
  */
@@ -93,28 +123,33 @@ static int __init rng_init (void)
 {
        int err;
 
-        err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
-        if(err < 0)
-                goto out;
+       err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
+       if (err < 0)
+               goto out;
 
-        random_fd = err;
+       random_fd = err;
 
-        err = os_set_fd_block(random_fd, 0);
-        if(err)
+       err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
+                            IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
+                            NULL);
+       if (err)
                goto err_out_cleanup_hw;
 
+       sigio_broken(random_fd, 1);
+
        err = misc_register (&rng_miscdev);
        if (err) {
-               printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
+               printk (KERN_ERR RNG_MODULE_NAME ": misc device register "
+                       "failed\n");
                goto err_out_cleanup_hw;
        }
+out:
+       return err;
 
- out:
-        return err;
-
- err_out_cleanup_hw:
-        random_fd = -1;
-        goto out;
+err_out_cleanup_hw:
+       os_close_file(random_fd);
+       random_fd = -1;
+       goto out;
 }
 
 /*
@@ -122,6 +157,7 @@ static int __init rng_init (void)
  */
 static void __exit rng_cleanup (void)
 {
+       os_close_file(random_fd);
        misc_deregister (&rng_miscdev);
 }
 
index 8b80505a3fb0117ed35676de600cce0b11b2f721..a1c2d2c98a942b9798994444f00501ddd5678132 100644 (file)
@@ -96,7 +96,7 @@ static int slip_tramp(char **argv, int fd)
        pid = err;
 
        output_len = UM_KERN_PAGE_SIZE;
-       output = kmalloc(output_len, UM_GFP_KERNEL);
+       output = uml_kmalloc(output_len, UM_GFP_KERNEL);
        if (output == NULL) {
                printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
                       "buffer\n");
index c930fedc517235979c72989826a1f552f6454279..495858a090e4f49e50d4a79db016173ea4b3a6df 100644 (file)
@@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
        }
        str++;
 
-       data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+       data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
        if (data == NULL)
                return NULL;
        *data = ((struct tty_chan) { .dev       = str,
index 5e45e39a8a8db5a5c57e4f27162804773c465c9e..44ad1607be2dc0d0d14d6a7d8539ffce94c452d7 100644 (file)
@@ -1178,8 +1178,8 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
         * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
         * for the original diagnosis.
         */
-       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
-                          sizeof(unsigned long) - 1))
+       if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
+                                        sizeof(unsigned long)) - 1))
                (*cow_offset)--;
 
        bitmap_words[0] = bitmap[*cow_offset];
index 8a1c18a9b2406e678e820fd7ccc6ba979da8079a..da2caa5a21efa91333ffd44c9c7743b467ec3f26 100644 (file)
@@ -30,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
 {
        struct xterm_chan *data;
 
-       data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+       data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
        if (data == NULL)
                return NULL;
        *data = ((struct xterm_chan) { .pid             = -1,
index cac542d8ff70783d10a153b6dd342852004cdf25..58e852dfb0ce95ff1e6877eaa549c2200b50e620 100644 (file)
  */
 
 #ifdef __ASSEMBLY__
-#define _AC(X, Y)      (Y)
+#define _UML_AC(X, Y)  (Y)
 #else
-#define __AC(X, Y)     (X (Y))
-#define _AC(X, Y)      __AC(X, Y)
+#define __UML_AC(X, Y) (X(Y))
+#define _UML_AC(X, Y)  __UML_AC(X, Y)
 #endif
 
-#define STUB_START _AC(, 0x100000)
-#define STUB_CODE _AC((unsigned long), STUB_START)
-#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
-#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
+#define STUB_START _UML_AC(, 0x100000)
+#define STUB_CODE _UML_AC((unsigned long), STUB_START)
+#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
+#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
 
index 1223f2c844b4085c798e79400419bcb718dc979c..311a0d3d93af2302224e9b9d6b76614643a23a67 100644 (file)
@@ -58,11 +58,11 @@ struct line {
 };
 
 #define LINE_INIT(str, d) \
-       { .count_lock = SPIN_LOCK_UNLOCKED, \
+       { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \
          .init_str =   str,    \
          .init_pri =   INIT_STATIC, \
          .valid =      1, \
-         .lock =       SPIN_LOCK_UNLOCKED, \
+         .lock =       __SPIN_LOCK_UNLOCKED((str).lock), \
          .driver =     d }
 
 extern void line_close(struct tty_struct *tty, struct file * filp);
@@ -71,7 +71,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines,
                      char *init, char **error_out);
 extern int line_write(struct tty_struct *tty, const unsigned char *buf,
                      int len);
-extern void line_put_char(struct tty_struct *tty, unsigned char ch);
+extern int line_put_char(struct tty_struct *tty, unsigned char ch);
 extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
 extern int line_chars_in_buffer(struct tty_struct *tty);
 extern void line_flush_buffer(struct tty_struct *tty);
index 32c799e3a495729cad00c48f7bc5da0cd03b925c..e2716ac8889accd7f33ca8d381f014d3b1bd7283 100644 (file)
@@ -290,6 +290,7 @@ extern void os_set_ioignore(void);
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
+extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
 extern int os_arch_prctl(int pid, int code, unsigned long *addr);
index 5af9157ff54fb0e300350bff1678340167d08848..bb873a51262e5a6707ae434e478b9bc13cbfe413 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
@@ -8,18 +8,10 @@
 
 #include <signal.h>
 
-extern void sig_handler(int sig, struct sigcontext sc);
-extern void alarm_handler(int sig, struct sigcontext sc);
+/* Copied from linux/compiler-gcc.h since we can't include it directly */
+#define barrier() __asm__ __volatile__("": : :"memory")
 
-#endif
+extern void sig_handler(int sig, struct sigcontext *sc);
+extern void alarm_handler(int sig, struct sigcontext *sc);
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
index cd2327d09c8dfe669732182bf7e4e8537a2e6482..3d31bbacd016c910bfcc311892a0f7789bdae8e8 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
 #include "sysdep/skas_ptrace.h"
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 75650723c38f15506144d12f5cfedfb0f63a8072..ef56247e414305f66824a954ee8ede30065e26b5 100644 (file)
 #define PT_SP_OFFSET PT_OFFSET(UESP)
 #define PT_SP(regs) ((regs)[UESP])
 
-#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
+#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE)
 
 #ifndef FRAME_SIZE
 #define FRAME_SIZE (17)
 #endif
-#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
-
-#define FP_FRAME_SIZE (27)
-#define FPX_FRAME_SIZE (128)
-
-#ifdef PTRACE_GETREGS
-#define UM_HAVE_GETREGS
-#endif
-
-#ifdef PTRACE_SETREGS
-#define UM_HAVE_SETREGS
-#endif
-
-#ifdef PTRACE_GETFPREGS
-#define UM_HAVE_GETFPREGS
-#endif
-
-#ifdef PTRACE_SETFPREGS
-#define UM_HAVE_SETFPREGS
-#endif
-
-#ifdef PTRACE_GETFPXREGS
-#define UM_HAVE_GETFPXREGS
-#endif
-
-#ifdef PTRACE_SETFPXREGS
-#define UM_HAVE_SETFPXREGS
-#endif
 
 #endif
index 67e77122aa45f42ba7f718d73e84907b065e4d76..f583c87111a0ca9a0a0e515539dc84fe95e8236e 100644 (file)
@@ -10,7 +10,7 @@
 
 #define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
 
-#define GET_FAULTINFO_FROM_SC(fi,sc) \
+#define GET_FAULTINFO_FROM_SC(fi, sc) \
        { \
                (fi).cr2 = SC_CR2(sc); \
                (fi).error_code = SC_ERR(sc); \
index 45c0bd881cb3a36b64b657ee9090ee8a0bdf3b5a..4dbccdb58f48980fe164bde4c65ee3d89c7d6b9b 100644 (file)
@@ -48,7 +48,8 @@
 #define PT_ORIG_RAX_OFFSET (ORIG_RAX)
 #define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
 
-/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+/*
+ * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
  * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
  * 2.4 name and value for 2.4 host compatibility.
  */
@@ -56,7 +57,8 @@
 #define PTRACE_OLDSETOPTIONS 21
 #endif
 
-/* These are before the system call, so the system call number is RAX
+/*
+ * These are before the system call, so the system call number is RAX
  * rather than ORIG_RAX, and arg4 is R10 rather than RCX
  */
 #define REGS_SYSCALL_NR PT_INDEX(RAX)
 #define FP_SIZE (HOST_FP_SIZE)
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 0ad17cb83d96ef6b0ace0a4ea800113a8cc05040..c554d706d1060b9a1e9502f33525a23c64aed60b 100644 (file)
@@ -8,15 +8,12 @@
 
 #include "kern_constants.h"
 
-extern void *__kmalloc(int size, int flags);
-static inline void *kmalloc(int size, int flags)
-{
-       return __kmalloc(size, flags);
-}
-
+extern void *uml_kmalloc(int size, int flags);
 extern void kfree(const void *ptr);
 
 extern void *vmalloc(unsigned long size);
 extern void vfree(void *ptr);
 
 #endif /* __UM_MALLOC_H__ */
+
+
index 26090b7f323ecf3806f0a86668250ebad253bc6f..9975e1ab44fb38aa71c720e70170eceee8c91198 100644 (file)
@@ -1,4 +1,5 @@
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT(ELF_FORMAT)
 OUTPUT_ARCH(ELF_ARCH)
@@ -21,7 +22,7 @@ SECTIONS
        _einittext = .;
   }
 
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
 
   /* Read-only sections, merged into text segment: */
   .hash           : { *(.hash) }
@@ -68,9 +69,9 @@ SECTIONS
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
 
-    . = ALIGN(4096);
+    . = ALIGN(PAGE_SIZE);
   } =0x90909090
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   .syscall_stub : {
        __syscall_stub_start = .;
        *(.__syscall_stub*)
index 2eea1ff235e6c2cac17b80fdc343f2a9394f52d4..b0ee64622ff70a91bc3a44d52965b402dfaa81c1 100644 (file)
@@ -375,3 +375,8 @@ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
        return pmd;
 }
 #endif
+
+void *uml_kmalloc(int size, int flags)
+{
+       return kmalloc(size, flags);
+}
index 9cffc628a37e0f9505f6da9a8283eaf0ee368e2f..128ee85bc8d96b78522fb7f1043a913ec0e9d269 100644 (file)
@@ -73,23 +73,6 @@ long old_mmap(unsigned long addr, unsigned long len,
  out:
        return err;
 }
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-long sys_pipe(unsigned long __user * fildes)
-{
-       int fd[2];
-       long error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, sizeof(fd)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 
 long sys_uname(struct old_utsname __user * name)
 {
index 0d0cea2ac98d5df30a308aa4468b14db3f7f681b..c3e2f369c33cae2af0c682eb5a9a32a03781e056 100644 (file)
@@ -75,7 +75,7 @@ static irqreturn_t um_timer(int irq, void *dev)
 
 static cycle_t itimer_read(void)
 {
-       return os_nsecs();
+       return os_nsecs() / 1000;
 }
 
 static struct clocksource itimer_clocksource = {
@@ -83,7 +83,7 @@ static struct clocksource itimer_clocksource = {
        .rating         = 300,
        .read           = itimer_read,
        .mask           = CLOCKSOURCE_MASK(64),
-       .mult           = 1,
+       .mult           = 1000,
        .shift          = 0,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
index 56deed623446bd0726e2e7408d6f6bbc687df2b0..9db85b2ce6987141f314ea0dcc8ddc7f8960cdeb 100644 (file)
@@ -150,7 +150,7 @@ __uml_setup("root=", uml_root_setup,
 static int __init no_skas_debug_setup(char *line, int *add)
 {
        printf("'debug' is not necessary to gdb UML in skas mode - run \n");
-       printf("'gdb linux'");
+       printf("'gdb linux'\n");
 
        return 0;
 }
@@ -258,6 +258,7 @@ int __init linux_main(int argc, char **argv)
 {
        unsigned long avail, diff;
        unsigned long virtmem_size, max_physmem;
+       unsigned long stack;
        unsigned int i;
        int add;
        char * mode;
@@ -348,7 +349,9 @@ int __init linux_main(int argc, char **argv)
        }
 
        virtmem_size = physmem_size;
-       avail = TASK_SIZE - start_vm;
+       stack = (unsigned long) argv;
+       stack &= ~(1024 * 1024 - 1);
+       avail = stack - start_vm;
        if (physmem_size > avail)
                virtmem_size = avail;
        end_vm = start_vm + virtmem_size;
index 5828c1d54505f7fa0603c86a1b819fd52e528e7a..11b835248b865338f025a88d40a2c276ad3b7d88 100644 (file)
@@ -1,4 +1,5 @@
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT(ELF_FORMAT)
 OUTPUT_ARCH(ELF_ARCH)
@@ -26,7 +27,7 @@ SECTIONS
        INIT_TEXT
        _einittext = .;
   }
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
 
   .text      :
   {
@@ -39,7 +40,7 @@ SECTIONS
     *(.gnu.linkonce.t*)
   }
 
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   .syscall_stub : {
        __syscall_stub_start = .;
        *(.__syscall_stub*)
@@ -79,7 +80,7 @@ SECTIONS
   .sdata     : { *(.sdata) }
   _edata  =  .;
   PROVIDE (edata = .);
-  . = ALIGN(0x1000);
+  . = ALIGN(PAGE_SIZE);
   .sbss      :
   {
    __bss_start = .;
index 6fb0b174f538df06711bf0f5b779f62ea4eb1f63..cc72cb2c1af61302ff98cc88516d0889dad40829 100644 (file)
@@ -52,7 +52,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
                return;
        }
 
-       output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+       output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
        if (output == NULL)
                printk(UM_KERN_ERR "etap_change : Failed to allocate output "
                       "buffer\n");
@@ -165,7 +165,7 @@ static int etap_open(void *data)
        err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
                         control_fds[1], data_fds[0], data_fds[1]);
        output_len = UM_KERN_PAGE_SIZE;
-       output = kmalloc(output_len, UM_GFP_KERNEL);
+       output = uml_kmalloc(output_len, UM_GFP_KERNEL);
        read_output(control_fds[0], output, output_len);
 
        if (output == NULL)
index f25c29a12d007676d736ed8b8fcb9c9e47a0eaed..74ca7aabf4e17374e8a38026b07b40b85580af76 100644 (file)
@@ -71,8 +71,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
        data.pre_data = pre_data;
        data.argv = argv;
        data.fd = fds[1];
-       data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
-                                       kmalloc(PATH_MAX, UM_GFP_KERNEL);
+       data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+                                       uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
        pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
        if (pid < 0) {
                ret = -errno;
index abb9b0ffd9600402e770d93fce945c9b0295b98b..eee69b9f52c92bfd355303fd72b5afbf70502d7e 100644 (file)
@@ -199,7 +199,7 @@ void *__wrap_malloc(int size)
                return __real_malloc(size);
        else if (size <= UM_KERN_PAGE_SIZE)
                /* finding contiguous pages can be hard*/
-               ret = kmalloc(size, UM_GFP_KERNEL);
+               ret = uml_kmalloc(size, UM_GFP_KERNEL);
        else ret = vmalloc(size);
 
        /*
index abf47a7c4abd795c039f4c98136163819adb92a4..eb8f2e4be1929c8f731b8349bbf161afea27c751 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
@@ -15,6 +15,7 @@
 #include "kern_util.h"
 #include "init.h"
 #include "os.h"
+#include "process.h"
 #include "sigio.h"
 #include "um_malloc.h"
 #include "user.h"
@@ -109,7 +110,7 @@ static int need_poll(struct pollfds *polls, int n)
        if (n <= polls->size)
                return 0;
 
-       new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
+       new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
        if (new == NULL) {
                printk(UM_KERN_ERR "need_poll : failed to allocate new "
                       "pollfds\n");
@@ -243,7 +244,7 @@ static struct pollfd *setup_initial_poll(int fd)
 {
        struct pollfd *p;
 
-       p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
+       p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
        if (p == NULL) {
                printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
                       "poll\n");
@@ -338,20 +339,10 @@ out_close1:
        close(l_write_sigio_fds[1]);
 }
 
-/* Changed during early boot */
-static int pty_output_sigio = 0;
-static int pty_close_sigio = 0;
-
-void maybe_sigio_broken(int fd, int read)
+void sigio_broken(int fd, int read)
 {
        int err;
 
-       if (!isatty(fd))
-               return;
-
-       if ((read || pty_output_sigio) && (!read || pty_close_sigio))
-               return;
-
        write_sigio_workaround();
 
        sigio_lock();
@@ -370,6 +361,21 @@ out:
        sigio_unlock();
 }
 
+/* Changed during early boot */
+static int pty_output_sigio;
+static int pty_close_sigio;
+
+void maybe_sigio_broken(int fd, int read)
+{
+       if (!isatty(fd))
+               return;
+
+       if ((read || pty_output_sigio) && (!read || pty_close_sigio))
+               return;
+
+       sigio_broken(fd, read);
+}
+
 static void sigio_cleanup(void)
 {
        if (write_sigio_pid == -1)
@@ -383,7 +389,7 @@ static void sigio_cleanup(void)
 __uml_exitcall(sigio_cleanup);
 
 /* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
+static int got_sigio;
 
 static void __init handler(int sig)
 {
@@ -498,7 +504,8 @@ static void tty_output(int master, int slave)
        if (errno != EAGAIN)
                printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
                       errno);
-       while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
+       while (((n = read(slave, buf, sizeof(buf))) > 0) &&
+              !({ barrier(); got_sigio; }))
                ;
 
        if (got_sigio) {
index 3f1694b134cb2606efa628deb4291c5813a549c0..5aade6027e40e71f78ae1c49d5253a2a79bcc534 100644 (file)
@@ -12,6 +12,7 @@
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
+#include "process.h"
 #include "sysdep/barrier.h"
 #include "sysdep/sigcontext.h"
 #include "user.h"
index 1e8cba6550a99824df296e468747fabc109d6d44..6be028ca1817cfa0cab378ad0a49816798040b7b 100644 (file)
@@ -442,7 +442,7 @@ void userspace(struct uml_pt_regs *regs)
                                unblock_signals();
                                break;
                        default:
-                               printk(UM_KERN_ERR "userspace - child stopped "
+                               printk(UM_KERN_ERR "userspace - child stopped "
                                       "with signal %d\n", sig);
                                fatal_sigsegv();
                        }
index 997d01944f91d5c84e4778c59b1ac429c814b4bb..b4b36e0f2e8960d3d195d9617576fe02a8d86f08 100644 (file)
@@ -23,6 +23,7 @@
 #include "mem_user.h"
 #include "ptrace_user.h"
 #include "registers.h"
+#include "skas.h"
 #include "skas_ptrace.h"
 
 static void ptrace_child(void)
@@ -140,14 +141,27 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
 }
 
 /* Changed only during early boot */
-int ptrace_faultinfo = 1;
-int ptrace_ldt = 1;
-int proc_mm = 1;
-int skas_needs_stub = 0;
+int ptrace_faultinfo;
+static int disable_ptrace_faultinfo;
+
+int ptrace_ldt;
+static int disable_ptrace_ldt;
+
+int proc_mm;
+static int disable_proc_mm;
+
+int have_switch_mm;
+static int disable_switch_mm;
+
+int skas_needs_stub;
 
 static int __init skas0_cmd_param(char *str, int* add)
 {
-       ptrace_faultinfo = proc_mm = 0;
+       disable_ptrace_faultinfo = 1;
+       disable_ptrace_ldt = 1;
+       disable_proc_mm = 1;
+       disable_switch_mm = 1;
+
        return 0;
 }
 
@@ -157,15 +171,12 @@ static int __init mode_skas0_cmd_param(char *str, int* add)
        __attribute__((alias("skas0_cmd_param")));
 
 __uml_setup("skas0", skas0_cmd_param,
-               "skas0\n"
-               "    Disables SKAS3 usage, so that SKAS0 is used, unless \n"
-               "    you specify mode=tt.\n\n");
+"skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
 
 __uml_setup("mode=skas0", mode_skas0_cmd_param,
-               "mode=skas0\n"
-               "    Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
-               "    specify mode=tt. Note that this was recently added - on \n"
-               "    older kernels you must use simply \"skas0\".\n\n");
+"mode=skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
 
 /* Changed only during early boot */
 static int force_sysemu_disabled = 0;
@@ -360,7 +371,7 @@ void __init os_early_checks(void)
 
 static int __init noprocmm_cmd_param(char *str, int* add)
 {
-       proc_mm = 0;
+       disable_proc_mm = 1;
        return 0;
 }
 
@@ -372,7 +383,7 @@ __uml_setup("noprocmm", noprocmm_cmd_param,
 
 static int __init noptracefaultinfo_cmd_param(char *str, int* add)
 {
-       ptrace_faultinfo = 0;
+       disable_ptrace_faultinfo = 1;
        return 0;
 }
 
@@ -384,7 +395,7 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
 
 static int __init noptraceldt_cmd_param(char *str, int* add)
 {
-       ptrace_ldt = 0;
+       disable_ptrace_ldt = 1;
        return 0;
 }
 
@@ -404,17 +415,15 @@ static inline void check_skas3_ptrace_faultinfo(void)
 
        n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
        if (n < 0) {
-               ptrace_faultinfo = 0;
                if (errno == EIO)
                        non_fatal("not found\n");
                else
                        perror("not found");
-       }
+       } else if (disable_ptrace_faultinfo)
+               non_fatal("found but disabled on command line\n");
        else {
-               if (!ptrace_faultinfo)
-                       non_fatal("found but disabled on command line\n");
-               else
-                       non_fatal("found\n");
+               ptrace_faultinfo = 1;
+               non_fatal("found\n");
        }
 
        stop_ptraced_child(pid, 1, 1);
@@ -437,38 +446,30 @@ static inline void check_skas3_ptrace_ldt(void)
        if (n < 0) {
                if (errno == EIO)
                        non_fatal("not found\n");
-               else {
+               else
                        perror("not found");
-               }
-               ptrace_ldt = 0;
-       }
+       } else if (disable_ptrace_ldt)
+               non_fatal("found, but use is disabled\n");
        else {
-               if (ptrace_ldt)
-                       non_fatal("found\n");
-               else
-                       non_fatal("found, but use is disabled\n");
+               ptrace_ldt = 1;
+               non_fatal("found\n");
        }
 
        stop_ptraced_child(pid, 1, 1);
-#else
-       /* PTRACE_LDT might be disabled via cmdline option.
-        * We want to override this, else we might use the stub
-        * without real need
-        */
-       ptrace_ldt = 1;
 #endif
 }
 
 static inline void check_skas3_proc_mm(void)
 {
        non_fatal("  - /proc/mm...");
-       if (access("/proc/mm", W_OK) < 0) {
-               proc_mm = 0;
+       if (access("/proc/mm", W_OK) < 0)
                perror("not found");
-       }
-       else if (!proc_mm)
+       else if (disable_proc_mm)
                non_fatal("found but disabled on command line\n");
-       else non_fatal("found\n");
+       else {
+               proc_mm = 1;
+               non_fatal("found\n");
+       }
 }
 
 void can_do_skas(void)
index b613473b3ec1c1ef9ba83da234a207ef6f08aa38..c6183e7aec3d73cb2a4d0b70e27578b7a364afc1 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <errno.h>
+#include <asm/user.h>
 #include "kern_constants.h"
 #include "longjmp.h"
 #include "user.h"
@@ -74,10 +75,10 @@ int put_fp_registers(int pid, unsigned long *regs)
 
 void arch_init_registers(int pid)
 {
-       unsigned long fpx_regs[HOST_XFP_SIZE];
+       struct user_fxsr_struct fpx_regs;
        int err;
 
-       err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
+       err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
        if (!err)
                return;
 
index e49280599465ec9ed4f44f4b0ffdf7e0807d2339..bee98f466d660543cd16d14ce355b6c2fc09db0a 100644 (file)
@@ -9,7 +9,9 @@
 #include <time.h>
 #include <sys/time.h>
 #include "kern_constants.h"
+#include "kern_util.h"
 #include "os.h"
+#include "process.h"
 #include "user.h"
 
 int set_interval(void)
@@ -58,12 +60,17 @@ static inline long long timeval_to_ns(const struct timeval *tv)
 long long disable_timer(void)
 {
        struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
+       int remain, max = UM_NSEC_PER_SEC / UM_HZ;
 
        if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
                printk(UM_KERN_ERR "disable_timer - setitimer failed, "
                       "errno = %d\n", errno);
 
-       return timeval_to_ns(&time.it_value);
+       remain = timeval_to_ns(&time.it_value);
+       if (remain > max)
+               remain = max;
+
+       return remain;
 }
 
 long long os_nsecs(void)
@@ -79,7 +86,44 @@ static int after_sleep_interval(struct timespec *ts)
 {
        return 0;
 }
+
+static void deliver_alarm(void)
+{
+       alarm_handler(SIGVTALRM, NULL);
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+       return nsecs;
+}
+
 #else
+unsigned long long last_tick;
+unsigned long long skew;
+
+static void deliver_alarm(void)
+{
+       unsigned long long this_tick = os_nsecs();
+       int one_tick = UM_NSEC_PER_SEC / UM_HZ;
+
+       if (last_tick == 0)
+               last_tick = this_tick - one_tick;
+
+       skew += this_tick - last_tick;
+
+       while (skew >= one_tick) {
+               alarm_handler(SIGVTALRM, NULL);
+               skew -= one_tick;
+       }
+
+       last_tick = this_tick;
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+       return nsecs > skew ? nsecs - skew : 0;
+}
+
 static inline long long timespec_to_us(const struct timespec *ts)
 {
        return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
@@ -102,6 +146,8 @@ static int after_sleep_interval(struct timespec *ts)
         */
        if (start_usecs > usec)
                start_usecs = usec;
+
+       start_usecs -= skew / UM_NSEC_PER_USEC;
        tv = ((struct timeval) { .tv_sec  = start_usecs / UM_USEC_PER_SEC,
                                 .tv_usec = start_usecs % UM_USEC_PER_SEC });
        interval = ((struct itimerval) { { 0, usec }, tv });
@@ -113,8 +159,6 @@ static int after_sleep_interval(struct timespec *ts)
 }
 #endif
 
-extern void alarm_handler(int sig, struct sigcontext *sc);
-
 void idle_sleep(unsigned long long nsecs)
 {
        struct timespec ts;
@@ -126,10 +170,12 @@ void idle_sleep(unsigned long long nsecs)
         */
        if (nsecs == 0)
                nsecs = UM_NSEC_PER_SEC / UM_HZ;
+
+       nsecs = sleep_time(nsecs);
        ts = ((struct timespec) { .tv_sec       = nsecs / UM_NSEC_PER_SEC,
                                  .tv_nsec      = nsecs % UM_NSEC_PER_SEC });
 
        if (nanosleep(&ts, &ts) == 0)
-               alarm_handler(SIGVTALRM, NULL);
+               deliver_alarm();
        after_sleep_interval(&ts);
 }
index 6b4499906a6c96be3139a594681b7c632b8139c1..c9b176534d65bd15d97a86769cf978c510b7c475 100644 (file)
@@ -148,14 +148,13 @@ int peek_user(struct task_struct *child, long addr, long data)
 int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
-       long fpregs[HOST_FP_SIZE];
+       struct user_i387_struct fpregs;
 
-       BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       err = save_fp_registers(userspace_pid[cpu], fpregs);
+       err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
        if (err)
                return err;
 
-       n = copy_to_user(buf, fpregs, sizeof(fpregs));
+       n = copy_to_user(buf, &fpregs, sizeof(fpregs));
        if(n > 0)
                return -EFAULT;
 
@@ -165,27 +164,26 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int n, cpu = ((struct thread_info *) child->stack)->cpu;
-       long fpregs[HOST_FP_SIZE];
+       struct user_i387_struct fpregs;
 
-       BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       n = copy_from_user(fpregs, buf, sizeof(fpregs));
+       n = copy_from_user(&fpregs, buf, sizeof(fpregs));
        if (n > 0)
                return -EFAULT;
 
-       return restore_fp_registers(userspace_pid[cpu], fpregs);
+       return restore_fp_registers(userspace_pid[cpu],
+                                   (unsigned long *) &fpregs);
 }
 
 int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
        int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
-       long fpregs[HOST_XFP_SIZE];
+       struct user_fxsr_struct fpregs;
 
-       BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       err = save_fpx_registers(userspace_pid[cpu], fpregs);
+       err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
        if (err)
                return err;
 
-       n = copy_to_user(buf, fpregs, sizeof(fpregs));
+       n = copy_to_user(buf, &fpregs, sizeof(fpregs));
        if(n > 0)
                return -EFAULT;
 
@@ -195,14 +193,14 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
        int n, cpu = ((struct thread_info *) child->stack)->cpu;
-       long fpregs[HOST_XFP_SIZE];
+       struct user_fxsr_struct fpregs;
 
-       BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       n = copy_from_user(fpregs, buf, sizeof(fpregs));
+       n = copy_from_user(&fpregs, buf, sizeof(fpregs));
        if (n > 0)
                return -EFAULT;
 
-       return restore_fpx_registers(userspace_pid[cpu], fpregs);
+       return restore_fpx_registers(userspace_pid[cpu],
+                                    (unsigned long *) &fpregs);
 }
 
 long subarch_ptrace(struct task_struct *child, long request, long addr,
index 39bd32bf84f0bbe029398e1c3076d7ca2092767f..5f883bfe773fe37899f361507131129e800059d8 100644 (file)
@@ -22,7 +22,7 @@ void foo(void)
        OFFSET(HOST_SC_CR2, sigcontext, cr2);
 
        DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
-       DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
+       DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct));
 
        DEFINE(HOST_IP, EIP);
        DEFINE(HOST_SP, UESP);
index 2f3443c6e859f4d890ef8b4e8c21c03c2e7bb152..973585414a66372e3f5e3e30f57a2842e10fed3f 100644 (file)
@@ -24,7 +24,6 @@ void foo(void)
        OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
 
        DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
-       DEFINE(HOST_XFP_SIZE, 0);
        DEFINE_LONGS(HOST_RBX, RBX);
        DEFINE_LONGS(HOST_RCX, RCX);
        DEFINE_LONGS(HOST_RDI, RDI);
index 003db9c8c44aa4fc9934c7cff03169af05a96e25..1a83daf8e24f069fb6873d963a0b4d6ac6d62352 100644 (file)
@@ -132,23 +132,6 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
        return ret;
 }
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-int sys_pipe (int *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe (fd);
-       if (!error) {
-               if (copy_to_user (fildes, fd, 2*sizeof (int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 static inline unsigned long
 do_mmap2 (unsigned long addr, size_t len,
         unsigned long prot, unsigned long flags,
index c3f880902d66555afd6e079292f23ec009126f34..fe361ae7ef2f18ecffe362e0c492c29d370347ba 100644 (file)
@@ -18,6 +18,7 @@ config X86_64
 ### Arch settings
 config X86
        def_bool y
+       select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_KPROBES
@@ -334,6 +335,7 @@ config X86_RDC321X
        select GENERIC_GPIO
        select LEDS_CLASS
        select LEDS_GPIO
+       select NEW_LEDS
        help
          This option is needed for RDC R-321x system-on-chip, also known
          as R-8610-(G).
index d01ea42187e6aa8ddcd1218f229e74e6dda13148..edaadea90aafcf9876256bcac9db5d68823874ea 100644 (file)
@@ -191,7 +191,7 @@ static void read_ehdr(FILE *fp)
                die("Cannot read ELF header: %s\n",
                        strerror(errno));
        }
-       if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) {
+       if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
                die("No ELF magic\n");
        }
        if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) {
index bbdacb398d48e05a05c17f23af0d2b650751d912..5e618c3b47208ed2f301c685a5596135b30cc78f 100644 (file)
@@ -83,9 +83,7 @@ obj-$(CONFIG_KVM_GUEST)               += kvm.o
 obj-$(CONFIG_KVM_CLOCK)                += kvmclock.o
 obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirt_patch_$(BITS).o
 
-ifdef CONFIG_INPUT_PCSPKR
-obj-y                          += pcspeaker.o
-endif
+obj-$(CONFIG_PCSPKR_PLATFORM)  += pcspeaker.o
 
 obj-$(CONFIG_SCx200)           += scx200.o
 scx200-y                       += scx200_32.o
index 7335959b6aff298ac4f0ee35f5886d606ec905db..fd5ca97a2ad5e017b48be06e23175d007cc85572 100644 (file)
@@ -10,5 +10,5 @@ endif
 $(obj)/wakeup_rm.o:    $(obj)/realmode/wakeup.bin
 
 $(obj)/realmode/wakeup.bin: FORCE
-       $(Q)$(MAKE) $(build)=$(obj)/realmode $@
+       $(Q)$(MAKE) $(build)=$(obj)/realmode
 
index 092900854acc79f54953facf917d565442d0305a..1c31cc0e9def070e26288672801396d042fa604a 100644 (file)
@@ -6,7 +6,8 @@
 # for more details.
 #
 
-targets                := wakeup.bin wakeup.elf
+always         := wakeup.bin
+targets                := wakeup.elf wakeup.lds
 
 wakeup-y       += wakeup.o wakemain.o video-mode.o copy.o
 
@@ -48,7 +49,7 @@ LDFLAGS_wakeup.elf    := -T
 
 CPPFLAGS_wakeup.lds += -P -C
 
-$(obj)/wakeup.elf: $(src)/wakeup.lds $(WAKEUP_OBJS) FORCE
+$(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE
        $(call if_changed,ld)
 
 OBJCOPYFLAGS_wakeup.bin        := -O binary
index 22fab6c4be157b3a09d2bb78d389da403451879f..7da00b799cdab3806c97a42e4e854754c57fe01b 100644 (file)
@@ -12,11 +12,6 @@ ENTRY(_start)
 
 SECTIONS
 {
-       . = HEADER_OFFSET;
-       .header : {
-                *(.header)
-       }
-
        . = 0;
        .text : {
                 *(.text*)
@@ -50,6 +45,11 @@ SECTIONS
                __bss_end = .;
        }
 
+       . = HEADER_OFFSET;
+       .header : {
+               *(.header)
+       }
+
        . = ALIGN(16);
        _end = .;
 
index 238468ae19931be3116e1e9de9ae0f0c1db1d2e2..c2e1ce33c7cb0e9a9bdab5d16c204c9a83447f7a 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/cpu.h>
 
+#include <asm/pat.h>
 #include <asm/processor.h>
 
 struct cpuid_bit {
@@ -48,3 +49,23 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, cb->feature);
        }
 }
+
+#ifdef CONFIG_X86_PAT
+void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
+{
+       switch (c->x86_vendor) {
+       case X86_VENDOR_AMD:
+               if (c->x86 >= 0xf && c->x86 <= 0x11)
+                       return;
+               break;
+       case X86_VENDOR_INTEL:
+               if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
+                       return;
+               break;
+       }
+
+       pat_disable(cpu_has_pat ?
+                   "PAT disabled. Not yet verified on this CPU type." :
+                   "PAT not supported by CPU.");
+}
+#endif
index 35b4f6a9c8effca5b2a609aedb669417d26b5f66..d0463a9462477716bd065b5c822cd34e96812282 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/mmu_context.h>
 #include <asm/mtrr.h>
 #include <asm/mce.h>
+#include <asm/pat.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/mpspec.h>
 #include <asm/apic.h>
@@ -308,19 +309,6 @@ static void __cpuinit early_get_cap(struct cpuinfo_x86 *c)
 
        }
 
-       clear_cpu_cap(c, X86_FEATURE_PAT);
-
-       switch (c->x86_vendor) {
-       case X86_VENDOR_AMD:
-               if (c->x86 >= 0xf && c->x86 <= 0x11)
-                       set_cpu_cap(c, X86_FEATURE_PAT);
-               break;
-       case X86_VENDOR_INTEL:
-               if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-                       set_cpu_cap(c, X86_FEATURE_PAT);
-               break;
-       }
-
 }
 
 /*
@@ -409,18 +397,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
                init_scattered_cpuid_features(c);
        }
 
-       clear_cpu_cap(c, X86_FEATURE_PAT);
-
-       switch (c->x86_vendor) {
-       case X86_VENDOR_AMD:
-               if (c->x86 >= 0xf && c->x86 <= 0x11)
-                       set_cpu_cap(c, X86_FEATURE_PAT);
-               break;
-       case X86_VENDOR_INTEL:
-               if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-                       set_cpu_cap(c, X86_FEATURE_PAT);
-               break;
-       }
 }
 
 static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
@@ -651,6 +627,7 @@ void __init early_cpu_init(void)
                cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
 
        early_cpu_detect();
+       validate_pat_support(&boot_cpu_data);
 }
 
 /* Make sure %fs is initialized properly in idle threads */
index 9dad6ca6cd70d2812426d7da93224aeaa2d69e33..e8edd63ab000cd5d13c3ecf8aab94341b2828df4 100644 (file)
@@ -161,6 +161,25 @@ void geode_gpio_setup_event(unsigned int gpio, int pair, int pme)
 }
 EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
 
+int geode_has_vsa2(void)
+{
+       static int has_vsa2 = -1;
+
+       if (has_vsa2 == -1) {
+               /*
+                * The VSA has virtual registers that we can query for a
+                * signature.
+                */
+               outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
+               outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
+
+               has_vsa2 = (inw(VSA_VRC_DATA) == VSA_SIG);
+       }
+
+       return has_vsa2;
+}
+EXPORT_SYMBOL_GPL(geode_has_vsa2);
+
 static int __init geode_southbridge_init(void)
 {
        if (!is_geode())
index db6839b53195e1a83d9186a76bf9a05562fc39e6..e03cc952f233db9a2d77a1592798a96cf68a0674 100644 (file)
@@ -450,7 +450,6 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
 
-       clear_fpu(tsk);
        return __copy_from_user(&tsk->thread.xstate->fsave, buf,
                                sizeof(struct i387_fsave_struct));
 }
@@ -461,7 +460,6 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf)
        struct user_i387_ia32_struct env;
        int err;
 
-       clear_fpu(tsk);
        err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
                               sizeof(struct i387_fxsave_struct));
        /* mxcsr reserved bits must be masked to zero for security reasons */
@@ -478,6 +476,16 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf)
        int err;
 
        if (HAVE_HWFP) {
+               struct task_struct *tsk = current;
+
+               clear_fpu(tsk);
+
+               if (!used_math()) {
+                       err = init_fpu(tsk);
+                       if (err)
+                               return err;
+               }
+
                if (cpu_has_fxsr)
                        err = restore_i387_fxsave(buf);
                else
index ddee04043aeb36716bc0910f5830e48d852c8b6a..4bc1be5d5472432e642dc491dc9821a55f57abad 100644 (file)
@@ -133,6 +133,7 @@ static int kvm_register_clock(void)
        return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high);
 }
 
+#ifdef CONFIG_X86_LOCAL_APIC
 static void kvm_setup_secondary_clock(void)
 {
        /*
@@ -143,6 +144,7 @@ static void kvm_setup_secondary_clock(void)
        /* ok, done with our trickery, call native */
        setup_secondary_APIC_clock();
 }
+#endif
 
 /*
  * After the clock is registered, the host will keep writing to the
@@ -177,7 +179,9 @@ void __init kvmclock_init(void)
                pv_time_ops.get_wallclock = kvm_get_wallclock;
                pv_time_ops.set_wallclock = kvm_set_wallclock;
                pv_time_ops.sched_clock = kvm_clock_read;
+#ifdef CONFIG_X86_LOCAL_APIC
                pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
+#endif
                machine_ops.shutdown  = kvm_shutdown;
 #ifdef CONFIG_KEXEC
                machine_ops.crash_shutdown  = kvm_crash_shutdown;
index 3e2c54dc8b29f2e907021bf84d55081b5f65ffa6..404683b94e79592c69e04930ed385056f8f5861c 100644 (file)
@@ -794,6 +794,11 @@ void __init find_smp_config(void)
                             ACPI-based MP Configuration
    -------------------------------------------------------------------------- */
 
+/*
+ * Keep this outside and initialized to 0, for !CONFIG_ACPI builds:
+ */
+int es7000_plat;
+
 #ifdef CONFIG_ACPI
 
 #ifdef CONFIG_X86_IO_APIC
@@ -909,8 +914,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
        MP_intsrc_info(&intsrc);
 }
 
-int es7000_plat;
-
 void __init mp_config_acpi_legacy_irqs(void)
 {
        struct mpc_config_intsrc intsrc;
index 0c37f16b69502e1fe31f4e94c80775dc1fd22060..c5ef1af8e79de6883b005cfa99d59bb9164e978c 100644 (file)
@@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
        if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
                return memory;
 
-       if (!dev)
+       if (!dev) {
                dev = &fallback_dev;
+               gfp |= GFP_DMA;
+       }
        dma_mask = dev->coherent_dma_mask;
        if (dma_mask == 0)
-               dma_mask = DMA_32BIT_MASK;
+               dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
 
        /* Device not DMA able */
        if (dev->dma_mask == NULL)
@@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
           larger than 16MB and in this case we have a chance of
           finding fitting memory in the next higher zone first. If
           not retry with true GFP_DMA. -AK */
-       if (dma_mask <= DMA_32BIT_MASK)
+       if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
                gfp |= GFP_DMA32;
 #endif
 
index fb03ef380f0e230ebf5f3835bc7ec57e1c9fed20..a7835f2829361bcd964f85118839751fba24b12b 100644 (file)
@@ -1303,6 +1303,9 @@ static const struct user_regset_view user_x86_64_view = {
 #define genregs32_get          genregs_get
 #define genregs32_set          genregs_set
 
+#define user_i387_ia32_struct  user_i387_struct
+#define user32_fxsr_struct     user_fxsr_struct
+
 #endif /* CONFIG_X86_64 */
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
@@ -1315,13 +1318,13 @@ static const struct user_regset x86_32_regsets[] = {
        },
        [REGSET_FP] = {
                .core_note_type = NT_PRFPREG,
-               .n = sizeof(struct user_i387_struct) / sizeof(u32),
+               .n = sizeof(struct user_i387_ia32_struct) / sizeof(u32),
                .size = sizeof(u32), .align = sizeof(u32),
                .active = fpregs_active, .get = fpregs_get, .set = fpregs_set
        },
        [REGSET_XFP] = {
                .core_note_type = NT_PRXFPREG,
-               .n = sizeof(struct user_i387_struct) / sizeof(u32),
+               .n = sizeof(struct user32_fxsr_struct) / sizeof(u32),
                .size = sizeof(u32), .align = sizeof(u32),
                .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
        },
index 07c6d42ab5ff326203f417c1b8ccbc9ae1fc5dac..f6be7d5f82f81d726bf3545732c1d78ad778b0f3 100644 (file)
@@ -149,7 +149,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                .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 Optiplex 745's DFF*/
index c0c68c18a788dff30e0103b144cb0b76a09ec775..6f80b852a1961a6b496bc2404c5194769557d97a 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
 
+#ifdef CONFIG_X86_LOCAL_APIC
 unsigned int num_processors;
 unsigned disabled_cpus __cpuinitdata;
 /* Processor that is doing the boot up */
@@ -23,8 +24,9 @@ EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
+#endif
 
-#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_SMP)
+#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP)
 /*
  * Copy data used in early init routines from the initial arrays to the
  * per cpu data areas.  These arrays then become expendable and the
index 2283422af7946fef30a86189dddb0a7a12fe3fc1..2c5f8b213e868658d8ad189bb925151dea3bc7b1 100644 (file)
@@ -127,7 +127,12 @@ static struct resource standard_io_resources[] = { {
 }, {
        .name   = "keyboard",
        .start  = 0x0060,
-       .end    = 0x006f,
+       .end    = 0x0060,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+       .name   = "keyboard",
+       .start  = 0x0064,
+       .end    = 0x0064,
        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 }, {
        .name   = "dma page reg",
index 22c14e21c97c435a8d172d8f23159738bf0dbe2f..6dff1286ad8adec4b9fc6bb7808c3a233c476fd2 100644 (file)
@@ -70,6 +70,7 @@
 #include <asm/ds.h>
 #include <asm/topology.h>
 #include <asm/trampoline.h>
+#include <asm/pat.h>
 
 #include <mach_apic.h>
 #ifdef CONFIG_PARAVIRT
@@ -128,7 +129,9 @@ static struct resource standard_io_resources[] = {
                .flags = IORESOURCE_BUSY | IORESOURCE_IO },
        { .name = "timer1", .start = 0x50, .end = 0x53,
                .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-       { .name = "keyboard", .start = 0x60, .end = 0x6f,
+       { .name = "keyboard", .start = 0x60, .end = 0x60,
+               .flags = IORESOURCE_BUSY | IORESOURCE_IO },
+       { .name = "keyboard", .start = 0x64, .end = 0x64,
                .flags = IORESOURCE_BUSY | IORESOURCE_IO },
        { .name = "dma page reg", .start = 0x80, .end = 0x8f,
                .flags = IORESOURCE_BUSY | IORESOURCE_IO },
@@ -948,7 +951,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
 {
        if (c->x86 == 0x6 && c->x86_model >= 0xf)
-               set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+               set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 }
 
 static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
@@ -1063,25 +1066,19 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
        if (c->extended_cpuid_level >= 0x80000007)
                c->x86_power = cpuid_edx(0x80000007);
 
-
-       clear_cpu_cap(c, X86_FEATURE_PAT);
-
        switch (c->x86_vendor) {
        case X86_VENDOR_AMD:
                early_init_amd(c);
-               if (c->x86 >= 0xf && c->x86 <= 0x11)
-                       set_cpu_cap(c, X86_FEATURE_PAT);
                break;
        case X86_VENDOR_INTEL:
                early_init_intel(c);
-               if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-                       set_cpu_cap(c, X86_FEATURE_PAT);
                break;
        case X86_VENDOR_CENTAUR:
                early_init_centaur(c);
                break;
        }
 
+       validate_pat_support(c);
 }
 
 /*
index 8f75893a6467e0e00c62e55b154fa674ae839e1c..0cb7aadc87cd44a5e0c2402731cadbfd8c88ce8d 100644 (file)
@@ -231,7 +231,8 @@ native_smp_call_function_mask(cpumask_t mask,
        wmb();
 
        /* Send a message to other CPUs */
-       if (cpus_equal(mask, allbutself))
+       if (cpus_equal(mask, allbutself) &&
+           cpus_equal(cpu_online_map, cpu_callout_map))
                send_IPI_allbutself(CALL_FUNCTION_VECTOR);
        else
                send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
index 84241a256dc819bbb1f2fcaff679f189782f8564..38988491c6222e99c6bb7772eb09ee0cc81fb270 100644 (file)
@@ -86,6 +86,7 @@ void *x86_bios_cpu_apicid_early_ptr;
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
+static int low_mappings;
 #endif
 
 /* State of each CPU */
@@ -299,7 +300,7 @@ static void __cpuinit smp_callin(void)
 /*
  * Activate a secondary processor.
  */
-void __cpuinit start_secondary(void *unused)
+static void __cpuinit start_secondary(void *unused)
 {
        /*
         * Don't put *anything* before cpu_init(), SMP booting is too
@@ -326,6 +327,12 @@ void __cpuinit start_secondary(void *unused)
                enable_8259A_irq(0);
        }
 
+#ifdef CONFIG_X86_32
+       while (low_mappings)
+               cpu_relax();
+       __flush_tlb_all();
+#endif
+
        /* This must be done before setting cpu_online_map */
        set_cpu_sibling_map(raw_smp_processor_id());
        wmb();
@@ -1040,14 +1047,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
 #ifdef CONFIG_X86_32
        /* init low mem mapping */
        clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-                       min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+               min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
        flush_tlb_all();
-#endif
+       low_mappings = 1;
 
        err = do_boot_cpu(apicid, cpu);
-       if (err < 0) {
+
+       zap_low_mappings();
+       low_mappings = 0;
+#else
+       err = do_boot_cpu(apicid, cpu);
+#endif
+       if (err) {
                Dprintk("do_boot_cpu failed %d\n", err);
-               return err;
+               return -EIO;
        }
 
        /*
@@ -1259,9 +1272,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        setup_ioapic_dest();
 #endif
        check_nmi_watchdog();
-#ifdef CONFIG_X86_32
-       zap_low_mappings();
-#endif
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -1306,7 +1316,7 @@ static void remove_siblinginfo(int cpu)
        cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
-int additional_cpus __initdata = -1;
+static int additional_cpus __initdata = -1;
 
 static __init int setup_additional_cpus(char *s)
 {
index a86d26f036e1ddcefee7f293964b917d1296b713..d2ab52cc1d6b17fa5ff72ef4e5b6111acc6903f5 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user * fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                          unsigned long prot, unsigned long flags,
                          unsigned long fd, unsigned long pgoff)
index bd802a5e1aa344680971c51d65444c019ed9fc87..3b360ef33817c9b618e661f452e682a43dfe91bc 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/ia32.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage long sys_pipe(int __user *fildes)
-{
-       int fd[2];
-       int error;
-
-       error = do_pipe(fd);
-       if (!error) {
-               if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                       error = -EFAULT;
-       }
-       return error;
-}
-
 asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
        unsigned long fd, unsigned long off)
 {
index 58882f9f2637b03c0647f52b5e0901ab2deac582..f6c05d0410fb08717fe7f736320225bc476f0533 100644 (file)
@@ -2,6 +2,7 @@
    All C exports should go in the respective C files. */
 
 #include <linux/module.h>
+#include <net/checksum.h>
 #include <linux/smp.h>
 
 #include <asm/processor.h>
@@ -29,6 +30,8 @@ EXPORT_SYMBOL(__copy_from_user_inatomic);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
 
+EXPORT_SYMBOL(csum_partial);
+
 /*
  * Export string functions. We normally rely on gcc builtin for most of these,
  * but gcc sometimes decides not to inline them.
index 361e31611276d03018f4b16d275a04b5e478f2cf..3324d90038e438ab1361d53f31be78948d72aba8 100644 (file)
@@ -35,7 +35,7 @@
 #include "i8254.h"
 
 #ifndef CONFIG_X86_64
-#define mod_64(x, y) ((x) - (y) * div64_64(x, y))
+#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
 #else
 #define mod_64(x, y) ((x) % (y))
 #endif
@@ -60,8 +60,8 @@ static u64 muldiv64(u64 a, u32 b, u32 c)
        rl = (u64)u.l.low * (u64)b;
        rh = (u64)u.l.high * (u64)b;
        rh += (rl >> 32);
-       res.l.high = div64_64(rh, c);
-       res.l.low = div64_64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
+       res.l.high = div64_u64(rh, c);
+       res.l.low = div64_u64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
        return res.ll;
 }
 
@@ -288,6 +288,8 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
         * mode 1 is one shot, mode 2 is period, otherwise del timer */
        switch (ps->channels[0].mode) {
        case 1:
+        /* FIXME: enhance mode 4 precision */
+       case 4:
                create_pit_timer(&ps->pit_timer, val, 0);
                break;
        case 2:
index 57ac4e4c556a5a3ca5bc79a8acbd1e35f3f33d9d..36809d79788bedffcd8332609c7313175aa09e3a 100644 (file)
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/math64.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/apicdef.h>
 #include <asm/atomic.h>
-#include <asm/div64.h>
 #include "irq.h"
 
 #define PRId64 "d"
@@ -526,8 +526,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
        } else
                passed = ktime_sub(now, apic->timer.last_update);
 
-       counter_passed = div64_64(ktime_to_ns(passed),
-                                 (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
+       counter_passed = div64_u64(ktime_to_ns(passed),
+                                  (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
 
        if (counter_passed > tmcct) {
                if (unlikely(!apic_lvtt_period(apic))) {
index 2ad6f5481671997c24c420b31fce7c9d67b31794..36c5406b1813d4a5c3a52faff20b64a16e5ee54f 100644 (file)
@@ -79,36 +79,6 @@ static int dbg = 1;
        }
 #endif
 
-#define PT64_PT_BITS 9
-#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
-#define PT32_PT_BITS 10
-#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS)
-
-#define PT_WRITABLE_SHIFT 1
-
-#define PT_PRESENT_MASK (1ULL << 0)
-#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT)
-#define PT_USER_MASK (1ULL << 2)
-#define PT_PWT_MASK (1ULL << 3)
-#define PT_PCD_MASK (1ULL << 4)
-#define PT_ACCESSED_MASK (1ULL << 5)
-#define PT_DIRTY_MASK (1ULL << 6)
-#define PT_PAGE_SIZE_MASK (1ULL << 7)
-#define PT_PAT_MASK (1ULL << 7)
-#define PT_GLOBAL_MASK (1ULL << 8)
-#define PT64_NX_SHIFT 63
-#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT)
-
-#define PT_PAT_SHIFT 7
-#define PT_DIR_PAT_SHIFT 12
-#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT)
-
-#define PT32_DIR_PSE36_SIZE 4
-#define PT32_DIR_PSE36_SHIFT 13
-#define PT32_DIR_PSE36_MASK \
-       (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT)
-
-
 #define PT_FIRST_AVAIL_BITS_SHIFT 9
 #define PT64_SECOND_AVAIL_BITS_SHIFT 52
 
@@ -154,10 +124,6 @@ static int dbg = 1;
 #define PFERR_USER_MASK (1U << 2)
 #define PFERR_FETCH_MASK (1U << 4)
 
-#define PT64_ROOT_LEVEL 4
-#define PT32_ROOT_LEVEL 2
-#define PT32E_ROOT_LEVEL 3
-
 #define PT_DIRECTORY_LEVEL 2
 #define PT_PAGE_TABLE_LEVEL 1
 
@@ -186,6 +152,12 @@ static struct kmem_cache *mmu_page_header_cache;
 
 static u64 __read_mostly shadow_trap_nonpresent_pte;
 static u64 __read_mostly shadow_notrap_nonpresent_pte;
+static u64 __read_mostly shadow_base_present_pte;
+static u64 __read_mostly shadow_nx_mask;
+static u64 __read_mostly shadow_x_mask;        /* mutual exclusive with nx_mask */
+static u64 __read_mostly shadow_user_mask;
+static u64 __read_mostly shadow_accessed_mask;
+static u64 __read_mostly shadow_dirty_mask;
 
 void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte)
 {
@@ -194,6 +166,23 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte)
 }
 EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes);
 
+void kvm_mmu_set_base_ptes(u64 base_pte)
+{
+       shadow_base_present_pte = base_pte;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes);
+
+void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
+               u64 dirty_mask, u64 nx_mask, u64 x_mask)
+{
+       shadow_user_mask = user_mask;
+       shadow_accessed_mask = accessed_mask;
+       shadow_dirty_mask = dirty_mask;
+       shadow_nx_mask = nx_mask;
+       shadow_x_mask = x_mask;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
+
 static int is_write_protection(struct kvm_vcpu *vcpu)
 {
        return vcpu->arch.cr0 & X86_CR0_WP;
@@ -232,7 +221,7 @@ static int is_writeble_pte(unsigned long pte)
 
 static int is_dirty_pte(unsigned long pte)
 {
-       return pte & PT_DIRTY_MASK;
+       return pte & shadow_dirty_mask;
 }
 
 static int is_rmap_pte(u64 pte)
@@ -387,7 +376,6 @@ static void account_shadowed(struct kvm *kvm, gfn_t gfn)
 
        write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn));
        *write_count += 1;
-       WARN_ON(*write_count > KVM_PAGES_PER_HPAGE);
 }
 
 static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn)
@@ -547,7 +535,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
                return;
        sp = page_header(__pa(spte));
        pfn = spte_to_pfn(*spte);
-       if (*spte & PT_ACCESSED_MASK)
+       if (*spte & shadow_accessed_mask)
                kvm_set_pfn_accessed(pfn);
        if (is_writeble_pte(*spte))
                kvm_release_pfn_dirty(pfn);
@@ -1073,17 +1061,17 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
         * whether the guest actually used the pte (in order to detect
         * demand paging).
         */
-       spte = PT_PRESENT_MASK | PT_DIRTY_MASK;
+       spte = shadow_base_present_pte | shadow_dirty_mask;
        if (!speculative)
                pte_access |= PT_ACCESSED_MASK;
        if (!dirty)
                pte_access &= ~ACC_WRITE_MASK;
-       if (!(pte_access & ACC_EXEC_MASK))
-               spte |= PT64_NX_MASK;
-
-       spte |= PT_PRESENT_MASK;
+       if (pte_access & ACC_EXEC_MASK)
+               spte |= shadow_x_mask;
+       else
+               spte |= shadow_nx_mask;
        if (pte_access & ACC_USER_MASK)
-               spte |= PT_USER_MASK;
+               spte |= shadow_user_mask;
        if (largepage)
                spte |= PT_PAGE_SIZE_MASK;
 
@@ -1188,8 +1176,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
                                return -ENOMEM;
                        }
 
-                       table[index] = __pa(new_table->spt) | PT_PRESENT_MASK
-                               | PT_WRITABLE_MASK | PT_USER_MASK;
+                       table[index] = __pa(new_table->spt)
+                               | PT_PRESENT_MASK | PT_WRITABLE_MASK
+                               | shadow_user_mask | shadow_x_mask;
                }
                table_addr = table[index] & PT64_BASE_ADDR_MASK;
        }
@@ -1244,7 +1233,6 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
        if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
                return;
        spin_lock(&vcpu->kvm->mmu_lock);
-#ifdef CONFIG_X86_64
        if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
                hpa_t root = vcpu->arch.mmu.root_hpa;
 
@@ -1256,7 +1244,6 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
                spin_unlock(&vcpu->kvm->mmu_lock);
                return;
        }
-#endif
        for (i = 0; i < 4; ++i) {
                hpa_t root = vcpu->arch.mmu.pae_root[i];
 
@@ -1282,7 +1269,6 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
 
        root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
 
-#ifdef CONFIG_X86_64
        if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
                hpa_t root = vcpu->arch.mmu.root_hpa;
 
@@ -1297,7 +1283,6 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
                vcpu->arch.mmu.root_hpa = root;
                return;
        }
-#endif
        metaphysical = !is_paging(vcpu);
        if (tdp_enabled)
                metaphysical = 1;
@@ -1377,7 +1362,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
        spin_lock(&vcpu->kvm->mmu_lock);
        kvm_mmu_free_some_pages(vcpu);
        r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
-                        largepage, gfn, pfn, TDP_ROOT_LEVEL);
+                        largepage, gfn, pfn, kvm_x86_ops->get_tdp_level());
        spin_unlock(&vcpu->kvm->mmu_lock);
 
        return r;
@@ -1484,7 +1469,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
        context->page_fault = tdp_page_fault;
        context->free = nonpaging_free;
        context->prefetch_page = nonpaging_prefetch_page;
-       context->shadow_root_level = TDP_ROOT_LEVEL;
+       context->shadow_root_level = kvm_x86_ops->get_tdp_level();
        context->root_hpa = INVALID_PAGE;
 
        if (!is_paging(vcpu)) {
@@ -1633,7 +1618,7 @@ static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu)
 {
        u64 *spte = vcpu->arch.last_pte_updated;
 
-       return !!(spte && (*spte & PT_ACCESSED_MASK));
+       return !!(spte && (*spte & shadow_accessed_mask));
 }
 
 static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
index e64e9f56a65eb04889cb2c5912c9fda9d36d96f1..1730757bbc7a88c9c26707ce12ab40c5c1a81194 100644 (file)
@@ -3,11 +3,38 @@
 
 #include <linux/kvm_host.h>
 
-#ifdef CONFIG_X86_64
-#define TDP_ROOT_LEVEL PT64_ROOT_LEVEL
-#else
-#define TDP_ROOT_LEVEL PT32E_ROOT_LEVEL
-#endif
+#define PT64_PT_BITS 9
+#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
+#define PT32_PT_BITS 10
+#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS)
+
+#define PT_WRITABLE_SHIFT 1
+
+#define PT_PRESENT_MASK (1ULL << 0)
+#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT)
+#define PT_USER_MASK (1ULL << 2)
+#define PT_PWT_MASK (1ULL << 3)
+#define PT_PCD_MASK (1ULL << 4)
+#define PT_ACCESSED_MASK (1ULL << 5)
+#define PT_DIRTY_MASK (1ULL << 6)
+#define PT_PAGE_SIZE_MASK (1ULL << 7)
+#define PT_PAT_MASK (1ULL << 7)
+#define PT_GLOBAL_MASK (1ULL << 8)
+#define PT64_NX_SHIFT 63
+#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT)
+
+#define PT_PAT_SHIFT 7
+#define PT_DIR_PAT_SHIFT 12
+#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT)
+
+#define PT32_DIR_PSE36_SIZE 4
+#define PT32_DIR_PSE36_SHIFT 13
+#define PT32_DIR_PSE36_MASK \
+       (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT)
+
+#define PT64_ROOT_LEVEL 4
+#define PT32_ROOT_LEVEL 2
+#define PT32E_ROOT_LEVEL 3
 
 static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {
index 89e0be2c10d0ee02153fd6f72df1ebd6e31f6e7b..ab22615eee896be9128ec6b047bd786bb004acf8 100644 (file)
@@ -1863,6 +1863,15 @@ static bool svm_cpu_has_accelerated_tpr(void)
        return false;
 }
 
+static int get_npt_level(void)
+{
+#ifdef CONFIG_X86_64
+       return PT64_ROOT_LEVEL;
+#else
+       return PT32E_ROOT_LEVEL;
+#endif
+}
+
 static struct kvm_x86_ops svm_x86_ops = {
        .cpu_has_kvm_support = has_svm,
        .disabled_by_bios = is_disabled,
@@ -1920,6 +1929,7 @@ static struct kvm_x86_ops svm_x86_ops = {
        .inject_pending_vectors = do_interrupt_requests,
 
        .set_tss_addr = svm_set_tss_addr,
+       .get_tdp_level = get_npt_level,
 };
 
 static int __init svm_init(void)
index 8e5d6645b90d11e08c6f71153e722a004c570457..bfe4db11989c08b79e63acb623a7289f1a2974dc 100644 (file)
@@ -42,6 +42,9 @@ module_param(enable_vpid, bool, 0);
 static int flexpriority_enabled = 1;
 module_param(flexpriority_enabled, bool, 0);
 
+static int enable_ept = 1;
+module_param(enable_ept, bool, 0);
+
 struct vmcs {
        u32 revision_id;
        u32 abort;
@@ -84,7 +87,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
        return container_of(vcpu, struct vcpu_vmx, vcpu);
 }
 
-static int init_rmode_tss(struct kvm *kvm);
+static int init_rmode(struct kvm *kvm);
 
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
 static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -107,6 +110,11 @@ static struct vmcs_config {
        u32 vmentry_ctrl;
 } vmcs_config;
 
+struct vmx_capability {
+       u32 ept;
+       u32 vpid;
+} vmx_capability;
+
 #define VMX_SEGMENT_FIELD(seg)                                 \
        [VCPU_SREG_##seg] = {                                   \
                .selector = GUEST_##seg##_SELECTOR,             \
@@ -214,6 +222,32 @@ static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
                    SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES);
 }
 
+static inline int cpu_has_vmx_invept_individual_addr(void)
+{
+       return (!!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT));
+}
+
+static inline int cpu_has_vmx_invept_context(void)
+{
+       return (!!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT));
+}
+
+static inline int cpu_has_vmx_invept_global(void)
+{
+       return (!!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT));
+}
+
+static inline int cpu_has_vmx_ept(void)
+{
+       return (vmcs_config.cpu_based_2nd_exec_ctrl &
+               SECONDARY_EXEC_ENABLE_EPT);
+}
+
+static inline int vm_need_ept(void)
+{
+       return (cpu_has_vmx_ept() && enable_ept);
+}
+
 static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
 {
        return ((cpu_has_vmx_virtualize_apic_accesses()) &&
@@ -250,6 +284,18 @@ static inline void __invvpid(int ext, u16 vpid, gva_t gva)
                  : : "a"(&operand), "c"(ext) : "cc", "memory");
 }
 
+static inline void __invept(int ext, u64 eptp, gpa_t gpa)
+{
+       struct {
+               u64 eptp, gpa;
+       } operand = {eptp, gpa};
+
+       asm volatile (ASM_VMX_INVEPT
+                       /* CF==1 or ZF==1 --> rc = -1 */
+                       "; ja 1f ; ud2 ; 1:\n"
+                       : : "a" (&operand), "c" (ext) : "cc", "memory");
+}
+
 static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
 {
        int i;
@@ -301,6 +347,33 @@ static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx)
        __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0);
 }
 
+static inline void ept_sync_global(void)
+{
+       if (cpu_has_vmx_invept_global())
+               __invept(VMX_EPT_EXTENT_GLOBAL, 0, 0);
+}
+
+static inline void ept_sync_context(u64 eptp)
+{
+       if (vm_need_ept()) {
+               if (cpu_has_vmx_invept_context())
+                       __invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0);
+               else
+                       ept_sync_global();
+       }
+}
+
+static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa)
+{
+       if (vm_need_ept()) {
+               if (cpu_has_vmx_invept_individual_addr())
+                       __invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR,
+                                       eptp, gpa);
+               else
+                       ept_sync_context(eptp);
+       }
+}
+
 static unsigned long vmcs_readl(unsigned long field)
 {
        unsigned long value;
@@ -388,6 +461,8 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
                eb |= 1u << 1;
        if (vcpu->arch.rmode.active)
                eb = ~0;
+       if (vm_need_ept())
+               eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
        vmcs_write32(EXCEPTION_BITMAP, eb);
 }
 
@@ -985,7 +1060,7 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
 static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
 {
        u32 vmx_msr_low, vmx_msr_high;
-       u32 min, opt;
+       u32 min, opt, min2, opt2;
        u32 _pin_based_exec_control = 0;
        u32 _cpu_based_exec_control = 0;
        u32 _cpu_based_2nd_exec_control = 0;
@@ -1003,6 +1078,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
              CPU_BASED_CR8_LOAD_EXITING |
              CPU_BASED_CR8_STORE_EXITING |
 #endif
+             CPU_BASED_CR3_LOAD_EXITING |
+             CPU_BASED_CR3_STORE_EXITING |
              CPU_BASED_USE_IO_BITMAPS |
              CPU_BASED_MOV_DR_EXITING |
              CPU_BASED_USE_TSC_OFFSETING;
@@ -1018,11 +1095,13 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                                           ~CPU_BASED_CR8_STORE_EXITING;
 #endif
        if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) {
-               min = 0;
-               opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+               min2 = 0;
+               opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
                        SECONDARY_EXEC_WBINVD_EXITING |
-                       SECONDARY_EXEC_ENABLE_VPID;
-               if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2,
+                       SECONDARY_EXEC_ENABLE_VPID |
+                       SECONDARY_EXEC_ENABLE_EPT;
+               if (adjust_vmx_controls(min2, opt2,
+                                       MSR_IA32_VMX_PROCBASED_CTLS2,
                                        &_cpu_based_2nd_exec_control) < 0)
                        return -EIO;
        }
@@ -1031,6 +1110,16 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                                SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
                _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
 #endif
+       if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
+               /* CR3 accesses don't need to cause VM Exits when EPT enabled */
+               min &= ~(CPU_BASED_CR3_LOAD_EXITING |
+                        CPU_BASED_CR3_STORE_EXITING);
+               if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
+                                       &_cpu_based_exec_control) < 0)
+                       return -EIO;
+               rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
+                     vmx_capability.ept, vmx_capability.vpid);
+       }
 
        min = 0;
 #ifdef CONFIG_X86_64
@@ -1256,7 +1345,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
 
        kvm_mmu_reset_context(vcpu);
-       init_rmode_tss(vcpu->kvm);
+       init_rmode(vcpu->kvm);
 }
 
 #ifdef CONFIG_X86_64
@@ -1304,8 +1393,64 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
        vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
 }
 
+static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
+{
+       if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
+               if (!load_pdptrs(vcpu, vcpu->arch.cr3)) {
+                       printk(KERN_ERR "EPT: Fail to load pdptrs!\n");
+                       return;
+               }
+               vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]);
+               vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]);
+               vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]);
+               vmcs_write64(GUEST_PDPTR3, vcpu->arch.pdptrs[3]);
+       }
+}
+
+static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
+
+static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
+                                       unsigned long cr0,
+                                       struct kvm_vcpu *vcpu)
+{
+       if (!(cr0 & X86_CR0_PG)) {
+               /* From paging/starting to nonpaging */
+               vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
+                            vmcs_config.cpu_based_exec_ctrl |
+                            (CPU_BASED_CR3_LOAD_EXITING |
+                             CPU_BASED_CR3_STORE_EXITING));
+               vcpu->arch.cr0 = cr0;
+               vmx_set_cr4(vcpu, vcpu->arch.cr4);
+               *hw_cr0 |= X86_CR0_PE | X86_CR0_PG;
+               *hw_cr0 &= ~X86_CR0_WP;
+       } else if (!is_paging(vcpu)) {
+               /* From nonpaging to paging */
+               vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
+                            vmcs_config.cpu_based_exec_ctrl &
+                            ~(CPU_BASED_CR3_LOAD_EXITING |
+                              CPU_BASED_CR3_STORE_EXITING));
+               vcpu->arch.cr0 = cr0;
+               vmx_set_cr4(vcpu, vcpu->arch.cr4);
+               if (!(vcpu->arch.cr0 & X86_CR0_WP))
+                       *hw_cr0 &= ~X86_CR0_WP;
+       }
+}
+
+static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
+                                       struct kvm_vcpu *vcpu)
+{
+       if (!is_paging(vcpu)) {
+               *hw_cr4 &= ~X86_CR4_PAE;
+               *hw_cr4 |= X86_CR4_PSE;
+       } else if (!(vcpu->arch.cr4 & X86_CR4_PAE))
+               *hw_cr4 &= ~X86_CR4_PAE;
+}
+
 static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
+       unsigned long hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) |
+                               KVM_VM_CR0_ALWAYS_ON;
+
        vmx_fpu_deactivate(vcpu);
 
        if (vcpu->arch.rmode.active && (cr0 & X86_CR0_PE))
@@ -1323,29 +1468,61 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        }
 #endif
 
+       if (vm_need_ept())
+               ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
+
        vmcs_writel(CR0_READ_SHADOW, cr0);
-       vmcs_writel(GUEST_CR0,
-                   (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
+       vmcs_writel(GUEST_CR0, hw_cr0);
        vcpu->arch.cr0 = cr0;
 
        if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE))
                vmx_fpu_activate(vcpu);
 }
 
+static u64 construct_eptp(unsigned long root_hpa)
+{
+       u64 eptp;
+
+       /* TODO write the value reading from MSR */
+       eptp = VMX_EPT_DEFAULT_MT |
+               VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
+       eptp |= (root_hpa & PAGE_MASK);
+
+       return eptp;
+}
+
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
+       unsigned long guest_cr3;
+       u64 eptp;
+
+       guest_cr3 = cr3;
+       if (vm_need_ept()) {
+               eptp = construct_eptp(cr3);
+               vmcs_write64(EPT_POINTER, eptp);
+               ept_sync_context(eptp);
+               ept_load_pdptrs(vcpu);
+               guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
+                       VMX_EPT_IDENTITY_PAGETABLE_ADDR;
+       }
+
        vmx_flush_tlb(vcpu);
-       vmcs_writel(GUEST_CR3, cr3);
+       vmcs_writel(GUEST_CR3, guest_cr3);
        if (vcpu->arch.cr0 & X86_CR0_PE)
                vmx_fpu_deactivate(vcpu);
 }
 
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
-       vmcs_writel(CR4_READ_SHADOW, cr4);
-       vmcs_writel(GUEST_CR4, cr4 | (vcpu->arch.rmode.active ?
-                   KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON));
+       unsigned long hw_cr4 = cr4 | (vcpu->arch.rmode.active ?
+                   KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
+
        vcpu->arch.cr4 = cr4;
+       if (vm_need_ept())
+               ept_update_paging_mode_cr4(&hw_cr4, vcpu);
+
+       vmcs_writel(CR4_READ_SHADOW, cr4);
+       vmcs_writel(GUEST_CR4, hw_cr4);
 }
 
 static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
@@ -1530,6 +1707,41 @@ out:
        return ret;
 }
 
+static int init_rmode_identity_map(struct kvm *kvm)
+{
+       int i, r, ret;
+       pfn_t identity_map_pfn;
+       u32 tmp;
+
+       if (!vm_need_ept())
+               return 1;
+       if (unlikely(!kvm->arch.ept_identity_pagetable)) {
+               printk(KERN_ERR "EPT: identity-mapping pagetable "
+                       "haven't been allocated!\n");
+               return 0;
+       }
+       if (likely(kvm->arch.ept_identity_pagetable_done))
+               return 1;
+       ret = 0;
+       identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT;
+       r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
+       if (r < 0)
+               goto out;
+       /* Set up identity-mapping pagetable for EPT in real mode */
+       for (i = 0; i < PT32_ENT_PER_PAGE; i++) {
+               tmp = (i << 22) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
+                       _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
+               r = kvm_write_guest_page(kvm, identity_map_pfn,
+                               &tmp, i * sizeof(tmp), sizeof(tmp));
+               if (r < 0)
+                       goto out;
+       }
+       kvm->arch.ept_identity_pagetable_done = true;
+       ret = 1;
+out:
+       return ret;
+}
+
 static void seg_setup(int seg)
 {
        struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -1564,6 +1776,31 @@ out:
        return r;
 }
 
+static int alloc_identity_pagetable(struct kvm *kvm)
+{
+       struct kvm_userspace_memory_region kvm_userspace_mem;
+       int r = 0;
+
+       down_write(&kvm->slots_lock);
+       if (kvm->arch.ept_identity_pagetable)
+               goto out;
+       kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
+       kvm_userspace_mem.flags = 0;
+       kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR;
+       kvm_userspace_mem.memory_size = PAGE_SIZE;
+       r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
+       if (r)
+               goto out;
+
+       down_read(&current->mm->mmap_sem);
+       kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
+                       VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT);
+       up_read(&current->mm->mmap_sem);
+out:
+       up_write(&kvm->slots_lock);
+       return r;
+}
+
 static void allocate_vpid(struct vcpu_vmx *vmx)
 {
        int vpid;
@@ -1638,6 +1875,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
                                CPU_BASED_CR8_LOAD_EXITING;
 #endif
        }
+       if (!vm_need_ept())
+               exec_control |= CPU_BASED_CR3_STORE_EXITING |
+                               CPU_BASED_CR3_LOAD_EXITING;
        vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
 
        if (cpu_has_secondary_exec_ctrls()) {
@@ -1647,6 +1887,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
                                ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
                if (vmx->vpid == 0)
                        exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
+               if (!vm_need_ept())
+                       exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
                vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
        }
 
@@ -1722,6 +1964,15 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
        return 0;
 }
 
+static int init_rmode(struct kvm *kvm)
+{
+       if (!init_rmode_tss(kvm))
+               return 0;
+       if (!init_rmode_identity_map(kvm))
+               return 0;
+       return 1;
+}
+
 static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1729,7 +1980,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
        int ret;
 
        down_read(&vcpu->kvm->slots_lock);
-       if (!init_rmode_tss(vmx->vcpu.kvm)) {
+       if (!init_rmode(vmx->vcpu.kvm)) {
                ret = -ENOMEM;
                goto out;
        }
@@ -1994,6 +2245,9 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
                error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
        if (is_page_fault(intr_info)) {
+               /* EPT won't cause page fault directly */
+               if (vm_need_ept())
+                       BUG();
                cr2 = vmcs_readl(EXIT_QUALIFICATION);
                KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
                            (u32)((u64)cr2 >> 32), handler);
@@ -2323,6 +2577,64 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        return kvm_task_switch(vcpu, tss_selector, reason);
 }
 
+static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       u64 exit_qualification;
+       enum emulation_result er;
+       gpa_t gpa;
+       unsigned long hva;
+       int gla_validity;
+       int r;
+
+       exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+
+       if (exit_qualification & (1 << 6)) {
+               printk(KERN_ERR "EPT: GPA exceeds GAW!\n");
+               return -ENOTSUPP;
+       }
+
+       gla_validity = (exit_qualification >> 7) & 0x3;
+       if (gla_validity != 0x3 && gla_validity != 0x1 && gla_validity != 0) {
+               printk(KERN_ERR "EPT: Handling EPT violation failed!\n");
+               printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
+                       (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
+                       (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS));
+               printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
+                       (long unsigned int)exit_qualification);
+               kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+               kvm_run->hw.hardware_exit_reason = 0;
+               return -ENOTSUPP;
+       }
+
+       gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
+       hva = gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT);
+       if (!kvm_is_error_hva(hva)) {
+               r = kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
+               if (r < 0) {
+                       printk(KERN_ERR "EPT: Not enough memory!\n");
+                       return -ENOMEM;
+               }
+               return 1;
+       } else {
+               /* must be MMIO */
+               er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+
+               if (er == EMULATE_FAIL) {
+                       printk(KERN_ERR
+                        "EPT: Fail to handle EPT violation vmexit!er is %d\n",
+                        er);
+                       printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
+                        (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
+                        (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS));
+                       printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
+                               (long unsigned int)exit_qualification);
+                       return -ENOTSUPP;
+               } else if (er == EMULATE_DO_MMIO)
+                       return 0;
+       }
+       return 1;
+}
+
 /*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
@@ -2346,6 +2658,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
        [EXIT_REASON_APIC_ACCESS]             = handle_apic_access,
        [EXIT_REASON_WBINVD]                  = handle_wbinvd,
        [EXIT_REASON_TASK_SWITCH]             = handle_task_switch,
+       [EXIT_REASON_EPT_VIOLATION]           = handle_ept_violation,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -2364,6 +2677,13 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)vmcs_readl(GUEST_RIP),
                    (u32)((u64)vmcs_readl(GUEST_RIP) >> 32), entryexit);
 
+       /* Access CR3 don't cause VMExit in paging mode, so we need
+        * to sync with guest real CR3. */
+       if (vm_need_ept() && is_paging(vcpu)) {
+               vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
+               ept_load_pdptrs(vcpu);
+       }
+
        if (unlikely(vmx->fail)) {
                kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
                kvm_run->fail_entry.hardware_entry_failure_reason
@@ -2372,7 +2692,8 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        }
 
        if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
-                               exit_reason != EXIT_REASON_EXCEPTION_NMI)
+                       (exit_reason != EXIT_REASON_EXCEPTION_NMI &&
+                       exit_reason != EXIT_REASON_EPT_VIOLATION))
                printk(KERN_WARNING "%s: unexpected, valid vectoring info and "
                       "exit reason is 0x%x\n", __func__, exit_reason);
        if (exit_reason < kvm_vmx_max_exit_handlers
@@ -2674,6 +2995,15 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
                return ERR_PTR(-ENOMEM);
 
        allocate_vpid(vmx);
+       if (id == 0 && vm_need_ept()) {
+               kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
+                       VMX_EPT_WRITABLE_MASK |
+                       VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
+               kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK,
+                               VMX_EPT_FAKE_DIRTY_MASK, 0ull,
+                               VMX_EPT_EXECUTABLE_MASK);
+               kvm_enable_tdp();
+       }
 
        err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
        if (err)
@@ -2706,6 +3036,10 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
                if (alloc_apic_access_page(kvm) != 0)
                        goto free_vmcs;
 
+       if (vm_need_ept())
+               if (alloc_identity_pagetable(kvm) != 0)
+                       goto free_vmcs;
+
        return &vmx->vcpu;
 
 free_vmcs:
@@ -2735,6 +3069,11 @@ static void __init vmx_check_processor_compat(void *rtn)
        }
 }
 
+static int get_ept_level(void)
+{
+       return VMX_EPT_DEFAULT_GAW + 1;
+}
+
 static struct kvm_x86_ops vmx_x86_ops = {
        .cpu_has_kvm_support = cpu_has_kvm_support,
        .disabled_by_bios = vmx_disabled_by_bios,
@@ -2791,6 +3130,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
        .inject_pending_vectors = do_interrupt_requests,
 
        .set_tss_addr = vmx_set_tss_addr,
+       .get_tdp_level = get_ept_level,
 };
 
 static int __init vmx_init(void)
@@ -2843,9 +3183,14 @@ static int __init vmx_init(void)
        vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP);
        vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP);
 
+       if (cpu_has_vmx_ept())
+               bypass_guest_pf = 0;
+
        if (bypass_guest_pf)
                kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull);
 
+       ept_sync_global();
+
        return 0;
 
 out2:
index 5dff4606b988591d4e0e82f6247945a829f7f977..79d94c610dfebf3c07f4b8ab0befd43aea83b3a7 100644 (file)
@@ -35,6 +35,8 @@
 #define CPU_BASED_MWAIT_EXITING                 0x00000400
 #define CPU_BASED_RDPMC_EXITING                 0x00000800
 #define CPU_BASED_RDTSC_EXITING                 0x00001000
+#define CPU_BASED_CR3_LOAD_EXITING             0x00008000
+#define CPU_BASED_CR3_STORE_EXITING            0x00010000
 #define CPU_BASED_CR8_LOAD_EXITING              0x00080000
 #define CPU_BASED_CR8_STORE_EXITING             0x00100000
 #define CPU_BASED_TPR_SHADOW                    0x00200000
@@ -49,6 +51,7 @@
  * Definitions of Secondary Processor-Based VM-Execution Controls.
  */
 #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
+#define SECONDARY_EXEC_ENABLE_EPT               0x00000002
 #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
 #define SECONDARY_EXEC_WBINVD_EXITING          0x00000040
 
@@ -100,10 +103,22 @@ enum vmcs_field {
        VIRTUAL_APIC_PAGE_ADDR_HIGH     = 0x00002013,
        APIC_ACCESS_ADDR                = 0x00002014,
        APIC_ACCESS_ADDR_HIGH           = 0x00002015,
+       EPT_POINTER                     = 0x0000201a,
+       EPT_POINTER_HIGH                = 0x0000201b,
+       GUEST_PHYSICAL_ADDRESS          = 0x00002400,
+       GUEST_PHYSICAL_ADDRESS_HIGH     = 0x00002401,
        VMCS_LINK_POINTER               = 0x00002800,
        VMCS_LINK_POINTER_HIGH          = 0x00002801,
        GUEST_IA32_DEBUGCTL             = 0x00002802,
        GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
+       GUEST_PDPTR0                    = 0x0000280a,
+       GUEST_PDPTR0_HIGH               = 0x0000280b,
+       GUEST_PDPTR1                    = 0x0000280c,
+       GUEST_PDPTR1_HIGH               = 0x0000280d,
+       GUEST_PDPTR2                    = 0x0000280e,
+       GUEST_PDPTR2_HIGH               = 0x0000280f,
+       GUEST_PDPTR3                    = 0x00002810,
+       GUEST_PDPTR3_HIGH               = 0x00002811,
        PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
        CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
        EXCEPTION_BITMAP                = 0x00004004,
@@ -226,6 +241,8 @@ enum vmcs_field {
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
 #define EXIT_REASON_APIC_ACCESS         44
+#define EXIT_REASON_EPT_VIOLATION       48
+#define EXIT_REASON_EPT_MISCONFIG       49
 #define EXIT_REASON_WBINVD             54
 
 /*
@@ -316,15 +333,36 @@ enum vmcs_field {
 #define MSR_IA32_VMX_CR4_FIXED1                 0x489
 #define MSR_IA32_VMX_VMCS_ENUM                  0x48a
 #define MSR_IA32_VMX_PROCBASED_CTLS2            0x48b
+#define MSR_IA32_VMX_EPT_VPID_CAP               0x48c
 
 #define MSR_IA32_FEATURE_CONTROL                0x3a
 #define MSR_IA32_FEATURE_CONTROL_LOCKED         0x1
 #define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED  0x4
 
 #define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT       9
+#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT     10
 
 #define VMX_NR_VPIDS                           (1 << 16)
 #define VMX_VPID_EXTENT_SINGLE_CONTEXT         1
 #define VMX_VPID_EXTENT_ALL_CONTEXT            2
 
+#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR         0
+#define VMX_EPT_EXTENT_CONTEXT                 1
+#define VMX_EPT_EXTENT_GLOBAL                  2
+#define VMX_EPT_EXTENT_INDIVIDUAL_BIT          (1ull << 24)
+#define VMX_EPT_EXTENT_CONTEXT_BIT             (1ull << 25)
+#define VMX_EPT_EXTENT_GLOBAL_BIT              (1ull << 26)
+#define VMX_EPT_DEFAULT_GAW                    3
+#define VMX_EPT_MAX_GAW                                0x4
+#define VMX_EPT_MT_EPTE_SHIFT                  3
+#define VMX_EPT_GAW_EPTP_SHIFT                 3
+#define VMX_EPT_DEFAULT_MT                     0x6ull
+#define VMX_EPT_READABLE_MASK                  0x1ull
+#define VMX_EPT_WRITABLE_MASK                  0x2ull
+#define VMX_EPT_EXECUTABLE_MASK                        0x4ull
+#define VMX_EPT_FAKE_ACCESSED_MASK             (1ull << 62)
+#define VMX_EPT_FAKE_DIRTY_MASK                        (1ull << 63)
+
+#define VMX_EPT_IDENTITY_PAGETABLE_ADDR                0xfffbc000ul
+
 #endif
index 0ce556372a4d1df614499224a634f4967afc8eb3..21338bdb28ff88a2577fb22d79aadfd9fee3cf39 100644 (file)
@@ -2417,6 +2417,9 @@ int kvm_arch_init(void *opaque)
 
        kvm_x86_ops = ops;
        kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
+       kvm_mmu_set_base_ptes(PT_PRESENT_MASK);
+       kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
+                       PT_DIRTY_MASK, PT64_NX_MASK, 0);
        return 0;
 
 out:
@@ -3019,6 +3022,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 
        kvm_x86_ops->decache_regs(vcpu);
 
+       vcpu->arch.exception.pending = false;
+
        vcpu_put(vcpu);
 
        return 0;
@@ -3481,7 +3486,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
        }
 
        if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) {
-               cseg_desc.type &= ~(1 << 8); //clear the B flag
+               cseg_desc.type &= ~(1 << 1); //clear the B flag
                save_guest_segment_descriptor(vcpu, tr_seg.selector,
                                              &cseg_desc);
        }
@@ -3507,7 +3512,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
        }
 
        if (reason != TASK_SWITCH_IRET) {
-               nseg_desc.type |= (1 << 8);
+               nseg_desc.type |= (1 << 1);
                save_guest_segment_descriptor(vcpu, tss_selector,
                                              &nseg_desc);
        }
@@ -3698,10 +3703,19 @@ void fx_init(struct kvm_vcpu *vcpu)
 {
        unsigned after_mxcsr_mask;
 
+       /*
+        * Touch the fpu the first time in non atomic context as if
+        * this is the first fpu instruction the exception handler
+        * will fire before the instruction returns and it'll have to
+        * allocate ram with GFP_KERNEL.
+        */
+       if (!used_math())
+               fx_save(&vcpu->arch.host_fx_image);
+
        /* Initialize guest FPU by resetting ours and saving into guest's */
        preempt_disable();
        fx_save(&vcpu->arch.host_fx_image);
-       fpu_init();
+       fx_finit();
        fx_save(&vcpu->arch.guest_fx_image);
        fx_restore(&vcpu->arch.host_fx_image);
        preempt_enable();
@@ -3906,6 +3920,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
        kvm_free_physmem(kvm);
        if (kvm->arch.apic_access_page)
                put_page(kvm->arch.apic_access_page);
+       if (kvm->arch.ept_identity_pagetable)
+               put_page(kvm->arch.ept_identity_pagetable);
        kfree(kvm);
 }
 
index 2ca08386f9937ea43c4d126ca011af96c10abde9..f2a696d6a24383b893504be0eb7a2a904d7abab3 100644 (file)
@@ -1761,6 +1761,7 @@ twobyte_insn:
                case 6: /* lmsw */
                        realmode_lmsw(ctxt->vcpu, (u16)c->src.val,
                                      &ctxt->eflags);
+                       c->dst.type = OP_NONE;
                        break;
                case 7: /* invlpg*/
                        emulate_invlpg(ctxt->vcpu, memop);
index bc503f506903a486a9a2fb4c56afd144466fff18..bf51144d97e1ffa4d19bc82968146f02db564888 100644 (file)
@@ -136,8 +136,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
                                                (__force u32)sum);
 }
 
-EXPORT_SYMBOL(csum_partial);
-
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
index 18378850e25aab13c3149903b5c2d6c611ca10a9..914ccf983687dd276b8cc5827d4430cf093fd822 100644 (file)
@@ -476,29 +476,3 @@ int memory_add_physaddr_to_nid(u64 addr)
 
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
-
-#ifndef CONFIG_HAVE_ARCH_PARSE_SRAT
-/*
- * XXX FIXME: Make SLIT table parsing available to 32-bit NUMA
- *
- * These stub functions are needed to compile 32-bit NUMA when SRAT is
- * not set. There are functions in srat_64.c for parsing this table
- * and it may be possible to make them common functions.
- */
-void acpi_numa_slit_init (struct acpi_table_slit *slit)
-{
-       printk(KERN_INFO "ACPI: No support for parsing SLIT table\n");
-}
-
-void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa)
-{
-}
-
-void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma)
-{
-}
-
-void acpi_numa_arch_fixup(void)
-{
-}
-#endif /* CONFIG_HAVE_ARCH_PARSE_SRAT */
index de236e419cb5f019feb154b710d519f6c3c95f55..ec30d10154b657a63ab07b5e25b4298c10f4aabe 100644 (file)
@@ -438,8 +438,6 @@ void zap_low_mappings(void)
 {
        int i;
 
-       save_pg_dir();
-
        /*
         * Zap initial low-memory mappings.
         *
@@ -663,16 +661,8 @@ void __init mem_init(void)
                test_wp_bit();
 
        cpa_init();
-
-       /*
-        * Subtle. SMP is doing it's boot stuff late (because it has to
-        * fork idle threads) - but it also needs low mappings for the
-        * protected-mode entry to work. We zap these entries only after
-        * the WP-bit has been tested.
-        */
-#ifndef CONFIG_SMP
+       save_pg_dir();
        zap_low_mappings();
-#endif
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
index 277446cd30b6de81a4634061949385cb6eaede69..bcb1a8e4b2db5b28626c1e153a625b2c304d4d24 100644 (file)
 #include <asm/mtrr.h>
 #include <asm/io.h>
 
-int pat_wc_enabled = 1;
+#ifdef CONFIG_X86_PAT
+int __read_mostly pat_wc_enabled = 1;
 
-static u64 __read_mostly boot_pat_state;
-
-static int nopat(char *str)
+void __init pat_disable(char *reason)
 {
        pat_wc_enabled = 0;
-       printk(KERN_INFO "x86: PAT support disabled.\n");
-
-       return 0;
+       printk(KERN_INFO "%s\n", reason);
 }
-early_param("nopat", nopat);
 
-static int pat_known_cpu(void)
+static int nopat(char *str)
 {
-       if (!pat_wc_enabled)
-               return 0;
-
-       if (cpu_has_pat)
-               return 1;
-
-       pat_wc_enabled = 0;
-       printk(KERN_INFO "CPU and/or kernel does not support PAT.\n");
+       pat_disable("PAT support disabled.");
        return 0;
 }
+early_param("nopat", nopat);
+#endif
+
+static u64 __read_mostly boot_pat_state;
 
 enum {
        PAT_UC = 0,             /* uncached */
@@ -66,17 +59,19 @@ void pat_init(void)
 {
        u64 pat;
 
-#ifndef CONFIG_X86_PAT
-       nopat(NULL);
-#endif
-
-       /* Boot CPU enables PAT based on CPU feature */
-       if (!smp_processor_id() && !pat_known_cpu())
+       if (!pat_wc_enabled)
                return;
 
-       /* APs enable PAT iff boot CPU has enabled it before */
-       if (smp_processor_id() && !pat_wc_enabled)
-               return;
+       /* Paranoia check. */
+       if (!cpu_has_pat) {
+               printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
+               /*
+                * Panic if this happens on the secondary CPU, and we
+                * switched to PAT on the boot CPU. We have no way to
+                * undo PAT.
+               */
+               BUG_ON(boot_pat_state);
+       }
 
        /* Set PWT to Write-Combining. All other bits stay the same */
        /*
@@ -95,9 +90,8 @@ void pat_init(void)
              PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);
 
        /* Boot CPU check */
-       if (!smp_processor_id()) {
+       if (!boot_pat_state)
                rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
-       }
 
        wrmsrl(MSR_IA32_CR_PAT, pat);
        printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",
@@ -561,7 +555,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
                "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
                        current->comm, current->pid,
                        cattr_name(flags),
-                       offset, offset + size);
+                       offset, (unsigned long long)(offset + size));
                return 0;
        }
 
@@ -582,7 +576,7 @@ void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
                "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
                        current->comm, current->pid,
                        cattr_name(want_flags),
-                       addr, addr + size,
+                       addr, (unsigned long long)(addr + size),
                        cattr_name(flags));
        }
 }
index 9ee007be914299ab8dae9d3f52df22ae606816f1..369cf065b6a48f78f9870ddaf9f27e59b6980c0c 100644 (file)
@@ -172,10 +172,3 @@ void reserve_top_address(unsigned long reserve)
        __FIXADDR_TOP = -reserve - PAGE_SIZE;
        __VMALLOC_RESERVE += reserve;
 }
-
-int pmd_bad(pmd_t pmd)
-{
-       WARN_ON_ONCE(pmd_bad_v1(pmd) != pmd_bad_v2(pmd));
-
-       return pmd_bad_v1(pmd);
-}
index 7fa519868d7091d4dd0b64fbb880c68517428f99..89ec35d00efde0ebde8488f84bc491cffe8fb092 100644 (file)
@@ -6,11 +6,19 @@ obj-$(CONFIG_PCI_DIRECT)      += direct.o
 obj-$(CONFIG_PCI_OLPC)         += olpc.o
 
 pci-y                          := fixup.o
+
+# Do not change the ordering here. There is a nasty init function
+# ordering dependency which breaks when you move acpi.o below
+# legacy/irq.o
 pci-$(CONFIG_ACPI)             += acpi.o
 pci-y                          += legacy.o irq.o
 
-pci-$(CONFIG_X86_VISWS)                += visws.o fixup.o
-pci-$(CONFIG_X86_NUMAQ)                += numa.o irq.o
+# Careful: VISWS and NUMAQ overrule the pci-y above. The colons are
+# therefor correct. This needs a proper fix by distangling the code.
+pci-$(CONFIG_X86_VISWS)                := visws.o fixup.o
+pci-$(CONFIG_X86_NUMAQ)                := numa.o irq.o
+
+# Necessary for NUMAQ as well
 pci-$(CONFIG_NUMA)             += mp_bus_to_node.o
 
 obj-y                          += $(pci-y) common.o early.o
index 1a9c0c6a1a1847f88c0024b06d18dfbd91d8cc22..d95de2f199cdaf45c3b44663dc32ed884de98b1d 100644 (file)
@@ -6,45 +6,6 @@
 #include <asm/numa.h>
 #include "pci.h"
 
-static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
-{
-       pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
-       printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
-       return 0;
-}
-
-static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = {
-/*
- * Systems where PCI IO resource ISA alignment can be skipped
- * when the ISA enable bit in the bridge control is not set
- */
-       {
-               .callback = can_skip_ioresource_align,
-               .ident = "IBM System x3800",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
-               },
-       },
-       {
-               .callback = can_skip_ioresource_align,
-               .ident = "IBM System x3850",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
-               },
-       },
-       {
-               .callback = can_skip_ioresource_align,
-               .ident = "IBM System x3950",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
-               },
-       },
-       {}
-};
-
 struct pci_root_info {
        char *name;
        unsigned int res_num;
@@ -196,8 +157,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
        int pxm;
 #endif
 
-       dmi_check_system(acpi_pciprobe_dmi_table);
-
        if (domain && !pci_domains_supported) {
                printk(KERN_WARNING "PCI: Multiple domains not supported "
                       "(dom %d, bus %d)\n", domain, busnum);
index 2a4d751818b731fd1ae0007ed2f1f9a94cdf12d1..8545c8a9d107c1947243eb38f1bba77dc1f58ff8 100644 (file)
@@ -77,17 +77,48 @@ int pcibios_scanned;
  */
 DEFINE_SPINLOCK(pci_config_lock);
 
-static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
 {
-       struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
-
-       if (rom_r->parent)
-               return;
-       if (rom_r->start)
-               /* we deal with BIOS assigned ROM later */
-               return;
-       if (!(pci_probe & PCI_ASSIGN_ROMS))
-               rom_r->start = rom_r->end = rom_r->flags = 0;
+       pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
+       printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
+       return 0;
+}
+
+static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
+/*
+ * Systems where PCI IO resource ISA alignment can be skipped
+ * when the ISA enable bit in the bridge control is not set
+ */
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3800",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+               },
+       },
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3850",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
+               },
+       },
+       {
+               .callback = can_skip_ioresource_align,
+               .ident = "IBM System x3950",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
+               },
+       },
+       {}
+};
+
+void __init dmi_check_skip_isa_align(void)
+{
+       dmi_check_system(can_skip_pciprobe_dmi_table);
 }
 
 /*
@@ -97,11 +128,7 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 
 void __devinit  pcibios_fixup_bus(struct pci_bus *b)
 {
-       struct pci_dev *dev;
-
        pci_read_bridge_bases(b);
-       list_for_each_entry(dev, &b->devices, bus_list)
-               pcibios_fixup_device_resources(dev);
 }
 
 /*
@@ -318,13 +345,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
        {}
 };
 
+void __init dmi_check_pciprobe(void)
+{
+       dmi_check_system(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);
-
        while ((bus = pci_find_next_bus(bus)) != NULL) {
                if (bus->number == busnum) {
                        /* Already scanned */
@@ -462,6 +492,9 @@ char * __devinit  pcibios_setup(char *str)
        } else if (!strcmp(str, "routeirq")) {
                pci_routeirq = 1;
                return NULL;
+       } else if (!strcmp(str, "skip_isa_align")) {
+               pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
+               return NULL;
        }
        return str;
 }
@@ -489,7 +522,7 @@ void pcibios_disable_device (struct pci_dev *dev)
                pcibios_disable_irq(dev);
 }
 
-struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
+struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
 {
        struct pci_bus *bus = NULL;
        struct pci_sysdata *sd;
@@ -512,7 +545,7 @@ struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
        return bus;
 }
 
-struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno)
 {
        return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
 }
index b60b2abd480cf774bad3f7c43e1e058c0a595681..ff3a6a33634231514c945a66f15328a6a8ce534a 100644 (file)
@@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
  */
 static void fam10h_pci_cfg_space_size(struct pci_dev *dev)
 {
-       dev->cfg_size = pci_cfg_space_size_ext(dev, 0);
+       dev->cfg_size = pci_cfg_space_size_ext(dev);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size);
index 8af0f0bae2af45f0baca08051056946235db7d1e..10fb308fded8efc85bfbbe7e4630f44342991e0a 100644 (file)
@@ -301,15 +301,13 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
        prot = pgprot_val(vma->vm_page_prot);
        if (pat_wc_enabled && write_combine)
                prot |= _PAGE_CACHE_WC;
-       else if (pat_wc_enabled)
+       else if (pat_wc_enabled || boot_cpu_data.x86 > 3)
                /*
                 * ioremap() and ioremap_nocache() defaults to UC MINUS for now.
                 * To avoid attribute conflicts, request UC MINUS here
                 * aswell.
                 */
                prot |= _PAGE_CACHE_UC_MINUS;
-       else if (boot_cpu_data.x86 > 3)
-               prot |= _PAGE_CACHE_UC;
 
        vma->vm_page_prot = __pgprot(prot);
 
index dd30c6076b5d74ff1be2929d7b8f84081c6a8250..e70b9c57b88e1f7e7d012a0fd5950170c163f5e5 100644 (file)
@@ -33,6 +33,10 @@ static __init int pci_access_init(void)
                printk(KERN_ERR
                "PCI: Fatal: No config space access function found\n");
 
+       dmi_check_pciprobe();
+
+       dmi_check_skip_isa_align();
+
        return 0;
 }
 arch_initcall(pci_access_init);
index ab6d4b18a88fdcc01fc63835ca60f1eded7827e1..5c2799c20e47b7a48b05e1fd15cbdbc79229d86b 100644 (file)
@@ -504,14 +504,6 @@ static int __init early_fill_mp_bus_info(void)
                }
        }
 
-#ifdef CONFIG_NUMA
-       for (i = 0; i < BUS_NR; i++) {
-               node = mp_bus_to_node[i];
-               if (node >= 0)
-                       printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
-       }
-#endif
-
        for (i = 0; i < pci_root_num; i++) {
                int res_num;
                int busnum;
index c58805a92db5788e508482dd1579640c782750d0..f3972b12c60a0066528e641028f3c9813e56786f 100644 (file)
@@ -38,6 +38,9 @@ enum pci_bf_sort_state {
        pci_dmi_bf,
 };
 
+extern void __init dmi_check_pciprobe(void);
+extern void __init dmi_check_skip_isa_align(void);
+
 /* pci-i386.c */
 
 extern unsigned int pcibios_max_latency;
index 4dceeb1fc5e0f229305c983d39c8cf6497b5a409..cf058fecfceec989354ec17a3d681cae65315935 100644 (file)
@@ -162,7 +162,7 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
        Elf32_Shdr *shdr;
        int i;
 
-       BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 ||
+       BUG_ON(memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 ||
               !elf_check_arch_ia32(ehdr) ||
               ehdr->e_type != ET_DYN);
 
index 4db42bff8c603ee216345bba6143ad5f5efd3dec..69527688f7940eebc63735a41f3431bdcbf280d6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- *
  * Copyright (C) 2007 Antonino Daplas <adaplas@gmail.com>
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -29,3 +28,4 @@ int fb_is_primary_device(struct fb_info *info)
        return retval;
 }
 EXPORT_SYMBOL(fb_is_primary_device);
+MODULE_LICENSE("GPL");
index 66e55288178c0840ba44ff0a859fc72c817baf89..a09ead19f9c5702a1ad76d709c54969176fe9e94 100644 (file)
@@ -26,8 +26,7 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,
 {
        if (ordered & (QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH) &&
            prepare_flush_fn == NULL) {
-               printk(KERN_ERR "%s: prepare_flush_fn required\n",
-                                                               __FUNCTION__);
+               printk(KERN_ERR "%s: prepare_flush_fn required\n", __func__);
                return -EINVAL;
        }
 
index 5d09f8c56024011588ec1b89e90bff2033a150ca..2987fe47b5eecaa565bce30a7c3d661813453351 100644 (file)
@@ -54,15 +54,16 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
 
 static void drive_stat_acct(struct request *rq, int new_io)
 {
+       struct hd_struct *part;
        int rw = rq_data_dir(rq);
 
        if (!blk_fs_request(rq) || !rq->rq_disk)
                return;
 
-       if (!new_io) {
-               __all_stat_inc(rq->rq_disk, merges[rw], rq->sector);
-       } else {
-               struct hd_struct *part = get_part(rq->rq_disk, rq->sector);
+       part = get_part(rq->rq_disk, rq->sector);
+       if (!new_io)
+               __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector);
+       else {
                disk_round_stats(rq->rq_disk);
                rq->rq_disk->in_flight++;
                if (part) {
@@ -136,7 +137,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
 
                if (unlikely(nbytes > bio->bi_size)) {
                        printk(KERN_ERR "%s: want %u bytes done, %u left\n",
-                              __FUNCTION__, nbytes, bio->bi_size);
+                              __func__, nbytes, bio->bi_size);
                        nbytes = bio->bi_size;
                }
 
@@ -253,9 +254,11 @@ EXPORT_SYMBOL(__generic_unplug_device);
  **/
 void generic_unplug_device(struct request_queue *q)
 {
-       spin_lock_irq(q->queue_lock);
-       __generic_unplug_device(q);
-       spin_unlock_irq(q->queue_lock);
+       if (blk_queue_plugged(q)) {
+               spin_lock_irq(q->queue_lock);
+               __generic_unplug_device(q);
+               spin_unlock_irq(q->queue_lock);
+       }
 }
 EXPORT_SYMBOL(generic_unplug_device);
 
@@ -1536,10 +1539,11 @@ static int __end_that_request_first(struct request *req, int error,
        }
 
        if (blk_fs_request(req) && req->rq_disk) {
+               struct hd_struct *part = get_part(req->rq_disk, req->sector);
                const int rw = rq_data_dir(req);
 
-               all_stat_add(req->rq_disk, sectors[rw],
-                            nr_bytes >> 9, req->sector);
+               all_stat_add(req->rq_disk, part, sectors[rw],
+                               nr_bytes >> 9, req->sector);
        }
 
        total_bytes = bio_nbytes = 0;
@@ -1566,8 +1570,7 @@ static int __end_that_request_first(struct request *req, int error,
                        if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
                                blk_dump_rq_flags(req, "__end_that");
                                printk(KERN_ERR "%s: bio idx %d >= vcnt %d\n",
-                                               __FUNCTION__, bio->bi_idx,
-                                               bio->bi_vcnt);
+                                      __func__, bio->bi_idx, bio->bi_vcnt);
                                break;
                        }
 
@@ -1726,8 +1729,8 @@ static void end_that_request_last(struct request *req, int error)
                const int rw = rq_data_dir(req);
                struct hd_struct *part = get_part(disk, req->sector);
 
-               __all_stat_inc(disk, ios[rw], req->sector);
-               __all_stat_add(disk, ticks[rw], duration, req->sector);
+               __all_stat_inc(disk, part, ios[rw], req->sector);
+               __all_stat_add(disk, part, ticks[rw], duration, req->sector);
                disk_round_stats(disk);
                disk->in_flight--;
                if (part) {
index e34df7c9fc367048de2c9e669a70291922467ba9..012f065ac8e248d4e42485a7ef9a728692bb43a1 100644 (file)
@@ -41,8 +41,8 @@ int put_io_context(struct io_context *ioc)
                rcu_read_lock();
                if (ioc->aic && ioc->aic->dtor)
                        ioc->aic->dtor(ioc->aic);
-               rcu_read_unlock();
                cfq_dtor(ioc);
+               rcu_read_unlock();
 
                kmem_cache_free(iocontext_cachep, ioc);
                return 1;
index 73b23562af20086f3a8623df6e9f32561ae330b5..651136aae76e45ba821205a830a919a3d6d105c5 100644 (file)
@@ -149,9 +149,9 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
 static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
                                 struct bio *nxt)
 {
-       if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+       if (!bio_flagged(bio, BIO_SEG_VALID))
                blk_recount_segments(q, bio);
-       if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID)))
+       if (!bio_flagged(nxt, BIO_SEG_VALID))
                blk_recount_segments(q, nxt);
        if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
            BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))
@@ -312,9 +312,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
                        q->last_merge = NULL;
                return 0;
        }
-       if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID)))
+       if (!bio_flagged(req->biotail, BIO_SEG_VALID))
                blk_recount_segments(q, req->biotail);
-       if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+       if (!bio_flagged(bio, BIO_SEG_VALID))
                blk_recount_segments(q, bio);
        len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size;
        if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio))
@@ -352,9 +352,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
                return 0;
        }
        len = bio->bi_hw_back_size + req->bio->bi_hw_front_size;
-       if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+       if (!bio_flagged(bio, BIO_SEG_VALID))
                blk_recount_segments(q, bio);
-       if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID)))
+       if (!bio_flagged(req->bio, BIO_SEG_VALID))
                blk_recount_segments(q, req->bio);
        if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) &&
            !BIOVEC_VIRT_OVERSIZE(len)) {
index 6089384ab06499becc951478d06dda2e22aa7e00..bb93d4c32775abdc2fdba16c3bc208fb20045f47 100644 (file)
@@ -168,8 +168,8 @@ void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
 {
        if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
                max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
-               printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__,
-                                                       max_sectors);
+               printk(KERN_INFO "%s: set to minimum %d\n",
+                      __func__, max_sectors);
        }
 
        if (BLK_DEF_MAX_SECTORS > max_sectors)
@@ -196,8 +196,8 @@ void blk_queue_max_phys_segments(struct request_queue *q,
 {
        if (!max_segments) {
                max_segments = 1;
-               printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__,
-                                                       max_segments);
+               printk(KERN_INFO "%s: set to minimum %d\n",
+                      __func__, max_segments);
        }
 
        q->max_phys_segments = max_segments;
@@ -220,8 +220,8 @@ void blk_queue_max_hw_segments(struct request_queue *q,
 {
        if (!max_segments) {
                max_segments = 1;
-               printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__,
-                                                       max_segments);
+               printk(KERN_INFO "%s: set to minimum %d\n",
+                      __func__, max_segments);
        }
 
        q->max_hw_segments = max_segments;
@@ -241,8 +241,8 @@ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size)
 {
        if (max_size < PAGE_CACHE_SIZE) {
                max_size = PAGE_CACHE_SIZE;
-               printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__,
-                                                       max_size);
+               printk(KERN_INFO "%s: set to minimum %d\n",
+                      __func__, max_size);
        }
 
        q->max_segment_size = max_size;
@@ -357,8 +357,8 @@ void blk_queue_segment_boundary(struct request_queue *q, unsigned long mask)
 {
        if (mask < PAGE_CACHE_SIZE - 1) {
                mask = PAGE_CACHE_SIZE - 1;
-               printk(KERN_INFO "%s: set to minimum %lx\n", __FUNCTION__,
-                                                       mask);
+               printk(KERN_INFO "%s: set to minimum %lx\n",
+                      __func__, mask);
        }
 
        q->seg_boundary_mask = mask;
index e85c4013e8a29a5924c4657447a2b6611eb17702..304ec73ab8215f270cbea1a50e870fd8b5b7bf54 100644 (file)
@@ -146,11 +146,13 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
        unsigned long nm;
        ssize_t ret = queue_var_store(&nm, page, count);
 
+       spin_lock_irq(q->queue_lock);
        if (nm)
-              set_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags);
+               queue_flag_set(QUEUE_FLAG_NOMERGES, q);
        else
-              clear_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags);
+               queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
 
+       spin_unlock_irq(q->queue_lock);
        return ret;
 }
 
index e176ddbe599e23796c004e3d0354cbc4c6b337cf..32667beb03eebf4d04b283f0a0cac999d66ad3e7 100644 (file)
@@ -70,7 +70,7 @@ void __blk_queue_free_tags(struct request_queue *q)
        __blk_free_tags(bqt);
 
        q->queue_tags = NULL;
-       queue_flag_clear(QUEUE_FLAG_QUEUED, q);
+       queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
 }
 
 /**
@@ -98,7 +98,7 @@ EXPORT_SYMBOL(blk_free_tags);
  **/
 void blk_queue_free_tags(struct request_queue *q)
 {
-       queue_flag_clear(QUEUE_FLAG_QUEUED, q);
+       queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
 }
 EXPORT_SYMBOL(blk_queue_free_tags);
 
@@ -112,7 +112,7 @@ init_tag_map(struct request_queue *q, struct blk_queue_tag *tags, int depth)
        if (q && depth > q->nr_requests * 2) {
                depth = q->nr_requests * 2;
                printk(KERN_ERR "%s: adjusted depth to %d\n",
-                               __FUNCTION__, depth);
+                      __func__, depth);
        }
 
        tag_index = kzalloc(depth * sizeof(struct request *), GFP_ATOMIC);
@@ -171,6 +171,9 @@ EXPORT_SYMBOL(blk_init_tags);
  * @q:  the request queue for the device
  * @depth:  the maximum queue depth supported
  * @tags: the tag to use
+ *
+ * Queue lock must be held here if the function is called to resize an
+ * existing map.
  **/
 int blk_queue_init_tags(struct request_queue *q, int depth,
                        struct blk_queue_tag *tags)
@@ -197,7 +200,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
         * assign it, all done
         */
        q->queue_tags = tags;
-       queue_flag_set(QUEUE_FLAG_QUEUED, q);
+       queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q);
        INIT_LIST_HEAD(&q->tag_busy_list);
        return 0;
 fail:
@@ -296,13 +299,13 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
 
        if (unlikely(bqt->tag_index[tag] == NULL))
                printk(KERN_ERR "%s: tag %d is missing\n",
-                      __FUNCTION__, tag);
+                      __func__, tag);
 
        bqt->tag_index[tag] = NULL;
 
        if (unlikely(!test_bit(tag, bqt->tag_map))) {
                printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
-                      __FUNCTION__, tag);
+                      __func__, tag);
                return;
        }
        /*
@@ -340,7 +343,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
        if (unlikely((rq->cmd_flags & REQ_QUEUED))) {
                printk(KERN_ERR
                       "%s: request %p for device [%s] already tagged %d",
-                      __FUNCTION__, rq,
+                      __func__, rq,
                       rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
                BUG();
        }
index 568588cd16b22d546771e18fb4e34f9be4811afe..b2cbb4e5d7673c7a49ea557d962022f7ba3594f9 100644 (file)
@@ -476,7 +476,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
 
        switch (cmd) {
        case BLKTRACESETUP:
-               strcpy(b, bdevname(bdev, b));
+               bdevname(bdev, b);
                ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
                break;
        case BLKTRACESTART:
index 23ea4fd1a66d9464b0b3af5dd53f997852f65c1a..f0b7cd3432160203ea6c650088ccfcd4acf2a3f6 100644 (file)
@@ -57,7 +57,7 @@ enum {
 #undef BSG_DEBUG
 
 #ifdef BSG_DEBUG
-#define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ##args)
+#define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ##args)
 #else
 #define dprintk(fmt, args...)
 #endif
@@ -174,7 +174,11 @@ unlock:
 static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
                                struct sg_io_v4 *hdr, int has_write_perm)
 {
-       memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
+       if (hdr->request_len > BLK_MAX_CDB) {
+               rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
+               if (!rq->cmd)
+                       return -ENOMEM;
+       }
 
        if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request,
                           hdr->request_len))
@@ -211,8 +215,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
 
        if (hdr->guard != 'Q')
                return -EINVAL;
-       if (hdr->request_len > BLK_MAX_CDB)
-               return -EINVAL;
        if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
            hdr->din_xfer_len > (q->max_sectors << 9))
                return -EIO;
@@ -302,6 +304,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
        }
        return rq;
 out:
+       if (rq->cmd != rq->__cmd)
+               kfree(rq->cmd);
        blk_put_request(rq);
        if (next_rq) {
                blk_rq_unmap_user(next_rq->bio);
@@ -455,6 +459,8 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
                ret = rq->errors;
 
        blk_rq_unmap_user(bio);
+       if (rq->cmd != rq->__cmd)
+               kfree(rq->cmd);
        blk_put_request(rq);
 
        return ret;
index f4e1006c253d3ade81cc9b39ce80da6612b277a6..b399c62936e01a503715273ffef29ac2fafef8a4 100644 (file)
@@ -1142,6 +1142,17 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
        kmem_cache_free(cfq_pool, cfqq);
 }
 
+static void
+__call_for_each_cic(struct io_context *ioc,
+                   void (*func)(struct io_context *, struct cfq_io_context *))
+{
+       struct cfq_io_context *cic;
+       struct hlist_node *n;
+
+       hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
+               func(ioc, cic);
+}
+
 /*
  * Call func for each cic attached to this ioc.
  */
@@ -1149,12 +1160,8 @@ static void
 call_for_each_cic(struct io_context *ioc,
                  void (*func)(struct io_context *, struct cfq_io_context *))
 {
-       struct cfq_io_context *cic;
-       struct hlist_node *n;
-
        rcu_read_lock();
-       hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
-               func(ioc, cic);
+       __call_for_each_cic(ioc, func);
        rcu_read_unlock();
 }
 
@@ -1198,7 +1205,7 @@ static void cfq_free_io_context(struct io_context *ioc)
         * should be ok to iterate over the known list, we will see all cic's
         * since no new ones are added.
         */
-       call_for_each_cic(ioc, cic_free_func);
+       __call_for_each_cic(ioc, cic_free_func);
 }
 
 static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -1296,10 +1303,10 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
                printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class);
        case IOPRIO_CLASS_NONE:
                /*
-                * no prio set, place us in the middle of the BE classes
+                * no prio set, inherit CPU scheduling settings
                 */
                cfqq->ioprio = task_nice_ioprio(tsk);
-               cfqq->ioprio_class = IOPRIO_CLASS_BE;
+               cfqq->ioprio_class = task_nice_ioclass(tsk);
                break;
        case IOPRIO_CLASS_RT:
                cfqq->ioprio = task_ioprio(ioc);
index c70d0b6f666fff96feb69f97fe9ed30e2990fa19..c23177e4623f1ba73804479460742dd63339556a 100644 (file)
@@ -555,7 +555,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
        if (copy_from_user(&cbuts, arg, sizeof(cbuts)))
                return -EFAULT;
 
-       strcpy(b, bdevname(bdev, b));
+       bdevname(bdev, b);
 
        buts = (struct blk_user_trace_setup) {
                .act_mask = cbuts.act_mask,
index ac5310ef8270984e32799e0524917abf4246853a..980f8ae147b4c396b15886be25bd9b2342322472 100644 (file)
@@ -650,7 +650,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
 
        default:
                printk(KERN_ERR "%s: bad insertion point %d\n",
-                      __FUNCTION__, where);
+                      __func__, where);
                BUG();
        }
 
@@ -808,8 +808,7 @@ struct request *elv_next_request(struct request_queue *q)
                        rq->cmd_flags |= REQ_QUIET;
                        end_queued_request(rq, 0);
                } else {
-                       printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
-                                                               ret);
+                       printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
                        break;
                }
        }
index ffa3720e6ca05de7830a466664327deed289aa12..78199c08ec92fc7c23549ef41c7d5b0862cfb938 100644 (file)
 #include <scsi/scsi_cmnd.h>
 
 /* Command group 3 is reserved and should never be used.  */
-const unsigned char scsi_command_size[8] =
+const unsigned char scsi_command_size_tbl[8] =
 {
        6, 10, 10, 12,
        16, 12, 10, 10
 };
-
-EXPORT_SYMBOL(scsi_command_size);
+EXPORT_SYMBOL(scsi_command_size_tbl);
 
 #include <scsi/sg.h>
 
index ed8ac5a6fa5ff0bc22fa67fc193a1b0629d4a063..4b226768752abed604033f708d093f0b04aee41b 100644 (file)
@@ -217,9 +217,10 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
                                           int err)
 {
        if (!err) {
-               struct aead_givcrypt_request *greq = req->data;
+               struct aead_request *areq = req->data;
+               struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
 
-               err = crypto_authenc_genicv(&greq->areq, greq->giv, 0);
+               err = crypto_authenc_genicv(areq, greq->giv, 0);
        }
 
        aead_request_complete(req->data, err);
index 250425263e00e59fad2b5a11436ce5a02b9dbe41..b150de562057f59bd85a69f0bb4e3267589c6bff 100644 (file)
@@ -190,8 +190,10 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
        int err;
 
        inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
-       if (IS_ERR(inst))
+       if (!inst) {
+               inst = ERR_PTR(-ENOMEM);
                goto out;
+       }
 
        err = -ENAMETOOLONG;
        if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
index b14f14e314b6cf3ada4bc0694aa9f5f364ab73e7..881d30910434831f528f5be244ab502bd984d0b6 100644 (file)
@@ -136,7 +136,8 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
        }
 
        ablkcipher_request_set_crypt(subreq, reqctx->src, dst,
-                                    req->creq.nbytes, req->creq.info);
+                                    req->creq.nbytes + ivsize,
+                                    req->creq.info);
 
        memcpy(req->creq.info, ctx->salt, ivsize);
 
index b60c3c7aa320ba08548c050f4fc05d231321de61..14c6351e639d9484aa093fac191c7919a99127b4 100644 (file)
@@ -57,14 +57,35 @@ static int hmac_setkey(struct crypto_hash *parent,
        if (keylen > bs) {
                struct hash_desc desc;
                struct scatterlist tmp;
+               int tmplen;
                int err;
 
                desc.tfm = tfm;
                desc.flags = crypto_hash_get_flags(parent);
                desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP;
-               sg_init_one(&tmp, inkey, keylen);
 
-               err = crypto_hash_digest(&desc, &tmp, keylen, digest);
+               err = crypto_hash_init(&desc);
+               if (err)
+                       return err;
+
+               tmplen = bs * 2 + ds;
+               sg_init_one(&tmp, ipad, tmplen);
+
+               for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) {
+                       memcpy(ipad, inkey, tmplen);
+                       err = crypto_hash_update(&desc, &tmp, tmplen);
+                       if (err)
+                               return err;
+               }
+
+               if (keylen) {
+                       memcpy(ipad, inkey, keylen);
+                       err = crypto_hash_update(&desc, &tmp, keylen);
+                       if (err)
+                               return err;
+               }
+
+               err = crypto_hash_final(&desc, digest);
                if (err)
                        return err;
 
index 1264c4b980942447afbade6fe1f0c947e311aea1..ef3b65bfdd0ac57d49a323174fab431b167c69c0 100644 (file)
@@ -1,7 +1,17 @@
 menuconfig ACCESSIBILITY
        bool "Accessibility support"
        ---help---
-         Enable a submenu where accessibility items may be enabled.
+         Accessibility handles all special kinds of hardware devices or
+         software adapters which help people with disabilities (e.g.
+         blindness) to use computers.
+
+         That includes braille devices, speech synthesis, keyboard
+         remapping, etc.
+
+         Say Y here to get to see options for accessibility.
+         This option alone does not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
 
          If unsure, say N.
 
index 1c11df9a5f32a92e3ff7fda7700450deccf228b4..9bf2986a2788d6bd11e26bdd459bdf9ed376fcb5 100644 (file)
@@ -205,8 +205,8 @@ config SATA_VITESSE
          If unsure, say N.
 
 config SATA_INIC162X
-       tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
+       tristate "Initio 162x SATA support"
+       depends on PCI
        help
          This option enables support for Initio 162x Serial ATA.
 
@@ -697,6 +697,15 @@ config PATA_SCC
 
          If unsure, say N.
 
+config PATA_SCH
+       tristate "Intel SCH PATA support"
+       depends on PCI
+       help
+         This option enables support for Intel SCH PATA on the Intel
+         SCH (US15W, US15L, UL11L) series host controllers.
+
+         If unsure, say N.
+
 config PATA_BF54X
        tristate "Blackfin 54x ATAPI support"
        depends on BF542 || BF548 || BF549
index b693d829383a3b7ff9e33bd0d181523f23297379..674965fa326dafa621311ed92dfcc91d80380296 100644 (file)
@@ -67,6 +67,7 @@ obj-$(CONFIG_PATA_SIS)                += pata_sis.o
 obj-$(CONFIG_PATA_TRIFLEX)     += pata_triflex.o
 obj-$(CONFIG_PATA_IXP4XX_CF)   += pata_ixp4xx_cf.o
 obj-$(CONFIG_PATA_SCC)         += pata_scc.o
+obj-$(CONFIG_PATA_SCH)         += pata_sch.o
 obj-$(CONFIG_PATA_BF54X)       += pata_bf54x.o
 obj-$(CONFIG_PATA_PLATFORM)    += pata_platform.o
 obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
index 8cace9aa9c0398bafe101115ba511bb5dd29f0fb..97f83fb2ee2eef25af748297cb474c859ba6545e 100644 (file)
@@ -1267,9 +1267,7 @@ static int ahci_check_ready(struct ata_link *link)
        void __iomem *port_mmio = ahci_port_base(link->ap);
        u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
 
-       if (!(status & ATA_BUSY))
-               return 1;
-       return 0;
+       return ata_check_ready(status);
 }
 
 static int ahci_softreset(struct ata_link *link, unsigned int *class,
index 47aeccd52fa951b900bacd63d4af7e71cf370039..75a406f5e6945525d4799bc44de7ccf6e1552feb 100644 (file)
@@ -152,6 +152,12 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
        if (dev->vendor == PCI_VENDOR_ID_AL)
                ata_pci_bmdma_clear_simplex(dev);
 
+       if (dev->vendor == PCI_VENDOR_ID_ATI) {
+               int rc = pcim_enable_device(dev);
+               if (rc < 0)
+                       return rc;
+               pcim_pin_device(dev);
+       }
        return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL);
 }
 
index ea2c7649d399b38c70c987703246de96e9e2b00a..a9027b8fbdd53fbb7ea3e2b6257a84924375b9f3 100644 (file)
@@ -1348,6 +1348,8 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct piix_host_priv *hpriv = host->private_data;
+       struct ata_device *dev0 = &host->ports[0]->link.device[0];
+       u32 scontrol;
        int i;
 
        /* check for availability */
@@ -1366,6 +1368,29 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
                return;
 
        hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
+
+       /* SCR access via SIDPR doesn't work on some configurations.
+        * Give it a test drive by inhibiting power save modes which
+        * we'll do anyway.
+        */
+       scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+       /* if IPM is already 3, SCR access is probably working.  Don't
+        * un-inhibit power save modes as BIOS might have inhibited
+        * them for a reason.
+        */
+       if ((scontrol & 0xf00) != 0x300) {
+               scontrol |= 0x300;
+               piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
+               scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+               if ((scontrol & 0xf00) != 0x300) {
+                       dev_printk(KERN_INFO, host->dev, "SCR access via "
+                                  "SIDPR is available but doesn't work\n");
+                       return;
+               }
+       }
+
        host->ports[0]->ops = &piix_sidpr_sata_ops;
        host->ports[1]->ops = &piix_sidpr_sata_ops;
 }
index 3bc488538204abe225b388346d3b2a65a1c5ed5d..927b692d723cb190f73e30d09891bf62336770ea 100644 (file)
@@ -6292,6 +6292,7 @@ EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
 EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
+EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
 EXPORT_SYMBOL_GPL(ata_do_eh);
 EXPORT_SYMBOL_GPL(ata_std_error_handler);
 
index 61dcd0026c64c301c8ce43a0ec89e5eebaf755f8..62e033146bedae50c7de7126f0f3a8b2aec67b17 100644 (file)
@@ -1357,7 +1357,7 @@ static void ata_eh_analyze_serror(struct ata_link *link)
  *     LOCKING:
  *     Kernel thread context (may sleep).
  */
-static void ata_eh_analyze_ncq_error(struct ata_link *link)
+void ata_eh_analyze_ncq_error(struct ata_link *link)
 {
        struct ata_port *ap = link->ap;
        struct ata_eh_context *ehc = &link->eh_context;
index 2ec65a8fda79ecc46986ed0da6de7d886c71ccf5..3c2d2289f85ee3233c259a4508fdb134e969053d 100644 (file)
@@ -314,11 +314,7 @@ static int ata_sff_check_ready(struct ata_link *link)
 {
        u8 status = link->ap->ops->sff_check_status(link->ap);
 
-       if (!(status & ATA_BUSY))
-               return 1;
-       if (status == 0xff)
-               return -ENODEV;
-       return 0;
+       return ata_check_ready(status);
 }
 
 /**
index c5f91e629945040130f53a28bd6bc7b920f87b36..fbe605711554a24dd1ae23be66d02128c8193b18 100644 (file)
@@ -259,6 +259,12 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops       = &pacpi_ops,
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
+       if (pdev->vendor == PCI_VENDOR_ID_ATI) {
+               int rc = pcim_enable_device(pdev);
+               if (rc < 0)
+                       return rc;
+               pcim_pin_device(pdev);
+       }
        return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
 }
 
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
new file mode 100644 (file)
index 0000000..c8cc027
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ *  pata_sch.c - Intel SCH PATA controllers
+ *
+ *  Copyright (c) 2008 Alek Du <alek.du@intel.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ *  Supports:
+ *    Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at:
+ *    http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/dmi.h>
+
+#define DRV_NAME       "pata_sch"
+#define DRV_VERSION    "0.2"
+
+/* see SCH datasheet page 351 */
+enum {
+       D0TIM   = 0x80,         /* Device 0 Timing Register */
+       D1TIM   = 0x84,         /* Device 1 Timing Register */
+       PM      = 0x07,         /* PIO Mode Bit Mask */
+       MDM     = (0x03 << 8),  /* Multi-word DMA Mode Bit Mask */
+       UDM     = (0x07 << 16), /* Ultra DMA Mode Bit Mask */
+       PPE     = (1 << 30),    /* Prefetch/Post Enable */
+       USD     = (1 << 31),    /* Use Synchronous DMA */
+};
+
+static int sch_init_one(struct pci_dev *pdev,
+                        const struct pci_device_id *ent);
+static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev);
+static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev);
+
+static const struct pci_device_id sch_pci_tbl[] = {
+       /* Intel SCH PATA Controller */
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 },
+       { }     /* terminate list */
+};
+
+static struct pci_driver sch_pci_driver = {
+       .name                   = DRV_NAME,
+       .id_table               = sch_pci_tbl,
+       .probe                  = sch_init_one,
+       .remove                 = ata_pci_remove_one,
+#ifdef CONFIG_PM
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = ata_pci_device_resume,
+#endif
+};
+
+static struct scsi_host_template sch_sht = {
+       ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations sch_pata_ops = {
+       .inherits               = &ata_bmdma_port_ops,
+       .cable_detect           = ata_cable_unknown,
+       .set_piomode            = sch_set_piomode,
+       .set_dmamode            = sch_set_dmamode,
+};
+
+static struct ata_port_info sch_port_info = {
+       .flags          = 0,
+       .pio_mask       = ATA_PIO4,   /* pio0-4 */
+       .mwdma_mask     = ATA_MWDMA2, /* mwdma0-2 */
+       .udma_mask      = ATA_UDMA5,  /* udma0-5 */
+       .port_ops       = &sch_pata_ops,
+};
+
+MODULE_AUTHOR("Alek Du <alek.du@intel.com>");
+MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, sch_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+/**
+ *     sch_set_piomode - Initialize host controller PATA PIO timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: ATA device
+ *
+ *     Set PIO mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+       unsigned int pio        = adev->pio_mode - XFER_PIO_0;
+       struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+       unsigned int port       = adev->devno ? D1TIM : D0TIM;
+       unsigned int data;
+
+       pci_read_config_dword(dev, port, &data);
+       /* see SCH datasheet page 351 */
+       /* set PIO mode */
+       data &= ~(PM | PPE);
+       data |= pio;
+       /* enable PPE for block device */
+       if (adev->class == ATA_DEV_ATA)
+               data |= PPE;
+       pci_write_config_dword(dev, port, data);
+}
+
+/**
+ *     sch_set_dmamode - Initialize host controller PATA DMA timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: ATA device
+ *
+ *     Set MW/UDMA mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+       unsigned int dma_mode   = adev->dma_mode;
+       struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+       unsigned int port       = adev->devno ? D1TIM : D0TIM;
+       unsigned int data;
+
+       pci_read_config_dword(dev, port, &data);
+       /* see SCH datasheet page 351 */
+       if (dma_mode >= XFER_UDMA_0) {
+               /* enable Synchronous DMA mode */
+               data |= USD;
+               data &= ~UDM;
+               data |= (dma_mode - XFER_UDMA_0) << 16;
+       } else { /* must be MWDMA mode, since we masked SWDMA already */
+               data &= ~(USD | MDM);
+               data |= (dma_mode - XFER_MW_DMA_0) << 8;
+       }
+       pci_write_config_dword(dev, port, data);
+}
+
+/**
+ *     sch_init_one - Register SCH ATA PCI device with kernel services
+ *     @pdev: PCI device to register
+ *     @ent: Entry in sch_pci_tbl matching with @pdev
+ *
+ *     LOCKING:
+ *     Inherited from PCI layer (may sleep).
+ *
+ *     RETURNS:
+ *     Zero on success, or -ERRNO value.
+ */
+
+static int __devinit sch_init_one(struct pci_dev *pdev,
+                                  const struct pci_device_id *ent)
+{
+       static int printed_version;
+       const struct ata_port_info *ppi[] = { &sch_port_info, NULL };
+       struct ata_host *host;
+       int rc;
+
+       if (!printed_version++)
+               dev_printk(KERN_DEBUG, &pdev->dev,
+                          "version " DRV_VERSION "\n");
+
+       /* enable device and prepare host */
+       rc = pcim_enable_device(pdev);
+       if (rc)
+               return rc;
+       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       if (rc)
+               return rc;
+       pci_set_master(pdev);
+       return ata_pci_sff_activate_host(host, ata_sff_interrupt, &sch_sht);
+}
+
+static int __init sch_init(void)
+{
+       return pci_register_driver(&sch_pci_driver);
+}
+
+static void __exit sch_exit(void)
+{
+       pci_unregister_driver(&sch_pci_driver);
+}
+
+module_init(sch_init);
+module_exit(sch_exit);
index d27bb9a2568f77678e82dfbc032df8045daa4b94..3ead02fe379e26ca1dac0130a323e06888ba7f35 100644 (file)
  * right.  Documentation is available at initio's website but it only
  * documents registers (not programming model).
  *
- * - ATA disks work.
- * - Hotplug works.
- * - ATAPI read works but burning doesn't.  This thing is really
- *   peculiar about ATAPI and I couldn't figure out how ATAPI PIO and
- *   ATAPI DMA WRITE should be programmed.  If you've got a clue, be
- *   my guest.
- * - Both STR and STD work.
+ * This driver has interesting history.  The first version was written
+ * from the documentation and a 2.4 IDE driver posted on a Taiwan
+ * company, which didn't use any IDMA features and couldn't handle
+ * LBA48.  The resulting driver couldn't handle LBA48 devices either
+ * making it pretty useless.
+ *
+ * After a while, initio picked the driver up, renamed it to
+ * sata_initio162x, updated it to use IDMA for ATA DMA commands and
+ * posted it on their website.  It only used ATA_PROT_DMA for IDMA and
+ * attaching both devices and issuing IDMA and !IDMA commands
+ * simultaneously broke it due to PIRQ masking interaction but it did
+ * show how to use the IDMA (ADMA + some initio specific twists)
+ * engine.
+ *
+ * Then, I picked up their changes again and here's the usable driver
+ * which uses IDMA for everything.  Everything works now including
+ * LBA48, CD/DVD burning, suspend/resume and hotplug.  There are some
+ * issues tho.  Result Tf is not resported properly, NCQ isn't
+ * supported yet and CD/DVD writing works with DMA assisted PIO
+ * protocol (which, for native SATA devices, shouldn't cause any
+ * noticeable difference).
+ *
+ * Anyways, so, here's finally a working driver for inic162x.  Enjoy!
+ *
+ * initio: If you guys wanna improve the driver regarding result TF
+ * access and other stuff, please feel free to contact me.  I'll be
+ * happy to assist.
  */
 
 #include <linux/kernel.h>
 #include <scsi/scsi_device.h>
 
 #define DRV_NAME       "sata_inic162x"
-#define DRV_VERSION    "0.3"
+#define DRV_VERSION    "0.4"
 
 enum {
-       MMIO_BAR                = 5,
+       MMIO_BAR_PCI            = 5,
+       MMIO_BAR_CARDBUS        = 1,
 
        NR_PORTS                = 2,
 
+       IDMA_CPB_TBL_SIZE       = 4 * 32,
+
+       INIC_DMA_BOUNDARY       = 0xffffff,
+
+       HOST_ACTRL              = 0x08,
        HOST_CTL                = 0x7c,
        HOST_STAT               = 0x7e,
        HOST_IRQ_STAT           = 0xbc,
@@ -43,22 +69,37 @@ enum {
        PORT_SIZE               = 0x40,
 
        /* registers for ATA TF operation */
-       PORT_TF                 = 0x00,
-       PORT_ALT_STAT           = 0x08,
+       PORT_TF_DATA            = 0x00,
+       PORT_TF_FEATURE         = 0x01,
+       PORT_TF_NSECT           = 0x02,
+       PORT_TF_LBAL            = 0x03,
+       PORT_TF_LBAM            = 0x04,
+       PORT_TF_LBAH            = 0x05,
+       PORT_TF_DEVICE          = 0x06,
+       PORT_TF_COMMAND         = 0x07,
+       PORT_TF_ALT_STAT        = 0x08,
        PORT_IRQ_STAT           = 0x09,
        PORT_IRQ_MASK           = 0x0a,
        PORT_PRD_CTL            = 0x0b,
        PORT_PRD_ADDR           = 0x0c,
        PORT_PRD_XFERLEN        = 0x10,
+       PORT_CPB_CPBLAR         = 0x18,
+       PORT_CPB_PTQFIFO        = 0x1c,
 
        /* IDMA register */
        PORT_IDMA_CTL           = 0x14,
+       PORT_IDMA_STAT          = 0x16,
+
+       PORT_RPQ_FIFO           = 0x1e,
+       PORT_RPQ_CNT            = 0x1f,
 
        PORT_SCR                = 0x20,
 
        /* HOST_CTL bits */
        HCTL_IRQOFF             = (1 << 8),  /* global IRQ off */
-       HCTL_PWRDWN             = (1 << 13), /* power down PHYs */
+       HCTL_FTHD0              = (1 << 10), /* fifo threshold 0 */
+       HCTL_FTHD1              = (1 << 11), /* fifo threshold 1*/
+       HCTL_PWRDWN             = (1 << 12), /* power down PHYs */
        HCTL_SOFTRST            = (1 << 13), /* global reset (no phy reset) */
        HCTL_RPGSEL             = (1 << 15), /* register page select */
 
@@ -81,9 +122,7 @@ enum {
        PIRQ_PENDING            = (1 << 7),  /* port IRQ pending (STAT only) */
 
        PIRQ_ERR                = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL,
-
-       PIRQ_MASK_DMA_READ      = PIRQ_REPLY | PIRQ_ATA,
-       PIRQ_MASK_OTHER         = PIRQ_REPLY | PIRQ_COMPLETE,
+       PIRQ_MASK_DEFAULT       = PIRQ_REPLY | PIRQ_ATA,
        PIRQ_MASK_FREEZE        = 0xff,
 
        /* PORT_PRD_CTL bits */
@@ -96,20 +135,104 @@ enum {
        IDMA_CTL_RST_IDMA       = (1 << 5),  /* reset IDMA machinary */
        IDMA_CTL_GO             = (1 << 7),  /* IDMA mode go */
        IDMA_CTL_ATA_NIEN       = (1 << 8),  /* ATA IRQ disable */
+
+       /* PORT_IDMA_STAT bits */
+       IDMA_STAT_PERR          = (1 << 0),  /* PCI ERROR MODE */
+       IDMA_STAT_CPBERR        = (1 << 1),  /* ADMA CPB error */
+       IDMA_STAT_LGCY          = (1 << 3),  /* ADMA legacy */
+       IDMA_STAT_UIRQ          = (1 << 4),  /* ADMA unsolicited irq */
+       IDMA_STAT_STPD          = (1 << 5),  /* ADMA stopped */
+       IDMA_STAT_PSD           = (1 << 6),  /* ADMA pause */
+       IDMA_STAT_DONE          = (1 << 7),  /* ADMA done */
+
+       IDMA_STAT_ERR           = IDMA_STAT_PERR | IDMA_STAT_CPBERR,
+
+       /* CPB Control Flags*/
+       CPB_CTL_VALID           = (1 << 0),  /* CPB valid */
+       CPB_CTL_QUEUED          = (1 << 1),  /* queued command */
+       CPB_CTL_DATA            = (1 << 2),  /* data, rsvd in datasheet */
+       CPB_CTL_IEN             = (1 << 3),  /* PCI interrupt enable */
+       CPB_CTL_DEVDIR          = (1 << 4),  /* device direction control */
+
+       /* CPB Response Flags */
+       CPB_RESP_DONE           = (1 << 0),  /* ATA command complete */
+       CPB_RESP_REL            = (1 << 1),  /* ATA release */
+       CPB_RESP_IGNORED        = (1 << 2),  /* CPB ignored */
+       CPB_RESP_ATA_ERR        = (1 << 3),  /* ATA command error */
+       CPB_RESP_SPURIOUS       = (1 << 4),  /* ATA spurious interrupt error */
+       CPB_RESP_UNDERFLOW      = (1 << 5),  /* APRD deficiency length error */
+       CPB_RESP_OVERFLOW       = (1 << 6),  /* APRD exccess length error */
+       CPB_RESP_CPB_ERR        = (1 << 7),  /* CPB error flag */
+
+       /* PRD Control Flags */
+       PRD_DRAIN               = (1 << 1),  /* ignore data excess */
+       PRD_CDB                 = (1 << 2),  /* atapi packet command pointer */
+       PRD_DIRECT_INTR         = (1 << 3),  /* direct interrupt */
+       PRD_DMA                 = (1 << 4),  /* data transfer method */
+       PRD_WRITE               = (1 << 5),  /* data dir, rsvd in datasheet */
+       PRD_IOM                 = (1 << 6),  /* io/memory transfer */
+       PRD_END                 = (1 << 7),  /* APRD chain end */
 };
 
+/* Comman Parameter Block */
+struct inic_cpb {
+       u8              resp_flags;     /* Response Flags */
+       u8              error;          /* ATA Error */
+       u8              status;         /* ATA Status */
+       u8              ctl_flags;      /* Control Flags */
+       __le32          len;            /* Total Transfer Length */
+       __le32          prd;            /* First PRD pointer */
+       u8              rsvd[4];
+       /* 16 bytes */
+       u8              feature;        /* ATA Feature */
+       u8              hob_feature;    /* ATA Ex. Feature */
+       u8              device;         /* ATA Device/Head */
+       u8              mirctl;         /* Mirror Control */
+       u8              nsect;          /* ATA Sector Count */
+       u8              hob_nsect;      /* ATA Ex. Sector Count */
+       u8              lbal;           /* ATA Sector Number */
+       u8              hob_lbal;       /* ATA Ex. Sector Number */
+       u8              lbam;           /* ATA Cylinder Low */
+       u8              hob_lbam;       /* ATA Ex. Cylinder Low */
+       u8              lbah;           /* ATA Cylinder High */
+       u8              hob_lbah;       /* ATA Ex. Cylinder High */
+       u8              command;        /* ATA Command */
+       u8              ctl;            /* ATA Control */
+       u8              slave_error;    /* Slave ATA Error */
+       u8              slave_status;   /* Slave ATA Status */
+       /* 32 bytes */
+} __packed;
+
+/* Physical Region Descriptor */
+struct inic_prd {
+       __le32          mad;            /* Physical Memory Address */
+       __le16          len;            /* Transfer Length */
+       u8              rsvd;
+       u8              flags;          /* Control Flags */
+} __packed;
+
+struct inic_pkt {
+       struct inic_cpb cpb;
+       struct inic_prd prd[LIBATA_MAX_PRD + 1];        /* + 1 for cdb */
+       u8              cdb[ATAPI_CDB_LEN];
+} __packed;
+
 struct inic_host_priv {
-       u16     cached_hctl;
+       void __iomem    *mmio_base;
+       u16             cached_hctl;
 };
 
 struct inic_port_priv {
-       u8      dfl_prdctl;
-       u8      cached_prdctl;
-       u8      cached_pirq_mask;
+       struct inic_pkt *pkt;
+       dma_addr_t      pkt_dma;
+       u32             *cpb_tbl;
+       dma_addr_t      cpb_tbl_dma;
 };
 
 static struct scsi_host_template inic_sht = {
-       ATA_BMDMA_SHT(DRV_NAME),
+       ATA_BASE_SHT(DRV_NAME),
+       .sg_tablesize   = LIBATA_MAX_PRD,       /* maybe it can be larger? */
+       .dma_boundary   = INIC_DMA_BOUNDARY,
 };
 
 static const int scr_map[] = {
@@ -120,54 +243,34 @@ static const int scr_map[] = {
 
 static void __iomem *inic_port_base(struct ata_port *ap)
 {
-       return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE;
-}
-
-static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask)
-{
-       void __iomem *port_base = inic_port_base(ap);
-       struct inic_port_priv *pp = ap->private_data;
+       struct inic_host_priv *hpriv = ap->host->private_data;
 
-       writeb(mask, port_base + PORT_IRQ_MASK);
-       pp->cached_pirq_mask = mask;
-}
-
-static void inic_set_pirq_mask(struct ata_port *ap, u8 mask)
-{
-       struct inic_port_priv *pp = ap->private_data;
-
-       if (pp->cached_pirq_mask != mask)
-               __inic_set_pirq_mask(ap, mask);
+       return hpriv->mmio_base + ap->port_no * PORT_SIZE;
 }
 
 static void inic_reset_port(void __iomem *port_base)
 {
        void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
-       u16 ctl;
 
-       ctl = readw(idma_ctl);
-       ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO);
+       /* stop IDMA engine */
+       readw(idma_ctl); /* flush */
+       msleep(1);
 
        /* mask IRQ and assert reset */
-       writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl);
+       writew(IDMA_CTL_RST_IDMA, idma_ctl);
        readw(idma_ctl); /* flush */
-
-       /* give it some time */
        msleep(1);
 
        /* release reset */
-       writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl);
+       writew(0, idma_ctl);
 
        /* clear irq */
        writeb(0xff, port_base + PORT_IRQ_STAT);
-
-       /* reenable ATA IRQ, turn off IDMA mode */
-       writew(ctl, idma_ctl);
 }
 
 static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
 {
-       void __iomem *scr_addr = ap->ioaddr.scr_addr;
+       void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
        void __iomem *addr;
 
        if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -184,120 +287,126 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
 
 static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
 {
-       void __iomem *scr_addr = ap->ioaddr.scr_addr;
-       void __iomem *addr;
+       void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
 
        if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
                return -EINVAL;
 
-       addr = scr_addr + scr_map[sc_reg] * 4;
        writel(val, scr_addr + scr_map[sc_reg] * 4);
        return 0;
 }
 
-/*
- * In TF mode, inic162x is very similar to SFF device.  TF registers
- * function the same.  DMA engine behaves similary using the same PRD
- * format as BMDMA but different command register, interrupt and event
- * notification methods are used.  The following inic_bmdma_*()
- * functions do the impedance matching.
- */
-static void inic_bmdma_setup(struct ata_queued_cmd *qc)
+static void inic_stop_idma(struct ata_port *ap)
 {
-       struct ata_port *ap = qc->ap;
-       struct inic_port_priv *pp = ap->private_data;
        void __iomem *port_base = inic_port_base(ap);
-       int rw = qc->tf.flags & ATA_TFLAG_WRITE;
-
-       /* make sure device sees PRD table writes */
-       wmb();
-
-       /* load transfer length */
-       writel(qc->nbytes, port_base + PORT_PRD_XFERLEN);
-
-       /* turn on DMA and specify data direction */
-       pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN;
-       if (!rw)
-               pp->cached_prdctl |= PRD_CTL_WR;
-       writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
 
-       /* issue r/w command */
-       ap->ops->sff_exec_command(ap, &qc->tf);
+       readb(port_base + PORT_RPQ_FIFO);
+       readb(port_base + PORT_RPQ_CNT);
+       writew(0, port_base + PORT_IDMA_CTL);
 }
 
-static void inic_bmdma_start(struct ata_queued_cmd *qc)
+static void inic_host_err_intr(struct ata_port *ap, u8 irq_stat, u16 idma_stat)
 {
-       struct ata_port *ap = qc->ap;
+       struct ata_eh_info *ehi = &ap->link.eh_info;
        struct inic_port_priv *pp = ap->private_data;
-       void __iomem *port_base = inic_port_base(ap);
+       struct inic_cpb *cpb = &pp->pkt->cpb;
+       bool freeze = false;
 
-       /* start host DMA transaction */
-       pp->cached_prdctl |= PRD_CTL_START;
-       writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
-}
+       ata_ehi_clear_desc(ehi);
+       ata_ehi_push_desc(ehi, "irq_stat=0x%x idma_stat=0x%x",
+                         irq_stat, idma_stat);
 
-static void inic_bmdma_stop(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct inic_port_priv *pp = ap->private_data;
-       void __iomem *port_base = inic_port_base(ap);
+       inic_stop_idma(ap);
 
-       /* stop DMA engine */
-       writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
-}
+       if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
+               ata_ehi_push_desc(ehi, "hotplug");
+               ata_ehi_hotplugged(ehi);
+               freeze = true;
+       }
 
-static u8 inic_bmdma_status(struct ata_port *ap)
-{
-       /* event is already verified by the interrupt handler */
-       return ATA_DMA_INTR;
+       if (idma_stat & IDMA_STAT_PERR) {
+               ata_ehi_push_desc(ehi, "PCI error");
+               freeze = true;
+       }
+
+       if (idma_stat & IDMA_STAT_CPBERR) {
+               ata_ehi_push_desc(ehi, "CPB error");
+
+               if (cpb->resp_flags & CPB_RESP_IGNORED) {
+                       __ata_ehi_push_desc(ehi, " ignored");
+                       ehi->err_mask |= AC_ERR_INVALID;
+                       freeze = true;
+               }
+
+               if (cpb->resp_flags & CPB_RESP_ATA_ERR)
+                       ehi->err_mask |= AC_ERR_DEV;
+
+               if (cpb->resp_flags & CPB_RESP_SPURIOUS) {
+                       __ata_ehi_push_desc(ehi, " spurious-intr");
+                       ehi->err_mask |= AC_ERR_HSM;
+                       freeze = true;
+               }
+
+               if (cpb->resp_flags &
+                   (CPB_RESP_UNDERFLOW | CPB_RESP_OVERFLOW)) {
+                       __ata_ehi_push_desc(ehi, " data-over/underflow");
+                       ehi->err_mask |= AC_ERR_HSM;
+                       freeze = true;
+               }
+       }
+
+       if (freeze)
+               ata_port_freeze(ap);
+       else
+               ata_port_abort(ap);
 }
 
 static void inic_host_intr(struct ata_port *ap)
 {
        void __iomem *port_base = inic_port_base(ap);
-       struct ata_eh_info *ehi = &ap->link.eh_info;
+       struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
        u8 irq_stat;
+       u16 idma_stat;
 
-       /* fetch and clear irq */
+       /* read and clear IRQ status */
        irq_stat = readb(port_base + PORT_IRQ_STAT);
        writeb(irq_stat, port_base + PORT_IRQ_STAT);
+       idma_stat = readw(port_base + PORT_IDMA_STAT);
 
-       if (likely(!(irq_stat & PIRQ_ERR))) {
-               struct ata_queued_cmd *qc =
-                       ata_qc_from_tag(ap, ap->link.active_tag);
+       if (unlikely((irq_stat & PIRQ_ERR) || (idma_stat & IDMA_STAT_ERR)))
+               inic_host_err_intr(ap, irq_stat, idma_stat);
 
-               if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
-                       ap->ops->sff_check_status(ap); /* clear ATA interrupt */
-                       return;
-               }
+       if (unlikely(!qc))
+               goto spurious;
 
-               if (likely(ata_sff_host_intr(ap, qc)))
-                       return;
+       if (likely(idma_stat & IDMA_STAT_DONE)) {
+               inic_stop_idma(ap);
 
-               ap->ops->sff_check_status(ap); /* clear ATA interrupt */
-               ata_port_printk(ap, KERN_WARNING, "unhandled "
-                               "interrupt, irq_stat=%x\n", irq_stat);
+               /* Depending on circumstances, device error
+                * isn't reported by IDMA, check it explicitly.
+                */
+               if (unlikely(readb(port_base + PORT_TF_COMMAND) &
+                            (ATA_DF | ATA_ERR)))
+                       qc->err_mask |= AC_ERR_DEV;
+
+               ata_qc_complete(qc);
                return;
        }
 
-       /* error */
-       ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat);
-
-       if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
-               ata_ehi_hotplugged(ehi);
-               ata_port_freeze(ap);
-       } else
-               ata_port_abort(ap);
+ spurious:
+       ata_port_printk(ap, KERN_WARNING, "unhandled interrupt: "
+                       "cmd=0x%x irq_stat=0x%x idma_stat=0x%x\n",
+                       qc ? qc->tf.command : 0xff, irq_stat, idma_stat);
 }
 
 static irqreturn_t inic_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
-       void __iomem *mmio_base = host->iomap[MMIO_BAR];
+       struct inic_host_priv *hpriv = host->private_data;
        u16 host_irq_stat;
        int i, handled = 0;;
 
-       host_irq_stat = readw(mmio_base + HOST_IRQ_STAT);
+       host_irq_stat = readw(hpriv->mmio_base + HOST_IRQ_STAT);
 
        if (unlikely(!(host_irq_stat & HIRQ_GLOBAL)))
                goto out;
@@ -327,60 +436,173 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance)
        return IRQ_RETVAL(handled);
 }
 
+static int inic_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+       /* For some reason ATAPI_PROT_DMA doesn't work for some
+        * commands including writes and other misc ops.  Use PIO
+        * protocol instead, which BTW is driven by the DMA engine
+        * anyway, so it shouldn't make much difference for native
+        * SATA devices.
+        */
+       if (atapi_cmd_type(qc->cdb[0]) == READ)
+               return 0;
+       return 1;
+}
+
+static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc)
+{
+       struct scatterlist *sg;
+       unsigned int si;
+       u8 flags = 0;
+
+       if (qc->tf.flags & ATA_TFLAG_WRITE)
+               flags |= PRD_WRITE;
+
+       if (ata_is_dma(qc->tf.protocol))
+               flags |= PRD_DMA;
+
+       for_each_sg(qc->sg, sg, qc->n_elem, si) {
+               prd->mad = cpu_to_le32(sg_dma_address(sg));
+               prd->len = cpu_to_le16(sg_dma_len(sg));
+               prd->flags = flags;
+               prd++;
+       }
+
+       WARN_ON(!si);
+       prd[-1].flags |= PRD_END;
+}
+
+static void inic_qc_prep(struct ata_queued_cmd *qc)
+{
+       struct inic_port_priv *pp = qc->ap->private_data;
+       struct inic_pkt *pkt = pp->pkt;
+       struct inic_cpb *cpb = &pkt->cpb;
+       struct inic_prd *prd = pkt->prd;
+       bool is_atapi = ata_is_atapi(qc->tf.protocol);
+       bool is_data = ata_is_data(qc->tf.protocol);
+       unsigned int cdb_len = 0;
+
+       VPRINTK("ENTER\n");
+
+       if (is_atapi)
+               cdb_len = qc->dev->cdb_len;
+
+       /* prepare packet, based on initio driver */
+       memset(pkt, 0, sizeof(struct inic_pkt));
+
+       cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN;
+       if (is_atapi || is_data)
+               cpb->ctl_flags |= CPB_CTL_DATA;
+
+       cpb->len = cpu_to_le32(qc->nbytes + cdb_len);
+       cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd));
+
+       cpb->device = qc->tf.device;
+       cpb->feature = qc->tf.feature;
+       cpb->nsect = qc->tf.nsect;
+       cpb->lbal = qc->tf.lbal;
+       cpb->lbam = qc->tf.lbam;
+       cpb->lbah = qc->tf.lbah;
+
+       if (qc->tf.flags & ATA_TFLAG_LBA48) {
+               cpb->hob_feature = qc->tf.hob_feature;
+               cpb->hob_nsect = qc->tf.hob_nsect;
+               cpb->hob_lbal = qc->tf.hob_lbal;
+               cpb->hob_lbam = qc->tf.hob_lbam;
+               cpb->hob_lbah = qc->tf.hob_lbah;
+       }
+
+       cpb->command = qc->tf.command;
+       /* don't load ctl - dunno why.  it's like that in the initio driver */
+
+       /* setup PRD for CDB */
+       if (is_atapi) {
+               memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN);
+               prd->mad = cpu_to_le32(pp->pkt_dma +
+                                      offsetof(struct inic_pkt, cdb));
+               prd->len = cpu_to_le16(cdb_len);
+               prd->flags = PRD_CDB | PRD_WRITE;
+               if (!is_data)
+                       prd->flags |= PRD_END;
+               prd++;
+       }
+
+       /* setup sg table */
+       if (is_data)
+               inic_fill_sg(prd, qc);
+
+       pp->cpb_tbl[0] = pp->pkt_dma;
+}
+
 static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       void __iomem *port_base = inic_port_base(ap);
 
-       /* ATA IRQ doesn't wait for DMA transfer completion and vice
-        * versa.  Mask IRQ selectively to detect command completion.
-        * Without it, ATA DMA read command can cause data corruption.
-        *
-        * Something similar might be needed for ATAPI writes.  I
-        * tried a lot of combinations but couldn't find the solution.
-        */
-       if (qc->tf.protocol == ATA_PROT_DMA &&
-           !(qc->tf.flags & ATA_TFLAG_WRITE))
-               inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ);
-       else
-               inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+       /* fire up the ADMA engine */
+       writew(HCTL_FTHD0, port_base + HOST_CTL);
+       writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
+       writeb(0, port_base + PORT_CPB_PTQFIFO);
+
+       return 0;
+}
+
+static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       void __iomem *port_base = inic_port_base(ap);
+
+       tf->feature     = readb(port_base + PORT_TF_FEATURE);
+       tf->nsect       = readb(port_base + PORT_TF_NSECT);
+       tf->lbal        = readb(port_base + PORT_TF_LBAL);
+       tf->lbam        = readb(port_base + PORT_TF_LBAM);
+       tf->lbah        = readb(port_base + PORT_TF_LBAH);
+       tf->device      = readb(port_base + PORT_TF_DEVICE);
+       tf->command     = readb(port_base + PORT_TF_COMMAND);
+}
 
-       /* Issuing a command to yet uninitialized port locks up the
-        * controller.  Most of the time, this happens for the first
-        * command after reset which are ATA and ATAPI IDENTIFYs.
-        * Fast fail if stat is 0x7f or 0xff for those commands.
+static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+       struct ata_taskfile *rtf = &qc->result_tf;
+       struct ata_taskfile tf;
+
+       /* FIXME: Except for status and error, result TF access
+        * doesn't work.  I tried reading from BAR0/2, CPB and BAR5.
+        * None works regardless of which command interface is used.
+        * For now return true iff status indicates device error.
+        * This means that we're reporting bogus sector for RW
+        * failures.  Eeekk....
         */
-       if (unlikely(qc->tf.command == ATA_CMD_ID_ATA ||
-                    qc->tf.command == ATA_CMD_ID_ATAPI)) {
-               u8 stat = ap->ops->sff_check_status(ap);
-               if (stat == 0x7f || stat == 0xff)
-                       return AC_ERR_HSM;
-       }
+       inic_tf_read(qc->ap, &tf);
 
-       return ata_sff_qc_issue(qc);
+       if (!(tf.command & ATA_ERR))
+               return false;
+
+       rtf->command = tf.command;
+       rtf->feature = tf.feature;
+       return true;
 }
 
 static void inic_freeze(struct ata_port *ap)
 {
        void __iomem *port_base = inic_port_base(ap);
 
-       __inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE);
-
-       ap->ops->sff_check_status(ap);
+       writeb(PIRQ_MASK_FREEZE, port_base + PORT_IRQ_MASK);
        writeb(0xff, port_base + PORT_IRQ_STAT);
-
-       readb(port_base + PORT_IRQ_STAT); /* flush */
 }
 
 static void inic_thaw(struct ata_port *ap)
 {
        void __iomem *port_base = inic_port_base(ap);
 
-       ap->ops->sff_check_status(ap);
        writeb(0xff, port_base + PORT_IRQ_STAT);
+       writeb(PIRQ_MASK_DEFAULT, port_base + PORT_IRQ_MASK);
+}
 
-       __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+static int inic_check_ready(struct ata_link *link)
+{
+       void __iomem *port_base = inic_port_base(link->ap);
 
-       readb(port_base + PORT_IRQ_STAT); /* flush */
+       return ata_check_ready(readb(port_base + PORT_TF_COMMAND));
 }
 
 /*
@@ -394,17 +616,15 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
        void __iomem *port_base = inic_port_base(ap);
        void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
        const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-       u16 val;
        int rc;
 
        /* hammer it into sane state */
        inic_reset_port(port_base);
 
-       val = readw(idma_ctl);
-       writew(val | IDMA_CTL_RST_ATA, idma_ctl);
+       writew(IDMA_CTL_RST_ATA, idma_ctl);
        readw(idma_ctl);        /* flush */
        msleep(1);
-       writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
+       writew(0, idma_ctl);
 
        rc = sata_link_resume(link, timing, deadline);
        if (rc) {
@@ -418,7 +638,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
                struct ata_taskfile tf;
 
                /* wait for link to become ready */
-               rc = ata_sff_wait_after_reset(link, 1, deadline);
+               rc = ata_wait_after_reset(link, deadline, inic_check_ready);
                /* link occupied, -ENODEV too is an error */
                if (rc) {
                        ata_link_printk(link, KERN_WARNING, "device not ready "
@@ -426,7 +646,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
                        return rc;
                }
 
-               ata_sff_tf_read(ap, &tf);
+               inic_tf_read(ap, &tf);
                *class = ata_dev_classify(&tf);
        }
 
@@ -436,18 +656,8 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
 static void inic_error_handler(struct ata_port *ap)
 {
        void __iomem *port_base = inic_port_base(ap);
-       struct inic_port_priv *pp = ap->private_data;
-       unsigned long flags;
 
-       /* reset PIO HSM and stop DMA engine */
        inic_reset_port(port_base);
-
-       spin_lock_irqsave(ap->lock, flags);
-       ap->hsm_task_state = HSM_ST_IDLE;
-       writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
-       spin_unlock_irqrestore(ap->lock, flags);
-
-       /* PIO and DMA engines have been stopped, perform recovery */
        ata_std_error_handler(ap);
 }
 
@@ -458,26 +668,18 @@ static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
                inic_reset_port(inic_port_base(qc->ap));
 }
 
-static void inic_dev_config(struct ata_device *dev)
-{
-       /* inic can only handle upto LBA28 max sectors */
-       if (dev->max_sectors > ATA_MAX_SECTORS)
-               dev->max_sectors = ATA_MAX_SECTORS;
-
-       if (dev->n_sectors >= 1 << 28) {
-               ata_dev_printk(dev, KERN_ERR,
-       "ERROR: This driver doesn't support LBA48 yet and may cause\n"
-       "                data corruption on such devices.  Disabling.\n");
-               ata_dev_disable(dev);
-       }
-}
-
 static void init_port(struct ata_port *ap)
 {
        void __iomem *port_base = inic_port_base(ap);
+       struct inic_port_priv *pp = ap->private_data;
 
-       /* Setup PRD address */
+       /* clear packet and CPB table */
+       memset(pp->pkt, 0, sizeof(struct inic_pkt));
+       memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE);
+
+       /* setup PRD and CPB lookup table addresses */
        writel(ap->prd_dma, port_base + PORT_PRD_ADDR);
+       writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR);
 }
 
 static int inic_port_resume(struct ata_port *ap)
@@ -488,28 +690,30 @@ static int inic_port_resume(struct ata_port *ap)
 
 static int inic_port_start(struct ata_port *ap)
 {
-       void __iomem *port_base = inic_port_base(ap);
+       struct device *dev = ap->host->dev;
        struct inic_port_priv *pp;
-       u8 tmp;
        int rc;
 
        /* alloc and initialize private data */
-       pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL);
+       pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
                return -ENOMEM;
        ap->private_data = pp;
 
-       /* default PRD_CTL value, DMAEN, WR and START off */
-       tmp = readb(port_base + PORT_PRD_CTL);
-       tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START);
-       pp->dfl_prdctl = tmp;
-
        /* Alloc resources */
        rc = ata_port_start(ap);
-       if (rc) {
-               kfree(pp);
+       if (rc)
                return rc;
-       }
+
+       pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt),
+                                     &pp->pkt_dma, GFP_KERNEL);
+       if (!pp->pkt)
+               return -ENOMEM;
+
+       pp->cpb_tbl = dmam_alloc_coherent(dev, IDMA_CPB_TBL_SIZE,
+                                         &pp->cpb_tbl_dma, GFP_KERNEL);
+       if (!pp->cpb_tbl)
+               return -ENOMEM;
 
        init_port(ap);
 
@@ -517,21 +721,18 @@ static int inic_port_start(struct ata_port *ap)
 }
 
 static struct ata_port_operations inic_port_ops = {
-       .inherits               = &ata_sff_port_ops,
+       .inherits               = &sata_port_ops,
 
-       .bmdma_setup            = inic_bmdma_setup,
-       .bmdma_start            = inic_bmdma_start,
-       .bmdma_stop             = inic_bmdma_stop,
-       .bmdma_status           = inic_bmdma_status,
+       .check_atapi_dma        = inic_check_atapi_dma,
+       .qc_prep                = inic_qc_prep,
        .qc_issue               = inic_qc_issue,
+       .qc_fill_rtf            = inic_qc_fill_rtf,
 
        .freeze                 = inic_freeze,
        .thaw                   = inic_thaw,
-       .softreset              = ATA_OP_NULL,  /* softreset is broken */
        .hardreset              = inic_hardreset,
        .error_handler          = inic_error_handler,
        .post_internal_cmd      = inic_post_internal_cmd,
-       .dev_config             = inic_dev_config,
 
        .scr_read               = inic_scr_read,
        .scr_write              = inic_scr_write,
@@ -541,12 +742,6 @@ static struct ata_port_operations inic_port_ops = {
 };
 
 static struct ata_port_info inic_port_info = {
-       /* For some reason, ATAPI_PROT_PIO is broken on this
-        * controller, and no, PIO_POLLING does't fix it.  It somehow
-        * manages to report the wrong ireason and ignoring ireason
-        * results in machine lock up.  Tell libata to always prefer
-        * DMA.
-        */
        .flags                  = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
        .pio_mask               = 0x1f, /* pio0-4 */
        .mwdma_mask             = 0x07, /* mwdma0-2 */
@@ -599,7 +794,6 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
        struct inic_host_priv *hpriv = host->private_data;
-       void __iomem *mmio_base = host->iomap[MMIO_BAR];
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
@@ -607,7 +801,7 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
                return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-               rc = init_controller(mmio_base, hpriv->cached_hctl);
+               rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
                if (rc)
                        return rc;
        }
@@ -625,6 +819,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct ata_host *host;
        struct inic_host_priv *hpriv;
        void __iomem * const *iomap;
+       int mmio_bar;
        int i, rc;
 
        if (!printed_version++)
@@ -638,38 +833,31 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        host->private_data = hpriv;
 
-       /* acquire resources and fill host */
+       /* Acquire resources and fill host.  Note that PCI and cardbus
+        * use different BARs.
+        */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
 
-       rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
+       if (pci_resource_flags(pdev, MMIO_BAR_PCI) & IORESOURCE_MEM)
+               mmio_bar = MMIO_BAR_PCI;
+       else
+               mmio_bar = MMIO_BAR_CARDBUS;
+
+       rc = pcim_iomap_regions(pdev, 1 << mmio_bar, DRV_NAME);
        if (rc)
                return rc;
        host->iomap = iomap = pcim_iomap_table(pdev);
+       hpriv->mmio_base = iomap[mmio_bar];
+       hpriv->cached_hctl = readw(hpriv->mmio_base + HOST_CTL);
 
        for (i = 0; i < NR_PORTS; i++) {
                struct ata_port *ap = host->ports[i];
-               struct ata_ioports *port = &ap->ioaddr;
-               unsigned int offset = i * PORT_SIZE;
-
-               port->cmd_addr = iomap[2 * i];
-               port->altstatus_addr =
-               port->ctl_addr = (void __iomem *)
-                       ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
-               port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR;
-
-               ata_sff_std_ports(port);
-
-               ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio");
-               ata_port_pbar_desc(ap, MMIO_BAR, offset, "port");
-               ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
-                 (unsigned long long)pci_resource_start(pdev, 2 * i),
-                 (unsigned long long)pci_resource_start(pdev, (2 * i + 1)) |
-                                     ATA_PCI_CTL_OFS);
-       }
 
-       hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
+               ata_port_pbar_desc(ap, mmio_bar, -1, "mmio");
+               ata_port_pbar_desc(ap, mmio_bar, i * PORT_SIZE, "port");
+       }
 
        /* Set dma_mask.  This devices doesn't support 64bit addressing. */
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
@@ -698,7 +886,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                return rc;
        }
 
-       rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
+       rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
        if (rc) {
                dev_printk(KERN_ERR, &pdev->dev,
                           "failed to initialize controller\n");
index 842b1a15b78cadfafb5e031a8fe57245e6045380..bb73b2222627b9b6a05f96057da351c7d417f935 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
+#include <linux/bitops.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -91,9 +92,9 @@ enum {
        MV_IRQ_COAL_TIME_THRESHOLD      = (MV_IRQ_COAL_REG_BASE + 0xd0),
 
        MV_SATAHC0_REG_BASE     = 0x20000,
-       MV_FLASH_CTL            = 0x1046c,
-       MV_GPIO_PORT_CTL        = 0x104f0,
-       MV_RESET_CFG            = 0x180d8,
+       MV_FLASH_CTL_OFS        = 0x1046c,
+       MV_GPIO_PORT_CTL_OFS    = 0x104f0,
+       MV_RESET_CFG_OFS        = 0x180d8,
 
        MV_PCI_REG_SZ           = MV_MAJOR_REG_AREA_SZ,
        MV_SATAHC_REG_SZ        = MV_MAJOR_REG_AREA_SZ,
@@ -147,18 +148,21 @@ enum {
        /* PCI interface registers */
 
        PCI_COMMAND_OFS         = 0xc00,
+       PCI_COMMAND_MRDTRIG     = (1 << 7),     /* PCI Master Read Trigger */
 
        PCI_MAIN_CMD_STS_OFS    = 0xd30,
        STOP_PCI_MASTER         = (1 << 2),
        PCI_MASTER_EMPTY        = (1 << 3),
        GLOB_SFT_RST            = (1 << 4),
 
-       MV_PCI_MODE             = 0xd00,
+       MV_PCI_MODE_OFS         = 0xd00,
+       MV_PCI_MODE_MASK        = 0x30,
+
        MV_PCI_EXP_ROM_BAR_CTL  = 0xd2c,
        MV_PCI_DISC_TIMER       = 0xd04,
        MV_PCI_MSI_TRIGGER      = 0xc38,
        MV_PCI_SERR_MASK        = 0xc28,
-       MV_PCI_XBAR_TMOUT       = 0x1d04,
+       MV_PCI_XBAR_TMOUT_OFS   = 0x1d04,
        MV_PCI_ERR_LOW_ADDRESS  = 0x1d40,
        MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
        MV_PCI_ERR_ATTRIBUTE    = 0x1d48,
@@ -225,16 +229,18 @@ enum {
        PHY_MODE4               = 0x314,
        PHY_MODE2               = 0x330,
        SATA_IFCTL_OFS          = 0x344,
+       SATA_TESTCTL_OFS        = 0x348,
        SATA_IFSTAT_OFS         = 0x34c,
        VENDOR_UNIQUE_FIS_OFS   = 0x35c,
 
-       FIS_CFG_OFS             = 0x360,
-       FIS_CFG_SINGLE_SYNC     = (1 << 16),    /* SYNC on DMA activation */
+       FISCFG_OFS              = 0x360,
+       FISCFG_WAIT_DEV_ERR     = (1 << 8),     /* wait for host on DevErr */
+       FISCFG_SINGLE_SYNC      = (1 << 16),    /* SYNC on DMA activation */
 
        MV5_PHY_MODE            = 0x74,
-       MV5_LT_MODE             = 0x30,
-       MV5_PHY_CTL             = 0x0C,
-       SATA_INTERFACE_CFG      = 0x050,
+       MV5_LTMODE_OFS          = 0x30,
+       MV5_PHY_CTL_OFS         = 0x0C,
+       SATA_INTERFACE_CFG_OFS  = 0x050,
 
        MV_M2_PREAMP_MASK       = 0x7e0,
 
@@ -332,10 +338,16 @@ enum {
        EDMA_CMD_OFS            = 0x28,         /* EDMA command register */
        EDMA_EN                 = (1 << 0),     /* enable EDMA */
        EDMA_DS                 = (1 << 1),     /* disable EDMA; self-negated */
-       ATA_RST                 = (1 << 2),     /* reset trans/link/phy */
+       EDMA_RESET              = (1 << 2),     /* reset eng/trans/link/phy */
+
+       EDMA_STATUS_OFS         = 0x30,         /* EDMA engine status */
+       EDMA_STATUS_CACHE_EMPTY = (1 << 6),     /* GenIIe command cache empty */
+       EDMA_STATUS_IDLE        = (1 << 7),     /* GenIIe EDMA enabled/idle */
 
-       EDMA_IORDY_TMOUT        = 0x34,
-       EDMA_ARB_CFG            = 0x38,
+       EDMA_IORDY_TMOUT_OFS    = 0x34,
+       EDMA_ARB_CFG_OFS        = 0x38,
+
+       EDMA_HALTCOND_OFS       = 0x60,         /* GenIIe halt conditions */
 
        GEN_II_NCQ_MAX_SECTORS  = 256,          /* max sects/io on Gen2 w/NCQ */
 
@@ -350,15 +362,19 @@ enum {
        MV_HP_GEN_II            = (1 << 7),     /* Generation II: 60xx */
        MV_HP_GEN_IIE           = (1 << 8),     /* Generation IIE: 6042/7042 */
        MV_HP_PCIE              = (1 << 9),     /* PCIe bus/regs: 7042 */
+       MV_HP_CUT_THROUGH       = (1 << 10),    /* can use EDMA cut-through */
 
        /* Port private flags (pp_flags) */
        MV_PP_FLAG_EDMA_EN      = (1 << 0),     /* is EDMA engine enabled? */
        MV_PP_FLAG_NCQ_EN       = (1 << 1),     /* is EDMA set up for NCQ? */
+       MV_PP_FLAG_FBS_EN       = (1 << 2),     /* is EDMA set up for FBS? */
+       MV_PP_FLAG_DELAYED_EH   = (1 << 3),     /* delayed dev err handling */
 };
 
 #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
 #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
+#define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE)
 #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC))
 
 #define WINDOW_CTRL(i)         (0x20030 + ((i) << 4))
@@ -433,6 +449,7 @@ struct mv_port_priv {
        unsigned int            resp_idx;
 
        u32                     pp_flags;
+       unsigned int            delayed_eh_pmp_map;
 };
 
 struct mv_port_signal {
@@ -479,6 +496,7 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
 static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
+static int mv_qc_defer(struct ata_queued_cmd *qc);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
@@ -527,6 +545,9 @@ static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
                                unsigned long deadline);
 static int  mv_softreset(struct ata_link *link, unsigned int *class,
                                unsigned long deadline);
+static void mv_pmp_error_handler(struct ata_port *ap);
+static void mv_process_crpb_entries(struct ata_port *ap,
+                                       struct mv_port_priv *pp);
 
 /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
  * because we have to allow room for worst case splitting of
@@ -548,6 +569,7 @@ static struct scsi_host_template mv6_sht = {
 static struct ata_port_operations mv5_ops = {
        .inherits               = &ata_sff_port_ops,
 
+       .qc_defer               = mv_qc_defer,
        .qc_prep                = mv_qc_prep,
        .qc_issue               = mv_qc_issue,
 
@@ -566,7 +588,6 @@ static struct ata_port_operations mv5_ops = {
 
 static struct ata_port_operations mv6_ops = {
        .inherits               = &mv5_ops,
-       .qc_defer               = sata_pmp_qc_defer_cmd_switch,
        .dev_config             = mv6_dev_config,
        .scr_read               = mv_scr_read,
        .scr_write              = mv_scr_write,
@@ -574,12 +595,11 @@ static struct ata_port_operations mv6_ops = {
        .pmp_hardreset          = mv_pmp_hardreset,
        .pmp_softreset          = mv_softreset,
        .softreset              = mv_softreset,
-       .error_handler          = sata_pmp_error_handler,
+       .error_handler          = mv_pmp_error_handler,
 };
 
 static struct ata_port_operations mv_iie_ops = {
        .inherits               = &mv6_ops,
-       .qc_defer               = ata_std_qc_defer, /* FIS-based switching */
        .dev_config             = ATA_OP_NULL,
        .qc_prep                = mv_qc_prep_iie,
 };
@@ -875,6 +895,29 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
        }
 }
 
+static void mv_wait_for_edma_empty_idle(struct ata_port *ap)
+{
+       void __iomem *port_mmio = mv_ap_base(ap);
+       const u32 empty_idle = (EDMA_STATUS_CACHE_EMPTY | EDMA_STATUS_IDLE);
+       const int per_loop = 5, timeout = (15 * 1000 / per_loop);
+       int i;
+
+       /*
+        * Wait for the EDMA engine to finish transactions in progress.
+        * No idea what a good "timeout" value might be, but measurements
+        * indicate that it often requires hundreds of microseconds
+        * with two drives in-use.  So we use the 15msec value above
+        * as a rough guess at what even more drives might require.
+        */
+       for (i = 0; i < timeout; ++i) {
+               u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS);
+               if ((edma_stat & empty_idle) == empty_idle)
+                       break;
+               udelay(per_loop);
+       }
+       /* ata_port_printk(ap, KERN_INFO, "%s: %u+ usecs\n", __func__, i); */
+}
+
 /**
  *      mv_stop_edma_engine - Disable eDMA engine
  *      @port_mmio: io base address
@@ -907,6 +950,7 @@ static int mv_stop_edma(struct ata_port *ap)
        if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
                return 0;
        pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+       mv_wait_for_edma_empty_idle(ap);
        if (mv_stop_edma_engine(port_mmio)) {
                ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
                return -EIO;
@@ -1057,26 +1101,95 @@ static void mv6_dev_config(struct ata_device *adev)
        }
 }
 
-static void mv_config_fbs(void __iomem *port_mmio, int enable_fbs)
+static int mv_qc_defer(struct ata_queued_cmd *qc)
 {
-       u32 old_fcfg, new_fcfg, old_ltmode, new_ltmode;
+       struct ata_link *link = qc->dev->link;
+       struct ata_port *ap = link->ap;
+       struct mv_port_priv *pp = ap->private_data;
+
+       /*
+        * Don't allow new commands if we're in a delayed EH state
+        * for NCQ and/or FIS-based switching.
+        */
+       if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
+               return ATA_DEFER_PORT;
        /*
-        * Various bit settings required for operation
-        * in FIS-based switching (fbs) mode on GenIIe:
+        * If the port is completely idle, then allow the new qc.
         */
-       old_fcfg   = readl(port_mmio + FIS_CFG_OFS);
-       old_ltmode = readl(port_mmio + LTMODE_OFS);
-       if (enable_fbs) {
-               new_fcfg   = old_fcfg   |  FIS_CFG_SINGLE_SYNC;
-               new_ltmode = old_ltmode |  LTMODE_BIT8;
-       } else { /* disable fbs */
-               new_fcfg   = old_fcfg   & ~FIS_CFG_SINGLE_SYNC;
-               new_ltmode = old_ltmode & ~LTMODE_BIT8;
-       }
-       if (new_fcfg != old_fcfg)
-               writelfl(new_fcfg, port_mmio + FIS_CFG_OFS);
+       if (ap->nr_active_links == 0)
+               return 0;
+
+       if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
+               /*
+                * The port is operating in host queuing mode (EDMA).
+                * It can accomodate a new qc if the qc protocol
+                * is compatible with the current host queue mode.
+                */
+               if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
+                       /*
+                        * The host queue (EDMA) is in NCQ mode.
+                        * If the new qc is also an NCQ command,
+                        * then allow the new qc.
+                        */
+                       if (qc->tf.protocol == ATA_PROT_NCQ)
+                               return 0;
+               } else {
+                       /*
+                        * The host queue (EDMA) is in non-NCQ, DMA mode.
+                        * If the new qc is also a non-NCQ, DMA command,
+                        * then allow the new qc.
+                        */
+                       if (qc->tf.protocol == ATA_PROT_DMA)
+                               return 0;
+               }
+       }
+       return ATA_DEFER_PORT;
+}
+
+static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+{
+       u32 new_fiscfg, old_fiscfg;
+       u32 new_ltmode, old_ltmode;
+       u32 new_haltcond, old_haltcond;
+
+       old_fiscfg   = readl(port_mmio + FISCFG_OFS);
+       old_ltmode   = readl(port_mmio + LTMODE_OFS);
+       old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+
+       new_fiscfg   = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
+       new_ltmode   = old_ltmode & ~LTMODE_BIT8;
+       new_haltcond = old_haltcond | EDMA_ERR_DEV;
+
+       if (want_fbs) {
+               new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
+               new_ltmode = old_ltmode | LTMODE_BIT8;
+               if (want_ncq)
+                       new_haltcond &= ~EDMA_ERR_DEV;
+               else
+                       new_fiscfg |=  FISCFG_WAIT_DEV_ERR;
+       }
+
+       if (new_fiscfg != old_fiscfg)
+               writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
        if (new_ltmode != old_ltmode)
                writelfl(new_ltmode, port_mmio + LTMODE_OFS);
+       if (new_haltcond != old_haltcond)
+               writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+}
+
+static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
+{
+       struct mv_host_priv *hpriv = ap->host->private_data;
+       u32 old, new;
+
+       /* workaround for 88SX60x1 FEr SATA#25 (part 1) */
+       old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS);
+       if (want_ncq)
+               new = old | (1 << 22);
+       else
+               new = old & ~(1 << 22);
+       if (new != old)
+               writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
 }
 
 static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
@@ -1088,25 +1201,40 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
 
        /* set up non-NCQ EDMA configuration */
        cfg = EDMA_CFG_Q_DEPTH;         /* always 0x1f for *all* chips */
+       pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
 
        if (IS_GEN_I(hpriv))
                cfg |= (1 << 8);        /* enab config burst size mask */
 
-       else if (IS_GEN_II(hpriv))
+       else if (IS_GEN_II(hpriv)) {
                cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN;
+               mv_60x1_errata_sata25(ap, want_ncq);
 
-       else if (IS_GEN_IIE(hpriv)) {
-               cfg |= (1 << 23);       /* do not mask PM field in rx'd FIS */
-               cfg |= (1 << 22);       /* enab 4-entry host queue cache */
-               cfg |= (1 << 18);       /* enab early completion */
-               cfg |= (1 << 17);       /* enab cut-through (dis stor&forwrd) */
+       } else if (IS_GEN_IIE(hpriv)) {
+               int want_fbs = sata_pmp_attached(ap);
+               /*
+                * Possible future enhancement:
+                *
+                * The chip can use FBS with non-NCQ, if we allow it,
+                * But first we need to have the error handling in place
+                * for this mode (datasheet section 7.3.15.4.2.3).
+                * So disallow non-NCQ FBS for now.
+                */
+               want_fbs &= want_ncq;
+
+               mv_config_fbs(port_mmio, want_ncq, want_fbs);
 
-               if (want_ncq && sata_pmp_attached(ap)) {
+               if (want_fbs) {
+                       pp->pp_flags |= MV_PP_FLAG_FBS_EN;
                        cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */
-                       mv_config_fbs(port_mmio, 1);
-               } else {
-                       mv_config_fbs(port_mmio, 0);
                }
+
+               cfg |= (1 << 23);       /* do not mask PM field in rx'd FIS */
+               cfg |= (1 << 22);       /* enab 4-entry host queue cache */
+               if (HAS_PCI(ap->host))
+                       cfg |= (1 << 18);       /* enab early completion */
+               if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
+                       cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
        }
 
        if (want_ncq) {
@@ -1483,25 +1611,186 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
        return qc;
 }
 
-static void mv_unexpected_intr(struct ata_port *ap)
+static void mv_pmp_error_handler(struct ata_port *ap)
 {
+       unsigned int pmp, pmp_map;
        struct mv_port_priv *pp = ap->private_data;
-       struct ata_eh_info *ehi = &ap->link.eh_info;
-       char *when = "";
 
+       if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) {
+               /*
+                * Perform NCQ error analysis on failed PMPs
+                * before we freeze the port entirely.
+                *
+                * The failed PMPs are marked earlier by mv_pmp_eh_prep().
+                */
+               pmp_map = pp->delayed_eh_pmp_map;
+               pp->pp_flags &= ~MV_PP_FLAG_DELAYED_EH;
+               for (pmp = 0; pmp_map != 0; pmp++) {
+                       unsigned int this_pmp = (1 << pmp);
+                       if (pmp_map & this_pmp) {
+                               struct ata_link *link = &ap->pmp_link[pmp];
+                               pmp_map &= ~this_pmp;
+                               ata_eh_analyze_ncq_error(link);
+                       }
+               }
+               ata_port_freeze(ap);
+       }
+       sata_pmp_error_handler(ap);
+}
+
+static unsigned int mv_get_err_pmp_map(struct ata_port *ap)
+{
+       void __iomem *port_mmio = mv_ap_base(ap);
+
+       return readl(port_mmio + SATA_TESTCTL_OFS) >> 16;
+}
+
+static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
+{
+       struct ata_eh_info *ehi;
+       unsigned int pmp;
+
+       /*
+        * Initialize EH info for PMPs which saw device errors
+        */
+       ehi = &ap->link.eh_info;
+       for (pmp = 0; pmp_map != 0; pmp++) {
+               unsigned int this_pmp = (1 << pmp);
+               if (pmp_map & this_pmp) {
+                       struct ata_link *link = &ap->pmp_link[pmp];
+
+                       pmp_map &= ~this_pmp;
+                       ehi = &link->eh_info;
+                       ata_ehi_clear_desc(ehi);
+                       ata_ehi_push_desc(ehi, "dev err");
+                       ehi->err_mask |= AC_ERR_DEV;
+                       ehi->action |= ATA_EH_RESET;
+                       ata_link_abort(link);
+               }
+       }
+}
+
+static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
+{
+       struct mv_port_priv *pp = ap->private_data;
+       int failed_links;
+       unsigned int old_map, new_map;
+
+       /*
+        * Device error during FBS+NCQ operation:
+        *
+        * Set a port flag to prevent further I/O being enqueued.
+        * Leave the EDMA running to drain outstanding commands from this port.
+        * Perform the post-mortem/EH only when all responses are complete.
+        * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.2).
+        */
+       if (!(pp->pp_flags & MV_PP_FLAG_DELAYED_EH)) {
+               pp->pp_flags |= MV_PP_FLAG_DELAYED_EH;
+               pp->delayed_eh_pmp_map = 0;
+       }
+       old_map = pp->delayed_eh_pmp_map;
+       new_map = old_map | mv_get_err_pmp_map(ap);
+
+       if (old_map != new_map) {
+               pp->delayed_eh_pmp_map = new_map;
+               mv_pmp_eh_prep(ap, new_map & ~old_map);
+       }
+       failed_links = hweight16(new_map);
+
+       ata_port_printk(ap, KERN_INFO, "%s: pmp_map=%04x qc_map=%04x "
+                       "failed_links=%d nr_active_links=%d\n",
+                       __func__, pp->delayed_eh_pmp_map,
+                       ap->qc_active, failed_links,
+                       ap->nr_active_links);
+
+       if (ap->nr_active_links <= failed_links) {
+               mv_process_crpb_entries(ap, pp);
+               mv_stop_edma(ap);
+               mv_eh_freeze(ap);
+               ata_port_printk(ap, KERN_INFO, "%s: done\n", __func__);
+               return 1;       /* handled */
+       }
+       ata_port_printk(ap, KERN_INFO, "%s: waiting\n", __func__);
+       return 1;       /* handled */
+}
+
+static int mv_handle_fbs_non_ncq_dev_err(struct ata_port *ap)
+{
        /*
-        * We got a device interrupt from something that
-        * was supposed to be using EDMA or polling.
+        * Possible future enhancement:
+        *
+        * FBS+non-NCQ operation is not yet implemented.
+        * See related notes in mv_edma_cfg().
+        *
+        * Device error during FBS+non-NCQ operation:
+        *
+        * We need to snapshot the shadow registers for each failed command.
+        * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.3).
         */
+       return 0;       /* not handled */
+}
+
+static int mv_handle_dev_err(struct ata_port *ap, u32 edma_err_cause)
+{
+       struct mv_port_priv *pp = ap->private_data;
+
+       if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
+               return 0;       /* EDMA was not active: not handled */
+       if (!(pp->pp_flags & MV_PP_FLAG_FBS_EN))
+               return 0;       /* FBS was not active: not handled */
+
+       if (!(edma_err_cause & EDMA_ERR_DEV))
+               return 0;       /* non DEV error: not handled */
+       edma_err_cause &= ~EDMA_ERR_IRQ_TRANSIENT;
+       if (edma_err_cause & ~(EDMA_ERR_DEV | EDMA_ERR_SELF_DIS))
+               return 0;       /* other problems: not handled */
+
+       if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
+               /*
+                * EDMA should NOT have self-disabled for this case.
+                * If it did, then something is wrong elsewhere,
+                * and we cannot handle it here.
+                */
+               if (edma_err_cause & EDMA_ERR_SELF_DIS) {
+                       ata_port_printk(ap, KERN_WARNING,
+                               "%s: err_cause=0x%x pp_flags=0x%x\n",
+                               __func__, edma_err_cause, pp->pp_flags);
+                       return 0; /* not handled */
+               }
+               return mv_handle_fbs_ncq_dev_err(ap);
+       } else {
+               /*
+                * EDMA should have self-disabled for this case.
+                * If it did not, then something is wrong elsewhere,
+                * and we cannot handle it here.
+                */
+               if (!(edma_err_cause & EDMA_ERR_SELF_DIS)) {
+                       ata_port_printk(ap, KERN_WARNING,
+                               "%s: err_cause=0x%x pp_flags=0x%x\n",
+                               __func__, edma_err_cause, pp->pp_flags);
+                       return 0; /* not handled */
+               }
+               return mv_handle_fbs_non_ncq_dev_err(ap);
+       }
+       return 0;       /* not handled */
+}
+
+static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled)
+{
+       struct ata_eh_info *ehi = &ap->link.eh_info;
+       char *when = "idle";
+
        ata_ehi_clear_desc(ehi);
-       if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-               when = " while EDMA enabled";
+       if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+               when = "disabled";
+       } else if (edma_was_enabled) {
+               when = "EDMA enabled";
        } else {
                struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
                if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
-                       when = " while polling";
+                       when = "polling";
        }
-       ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when);
+       ata_ehi_push_desc(ehi, "unexpected device interrupt while %s", when);
        ehi->err_mask |= AC_ERR_OTHER;
        ehi->action   |= ATA_EH_RESET;
        ata_port_freeze(ap);
@@ -1519,7 +1808,7 @@ static void mv_unexpected_intr(struct ata_port *ap)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+static void mv_err_intr(struct ata_port *ap)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
        u32 edma_err_cause, eh_freeze_mask, serr = 0;
@@ -1527,24 +1816,42 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        struct mv_host_priv *hpriv = ap->host->private_data;
        unsigned int action = 0, err_mask = 0;
        struct ata_eh_info *ehi = &ap->link.eh_info;
-
-       ata_ehi_clear_desc(ehi);
+       struct ata_queued_cmd *qc;
+       int abort = 0;
 
        /*
-        * Read and clear the err_cause bits.  This won't actually
-        * clear for some errors (eg. SError), but we will be doing
-        * a hard reset in those cases regardless, which *will* clear it.
+        * Read and clear the SError and err_cause bits.
         */
+       sata_scr_read(&ap->link, SCR_ERROR, &serr);
+       sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
+
        edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
        writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-       ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause);
+       ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n",
+                       __func__, edma_err_cause, pp->pp_flags);
+
+       if (edma_err_cause & EDMA_ERR_DEV) {
+               /*
+                * Device errors during FIS-based switching operation
+                * require special handling.
+                */
+               if (mv_handle_dev_err(ap, edma_err_cause))
+                       return;
+       }
 
+       qc = mv_get_active_qc(ap);
+       ata_ehi_clear_desc(ehi);
+       ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x",
+                         edma_err_cause, pp->pp_flags);
        /*
         * All generations share these EDMA error cause bits:
         */
-       if (edma_err_cause & EDMA_ERR_DEV)
+       if (edma_err_cause & EDMA_ERR_DEV) {
                err_mask |= AC_ERR_DEV;
+               action |= ATA_EH_RESET;
+               ata_ehi_push_desc(ehi, "dev error");
+       }
        if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
                        EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR |
                        EDMA_ERR_INTRL_PAR)) {
@@ -1576,13 +1883,6 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
                        ata_ehi_push_desc(ehi, "EDMA self-disable");
                }
                if (edma_err_cause & EDMA_ERR_SERR) {
-                       /*
-                        * Ensure that we read our own SCR, not a pmp link SCR:
-                        */
-                       ap->ops->scr_read(ap, SCR_ERROR, &serr);
-                       /*
-                        * Don't clear SError here; leave it for libata-eh:
-                        */
                        ata_ehi_push_desc(ehi, "SError=%08x", serr);
                        err_mask |= AC_ERR_ATA_BUS;
                        action |= ATA_EH_RESET;
@@ -1602,10 +1902,29 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        else
                ehi->err_mask |= err_mask;
 
-       if (edma_err_cause & eh_freeze_mask)
+       if (err_mask == AC_ERR_DEV) {
+               /*
+                * Cannot do ata_port_freeze() here,
+                * because it would kill PIO access,
+                * which is needed for further diagnosis.
+                */
+               mv_eh_freeze(ap);
+               abort = 1;
+       } else if (edma_err_cause & eh_freeze_mask) {
+               /*
+                * Note to self: ata_port_freeze() calls ata_port_abort()
+                */
                ata_port_freeze(ap);
-       else
-               ata_port_abort(ap);
+       } else {
+               abort = 1;
+       }
+
+       if (abort) {
+               if (qc)
+                       ata_link_abort(qc->dev->link);
+               else
+                       ata_port_abort(ap);
+       }
 }
 
 static void mv_process_crpb_response(struct ata_port *ap,
@@ -1632,8 +1951,9 @@ static void mv_process_crpb_response(struct ata_port *ap,
                        }
                }
                ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
-               qc->err_mask |= ac_err_mask(ata_status);
-               ata_qc_complete(qc);
+               if (!ac_err_mask(ata_status))
+                       ata_qc_complete(qc);
+               /* else: leave it for mv_err_intr() */
        } else {
                ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
                                __func__, tag);
@@ -1677,6 +1997,44 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
                         port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 }
 
+static void mv_port_intr(struct ata_port *ap, u32 port_cause)
+{
+       struct mv_port_priv *pp;
+       int edma_was_enabled;
+
+       if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+               mv_unexpected_intr(ap, 0);
+               return;
+       }
+       /*
+        * Grab a snapshot of the EDMA_EN flag setting,
+        * so that we have a consistent view for this port,
+        * even if something we call of our routines changes it.
+        */
+       pp = ap->private_data;
+       edma_was_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN);
+       /*
+        * Process completed CRPB response(s) before other events.
+        */
+       if (edma_was_enabled && (port_cause & DONE_IRQ)) {
+               mv_process_crpb_entries(ap, pp);
+               if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
+                       mv_handle_fbs_ncq_dev_err(ap);
+       }
+       /*
+        * Handle chip-reported errors, or continue on to handle PIO.
+        */
+       if (unlikely(port_cause & ERR_IRQ)) {
+               mv_err_intr(ap);
+       } else if (!edma_was_enabled) {
+               struct ata_queued_cmd *qc = mv_get_active_qc(ap);
+               if (qc)
+                       ata_sff_host_intr(ap, qc);
+               else
+                       mv_unexpected_intr(ap, edma_was_enabled);
+       }
+}
+
 /**
  *      mv_host_intr - Handle all interrupts on the given host controller
  *      @host: host specific structure
@@ -1688,66 +2046,58 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
 static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
 {
        struct mv_host_priv *hpriv = host->private_data;
-       void __iomem *mmio = hpriv->base, *hc_mmio = NULL;
-       u32 hc_irq_cause = 0;
+       void __iomem *mmio = hpriv->base, *hc_mmio;
        unsigned int handled = 0, port;
 
        for (port = 0; port < hpriv->n_ports; port++) {
                struct ata_port *ap = host->ports[port];
-               struct mv_port_priv *pp;
-               unsigned int shift, hardport, port_cause;
-               /*
-                * When we move to the second hc, flag our cached
-                * copies of hc_mmio (and hc_irq_cause) as invalid again.
-                */
-               if (port == MV_PORTS_PER_HC)
-                       hc_mmio = NULL;
-               /*
-                * Do nothing if port is not interrupting or is disabled:
-                */
+               unsigned int p, shift, hardport, port_cause;
+
                MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
-               port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ);
-               if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED))
-                       continue;
                /*
-                * Each hc within the host has its own hc_irq_cause register.
-                * We defer reading it until we know we need it, right now:
-                *
-                * FIXME later: we don't really need to read this register
-                * (some logic changes required below if we go that way),
-                * because it doesn't tell us anything new.  But we do need
-                * to write to it, outside the top of this loop,
-                * to reset the interrupt triggers for next time.
+                * Each hc within the host has its own hc_irq_cause register,
+                * where the interrupting ports bits get ack'd.
                 */
-               if (!hc_mmio) {
+               if (hardport == 0) {    /* first port on this hc ? */
+                       u32 hc_cause = (main_irq_cause >> shift) & HC0_IRQ_PEND;
+                       u32 port_mask, ack_irqs;
+                       /*
+                        * Skip this entire hc if nothing pending for any ports
+                        */
+                       if (!hc_cause) {
+                               port += MV_PORTS_PER_HC - 1;
+                               continue;
+                       }
+                       /*
+                        * We don't need/want to read the hc_irq_cause register,
+                        * because doing so hurts performance, and
+                        * main_irq_cause already gives us everything we need.
+                        *
+                        * But we do have to *write* to the hc_irq_cause to ack
+                        * the ports that we are handling this time through.
+                        *
+                        * This requires that we create a bitmap for those
+                        * ports which interrupted us, and use that bitmap
+                        * to ack (only) those ports via hc_irq_cause.
+                        */
+                       ack_irqs = 0;
+                       for (p = 0; p < MV_PORTS_PER_HC; ++p) {
+                               if ((port + p) >= hpriv->n_ports)
+                                       break;
+                               port_mask = (DONE_IRQ | ERR_IRQ) << (p * 2);
+                               if (hc_cause & port_mask)
+                                       ack_irqs |= (DMA_IRQ | DEV_IRQ) << p;
+                       }
                        hc_mmio = mv_hc_base_from_port(mmio, port);
-                       hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
-                       writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+                       writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS);
                        handled = 1;
                }
                /*
-                * Process completed CRPB response(s) before other events.
-                */
-               pp = ap->private_data;
-               if (hc_irq_cause & (DMA_IRQ << hardport)) {
-                       if (pp->pp_flags & MV_PP_FLAG_EDMA_EN)
-                               mv_process_crpb_entries(ap, pp);
-               }
-               /*
-                * Handle chip-reported errors, or continue on to handle PIO.
+                * Handle interrupts signalled for this port:
                 */
-               if (unlikely(port_cause & ERR_IRQ)) {
-                       mv_err_intr(ap, mv_get_active_qc(ap));
-               } else if (hc_irq_cause & (DEV_IRQ << hardport)) {
-                       if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
-                               struct ata_queued_cmd *qc = mv_get_active_qc(ap);
-                               if (qc) {
-                                       ata_sff_host_intr(ap, qc);
-                                       continue;
-                               }
-                       }
-                       mv_unexpected_intr(ap);
-               }
+               port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ);
+               if (port_cause)
+                       mv_port_intr(ap, port_cause);
        }
        return handled;
 }
@@ -1894,7 +2244,7 @@ static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio)
 
 static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-       writel(0x0fcfffff, mmio + MV_FLASH_CTL);
+       writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS);
 }
 
 static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
@@ -1913,7 +2263,7 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
        u32 tmp;
 
-       writel(0, mmio + MV_GPIO_PORT_CTL);
+       writel(0, mmio + MV_GPIO_PORT_CTL_OFS);
 
        /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
 
@@ -1931,14 +2281,14 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
        int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0);
 
        if (fix_apm_sq) {
-               tmp = readl(phy_mmio + MV5_LT_MODE);
+               tmp = readl(phy_mmio + MV5_LTMODE_OFS);
                tmp |= (1 << 19);
-               writel(tmp, phy_mmio + MV5_LT_MODE);
+               writel(tmp, phy_mmio + MV5_LTMODE_OFS);
 
-               tmp = readl(phy_mmio + MV5_PHY_CTL);
+               tmp = readl(phy_mmio + MV5_PHY_CTL_OFS);
                tmp &= ~0x3;
                tmp |= 0x1;
-               writel(tmp, phy_mmio + MV5_PHY_CTL);
+               writel(tmp, phy_mmio + MV5_PHY_CTL_OFS);
        }
 
        tmp = readl(phy_mmio + MV5_PHY_MODE);
@@ -1956,11 +2306,6 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
 {
        void __iomem *port_mmio = mv_port_base(mmio, port);
 
-       /*
-        * The datasheet warns against setting ATA_RST when EDMA is active
-        * (but doesn't say what the problem might be).  So we first try
-        * to disable the EDMA engine before doing the ATA_RST operation.
-        */
        mv_reset_channel(hpriv, mmio, port);
 
        ZERO(0x028);    /* command */
@@ -1975,7 +2320,7 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
        ZERO(0x024);    /* respq outp */
        ZERO(0x020);    /* respq inp */
        ZERO(0x02c);    /* test control */
-       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
 }
 #undef ZERO
 
@@ -2021,13 +2366,13 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio)
        struct mv_host_priv *hpriv = host->private_data;
        u32 tmp;
 
-       tmp = readl(mmio + MV_PCI_MODE);
+       tmp = readl(mmio + MV_PCI_MODE_OFS);
        tmp &= 0xff00ffff;
-       writel(tmp, mmio + MV_PCI_MODE);
+       writel(tmp, mmio + MV_PCI_MODE_OFS);
 
        ZERO(MV_PCI_DISC_TIMER);
        ZERO(MV_PCI_MSI_TRIGGER);
-       writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
+       writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS);
        ZERO(PCI_HC_MAIN_IRQ_MASK_OFS);
        ZERO(MV_PCI_SERR_MASK);
        ZERO(hpriv->irq_cause_ofs);
@@ -2045,10 +2390,10 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
 
        mv5_reset_flash(hpriv, mmio);
 
-       tmp = readl(mmio + MV_GPIO_PORT_CTL);
+       tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS);
        tmp &= 0x3;
        tmp |= (1 << 5) | (1 << 6);
-       writel(tmp, mmio + MV_GPIO_PORT_CTL);
+       writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS);
 }
 
 /**
@@ -2121,7 +2466,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
        void __iomem *port_mmio;
        u32 tmp;
 
-       tmp = readl(mmio + MV_RESET_CFG);
+       tmp = readl(mmio + MV_RESET_CFG_OFS);
        if ((tmp & (1 << 0)) == 0) {
                hpriv->signal[idx].amps = 0x7 << 8;
                hpriv->signal[idx].pre = 0x1 << 5;
@@ -2137,7 +2482,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
 
 static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-       writel(0x00000060, mmio + MV_GPIO_PORT_CTL);
+       writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS);
 }
 
 static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -2235,11 +2580,6 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
 {
        void __iomem *port_mmio = mv_port_base(mmio, port);
 
-       /*
-        * The datasheet warns against setting ATA_RST when EDMA is active
-        * (but doesn't say what the problem might be).  So we first try
-        * to disable the EDMA engine before doing the ATA_RST operation.
-        */
        mv_reset_channel(hpriv, mmio, port);
 
        ZERO(0x028);            /* command */
@@ -2254,7 +2594,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
        ZERO(0x024);            /* respq outp */
        ZERO(0x020);            /* respq inp */
        ZERO(0x02c);            /* test control */
-       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
 }
 
 #undef ZERO
@@ -2297,38 +2637,39 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
        return;
 }
 
-static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i)
+static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
 {
-       u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
+       u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
 
-       ifctl = (ifctl & 0xf7f) | 0x9b1000;     /* from chip spec */
+       ifcfg = (ifcfg & 0xf7f) | 0x9b1000;     /* from chip spec */
        if (want_gen2i)
-               ifctl |= (1 << 7);              /* enable gen2i speed */
-       writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
+               ifcfg |= (1 << 7);              /* enable gen2i speed */
+       writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS);
 }
 
-/*
- * Caller must ensure that EDMA is not active,
- * by first doing mv_stop_edma() where needed.
- */
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
                             unsigned int port_no)
 {
        void __iomem *port_mmio = mv_port_base(mmio, port_no);
 
+       /*
+        * The datasheet warns against setting EDMA_RESET when EDMA is active
+        * (but doesn't say what the problem might be).  So we first try
+        * to disable the EDMA engine before doing the EDMA_RESET operation.
+        */
        mv_stop_edma_engine(port_mmio);
-       writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+       writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
 
        if (!IS_GEN_I(hpriv)) {
-               /* Enable 3.0gb/s link speed */
-               mv_setup_ifctl(port_mmio, 1);
+               /* Enable 3.0gb/s link speed: this survives EDMA_RESET */
+               mv_setup_ifcfg(port_mmio, 1);
        }
        /*
-        * Strobing ATA_RST here causes a hard reset of the SATA transport,
+        * Strobing EDMA_RESET here causes a hard reset of the SATA transport,
         * link, and physical layers.  It resets all SATA interface registers
         * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
         */
-       writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+       writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
        udelay(25);     /* allow reset propagation */
        writelfl(0, port_mmio + EDMA_CMD_OFS);
 
@@ -2392,7 +2733,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
                sata_scr_read(link, SCR_STATUS, &sstatus);
                if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) {
                        /* Force 1.5gb/s link speed and try again */
-                       mv_setup_ifctl(mv_ap_base(ap), 0);
+                       mv_setup_ifcfg(mv_ap_base(ap), 0);
                        if (time_after(jiffies + HZ, deadline))
                                extra = HZ; /* only extend it once, max */
                }
@@ -2493,6 +2834,34 @@ static void mv_port_init(struct ata_ioports *port,  void __iomem *port_mmio)
                readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
 }
 
+static unsigned int mv_in_pcix_mode(struct ata_host *host)
+{
+       struct mv_host_priv *hpriv = host->private_data;
+       void __iomem *mmio = hpriv->base;
+       u32 reg;
+
+       if (!HAS_PCI(host) || !IS_PCIE(hpriv))
+               return 0;       /* not PCI-X capable */
+       reg = readl(mmio + MV_PCI_MODE_OFS);
+       if ((reg & MV_PCI_MODE_MASK) == 0)
+               return 0;       /* conventional PCI mode */
+       return 1;       /* chip is in PCI-X mode */
+}
+
+static int mv_pci_cut_through_okay(struct ata_host *host)
+{
+       struct mv_host_priv *hpriv = host->private_data;
+       void __iomem *mmio = hpriv->base;
+       u32 reg;
+
+       if (!mv_in_pcix_mode(host)) {
+               reg = readl(mmio + PCI_COMMAND_OFS);
+               if (reg & PCI_COMMAND_MRDTRIG)
+                       return 0; /* not okay */
+       }
+       return 1; /* okay */
+}
+
 static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -2560,7 +2929,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
                break;
 
        case chip_7042:
-               hp_flags |= MV_HP_PCIE;
+               hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH;
                if (pdev->vendor == PCI_VENDOR_ID_TTI &&
                    (pdev->device == 0x2300 || pdev->device == 0x2310))
                {
@@ -2590,9 +2959,12 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
                                " and avoid the final two gigabytes on"
                                " all RocketRAID BIOS initialized drives.\n");
                }
+               /* drop through */
        case chip_6042:
                hpriv->ops = &mv6xxx_ops;
                hp_flags |= MV_HP_GEN_IIE;
+               if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
+                       hp_flags |= MV_HP_CUT_THROUGH;
 
                switch (pdev->revision) {
                case 0x0:
index 6fe417429977058b40f9ac2caee0b5b933078070..e38dfed41d80b8e6dff45379ee1fdfb8e8d3c750 100644 (file)
@@ -18,7 +18,7 @@ struct sysdev_class cpu_sysdev_class = {
 };
 EXPORT_SYMBOL(cpu_sysdev_class);
 
-static struct sys_device *cpu_sys_devices[NR_CPUS];
+static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
 
 #ifdef CONFIG_HOTPLUG_CPU
 static ssize_t show_online(struct sys_device *dev, char *buf)
@@ -68,7 +68,7 @@ void unregister_cpu(struct cpu *cpu)
        sysdev_remove_file(&cpu->sysdev, &attr_online);
 
        sysdev_unregister(&cpu->sysdev);
-       cpu_sys_devices[logical_cpu] = NULL;
+       per_cpu(cpu_sys_devices, logical_cpu) = NULL;
        return;
 }
 #else /* ... !CONFIG_HOTPLUG_CPU */
@@ -167,7 +167,7 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
        if (!error && cpu->hotpluggable)
                register_cpu_control(cpu);
        if (!error)
-               cpu_sys_devices[num] = &cpu->sysdev;
+               per_cpu(cpu_sys_devices, num) = &cpu->sysdev;
        if (!error)
                register_cpu_under_node(num, cpu_to_node(num));
 
@@ -180,8 +180,8 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
 
 struct sys_device *get_cpu_sysdev(unsigned cpu)
 {
-       if (cpu < NR_CPUS)
-               return cpu_sys_devices[cpu];
+       if (cpu < nr_cpu_ids && cpu_possible(cpu))
+               return per_cpu(cpu_sys_devices, cpu);
        else
                return NULL;
 }
index 4fbb56bcb1eefbd60b5a189963e1e742ef794865..358bb0be3c0838b9233bae7b1eab1cc2b05ef1e6 100644 (file)
@@ -175,8 +175,7 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
        }
 
        /* Check whether this driver has already been added to a class. */
-       if ((drv->entry.next != drv->entry.prev) ||
-           (drv->entry.next != NULL)) {
+       if (drv->entry.next && !list_empty(&drv->entry)) {
                printk(KERN_WARNING "sysdev: class %s: driver (%p) has already"
                        " been registered to a class, something is wrong, but "
                        "will forge on!\n", cls->name, drv);
index 8fc429cf82b6b41d9ddf91d41a339831ac96a778..41f818be2f7ec8c4c737acaa16ecfeddc94f42b4 100644 (file)
@@ -755,11 +755,13 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
 {
        unsigned long n_sect = bio->bi_size >> 9;
        const int rw = bio_data_dir(bio);
+       struct hd_struct *part;
 
-       all_stat_inc(disk, ios[rw], sector);
-       all_stat_add(disk, ticks[rw], duration, sector);
-       all_stat_add(disk, sectors[rw], n_sect, sector);
-       all_stat_add(disk, io_ticks, duration, sector);
+       part = get_part(disk, sector);
+       all_stat_inc(disk, part, ios[rw], sector);
+       all_stat_add(disk, part, ticks[rw], duration, sector);
+       all_stat_add(disk, part, sectors[rw], n_sect, sector);
+       all_stat_add(disk, part, io_ticks, duration, sector);
 }
 
 void
index e539be5750dc694703af89853fee7a41ffed5bac..e336b05fe4a7f5d763dd0db8c61dc740b93635a9 100644 (file)
@@ -428,13 +428,9 @@ static void __devinit cciss_procinit(int i)
                proc_cciss = proc_mkdir("driver/cciss", NULL);
        if (!proc_cciss)
                return;
-       pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
+       pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
                                        S_IROTH, proc_cciss,
-                                       &cciss_proc_fops);
-       if (!pde)
-               return;
-
-       pde->data = hba[i];
+                                       &cciss_proc_fops, hba[i]);
 }
 #endif                         /* CONFIG_PROC_FS */
 
index e322cce8c12d7870d45b2b202c8ff60e9e924c9f..3a281ef11ffa9a96543358dc91c817805eedc981 100644 (file)
@@ -205,6 +205,7 @@ struct ub_scsi_cmd {
        unsigned char key, asc, ascq;   /* May be valid if error==-EIO */
 
        int stat_count;                 /* Retries getting status. */
+       unsigned int timeo;             /* jiffies until rq->timeout changes */
 
        unsigned int len;               /* Requested length */
        unsigned int current_sg;
@@ -318,6 +319,7 @@ struct ub_dev {
        int openc;                      /* protected by ub_lock! */
                                        /* kref is too implicit for our taste */
        int reset;                      /* Reset is running */
+       int bad_resid;
        unsigned int tagcnt;
        char name[12];
        struct usb_device *dev;
@@ -764,6 +766,12 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
        cmd->cdb_len = rq->cmd_len;
 
        cmd->len = rq->data_len;
+
+       /*
+        * To reapply this to every URB is not as incorrect as it looks.
+        * In return, we avoid any complicated tracking calculations.
+        */
+       cmd->timeo = rq->timeout;
 }
 
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
@@ -785,10 +793,6 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        scsi_status = 0;
                } else {
                        if (cmd->act_len != cmd->len) {
-                               if ((cmd->key == MEDIUM_ERROR ||
-                                    cmd->key == UNIT_ATTENTION) &&
-                                   ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
-                                       return;
                                scsi_status = SAM_STAT_CHECK_CONDITION;
                        } else {
                                scsi_status = 0;
@@ -804,7 +808,10 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        else
                                scsi_status = DID_ERROR << 16;
                } else {
-                       if (cmd->error == -EIO) {
+                       if (cmd->error == -EIO &&
+                           (cmd->key == 0 ||
+                            cmd->key == MEDIUM_ERROR ||
+                            cmd->key == UNIT_ATTENTION)) {
                                if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
                                        return;
                        }
@@ -1259,14 +1266,19 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        return;
                }
 
-               len = le32_to_cpu(bcs->Residue);
-               if (len != cmd->len - cmd->act_len) {
-                       /*
-                        * It is all right to transfer less, the caller has
-                        * to check. But it's not all right if the device
-                        * counts disagree with our counts.
-                        */
-                       goto Bad_End;
+               if (!sc->bad_resid) {
+                       len = le32_to_cpu(bcs->Residue);
+                       if (len != cmd->len - cmd->act_len) {
+                               /*
+                                * Only start ignoring if this cmd ended well.
+                                */
+                               if (cmd->len == cmd->act_len) {
+                                       printk(KERN_NOTICE "%s: "
+                                           "bad residual %d of %d, ignoring\n",
+                                           sc->name, len, cmd->len);
+                                       sc->bad_resid = 1;
+                               }
+                       }
                }
 
                switch (bcs->Status) {
@@ -1297,8 +1309,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                ub_state_done(sc, cmd, -EIO);
 
        } else {
-               printk(KERN_WARNING "%s: "
-                   "wrong command state %d\n",
+               printk(KERN_WARNING "%s: wrong command state %d\n",
                    sc->name, cmd->state);
                ub_state_done(sc, cmd, -EINVAL);
                return;
@@ -1336,7 +1347,10 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                return;
        }
 
-       sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
+       if (cmd->timeo)
+               sc->work_timer.expires = jiffies + cmd->timeo;
+       else
+               sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
        add_timer(&sc->work_timer);
 
        cmd->state = UB_CMDST_DATA;
@@ -1376,7 +1390,10 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                return -1;
        }
 
-       sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
+       if (cmd->timeo)
+               sc->work_timer.expires = jiffies + cmd->timeo;
+       else
+               sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
        add_timer(&sc->work_timer);
        return 0;
 }
@@ -1515,8 +1532,7 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
                return;
        }
        if (cmd->state != UB_CMDST_SENSE) {
-               printk(KERN_WARNING "%s: "
-                   "sense done with bad cmd state %d\n",
+               printk(KERN_WARNING "%s: sense done with bad cmd state %d\n",
                    sc->name, cmd->state);
                return;
        }
@@ -1720,7 +1736,7 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp,
 }
 
 /*
- * This is called once a new disk was seen by the block layer or by ub_probe().
+ * This is called by check_disk_change if we reported a media change.
  * The main onjective here is to discover the features of the media such as
  * the capacity, read-only status, etc. USB storage generally does not
  * need to be spun up, but if we needed it, this would be the place.
@@ -2136,8 +2152,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
        }
 
        if (ep_in == NULL || ep_out == NULL) {
-               printk(KERN_NOTICE "%s: failed endpoint check\n",
-                   sc->name);
+               printk(KERN_NOTICE "%s: failed endpoint check\n", sc->name);
                return -ENODEV;
        }
 
@@ -2354,7 +2369,7 @@ static void ub_disconnect(struct usb_interface *intf)
        spin_unlock_irqrestore(&ub_lock, flags);
 
        /*
-        * Fence stall clearnings, operations triggered by unlinkings and so on.
+        * Fence stall clearings, operations triggered by unlinkings and so on.
         * We do not attempt to unlink any URBs, because we do not trust the
         * unlink paths in HC drivers. Also, we get -84 upon disconnect anyway.
         */
@@ -2417,7 +2432,7 @@ static void ub_disconnect(struct usb_interface *intf)
        spin_unlock_irqrestore(sc->lock, flags);
 
        /*
-        * There is virtually no chance that other CPU runs times so long
+        * There is virtually no chance that other CPU runs a timeout so long
         * after ub_urb_complete should have called del_timer, but only if HCD
         * didn't forget to deliver a callback on unlink.
         */
index 0cfbe8c594a55c208a7727cc20a86db0e33ba704..84e064ffee5229e73d2f9f45af19a3ec581f5315 100644 (file)
@@ -35,7 +35,7 @@ struct virtblk_req
        struct list_head list;
        struct request *req;
        struct virtio_blk_outhdr out_hdr;
-       struct virtio_blk_inhdr in_hdr;
+       u8 status;
 };
 
 static void blk_done(struct virtqueue *vq)
@@ -48,7 +48,7 @@ static void blk_done(struct virtqueue *vq)
        spin_lock_irqsave(&vblk->lock, flags);
        while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
                int uptodate;
-               switch (vbr->in_hdr.status) {
+               switch (vbr->status) {
                case VIRTIO_BLK_S_OK:
                        uptodate = 1;
                        break;
@@ -101,7 +101,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
        sg_init_table(vblk->sg, VIRTIO_MAX_SG);
        sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
        num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
-       sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
+       sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status));
 
        if (rq_data_dir(vbr->req) == WRITE) {
                vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
@@ -157,10 +157,25 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp,
 /* We provide getgeo only to please some old bootloader/partitioning tools */
 static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
 {
-       /* some standard values, similar to sd */
-       geo->heads = 1 << 6;
-       geo->sectors = 1 << 5;
-       geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+       struct virtio_blk *vblk = bd->bd_disk->private_data;
+       struct virtio_blk_geometry vgeo;
+       int err;
+
+       /* see if the host passed in geometry config */
+       err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
+                               offsetof(struct virtio_blk_config, geometry),
+                               &vgeo);
+
+       if (!err) {
+               geo->heads = vgeo.heads;
+               geo->sectors = vgeo.sectors;
+               geo->cylinders = vgeo.cylinders;
+       } else {
+               /* some standard values, similar to sd */
+               geo->heads = 1 << 6;
+               geo->sectors = 1 << 5;
+               geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+       }
        return 0;
 }
 
@@ -242,12 +257,12 @@ static int virtblk_probe(struct virtio_device *vdev)
        index++;
 
        /* If barriers are supported, tell block layer that queue is ordered */
-       if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER))
+       if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
                blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
 
        /* Host must always specify the capacity. */
-       __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity),
-                           &cap);
+       vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity),
+                         &cap, sizeof(cap));
 
        /* If capacity is too big, truncate with warning. */
        if ((sector_t)cap != cap) {
@@ -289,7 +304,6 @@ out:
 static void virtblk_remove(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk = vdev->priv;
-       int major = vblk->disk->major;
 
        /* Nothing should be pending. */
        BUG_ON(!list_empty(&vblk->reqs));
@@ -299,7 +313,6 @@ static void virtblk_remove(struct virtio_device *vdev)
 
        blk_cleanup_queue(vblk->disk->queue);
        put_disk(vblk->disk);
-       unregister_blkdev(major, "virtblk");
        mempool_destroy(vblk->pool);
        vdev->config->del_vq(vblk->vq);
        kfree(vblk);
@@ -310,7 +323,14 @@ static struct virtio_device_id id_table[] = {
        { 0 },
 };
 
+static unsigned int features[] = {
+       VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
+       VIRTIO_BLK_F_GEOMETRY,
+};
+
 static struct virtio_driver virtio_blk = {
+       .feature_table = features,
+       .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table =     id_table,
index f49037b744f99ef52455bfad7588f5d1610b7c35..b60d425ce8d1502fcadcfba5350770525d9be2dd 100644 (file)
@@ -77,6 +77,10 @@ static int power_status;
 module_param(power_status, bool, 0600);
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 
+static int fan_mult = I8K_FAN_MULT;
+module_param(fan_mult, int, 0);
+MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with");
+
 static int i8k_open_fs(struct inode *inode, struct file *file);
 static int i8k_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
@@ -239,7 +243,7 @@ static int i8k_get_fan_speed(int fan)
        struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 
        regs.ebx = fan & 0xff;
-       return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
+       return i8k_smm(&regs) ? : (regs.eax & 0xffff) * fan_mult;
 }
 
 /*
index d83db5d880e068ac4296c2b07767d849067a1037..192961fd71739d22ad4ff9a65df5a101bc460fbd 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/miscdevice.h>
 #include <linux/posix-timers.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/math64.h>
 
 #include <asm/uaccess.h>
 #include <asm/sn/addrs.h>
@@ -472,8 +474,8 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp)
 
        nsec = rtc_time() * sgi_clock_period
                        + sgi_clock_offset.tv_nsec;
-       tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec)
-                       + sgi_clock_offset.tv_sec;
+       *tp = ns_to_timespec(nsec);
+       tp->tv_sec += sgi_clock_offset.tv_sec;
        return 0;
 };
 
@@ -481,11 +483,11 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp)
 {
 
        u64 nsec;
-       u64 rem;
+       u32 rem;
 
        nsec = rtc_time() * sgi_clock_period;
 
-       sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
+       sgi_clock_offset.tv_sec = tp->tv_sec - div_u64_rem(nsec, NSEC_PER_SEC, &rem);
 
        if (rem <= tp->tv_nsec)
                sgi_clock_offset.tv_nsec = tp->tv_sec - rem;
@@ -644,9 +646,6 @@ static int sgi_timer_del(struct k_itimer *timr)
        return 0;
 }
 
-#define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC)
-#define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec)
-
 /* Assumption: it_lock is already held with irq's disabled */
 static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
 {
@@ -659,9 +658,8 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
                return;
        }
 
-       ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period);
-       ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period);
-       return;
+       cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period);
+       cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period);
 }
 
 
@@ -679,8 +677,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
                sgi_timer_get(timr, old_setting);
 
        sgi_timer_del(timr);
-       when = timespec_to_ns(new_setting->it_value);
-       period = timespec_to_ns(new_setting->it_interval);
+       when = timespec_to_ns(&new_setting->it_value);
+       period = timespec_to_ns(&new_setting->it_interval);
 
        if (when == 0)
                /* Clear timer */
@@ -695,7 +693,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
                unsigned long now;
 
                getnstimeofday(&n);
-               now = timespec_to_ns(n);
+               now = timespec_to_ns(&n);
                if (when > now)
                        when -= now;
                else
index fd2db07a50fce9bf39e2bcaf0060bc7fc71f8a09..3b23270eaa65385f56a2cef7652aeb2ccea77055 100644 (file)
@@ -1073,7 +1073,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch)
                return 0;
 
        if (!info->xmit_buf)
-               return;
+               return 0;
 
        local_irq_save(flags);
        if (info->xmit_cnt >= PAGE_SIZE - 1) {
index f39f6fd8935064f01af2b91115e70111ddaa6769..b1a7a8cb65ea0252f0cbc0c5194dbc9ad9c8dcd9 100644 (file)
@@ -970,7 +970,8 @@ static int sx_set_real_termios(void *ptr)
                sx_write_channel_byte(port, hi_mask, 0x1f);
                break;
        default:
-               printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
+               printk(KERN_INFO "sx: Invalid wordsize: %u\n",
+                       (unsigned int)CFLAG & CSIZE);
                break;
        }
 
@@ -997,7 +998,8 @@ static int sx_set_real_termios(void *ptr)
                set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
        }
        sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
-                       port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty));
+                       (unsigned int)port->gs.tty->termios->c_iflag,
+                       I_OTHER(port->gs.tty));
 
 /* Tell line discipline whether we will do output cooking.
  * If OPOST is set and no other output flags are set then we can do output
@@ -1010,7 +1012,8 @@ static int sx_set_real_termios(void *ptr)
                clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
        }
        sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
-                       port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty));
+                       (unsigned int)port->gs.tty->termios->c_oflag,
+                       O_OTHER(port->gs.tty));
        /* port->c_dcd = sx_get_CD (port); */
        func_exit();
        return 0;
index 513b7c2f3e264fc2dd809c7865ebd4b0dd66ee53..ac5080df2565aef4cd85e96a112d3cd3ffa7820f 100644 (file)
@@ -2028,13 +2028,13 @@ static void mgsl_change_params(struct mgsl_struct *info)
  */
 static int mgsl_put_char(struct tty_struct *tty, unsigned char ch)
 {
-       struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;
+       struct mgsl_struct *info = tty->driver_data;
        unsigned long flags;
-       int ret;
+       int ret = 0;
 
-       if ( debug_level >= DEBUG_LEVEL_INFO ) {
-               printk( "%s(%d):mgsl_put_char(%d) on %s\n",
-                       __FILE__,__LINE__,ch,info->device_name);
+       if (debug_level >= DEBUG_LEVEL_INFO) {
+               printk(KERN_DEBUG "%s(%d):mgsl_put_char(%d) on %s\n",
+                       __FILE__, __LINE__, ch, info->device_name);
        }               
        
        if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char"))
@@ -2043,9 +2043,9 @@ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch)
        if (!tty || !info->xmit_buf)
                return 0;
 
-       spin_lock_irqsave(&info->irq_spinlock,flags);
+       spin_lock_irqsave(&info->irq_spinlock, flags);
        
-       if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) {
+       if ((info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active) {
                if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) {
                        info->xmit_buf[info->xmit_head++] = ch;
                        info->xmit_head &= SERIAL_XMIT_SIZE-1;
@@ -2053,7 +2053,7 @@ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch)
                        ret = 1;
                }
        }
-       spin_unlock_irqrestore(&info->irq_spinlock,flags);
+       spin_unlock_irqrestore(&info->irq_spinlock, flags);
        return ret;
        
 }      /* end of mgsl_put_char() */
index 2001b0e52dc69c51a765ff8ffdef2a426e202b01..55c1653be00ca86f0f76051d940cfe7e5e933145 100644 (file)
@@ -916,7 +916,7 @@ static int put_char(struct tty_struct *tty, unsigned char ch)
 {
        struct slgt_info *info = tty->driver_data;
        unsigned long flags;
-       int ret;
+       int ret = 0;
 
        if (sanity_check(info, tty->name, "put_char"))
                return 0;
index 6342b0534f4d3cda24aaac72cd5cb25deeb3021d..3582f43345a8c1d40397d2284dd2bc11d77a9fd4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/audit.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/tty.h>
 
 struct tty_audit_buf {
index 1d298c2cf9301c0a1ac2026577463e6a3a6b1813..49c1a2267a55c7490c504ba7486b276575851ae8 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/tty_flip.h>
 #include <linux/devpts_fs.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/console.h>
 #include <linux/timer.h>
 #include <linux/ctype.h>
index e458b08139afb6fd638b125334ca1b602eb8e136..fa1ffbf2c621a88aa231f1262a57bd470df97e9e 100644 (file)
@@ -2742,6 +2742,10 @@ static int con_open(struct tty_struct *tty, struct file *filp)
                                tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
                                tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
                        }
+                       if (vc->vc_utf)
+                               tty->termios->c_iflag |= IUTF8;
+                       else
+                               tty->termios->c_iflag &= ~IUTF8;
                        release_console_sem();
                        vcs_make_sysfs(tty);
                        return ret;
@@ -2918,6 +2922,8 @@ int __init vty_init(void)
        console_driver->minor_start = 1;
        console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
        console_driver->init_termios = tty_std_termios;
+       if (default_utf8)
+               console_driver->init_termios.c_iflag |= IUTF8;
        console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
        tty_set_operations(console_driver, &con_ops);
        if (tty_register_driver(console_driver))
index dfe6907ae15be44641591f4c28fea94d1a4e66f6..3edf1fc1296312e09670427b6500a442d50a7c5f 100644 (file)
@@ -623,8 +623,8 @@ static int __devinit hwicap_setup(struct device *dev, int id,
 
        if (!request_mem_region(drvdata->mem_start,
                                        drvdata->mem_size, DRIVER_NAME)) {
-               dev_err(dev, "Couldn't lock memory region at %p\n",
-                       (void *)regs_res->start);
+               dev_err(dev, "Couldn't lock memory region at %Lx\n",
+                       regs_res->start);
                retval = -EBUSY;
                goto failed1;
        }
@@ -643,7 +643,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
        mutex_init(&drvdata->sem);
        drvdata->is_open = 0;
 
-       dev_info(dev, "ioremap %lx to %p with size %x\n",
+       dev_info(dev, "ioremap %lx to %p with size %Lx\n",
                 (unsigned long int)drvdata->mem_start,
                        drvdata->base_address, drvdata->mem_size);
 
index a9aa845dbe74c864d9b5126d272051b5e18223f6..b27b13c5eb5ad3871c88247887460a253d1a5276 100644 (file)
@@ -97,7 +97,7 @@ extern int edac_debug_level;
 #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
        PCI_DEVICE_ID_ ## vend ## _ ## dev
 
-#define dev_name(dev) (dev)->dev_name
+#define edac_dev_name(dev) (dev)->dev_name
 
 /* memory devices */
 enum dev_type {
index 63372fa7ecfe63ec6de319e4177a141c45bb508c..5fcd3d89c75d91cda65acd42fe34be8d987e9c67 100644 (file)
@@ -333,7 +333,7 @@ static int add_edac_dev_to_global_list(struct edac_device_ctl_info *edac_dev)
 fail0:
        edac_printk(KERN_WARNING, EDAC_MC,
                        "%s (%s) %s %s already assigned %d\n",
-                       rover->dev->bus_id, dev_name(rover),
+                       rover->dev->bus_id, edac_dev_name(rover),
                        rover->mod_name, rover->ctl_name, rover->dev_idx);
        return 1;
 
@@ -538,7 +538,7 @@ int edac_device_add_device(struct edac_device_ctl_info *edac_dev)
                                "'%s': DEV '%s' (%s)\n",
                                edac_dev->mod_name,
                                edac_dev->ctl_name,
-                               dev_name(edac_dev),
+                               edac_dev_name(edac_dev),
                                edac_op_state_to_string(edac_dev->op_state));
 
        mutex_unlock(&device_ctls_mutex);
@@ -599,7 +599,7 @@ struct edac_device_ctl_info *edac_device_del_device(struct device *dev)
        edac_printk(KERN_INFO, EDAC_MC,
                "Removed device %d for %s %s: DEV %s\n",
                edac_dev->dev_idx,
-               edac_dev->mod_name, edac_dev->ctl_name, dev_name(edac_dev));
+               edac_dev->mod_name, edac_dev->ctl_name, edac_dev_name(edac_dev));
 
        return edac_dev;
 }
index a4cf1645f588c998bbebb4c812bd567a229cc0e2..d110392d48f4cd17a854744abdfaef372cd73a84 100644 (file)
@@ -402,7 +402,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci)
 fail0:
        edac_printk(KERN_WARNING, EDAC_MC,
                "%s (%s) %s %s already assigned %d\n", p->dev->bus_id,
-               dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
+               edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
        return 1;
 
 fail1:
@@ -517,7 +517,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
 
        /* Report action taken */
        edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':"
-               " DEV %s\n", mci->mod_name, mci->ctl_name, dev_name(mci));
+               " DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci));
 
        mutex_unlock(&mem_ctls_mutex);
        return 0;
@@ -565,7 +565,7 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
 
        edac_printk(KERN_INFO, EDAC_MC,
                "Removed device %d for %s %s: DEV %s\n", mci->mc_idx,
-               mci->mod_name, mci->ctl_name, dev_name(mci));
+               mci->mod_name, mci->ctl_name, edac_dev_name(mci));
 
        return mci;
 }
index 9b24340b52e1eb3d30666181e668abf83ebd78f2..22ec9d5d4312940199a7cf425cb73f3d10b11229 100644 (file)
@@ -150,7 +150,7 @@ static int add_edac_pci_to_global_list(struct edac_pci_ctl_info *pci)
 fail0:
        edac_printk(KERN_WARNING, EDAC_PCI,
                "%s (%s) %s %s already assigned %d\n",
-               rover->dev->bus_id, dev_name(rover),
+               rover->dev->bus_id, edac_dev_name(rover),
                rover->mod_name, rover->ctl_name, rover->pci_idx);
        return 1;
 
@@ -360,7 +360,7 @@ int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx)
                        " DEV '%s' (%s)\n",
                        pci->mod_name,
                        pci->ctl_name,
-                       dev_name(pci), edac_op_state_to_string(pci->op_state));
+                       edac_dev_name(pci), edac_op_state_to_string(pci->op_state));
 
        mutex_unlock(&edac_pci_ctls_mutex);
        return 0;
@@ -415,7 +415,7 @@ struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev)
 
        edac_printk(KERN_INFO, EDAC_PCI,
                "Removed device %d for %s %s: DEV %s\n",
-               pci->pci_idx, pci->mod_name, pci->ctl_name, dev_name(pci));
+               pci->pci_idx, pci->mod_name, pci->ctl_name, edac_dev_name(pci));
 
        return pci;
 }
index 2a999373863eb206927d23e4a8f775cf3c92c053..b2458bb8e9cade2fd79fea620b60eb9edd0aa7e0 100644 (file)
@@ -784,7 +784,7 @@ static void sbp2_release_target(struct kref *kref)
                kfree(lu);
        }
        scsi_remove_host(shost);
-       fw_notify("released %s\n", tgt->bus_id);
+       fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no);
 
        fw_unit_put(tgt->unit);
        scsi_host_put(shost);
@@ -1487,7 +1487,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
                goto out;
 
-       memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
+       memcpy(orb->request.command_block, cmd->cmnd, cmd->cmd_len);
 
        orb->base.callback = complete_command_orb;
        orb->base.request_bus =
index 5a99e81d27843c8ce9e376684196b5daa253f90a..93f916720b139e40b20591839126609db0e778a0 100644 (file)
@@ -30,6 +30,8 @@ static const struct i2c_device_id pca953x_id[] = {
        { "pca9537", 4, },
        { "pca9538", 8, },
        { "pca9539", 16, },
+       { "pca9555", 16, },
+       { "pca9557", 8, },
        /* REVISIT several pca955x parts should work here too */
        { }
 };
@@ -193,7 +195,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
-       int ret, i;
+       int ret;
 
        pdata = client->dev.platform_data;
        if (pdata == NULL)
index 9587869bdba0eb5bf58314b56c76d98f91b28507..c1009d6f97965b160d26ac4723235d97280a427c 100644 (file)
@@ -422,18 +422,14 @@ static ssize_t show_volt(struct device *dev, struct device_attribute *devattr,
  * number in the range -128 to 127, or as an unsigned number that must
  * be offset by 64.
  */
-static int decode_temp(struct adt7473_data *data, u8 raw)
+static int decode_temp(u8 twos_complement, u8 raw)
 {
-       if (data->temp_twos_complement)
-               return (s8)raw;
-       return raw - 64;
+       return twos_complement ? (s8)raw : raw - 64;
 }
 
-static u8 encode_temp(struct adt7473_data *data, int cooked)
+static u8 encode_temp(u8 twos_complement, int cooked)
 {
-       if (data->temp_twos_complement)
-               return (cooked & 0xFF);
-       return cooked + 64;
+       return twos_complement ? cooked & 0xFF : cooked + 64;
 }
 
 static ssize_t show_temp_min(struct device *dev,
@@ -442,8 +438,9 @@ static ssize_t show_temp_min(struct device *dev,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adt7473_data *data = adt7473_update_device(dev);
-       return sprintf(buf, "%d\n",
-                      1000 * decode_temp(data, data->temp_min[attr->index]));
+       return sprintf(buf, "%d\n", 1000 * decode_temp(
+                                               data->temp_twos_complement,
+                                               data->temp_min[attr->index]));
 }
 
 static ssize_t set_temp_min(struct device *dev,
@@ -455,7 +452,7 @@ static ssize_t set_temp_min(struct device *dev,
        struct i2c_client *client = to_i2c_client(dev);
        struct adt7473_data *data = i2c_get_clientdata(client);
        int temp = simple_strtol(buf, NULL, 10) / 1000;
-       temp = encode_temp(data, temp);
+       temp = encode_temp(data->temp_twos_complement, temp);
 
        mutex_lock(&data->lock);
        data->temp_min[attr->index] = temp;
@@ -472,8 +469,9 @@ static ssize_t show_temp_max(struct device *dev,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adt7473_data *data = adt7473_update_device(dev);
-       return sprintf(buf, "%d\n",
-                      1000 * decode_temp(data, data->temp_max[attr->index]));
+       return sprintf(buf, "%d\n", 1000 * decode_temp(
+                                               data->temp_twos_complement,
+                                               data->temp_max[attr->index]));
 }
 
 static ssize_t set_temp_max(struct device *dev,
@@ -485,7 +483,7 @@ static ssize_t set_temp_max(struct device *dev,
        struct i2c_client *client = to_i2c_client(dev);
        struct adt7473_data *data = i2c_get_clientdata(client);
        int temp = simple_strtol(buf, NULL, 10) / 1000;
-       temp = encode_temp(data, temp);
+       temp = encode_temp(data->temp_twos_complement, temp);
 
        mutex_lock(&data->lock);
        data->temp_max[attr->index] = temp;
@@ -501,8 +499,9 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adt7473_data *data = adt7473_update_device(dev);
-       return sprintf(buf, "%d\n",
-                      1000 * decode_temp(data, data->temp[attr->index]));
+       return sprintf(buf, "%d\n", 1000 * decode_temp(
+                                               data->temp_twos_complement,
+                                               data->temp[attr->index]));
 }
 
 static ssize_t show_fan_min(struct device *dev,
@@ -671,8 +670,9 @@ static ssize_t show_temp_tmax(struct device *dev,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adt7473_data *data = adt7473_update_device(dev);
-       return sprintf(buf, "%d\n",
-                      1000 * decode_temp(data, data->temp_tmax[attr->index]));
+       return sprintf(buf, "%d\n", 1000 * decode_temp(
+                                               data->temp_twos_complement,
+                                               data->temp_tmax[attr->index]));
 }
 
 static ssize_t set_temp_tmax(struct device *dev,
@@ -684,7 +684,7 @@ static ssize_t set_temp_tmax(struct device *dev,
        struct i2c_client *client = to_i2c_client(dev);
        struct adt7473_data *data = i2c_get_clientdata(client);
        int temp = simple_strtol(buf, NULL, 10) / 1000;
-       temp = encode_temp(data, temp);
+       temp = encode_temp(data->temp_twos_complement, temp);
 
        mutex_lock(&data->lock);
        data->temp_tmax[attr->index] = temp;
@@ -701,8 +701,9 @@ static ssize_t show_temp_tmin(struct device *dev,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct adt7473_data *data = adt7473_update_device(dev);
-       return sprintf(buf, "%d\n",
-                      1000 * decode_temp(data, data->temp_tmin[attr->index]));
+       return sprintf(buf, "%d\n", 1000 * decode_temp(
+                                               data->temp_twos_complement,
+                                               data->temp_tmin[attr->index]));
 }
 
 static ssize_t set_temp_tmin(struct device *dev,
@@ -714,7 +715,7 @@ static ssize_t set_temp_tmin(struct device *dev,
        struct i2c_client *client = to_i2c_client(dev);
        struct adt7473_data *data = i2c_get_clientdata(client);
        int temp = simple_strtol(buf, NULL, 10) / 1000;
-       temp = encode_temp(data, temp);
+       temp = encode_temp(data->temp_twos_complement, temp);
 
        mutex_lock(&data->lock);
        data->temp_tmin[attr->index] = temp;
index 84712a22acea1f4f17077cf59108701f91e07847..fe2eea4d799b60b4b4ab5df992eeb1aa200175bf 100644 (file)
@@ -953,12 +953,8 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
 static void asb100_init_client(struct i2c_client *client)
 {
        struct asb100_data *data = i2c_get_clientdata(client);
-       int vid = 0;
 
-       vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f;
-       vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4;
        data->vrm = vid_which_vrm();
-       vid = vid_from_reg(vid, data->vrm);
 
        /* Start monitoring */
        asb100_write_value(client, ASB100_REG_CONFIG,
index 115f4090b98e3c94cab67e058a7e1676e9b3546c..fa7696905154ca1e14444ca2a95e946470084cd4 100644 (file)
@@ -248,7 +248,7 @@ static int lm75_detach_client(struct i2c_client *client)
 
 /* All registers are word-sized, except for the configuration register.
    LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
+   the SMBus standard. */
 static int lm75_read_value(struct i2c_client *client, u8 reg)
 {
        if (reg == LM75_REG_CONF)
@@ -257,9 +257,6 @@ static int lm75_read_value(struct i2c_client *client, u8 reg)
                return swab16(i2c_smbus_read_word_data(client, reg));
 }
 
-/* All registers are word-sized, except for the configuration register.
-   LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
 static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
 {
        if (reg == LM75_REG_CONF)
index f61d8f4185b243efcf7bd3fb0f10fa6284dde6d2..eb03544c731ca47dd94c6d7d940b3f66a43dbcdd 100644 (file)
@@ -335,11 +335,23 @@ exit:
 static int __init smsc47b397_find(unsigned short *addr)
 {
        u8 id, rev;
+       char *name;
 
        superio_enter();
        id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
 
-       if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) {
+       switch(id) {
+       case 0x81:
+               name = "SCH5307-NS";
+               break;
+       case 0x6f:
+               name = "LPC47B397-NC";
+               break;
+       case 0x85:
+       case 0x8c:
+               name = "SCH5317";
+               break;
+       default:
                superio_exit();
                return -ENODEV;
        }
@@ -352,8 +364,7 @@ static int __init smsc47b397_find(unsigned short *addr)
 
        printk(KERN_INFO DRVNAME ": found SMSC %s "
                "(base address 0x%04x, revision %u)\n",
-               id == 0x81 ? "SCH5307-NS" : id == 0x85 ? "SCH5317" :
-              "LPC47B397-NC", *addr, rev);
+               name, *addr, rev);
 
        superio_exit();
        return 0;
index ee35af93b574d37879acf53d813bd24f12c8dc29..ed3c019b78c7284f805a83596abba56f77664028 100644 (file)
@@ -1024,10 +1024,9 @@ static struct sensor_device_attribute_2 w83793_vid[] = {
        SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0),
        SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1),
 };
+static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm);
 
 static struct sensor_device_attribute_2 sda_single_files[] = {
-       SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm,
-                     NOT_USED, NOT_USED),
        SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
                      store_chassis_clear, ALARM_STATUS, 30),
        SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
@@ -1080,6 +1079,7 @@ static int w83793_detach_client(struct i2c_client *client)
 
                for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
                        device_remove_file(dev, &w83793_vid[i].dev_attr);
+               device_remove_file(dev, &dev_attr_vrm);
 
                for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
                        device_remove_file(dev, &w83793_left_fan[i].dev_attr);
@@ -1282,7 +1282,6 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        /* Initialize the chip */
        w83793_init_client(client);
 
-       data->vrm = vid_which_vrm();
        /*
           Only fan 1-5 has their own input pins,
           Pwm 1-3 has their own pins
@@ -1293,7 +1292,9 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        val = w83793_read_value(client, W83793_REG_FANIN_CTRL);
 
        /* check the function of pins 49-56 */
-       if (!(tmp & 0x80)) {
+       if (tmp & 0x80) {
+               data->has_vid |= 0x2;   /* has VIDB */
+       } else {
                data->has_pwm |= 0x18;  /* pwm 4,5 */
                if (val & 0x01) {       /* fan 6 */
                        data->has_fan |= 0x20;
@@ -1309,13 +1310,15 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                }
        }
 
+       /* check the function of pins 37-40 */
+       if (!(tmp & 0x29))
+               data->has_vid |= 0x1;   /* has VIDA */
        if (0x08 == (tmp & 0x0c)) {
                if (val & 0x08) /* fan 9 */
                        data->has_fan |= 0x100;
                if (val & 0x10) /* fan 10 */
                        data->has_fan |= 0x200;
        }
-
        if (0x20 == (tmp & 0x30)) {
                if (val & 0x20) /* fan 11 */
                        data->has_fan |= 0x400;
@@ -1359,13 +1362,6 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        if (tmp & 0x02)
                data->has_temp |= 0x20;
 
-       /* Detect the VID usage and ignore unused input */
-       tmp = w83793_read_value(client, W83793_REG_MFC);
-       if (!(tmp & 0x29))
-               data->has_vid |= 0x1;   /* has VIDA */
-       if (tmp & 0x80)
-               data->has_vid |= 0x2;   /* has VIDB */
-
        /* Register sysfs hooks */
        for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) {
                err = device_create_file(dev,
@@ -1381,6 +1377,12 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                if (err)
                        goto exit_remove;
        }
+       if (data->has_vid) {
+               data->vrm = vid_which_vrm();
+               err = device_create_file(dev, &dev_attr_vrm);
+               if (err)
+                       goto exit_remove;
+       }
 
        for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
                err = device_create_file(dev, &sda_single_files[i].dev_attr);
index 77f2d482888b1fe3293080be6d83d17a17a4fd08..52e268e25dab01e574f97293008ec8e7a7e869fc 100644 (file)
@@ -301,8 +301,8 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
                msleep(i);
        }
 
-       dev_err(&client->dev, "Couldn't read value from register 0x%02x. "
-               "Please report.\n", reg);
+       dev_err(&client->dev, "Couldn't read value from register 0x%02x.\n",
+               reg);
        return defval;
 }
 
index 491718fe46b78a00ac959885fe00745cb682c18a..cae9dc89d88cc0737379cf38f1ce55116f1abbac 100644 (file)
@@ -335,7 +335,7 @@ i2c_au1550_probe(struct platform_device *pdev)
                goto out_mem;
        }
 
-       priv->psc_base = r->start;
+       priv->psc_base = CKSEG1ADDR(r->start);
        priv->xfer_timeout = 200;
        priv->ack_timeout = 200;
 
index 18beb0ad7bf3ad1b9fc703c3c75952fd6017e848..a076129de7e811acb2434864ef2d48fccbeafa3b 100644 (file)
@@ -99,7 +99,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
        u32 x;
        int result = 0;
 
-       if (i2c->irq == 0)
+       if (i2c->irq == NO_IRQ)
        {
                while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
                        schedule();
@@ -329,10 +329,9 @@ static int fsl_i2c_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        i2c->irq = platform_get_irq(pdev, 0);
-       if (i2c->irq < 0) {
-               result = -ENXIO;
-               goto fail_get_irq;
-       }
+       if (i2c->irq < 0)
+               i2c->irq = NO_IRQ; /* Use polling */
+
        i2c->flags = pdata->device_flags;
        init_waitqueue_head(&i2c->queue);
 
@@ -344,7 +343,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
                goto fail_map;
        }
 
-       if (i2c->irq != 0)
+       if (i2c->irq != NO_IRQ)
                if ((result = request_irq(i2c->irq, mpc_i2c_isr,
                                          IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
                        printk(KERN_ERR
@@ -367,12 +366,11 @@ static int fsl_i2c_probe(struct platform_device *pdev)
        return result;
 
       fail_add:
-       if (i2c->irq != 0)
+       if (i2c->irq != NO_IRQ)
                free_irq(i2c->irq, i2c);
       fail_irq:
        iounmap(i2c->base);
       fail_map:
-      fail_get_irq:
        kfree(i2c);
        return result;
 };
@@ -384,7 +382,7 @@ static int fsl_i2c_remove(struct platform_device *pdev)
        i2c_del_adapter(&i2c->adap);
        platform_set_drvdata(pdev, NULL);
 
-       if (i2c->irq != 0)
+       if (i2c->irq != NO_IRQ)
                free_irq(i2c->irq, i2c);
 
        iounmap(i2c->base);
index fdc9ad805e358528b8599f0dbd4635bb817155e7..ac916596858764481f08afdde261b770be1a1b54 100644 (file)
@@ -104,10 +104,31 @@ MODULE_PARM_DESC(force_addr,
 static int piix4_transaction(void);
 
 static unsigned short piix4_smba;
+static int srvrworks_csb5_delay;
 static struct pci_driver piix4_driver;
 static struct i2c_adapter piix4_adapter;
 
-static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
+static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
+       {
+               .ident = "Sapphire AM2RD790",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
+               },
+       },
+       {
+               .ident = "DFI Lanparty UT 790FX",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
+               },
+       },
+       { }
+};
+
+/* The IBM entry is in a separate table because we only check it
+   on Intel-based systems */
+static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
        {
                .ident = "IBM",
                .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
@@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
 
        dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
 
+       if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+           (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
+               srvrworks_csb5_delay = 1;
+
+       /* On some motherboards, it was reported that accessing the SMBus
+          caused severe hardware problems */
+       if (dmi_check_system(piix4_dmi_blacklist)) {
+               dev_err(&PIIX4_dev->dev,
+                       "Accessing the SMBus on this system is unsafe!\n");
+               return -EPERM;
+       }
+
        /* Don't access SMBus on IBM systems which get corrupted eeproms */
-       if (dmi_check_system(piix4_dmi_table) &&
+       if (dmi_check_system(piix4_dmi_ibm) &&
                        PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
                dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
                        "may corrupt your serial eeprom! Refusing to load "
@@ -230,10 +263,14 @@ static int piix4_transaction(void)
        outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
 
        /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
-       do {
+       if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
+               msleep(2);
+       else
+               msleep(1);
+
+       while ((timeout++ < MAX_TIMEOUT) &&
+              ((temp = inb_p(SMBHSTSTS)) & 0x01))
                msleep(1);
-               temp = inb_p(SMBHSTSTS);
-       } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
index 8fbbdb4c2f35d0c81c2252f84b2e99ade7ca36a4..114634da6c6e9f3a7bd7ca77bf04476fc1c2818c 100644 (file)
@@ -132,14 +132,14 @@ static const struct i2c_algorithm i2c_sibyte_algo = {
 /*
  * registering functions to load algorithms at runtime
  */
-int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
+static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
 {
        struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
 
-       /* register new adapter to i2c module... */
+       /* Register new adapter to i2c module... */
        i2c_adap->algo = &i2c_sibyte_algo;
 
-       /* Set the frequency to 100 kHz */
+       /* Set the requested frequency. */
        csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
        csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
 
index 26384daccb968180c369207e70f35e0a3598e04d..c99ebeadb558bc54069aed54af89ecc321dc4486 100644 (file)
@@ -327,6 +327,11 @@ void i2c_unregister_device(struct i2c_client *client)
 EXPORT_SYMBOL_GPL(i2c_unregister_device);
 
 
+static const struct i2c_device_id dummy_id[] = {
+       { "dummy", 0 },
+       { },
+};
+
 static int dummy_probe(struct i2c_client *client,
                       const struct i2c_device_id *id)
 {
@@ -342,13 +347,13 @@ static struct i2c_driver dummy_driver = {
        .driver.name    = "dummy",
        .probe          = dummy_probe,
        .remove         = dummy_remove,
+       .id_table       = dummy_id,
 };
 
 /**
  * i2c_new_dummy - return a new i2c device bound to a dummy driver
  * @adapter: the adapter managing the device
  * @address: seven bit address to be used
- * @type: optional label used for i2c_client.name
  * Context: can sleep
  *
  * This returns an I2C client bound to the "dummy" driver, intended for use
@@ -364,15 +369,12 @@ static struct i2c_driver dummy_driver = {
  * i2c_unregister_device(); or NULL to indicate an error.
  */
 struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type)
+i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
 {
        struct i2c_board_info info = {
-               .driver_name    = "dummy",
-               .addr           = address,
+               I2C_BOARD_INFO("dummy", address),
        };
 
-       if (type)
-               strlcpy(info.type, type, sizeof info.type);
        return i2c_new_device(adapter, &info);
 }
 EXPORT_SYMBOL_GPL(i2c_new_dummy);
index 099a0fe1745b3c209cfc9f065b60308f643f3196..34b0d4f26b5885bb22a3ea88a3898b4900e5678d 100644 (file)
@@ -1347,19 +1347,14 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
            (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
                hwif->irq = port ? 15 : 14;
 
-       hwif->host_flags = d->host_flags;
+       /* ->host_flags may be set by ->init_iops (or even earlier...) */
+       hwif->host_flags |= d->host_flags;
        hwif->pio_mask = d->pio_mask;
 
        /* ->set_pio_mode for DTC2278 is currently limited to port 0 */
        if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
                hwif->port_ops = d->port_ops;
 
-       if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
-           ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) {
-               if (hwif->mate)
-                       hwif->mate->serialized = hwif->serialized = 1;
-       }
-
        hwif->swdma_mask = d->swdma_mask;
        hwif->mwdma_mask = d->mwdma_mask;
        hwif->ultra_mask = d->udma_mask;
@@ -1381,6 +1376,12 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
                        hwif->dma_ops = d->dma_ops;
        }
 
+       if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
+           ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) {
+               if (hwif->mate)
+                       hwif->mate->serialized = hwif->serialized = 1;
+       }
+
        if (d->host_flags & IDE_HFLAG_RQSIZE_256)
                hwif->rqsize = 256;
 
index 83555ca513b58c6b0f9330398431a151bd5ee027..9e449a0c623f78cc82868c2facca4cb9737daf96 100644 (file)
@@ -61,7 +61,7 @@ static void falconide_output_data(ide_drive_t *drive, struct request *rq,
        unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
        if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-               return outsw(data_adr, buf, (len + 1) / 2);
+               return outsw(data_addr, buf, (len + 1) / 2);
 
        outsw_swapw(data_addr, buf, (len + 1) / 2);
 }
index 29d833e71cbfbc3c8ef0be7137186cc07afa553e..05710c7c12206aa1a9fcca8bad4db2eac3be7697 100644 (file)
@@ -520,8 +520,11 @@ static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
        char *scratch = buf;
 
        driver = container_of(drv, struct hpsb_protocol_driver, driver);
+       id = driver->id_table;
+       if (!id)
+               return 0;
 
-       for (id = driver->id_table; id->match_flags != 0; id++) {
+       for (; id->match_flags != 0; id++) {
                int need_coma = 0;
 
                if (id->match_flags & IEEE1394_MATCH_VENDOR_ID) {
index ed2ee4ba4b7c3e9e50ed8d162fbc40b5482945ca..ebf9d3043f80544dc32420b4483ef67111494ae9 100644 (file)
@@ -359,9 +359,10 @@ static void insert_recv_cqe(struct t3_wq *wq, struct t3_cq *cq)
        cq->sw_wptr++;
 }
 
-void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count)
+int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count)
 {
        u32 ptr;
+       int flushed = 0;
 
        PDBG("%s wq %p cq %p\n", __func__, wq, cq);
 
@@ -369,8 +370,11 @@ void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count)
        PDBG("%s rq_rptr %u rq_wptr %u skip count %u\n", __func__,
            wq->rq_rptr, wq->rq_wptr, count);
        ptr = wq->rq_rptr + count;
-       while (ptr++ != wq->rq_wptr)
+       while (ptr++ != wq->rq_wptr) {
                insert_recv_cqe(wq, cq);
+               flushed++;
+       }
+       return flushed;
 }
 
 static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq,
@@ -394,9 +398,10 @@ static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq,
        cq->sw_wptr++;
 }
 
-void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
+int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
 {
        __u32 ptr;
+       int flushed = 0;
        struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2);
 
        ptr = wq->sq_rptr + count;
@@ -405,7 +410,9 @@ void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
                insert_sq_cqe(wq, cq, sqp);
                sqp++;
                ptr++;
+               flushed++;
        }
+       return flushed;
 }
 
 /*
@@ -581,7 +588,7 @@ static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p)
  * caller aquires the ctrl_qp lock before the call
  */
 static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
-                                     u32 len, void *data, int completion)
+                                     u32 len, void *data)
 {
        u32 i, nr_wqe, copy_len;
        u8 *copy_data;
@@ -617,7 +624,7 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
                flag = 0;
                if (i == (nr_wqe - 1)) {
                        /* last WQE */
-                       flag = completion ? T3_COMPLETION_FLAG : 0;
+                       flag = T3_COMPLETION_FLAG;
                        if (len % 32)
                                utx_len = len / 32 + 1;
                        else
@@ -676,21 +683,20 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
        return 0;
 }
 
-/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl, and pbl_size
- * OUT: stag index, actual pbl_size, pbl_addr allocated.
+/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl_size and pbl_addr
+ * OUT: stag index
  * TBD: shared memory region support
  */
 static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
                         u32 *stag, u8 stag_state, u32 pdid,
                         enum tpt_mem_type type, enum tpt_mem_perm perm,
-                        u32 zbva, u64 to, u32 len, u8 page_size, __be64 *pbl,
-                        u32 *pbl_size, u32 *pbl_addr)
+                        u32 zbva, u64 to, u32 len, u8 page_size,
+                        u32 pbl_size, u32 pbl_addr)
 {
        int err;
        struct tpt_entry tpt;
        u32 stag_idx;
        u32 wptr;
-       int rereg = (*stag != T3_STAG_UNSET);
 
        stag_state = stag_state > 0;
        stag_idx = (*stag) >> 8;
@@ -704,30 +710,8 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
        PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
             __func__, stag_state, type, pdid, stag_idx);
 
-       if (reset_tpt_entry)
-               cxio_hal_pblpool_free(rdev_p, *pbl_addr, *pbl_size << 3);
-       else if (!rereg) {
-               *pbl_addr = cxio_hal_pblpool_alloc(rdev_p, *pbl_size << 3);
-               if (!*pbl_addr) {
-                       return -ENOMEM;
-               }
-       }
-
        mutex_lock(&rdev_p->ctrl_qp.lock);
 
-       /* write PBL first if any - update pbl only if pbl list exist */
-       if (pbl) {
-
-               PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
-                    __func__, *pbl_addr, rdev_p->rnic_info.pbl_base,
-                    *pbl_size);
-               err = cxio_hal_ctrl_qp_write_mem(rdev_p,
-                               (*pbl_addr >> 5),
-                               (*pbl_size << 3), pbl, 0);
-               if (err)
-                       goto ret;
-       }
-
        /* write TPT entry */
        if (reset_tpt_entry)
                memset(&tpt, 0, sizeof(tpt));
@@ -742,23 +726,23 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
                                V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) |
                                V_TPT_PAGE_SIZE(page_size));
                tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 :
-                                   cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, *pbl_addr)>>3));
+                                   cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3));
                tpt.len = cpu_to_be32(len);
                tpt.va_hi = cpu_to_be32((u32) (to >> 32));
                tpt.va_low_or_fbo = cpu_to_be32((u32) (to & 0xFFFFFFFFULL));
                tpt.rsvd_bind_cnt_or_pstag = 0;
                tpt.rsvd_pbl_size = reset_tpt_entry ? 0 :
-                                 cpu_to_be32(V_TPT_PBL_SIZE((*pbl_size) >> 2));
+                                 cpu_to_be32(V_TPT_PBL_SIZE(pbl_size >> 2));
        }
        err = cxio_hal_ctrl_qp_write_mem(rdev_p,
                                       stag_idx +
                                       (rdev_p->rnic_info.tpt_base >> 5),
-                                      sizeof(tpt), &tpt, 1);
+                                      sizeof(tpt), &tpt);
 
        /* release the stag index to free pool */
        if (reset_tpt_entry)
                cxio_hal_put_stag(rdev_p->rscp, stag_idx);
-ret:
+
        wptr = rdev_p->ctrl_qp.wptr;
        mutex_unlock(&rdev_p->ctrl_qp.lock);
        if (!err)
@@ -769,44 +753,67 @@ ret:
        return err;
 }
 
+int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
+                  u32 pbl_addr, u32 pbl_size)
+{
+       u32 wptr;
+       int err;
+
+       PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
+            __func__, pbl_addr, rdev_p->rnic_info.pbl_base,
+            pbl_size);
+
+       mutex_lock(&rdev_p->ctrl_qp.lock);
+       err = cxio_hal_ctrl_qp_write_mem(rdev_p, pbl_addr >> 5, pbl_size << 3,
+                                        pbl);
+       wptr = rdev_p->ctrl_qp.wptr;
+       mutex_unlock(&rdev_p->ctrl_qp.lock);
+       if (err)
+               return err;
+
+       if (wait_event_interruptible(rdev_p->ctrl_qp.waitq,
+                                    SEQ32_GE(rdev_p->ctrl_qp.rptr,
+                                             wptr)))
+               return -ERESTARTSYS;
+
+       return 0;
+}
+
 int cxio_register_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid,
                           enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-                          u8 page_size, __be64 *pbl, u32 *pbl_size,
-                          u32 *pbl_addr)
+                          u8 page_size, u32 pbl_size, u32 pbl_addr)
 {
        *stag = T3_STAG_UNSET;
        return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm,
-                            zbva, to, len, page_size, pbl, pbl_size, pbl_addr);
+                            zbva, to, len, page_size, pbl_size, pbl_addr);
 }
 
 int cxio_reregister_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid,
                           enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-                          u8 page_size, __be64 *pbl, u32 *pbl_size,
-                          u32 *pbl_addr)
+                          u8 page_size, u32 pbl_size, u32 pbl_addr)
 {
        return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm,
-                            zbva, to, len, page_size, pbl, pbl_size, pbl_addr);
+                            zbva, to, len, page_size, pbl_size, pbl_addr);
 }
 
 int cxio_dereg_mem(struct cxio_rdev *rdev_p, u32 stag, u32 pbl_size,
                   u32 pbl_addr)
 {
-       return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL,
-                            &pbl_size, &pbl_addr);
+       return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0,
+                            pbl_size, pbl_addr);
 }
 
 int cxio_allocate_window(struct cxio_rdev *rdev_p, u32 * stag, u32 pdid)
 {
-       u32 pbl_size = 0;
        *stag = T3_STAG_UNSET;
        return __cxio_tpt_op(rdev_p, 0, stag, 0, pdid, TPT_MW, 0, 0, 0ULL, 0, 0,
-                            NULL, &pbl_size, NULL);
+                            0, 0);
 }
 
 int cxio_deallocate_window(struct cxio_rdev *rdev_p, u32 stag)
 {
-       return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL,
-                            NULL, NULL);
+       return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0,
+                            0, 0);
 }
 
 int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
index 2bcff7f5046e3a00c10675643f40872319bb51ef..6e128f6bab05140282e1d86930aaab98ddb4cc0c 100644 (file)
@@ -154,14 +154,14 @@ int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq,
 int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq,
                    struct cxio_ucontext *uctx);
 int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode);
+int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
+                  u32 pbl_addr, u32 pbl_size);
 int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
                           enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-                          u8 page_size, __be64 *pbl, u32 *pbl_size,
-                          u32 *pbl_addr);
+                          u8 page_size, u32 pbl_size, u32 pbl_addr);
 int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
                           enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-                          u8 page_size, __be64 *pbl, u32 *pbl_size,
-                          u32 *pbl_addr);
+                          u8 page_size, u32 pbl_size, u32 pbl_addr);
 int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size,
                   u32 pbl_addr);
 int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid);
@@ -173,8 +173,8 @@ u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp);
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid);
 int __init cxio_hal_init(void);
 void __exit cxio_hal_exit(void);
-void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
-void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
+int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
+int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
 void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
 void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
 void cxio_flush_hw_cq(struct t3_cq *cq);
index 45ed4f25ef785b1efa23cd6f335d8569e4c81c55..bd233c087653de5fed49dfbbf95f4d53cb43b7d0 100644 (file)
@@ -250,7 +250,6 @@ void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
  */
 
 #define MIN_PBL_SHIFT 8                        /* 256B == min PBL size (32 entries) */
-#define PBL_CHUNK 2*1024*1024
 
 u32 cxio_hal_pblpool_alloc(struct cxio_rdev *rdev_p, int size)
 {
@@ -267,14 +266,35 @@ void cxio_hal_pblpool_free(struct cxio_rdev *rdev_p, u32 addr, int size)
 
 int cxio_hal_pblpool_create(struct cxio_rdev *rdev_p)
 {
-       unsigned long i;
+       unsigned pbl_start, pbl_chunk;
+
        rdev_p->pbl_pool = gen_pool_create(MIN_PBL_SHIFT, -1);
-       if (rdev_p->pbl_pool)
-               for (i = rdev_p->rnic_info.pbl_base;
-                    i <= rdev_p->rnic_info.pbl_top - PBL_CHUNK + 1;
-                    i += PBL_CHUNK)
-                       gen_pool_add(rdev_p->pbl_pool, i, PBL_CHUNK, -1);
-       return rdev_p->pbl_pool ? 0 : -ENOMEM;
+       if (!rdev_p->pbl_pool)
+               return -ENOMEM;
+
+       pbl_start = rdev_p->rnic_info.pbl_base;
+       pbl_chunk = rdev_p->rnic_info.pbl_top - pbl_start + 1;
+
+       while (pbl_start < rdev_p->rnic_info.pbl_top) {
+               pbl_chunk = min(rdev_p->rnic_info.pbl_top - pbl_start + 1,
+                               pbl_chunk);
+               if (gen_pool_add(rdev_p->pbl_pool, pbl_start, pbl_chunk, -1)) {
+                       PDBG("%s failed to add PBL chunk (%x/%x)\n",
+                            __func__, pbl_start, pbl_chunk);
+                       if (pbl_chunk <= 1024 << MIN_PBL_SHIFT) {
+                               printk(KERN_WARNING MOD "%s: Failed to add all PBL chunks (%x/%x)\n",
+                                      __func__, pbl_start, rdev_p->rnic_info.pbl_top - pbl_start);
+                               return 0;
+                       }
+                       pbl_chunk >>= 1;
+               } else {
+                       PDBG("%s added PBL chunk (%x/%x)\n",
+                            __func__, pbl_start, pbl_chunk);
+                       pbl_start += pbl_chunk;
+               }
+       }
+
+       return 0;
 }
 
 void cxio_hal_pblpool_destroy(struct cxio_rdev *rdev_p)
index d44a6df9ad8c4a7ebd915b00817a8a980ae2f237..c325c44807e8226b1744796a7463e6aab384e950 100644 (file)
@@ -67,10 +67,10 @@ int peer2peer = 0;
 module_param(peer2peer, int, 0644);
 MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)");
 
-static int ep_timeout_secs = 10;
+static int ep_timeout_secs = 60;
 module_param(ep_timeout_secs, int, 0644);
 MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "
-                                  "in seconds (default=10)");
+                                  "in seconds (default=60)");
 
 static int mpa_rev = 1;
 module_param(mpa_rev, int, 0644);
@@ -1650,8 +1650,8 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                release = 1;
                break;
        case ABORTING:
-               break;
        case DEAD:
+               break;
        default:
                BUG_ON(1);
                break;
index 58c3d61bcd14a24ec0623b0cec8d8eb6771bbaa9..ec49a5cbdebbc19705968069b58d2ab9f98d7d8e 100644 (file)
 #include <rdma/ib_verbs.h>
 
 #include "cxio_hal.h"
+#include "cxio_resource.h"
 #include "iwch.h"
 #include "iwch_provider.h"
 
-int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-                                       struct iwch_mr *mhp,
-                                       int shift,
-                                       __be64 *page_list)
+static void iwch_finish_mem_reg(struct iwch_mr *mhp, u32 stag)
 {
-       u32 stag;
        u32 mmid;
 
+       mhp->attr.state = 1;
+       mhp->attr.stag = stag;
+       mmid = stag >> 8;
+       mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
+       insert_handle(mhp->rhp, &mhp->rhp->mmidr, mhp, mmid);
+       PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+}
+
+int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
+                     struct iwch_mr *mhp, int shift)
+{
+       u32 stag;
 
        if (cxio_register_phys_mem(&rhp->rdev,
                                   &stag, mhp->attr.pdid,
@@ -53,28 +62,21 @@ int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
                                   mhp->attr.zbva,
                                   mhp->attr.va_fbo,
                                   mhp->attr.len,
-                                  shift-12,
-                                  page_list,
-                                  &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
+                                  shift - 12,
+                                  mhp->attr.pbl_size, mhp->attr.pbl_addr))
                return -ENOMEM;
-       mhp->attr.state = 1;
-       mhp->attr.stag = stag;
-       mmid = stag >> 8;
-       mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
-       insert_handle(rhp, &rhp->mmidr, mhp, mmid);
-       PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+
+       iwch_finish_mem_reg(mhp, stag);
+
        return 0;
 }
 
 int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
                                        struct iwch_mr *mhp,
                                        int shift,
-                                       __be64 *page_list,
                                        int npages)
 {
        u32 stag;
-       u32 mmid;
-
 
        /* We could support this... */
        if (npages > mhp->attr.pbl_size)
@@ -87,19 +89,40 @@ int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
                                   mhp->attr.zbva,
                                   mhp->attr.va_fbo,
                                   mhp->attr.len,
-                                  shift-12,
-                                  page_list,
-                                  &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
+                                  shift - 12,
+                                  mhp->attr.pbl_size, mhp->attr.pbl_addr))
                return -ENOMEM;
-       mhp->attr.state = 1;
-       mhp->attr.stag = stag;
-       mmid = stag >> 8;
-       mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
-       insert_handle(rhp, &rhp->mmidr, mhp, mmid);
-       PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+
+       iwch_finish_mem_reg(mhp, stag);
+
+       return 0;
+}
+
+int iwch_alloc_pbl(struct iwch_mr *mhp, int npages)
+{
+       mhp->attr.pbl_addr = cxio_hal_pblpool_alloc(&mhp->rhp->rdev,
+                                                   npages << 3);
+
+       if (!mhp->attr.pbl_addr)
+               return -ENOMEM;
+
+       mhp->attr.pbl_size = npages;
+
        return 0;
 }
 
+void iwch_free_pbl(struct iwch_mr *mhp)
+{
+       cxio_hal_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
+                             mhp->attr.pbl_size << 3);
+}
+
+int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset)
+{
+       return cxio_write_pbl(&mhp->rhp->rdev, pages,
+                             mhp->attr.pbl_addr + (offset << 3), npages);
+}
+
 int build_phys_page_list(struct ib_phys_buf *buffer_list,
                                        int num_phys_buf,
                                        u64 *iova_start,
index d07d3a377b5f2b02644e2164db56b858ac898e07..8934178a23ee6d615ed2a7badfd1758c3aab3f6b 100644 (file)
@@ -442,6 +442,7 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr)
        mmid = mhp->attr.stag >> 8;
        cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
                       mhp->attr.pbl_addr);
+       iwch_free_pbl(mhp);
        remove_handle(rhp, &rhp->mmidr, mmid);
        if (mhp->kva)
                kfree((void *) (unsigned long) mhp->kva);
@@ -475,6 +476,8 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
        if (!mhp)
                return ERR_PTR(-ENOMEM);
 
+       mhp->rhp = rhp;
+
        /* First check that we have enough alignment */
        if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) {
                ret = -EINVAL;
@@ -492,7 +495,17 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
        if (ret)
                goto err;
 
-       mhp->rhp = rhp;
+       ret = iwch_alloc_pbl(mhp, npages);
+       if (ret) {
+               kfree(page_list);
+               goto err_pbl;
+       }
+
+       ret = iwch_write_pbl(mhp, page_list, npages, 0);
+       kfree(page_list);
+       if (ret)
+               goto err_pbl;
+
        mhp->attr.pdid = php->pdid;
        mhp->attr.zbva = 0;
 
@@ -502,12 +515,15 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
 
        mhp->attr.len = (u32) total_size;
        mhp->attr.pbl_size = npages;
-       ret = iwch_register_mem(rhp, php, mhp, shift, page_list);
-       kfree(page_list);
-       if (ret) {
-               goto err;
-       }
+       ret = iwch_register_mem(rhp, php, mhp, shift);
+       if (ret)
+               goto err_pbl;
+
        return &mhp->ibmr;
+
+err_pbl:
+       iwch_free_pbl(mhp);
+
 err:
        kfree(mhp);
        return ERR_PTR(ret);
@@ -560,7 +576,7 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr,
                        return ret;
        }
 
-       ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages);
+       ret = iwch_reregister_mem(rhp, php, &mh, shift, npages);
        kfree(page_list);
        if (ret) {
                return ret;
@@ -602,6 +618,8 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        if (!mhp)
                return ERR_PTR(-ENOMEM);
 
+       mhp->rhp = rhp;
+
        mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0);
        if (IS_ERR(mhp->umem)) {
                err = PTR_ERR(mhp->umem);
@@ -615,10 +633,14 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        list_for_each_entry(chunk, &mhp->umem->chunk_list, list)
                n += chunk->nents;
 
-       pages = kmalloc(n * sizeof(u64), GFP_KERNEL);
+       err = iwch_alloc_pbl(mhp, n);
+       if (err)
+               goto err;
+
+       pages = (__be64 *) __get_free_page(GFP_KERNEL);
        if (!pages) {
                err = -ENOMEM;
-               goto err;
+               goto err_pbl;
        }
 
        i = n = 0;
@@ -630,25 +652,38 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                pages[i++] = cpu_to_be64(sg_dma_address(
                                        &chunk->page_list[j]) +
                                        mhp->umem->page_size * k);
+                               if (i == PAGE_SIZE / sizeof *pages) {
+                                       err = iwch_write_pbl(mhp, pages, i, n);
+                                       if (err)
+                                               goto pbl_done;
+                                       n += i;
+                                       i = 0;
+                               }
                        }
                }
 
-       mhp->rhp = rhp;
+       if (i)
+               err = iwch_write_pbl(mhp, pages, i, n);
+
+pbl_done:
+       free_page((unsigned long) pages);
+       if (err)
+               goto err_pbl;
+
        mhp->attr.pdid = php->pdid;
        mhp->attr.zbva = 0;
        mhp->attr.perms = iwch_ib_to_tpt_access(acc);
        mhp->attr.va_fbo = virt;
        mhp->attr.page_size = shift - 12;
        mhp->attr.len = (u32) length;
-       mhp->attr.pbl_size = i;
-       err = iwch_register_mem(rhp, php, mhp, shift, pages);
-       kfree(pages);
+
+       err = iwch_register_mem(rhp, php, mhp, shift);
        if (err)
-               goto err;
+               goto err_pbl;
 
        if (udata && !t3a_device(rhp)) {
                uresp.pbl_addr = (mhp->attr.pbl_addr -
-                                rhp->rdev.rnic_info.pbl_base) >> 3;
+                                rhp->rdev.rnic_info.pbl_base) >> 3;
                PDBG("%s user resp pbl_addr 0x%x\n", __func__,
                     uresp.pbl_addr);
 
@@ -661,6 +696,9 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 
        return &mhp->ibmr;
 
+err_pbl:
+       iwch_free_pbl(mhp);
+
 err:
        ib_umem_release(mhp->umem);
        kfree(mhp);
index db5100d27ca2e9f7746cb26444488c80883be292..836163fc54291cdd2cbaab8980cf8bba448c68a9 100644 (file)
@@ -340,14 +340,14 @@ int iwch_quiesce_qps(struct iwch_cq *chp);
 int iwch_resume_qps(struct iwch_cq *chp);
 void stop_read_rep_timer(struct iwch_qp *qhp);
 int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-                                       struct iwch_mr *mhp,
-                                       int shift,
-                                       __be64 *page_list);
+                     struct iwch_mr *mhp, int shift);
 int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
                                        struct iwch_mr *mhp,
                                        int shift,
-                                       __be64 *page_list,
                                        int npages);
+int iwch_alloc_pbl(struct iwch_mr *mhp, int npages);
+void iwch_free_pbl(struct iwch_mr *mhp);
+int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset);
 int build_phys_page_list(struct ib_phys_buf *buffer_list,
                                        int num_phys_buf,
                                        u64 *iova_start,
index 9b4be889c58ea8d9d378200e0297958a337ef16c..79dbe5beae52b3ee3095ac24aa78f12ee0217b4e 100644 (file)
@@ -655,6 +655,7 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag)
 {
        struct iwch_cq *rchp, *schp;
        int count;
+       int flushed;
 
        rchp = get_chp(qhp->rhp, qhp->attr.rcq);
        schp = get_chp(qhp->rhp, qhp->attr.scq);
@@ -669,20 +670,22 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag)
        spin_lock(&qhp->lock);
        cxio_flush_hw_cq(&rchp->cq);
        cxio_count_rcqes(&rchp->cq, &qhp->wq, &count);
-       cxio_flush_rq(&qhp->wq, &rchp->cq, count);
+       flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count);
        spin_unlock(&qhp->lock);
        spin_unlock_irqrestore(&rchp->lock, *flag);
-       (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
+       if (flushed)
+               (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
 
        /* locking heirarchy: cq lock first, then qp lock. */
        spin_lock_irqsave(&schp->lock, *flag);
        spin_lock(&qhp->lock);
        cxio_flush_hw_cq(&schp->cq);
        cxio_count_scqes(&schp->cq, &qhp->wq, &count);
-       cxio_flush_sq(&qhp->wq, &schp->cq, count);
+       flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count);
        spin_unlock(&qhp->lock);
        spin_unlock_irqrestore(&schp->lock, *flag);
-       (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
+       if (flushed)
+               (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
 
        /* deref */
        if (atomic_dec_and_test(&qhp->refcnt))
@@ -880,7 +883,6 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
                                ep = qhp->ep;
                                get_ep(&ep->com);
                        }
-                       flush_qp(qhp, &flag);
                        break;
                case IWCH_QP_STATE_TERMINATE:
                        qhp->attr.state = IWCH_QP_STATE_TERMINATE;
@@ -911,6 +913,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
                }
                switch (attrs->next_state) {
                        case IWCH_QP_STATE_IDLE:
+                               flush_qp(qhp, &flag);
                                qhp->attr.state = IWCH_QP_STATE_IDLE;
                                qhp->attr.llp_stream_handle = NULL;
                                put_ep(&qhp->ep->com);
index 00bab60f6de474a1ed24e77ee9331f46efe7103f..1e9e99a13933bd7dfa671cc8a125c9abddb526fc 100644 (file)
@@ -192,6 +192,8 @@ struct ehca_qp {
        int mtu_shift;
        u32 message_count;
        u32 packet_count;
+       atomic_t nr_events; /* events seen */
+       wait_queue_head_t wait_completion;
 };
 
 #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
index 2515cbde7e65449e1a54fafd507ac57cabf482cd..bc3b37d2070f338b6a41003ad1e6a6c125e1d555 100644 (file)
@@ -101,7 +101,6 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
        props->max_ee          = limit_uint(rblock->max_rd_ee_context);
        props->max_rdd         = limit_uint(rblock->max_rd_domain);
        props->max_fmr         = limit_uint(rblock->max_mr);
-       props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
        props->max_qp_rd_atom  = limit_uint(rblock->max_rr_qp);
        props->max_ee_rd_atom  = limit_uint(rblock->max_rr_ee_context);
        props->max_res_rd_atom = limit_uint(rblock->max_rr_hca);
@@ -115,7 +114,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
        }
 
        props->max_pkeys           = 16;
-       props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
+       props->local_ca_ack_delay  = min_t(u8, rblock->local_ca_ack_delay, 255);
        props->max_raw_ipv6_qp     = limit_uint(rblock->max_raw_ipv6_qp);
        props->max_raw_ethy_qp     = limit_uint(rblock->max_raw_ethy_qp);
        props->max_mcast_grp       = limit_uint(rblock->max_mcast_grp);
@@ -136,7 +135,7 @@ query_device1:
        return ret;
 }
 
-static int map_mtu(struct ehca_shca *shca, u32 fw_mtu)
+static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu)
 {
        switch (fw_mtu) {
        case 0x1:
@@ -156,7 +155,7 @@ static int map_mtu(struct ehca_shca *shca, u32 fw_mtu)
        }
 }
 
-static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
+static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
 {
        switch (vl_cap) {
        case 0x1:
index ca5eb0cb628cf74cb4df726667cd2f378199448c..ce1ab0571be38303b8554bd69dcde739f252c826 100644 (file)
@@ -204,6 +204,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
 
        read_lock(&ehca_qp_idr_lock);
        qp = idr_find(&ehca_qp_idr, token);
+       if (qp)
+               atomic_inc(&qp->nr_events);
        read_unlock(&ehca_qp_idr_lock);
 
        if (!qp)
@@ -223,6 +225,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
        if (fatal && qp->ext_type == EQPT_SRQBASE)
                dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED);
 
+       if (atomic_dec_and_test(&qp->nr_events))
+               wake_up(&qp->wait_completion);
        return;
 }
 
index 18fba92fa7ae107311121b7cc591aa077c7b51eb..3f59587338ea5fc03a2404500f0d9633a468439f 100644 (file)
@@ -566,6 +566,8 @@ static struct ehca_qp *internal_create_qp(
                return ERR_PTR(-ENOMEM);
        }
 
+       atomic_set(&my_qp->nr_events, 0);
+       init_waitqueue_head(&my_qp->wait_completion);
        spin_lock_init(&my_qp->spinlock_s);
        spin_lock_init(&my_qp->spinlock_r);
        my_qp->qp_type = qp_type;
@@ -1934,6 +1936,9 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
        idr_remove(&ehca_qp_idr, my_qp->token);
        write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
+       /* now wait until all pending events have completed */
+       wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events));
+
        h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
        if (h_ret != H_SUCCESS) {
                ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li "
index acf30c06a0c0ff8eb1981e692c7cc2818b78c4cc..ce7b7c34360eae4b1ec985a07f8062899b1242cc 100644 (file)
@@ -1197,7 +1197,7 @@ void ipath_kreceive(struct ipath_portdata *pd)
        }
 
 reloop:
-       for (last = 0, i = 1; !last; i++) {
+       for (last = 0, i = 1; !last; i += !last) {
                hdr = dd->ipath_f_get_msgheader(dd, rhf_addr);
                eflags = ipath_hdrget_err_flags(rhf_addr);
                etype = ipath_hdrget_rcv_type(rhf_addr);
@@ -1428,6 +1428,40 @@ static void ipath_update_pio_bufs(struct ipath_devdata *dd)
        spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
 }
 
+/*
+ * used to force update of pioavailshadow if we can't get a pio buffer.
+ * Needed primarily due to exitting freeze mode after recovering
+ * from errors.  Done lazily, because it's safer (known to not
+ * be writing pio buffers).
+ */
+static void ipath_reset_availshadow(struct ipath_devdata *dd)
+{
+       int i, im;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ipath_pioavail_lock, flags);
+       for (i = 0; i < dd->ipath_pioavregs; i++) {
+               u64 val, oldval;
+               /* deal with 6110 chip bug on high register #s */
+               im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
+                       i ^ 1 : i;
+               val = le64_to_cpu(dd->ipath_pioavailregs_dma[im]);
+               /*
+                * busy out the buffers not in the kernel avail list,
+                * without changing the generation bits.
+                */
+               oldval = dd->ipath_pioavailshadow[i];
+               dd->ipath_pioavailshadow[i] = val |
+                       ((~dd->ipath_pioavailkernel[i] <<
+                       INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT) &
+                       0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */
+               if (oldval != dd->ipath_pioavailshadow[i])
+                       ipath_dbg("shadow[%d] was %Lx, now %lx\n",
+                               i, oldval, dd->ipath_pioavailshadow[i]);
+       }
+       spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
+}
+
 /**
  * ipath_setrcvhdrsize - set the receive header size
  * @dd: the infinipath device
@@ -1482,9 +1516,12 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd)
         */
        ipath_stats.sps_nopiobufs++;
        if (!(++dd->ipath_consec_nopiobuf % 100000)) {
-               ipath_dbg("%u pio sends with no bufavail; dmacopy: "
-                       "%llx %llx %llx %llx; shadow:  %lx %lx %lx %lx\n",
+               ipath_force_pio_avail_update(dd); /* at start */
+               ipath_dbg("%u tries no piobufavail ts%lx; dmacopy: "
+                       "%llx %llx %llx %llx\n"
+                       "ipath  shadow:  %lx %lx %lx %lx\n",
                        dd->ipath_consec_nopiobuf,
+                       (unsigned long)get_cycles(),
                        (unsigned long long) le64_to_cpu(dma[0]),
                        (unsigned long long) le64_to_cpu(dma[1]),
                        (unsigned long long) le64_to_cpu(dma[2]),
@@ -1496,14 +1533,17 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd)
                 */
                if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) >
                    (sizeof(shadow[0]) * 4 * 4))
-                       ipath_dbg("2nd group: dmacopy: %llx %llx "
-                                 "%llx %llx; shadow: %lx %lx %lx %lx\n",
+                       ipath_dbg("2nd group: dmacopy: "
+                                 "%llx %llx %llx %llx\n"
+                                 "ipath  shadow:  %lx %lx %lx %lx\n",
                                  (unsigned long long)le64_to_cpu(dma[4]),
                                  (unsigned long long)le64_to_cpu(dma[5]),
                                  (unsigned long long)le64_to_cpu(dma[6]),
                                  (unsigned long long)le64_to_cpu(dma[7]),
-                                 shadow[4], shadow[5], shadow[6],
-                                 shadow[7]);
+                                 shadow[4], shadow[5], shadow[6], shadow[7]);
+
+               /* at end, so update likely happened */
+               ipath_reset_availshadow(dd);
        }
 }
 
@@ -1652,19 +1692,46 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start,
                              unsigned len, int avail)
 {
        unsigned long flags;
-       unsigned end;
+       unsigned end, cnt = 0, next;
 
        /* There are two bits per send buffer (busy and generation) */
        start *= 2;
-       len *= 2;
-       end = start + len;
+       end = start + len * 2;
 
-       /* Set or clear the generation bits. */
        spin_lock_irqsave(&ipath_pioavail_lock, flags);
+       /* Set or clear the busy bit in the shadow. */
        while (start < end) {
                if (avail) {
-                       __clear_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT,
-                               dd->ipath_pioavailshadow);
+                       unsigned long dma;
+                       int i, im;
+                       /*
+                        * the BUSY bit will never be set, because we disarm
+                        * the user buffers before we hand them back to the
+                        * kernel.  We do have to make sure the generation
+                        * bit is set correctly in shadow, since it could
+                        * have changed many times while allocated to user.
+                        * We can't use the bitmap functions on the full
+                        * dma array because it is always little-endian, so
+                        * we have to flip to host-order first.
+                        * BITS_PER_LONG is slightly wrong, since it's
+                        * always 64 bits per register in chip...
+                        * We only work on 64 bit kernels, so that's OK.
+                        */
+                       /* deal with 6110 chip bug on high register #s */
+                       i = start / BITS_PER_LONG;
+                       im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
+                               i ^ 1 : i;
+                       __clear_bit(INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT
+                               + start, dd->ipath_pioavailshadow);
+                       dma = (unsigned long) le64_to_cpu(
+                               dd->ipath_pioavailregs_dma[im]);
+                       if (test_bit((INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+                               + start) % BITS_PER_LONG, &dma))
+                               __set_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+                                       + start, dd->ipath_pioavailshadow);
+                       else
+                               __clear_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+                                       + start, dd->ipath_pioavailshadow);
                        __set_bit(start, dd->ipath_pioavailkernel);
                } else {
                        __set_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT,
@@ -1673,7 +1740,44 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start,
                }
                start += 2;
        }
+
+       if (dd->ipath_pioupd_thresh) {
+               end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
+               next = find_first_bit(dd->ipath_pioavailkernel, end);
+               while (next < end) {
+                       cnt++;
+                       next = find_next_bit(dd->ipath_pioavailkernel, end,
+                                       next + 1);
+               }
+       }
        spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
+
+       /*
+        * When moving buffers from kernel to user, if number assigned to
+        * the user is less than the pio update threshold, and threshold
+        * is supported (cnt was computed > 0), drop the update threshold
+        * so we update at least once per allocated number of buffers.
+        * In any case, if the kernel buffers are less than the threshold,
+        * drop the threshold.  We don't bother increasing it, having once
+        * decreased it, since it would typically just cycle back and forth.
+        * If we don't decrease below buffers in use, we can wait a long
+        * time for an update, until some other context uses PIO buffers.
+        */
+       if (!avail && len < cnt)
+               cnt = len;
+       if (cnt < dd->ipath_pioupd_thresh) {
+               dd->ipath_pioupd_thresh = cnt;
+               ipath_dbg("Decreased pio update threshold to %u\n",
+                       dd->ipath_pioupd_thresh);
+               spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
+               dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK
+                       << INFINIPATH_S_UPDTHRESH_SHIFT);
+               dd->ipath_sendctrl |= dd->ipath_pioupd_thresh
+                       << INFINIPATH_S_UPDTHRESH_SHIFT;
+               ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
+                       dd->ipath_sendctrl);
+               spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
+       }
 }
 
 /**
@@ -1794,8 +1898,8 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
 
                spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
                skip_cancel =
-                       !test_bit(IPATH_SDMA_DISABLED, statp) &&
-                       test_and_set_bit(IPATH_SDMA_ABORTING, statp);
+                       test_and_set_bit(IPATH_SDMA_ABORTING, statp)
+                       && !test_bit(IPATH_SDMA_DISABLED, statp);
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
                if (skip_cancel)
                        goto bail;
@@ -1826,6 +1930,9 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
        ipath_disarm_piobufs(dd, 0,
                dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
 
+       if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
+               set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
+
        if (restore_sendctrl) {
                /* else done by caller later if needed */
                spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
@@ -1845,7 +1952,6 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
                /* only wait so long for intr */
                dd->ipath_sdma_abort_intr_timeout = jiffies + HZ;
                dd->ipath_sdma_reset_wait = 200;
-               __set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
                if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
                        tasklet_hi_schedule(&dd->ipath_sdma_abort_task);
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
index 8b1752202e78a8d69c09579428a339df283bd55c..3295177c937e3ef530cfa63c1affaf956db8160b 100644 (file)
@@ -173,47 +173,25 @@ static int ipath_get_base_info(struct file *fp,
                (void *) dd->ipath_statusp -
                (void *) dd->ipath_pioavailregs_dma;
        if (!shared) {
-               kinfo->spi_piocnt = dd->ipath_pbufsport;
+               kinfo->spi_piocnt = pd->port_piocnt;
                kinfo->spi_piobufbase = (u64) pd->port_piobufs;
                kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
                        dd->ipath_ureg_align * pd->port_port;
        } else if (master) {
-               kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) +
-                                   (dd->ipath_pbufsport % subport_cnt);
+               kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) +
+                                   (pd->port_piocnt % subport_cnt);
                /* Master's PIO buffers are after all the slave's */
                kinfo->spi_piobufbase = (u64) pd->port_piobufs +
                        dd->ipath_palign *
-                       (dd->ipath_pbufsport - kinfo->spi_piocnt);
+                       (pd->port_piocnt - kinfo->spi_piocnt);
        } else {
                unsigned slave = subport_fp(fp) - 1;
 
-               kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt;
+               kinfo->spi_piocnt = pd->port_piocnt / subport_cnt;
                kinfo->spi_piobufbase = (u64) pd->port_piobufs +
                        dd->ipath_palign * kinfo->spi_piocnt * slave;
        }
 
-       /*
-        * Set the PIO avail update threshold to no larger
-        * than the number of buffers per process. Note that
-        * we decrease it here, but won't ever increase it.
-        */
-       if (dd->ipath_pioupd_thresh &&
-           kinfo->spi_piocnt < dd->ipath_pioupd_thresh) {
-               unsigned long flags;
-
-               dd->ipath_pioupd_thresh = kinfo->spi_piocnt;
-               ipath_dbg("Decreased pio update threshold to %u\n",
-                       dd->ipath_pioupd_thresh);
-               spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
-               dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK
-                       << INFINIPATH_S_UPDTHRESH_SHIFT);
-               dd->ipath_sendctrl |= dd->ipath_pioupd_thresh
-                       << INFINIPATH_S_UPDTHRESH_SHIFT;
-               ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-                       dd->ipath_sendctrl);
-               spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
-       }
-
        if (shared) {
                kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase +
                        dd->ipath_ureg_align * pd->port_port;
@@ -1309,19 +1287,19 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
        ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port;
        if (!pd->port_subport_cnt) {
                /* port is not shared */
-               piocnt = dd->ipath_pbufsport;
+               piocnt = pd->port_piocnt;
                piobufs = pd->port_piobufs;
        } else if (!subport_fp(fp)) {
                /* caller is the master */
-               piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) +
-                        (dd->ipath_pbufsport % pd->port_subport_cnt);
+               piocnt = (pd->port_piocnt / pd->port_subport_cnt) +
+                        (pd->port_piocnt % pd->port_subport_cnt);
                piobufs = pd->port_piobufs +
-                       dd->ipath_palign * (dd->ipath_pbufsport - piocnt);
+                       dd->ipath_palign * (pd->port_piocnt - piocnt);
        } else {
                unsigned slave = subport_fp(fp) - 1;
 
                /* caller is a slave */
-               piocnt = dd->ipath_pbufsport / pd->port_subport_cnt;
+               piocnt = pd->port_piocnt / pd->port_subport_cnt;
                piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave;
        }
 
@@ -1633,9 +1611,6 @@ static int try_alloc_port(struct ipath_devdata *dd, int port,
                port_fp(fp) = pd;
                pd->port_pid = current->pid;
                strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
-               ipath_chg_pioavailkernel(dd,
-                       dd->ipath_pbufsport * (pd->port_port - 1),
-                       dd->ipath_pbufsport, 0);
                ipath_stats.sps_ports++;
                ret = 0;
        } else
@@ -1938,11 +1913,25 @@ static int ipath_do_user_init(struct file *fp,
 
        /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
 
+       /* some ports may get extra buffers, calculate that here */
+       if (pd->port_port <= dd->ipath_ports_extrabuf)
+               pd->port_piocnt = dd->ipath_pbufsport + 1;
+       else
+               pd->port_piocnt = dd->ipath_pbufsport;
+
        /* for right now, kernel piobufs are at end, so port 1 is at 0 */
+       if (pd->port_port <= dd->ipath_ports_extrabuf)
+               pd->port_pio_base = (dd->ipath_pbufsport + 1)
+                       * (pd->port_port - 1);
+       else
+               pd->port_pio_base = dd->ipath_ports_extrabuf +
+                       dd->ipath_pbufsport * (pd->port_port - 1);
        pd->port_piobufs = dd->ipath_piobufbase +
-               dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign;
-       ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
-                  pd->port_port, pd->port_piobufs);
+               pd->port_pio_base * dd->ipath_palign;
+       ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u,"
+               " first pio %u\n", pd->port_port, pd->port_piobufs,
+               pd->port_piocnt, pd->port_pio_base);
+       ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0);
 
        /*
         * Now allocate the rcvhdr Q and eager TIDs; skip the TID
@@ -2107,7 +2096,6 @@ static int ipath_close(struct inode *in, struct file *fp)
        }
 
        if (dd->ipath_kregbase) {
-               int i;
                /* atomically clear receive enable port and intr avail. */
                clear_bit(dd->ipath_r_portenable_shift + port,
                          &dd->ipath_rcvctrl);
@@ -2136,9 +2124,9 @@ static int ipath_close(struct inode *in, struct file *fp)
                ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr,
                        pd->port_port, dd->ipath_dummy_hdrq_phys);
 
-               i = dd->ipath_pbufsport * (port - 1);
-               ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport);
-               ipath_chg_pioavailkernel(dd, i, dd->ipath_pbufsport, 1);
+               ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt);
+               ipath_chg_pioavailkernel(dd, pd->port_pio_base,
+                       pd->port_piocnt, 1);
 
                dd->ipath_f_clear_tids(dd, pd->port_port);
 
index e3ec0d1bdf505ae50d592174bfb2633a6d48b522..8eee7830f042b3d05b20fa4955295905294378a3 100644 (file)
@@ -595,7 +595,7 @@ static void ipath_7220_txe_recover(struct ipath_devdata *dd)
 
        dev_info(&dd->pcidev->dev,
                "Recovering from TXE PIO parity error\n");
-       ipath_disarm_senderrbufs(dd, 1);
+       ipath_disarm_senderrbufs(dd);
 }
 
 
@@ -675,10 +675,8 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg,
        ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
        if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) {
                /*
-                * Parity errors in send memory are recoverable,
-                * just cancel the send (if indicated in * sendbuffererror),
-                * count the occurrence, unfreeze (if no other handled
-                * hardware error bits are set), and continue.
+                * Parity errors in send memory are recoverable by h/w
+                * just do housekeeping, exit freeze mode and continue.
                 */
                if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
                               INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
@@ -687,13 +685,6 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                        hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
                                     INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
                                    << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
-                       if (!hwerrs) {
-                               /* else leave in freeze mode */
-                               ipath_write_kreg(dd,
-                                                dd->ipath_kregs->kr_control,
-                                                dd->ipath_control);
-                               goto bail;
-                       }
                }
                if (hwerrs) {
                        /*
@@ -723,8 +714,8 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg,
                        *dd->ipath_statusp |= IPATH_STATUS_HWERROR;
                        dd->ipath_flags &= ~IPATH_INITTED;
                } else {
-                       ipath_dbg("Clearing freezemode on ignored hardware "
-                                 "error\n");
+                       ipath_dbg("Clearing freezemode on ignored or "
+                               "recovered hardware error\n");
                        ipath_clear_freeze(dd);
                }
        }
@@ -870,8 +861,9 @@ static int ipath_7220_boardname(struct ipath_devdata *dd, char *name,
                              "revision %u.%u!\n",
                              dd->ipath_majrev, dd->ipath_minrev);
                ret = 1;
-       } else if (dd->ipath_minrev == 1) {
-               /* Rev1 chips are prototype. Complain, but allow use */
+       } else if (dd->ipath_minrev == 1 &&
+               !(dd->ipath_flags & IPATH_INITTED)) {
+               /* Rev1 chips are prototype. Complain at init, but allow use */
                ipath_dev_err(dd, "Unsupported hardware "
                              "revision %u.%u, Contact support@qlogic.com\n",
                              dd->ipath_majrev, dd->ipath_minrev);
@@ -1966,7 +1958,7 @@ static void ipath_7220_config_ports(struct ipath_devdata *dd, ushort cfgports)
                         dd->ipath_rcvctrl);
        dd->ipath_p0_rcvegrcnt = 2048; /* always */
        if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
-               dd->ipath_pioreserved = 1; /* reserve a buffer */
+               dd->ipath_pioreserved = 3; /* kpiobufs used for PIO */
 }
 
 
index 27dd89476660846c723f60518828d4692206f213..3e5baa43fc822468b232819f62716a2aba1d8c1d 100644 (file)
@@ -41,7 +41,7 @@
 /*
  * min buffers we want to have per port, after driver
  */
-#define IPATH_MIN_USER_PORT_BUFCNT 8
+#define IPATH_MIN_USER_PORT_BUFCNT 7
 
 /*
  * Number of ports we are configured to use (to allow for more pio
@@ -54,13 +54,9 @@ MODULE_PARM_DESC(cfgports, "Set max number of ports to use");
 
 /*
  * Number of buffers reserved for driver (verbs and layered drivers.)
- * Reserved at end of buffer list.   Initialized based on
- * number of PIO buffers if not set via module interface.
+ * Initialized based on number of PIO buffers if not set via module interface.
  * The problem with this is that it's global, but we'll use different
- * numbers for different chip types.  So the default value is not
- * very useful.  I've redefined it for the 1.3 release so that it's
- * zero unless set by the user to something else, in which case we
- * try to respect it.
+ * numbers for different chip types.
  */
 static ushort ipath_kpiobufs;
 
@@ -546,9 +542,12 @@ static void enable_chip(struct ipath_devdata *dd, int reinit)
                        pioavail = dd->ipath_pioavailregs_dma[i ^ 1];
                else
                        pioavail = dd->ipath_pioavailregs_dma[i];
-               dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail) |
-                       (~dd->ipath_pioavailkernel[i] <<
-                       INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT);
+               /*
+                * don't need to worry about ipath_pioavailkernel here
+                * because we will call ipath_chg_pioavailkernel() later
+                * in initialization, to busy out buffers as needed
+                */
+               dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail);
        }
        /* can get counters, stats, etc. */
        dd->ipath_flags |= IPATH_PRESENT;
@@ -708,12 +707,11 @@ static void verify_interrupt(unsigned long opaque)
 int ipath_init_chip(struct ipath_devdata *dd, int reinit)
 {
        int ret = 0;
-       u32 val32, kpiobufs;
+       u32 kpiobufs, defkbufs;
        u32 piobufs, uports;
        u64 val;
        struct ipath_portdata *pd;
        gfp_t gfp_flags = GFP_USER | __GFP_COMP;
-       unsigned long flags;
 
        ret = init_housekeeping(dd, reinit);
        if (ret)
@@ -753,69 +751,52 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
        dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2)
                / (sizeof(u64) * BITS_PER_BYTE / 2);
        uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0;
-       if (ipath_kpiobufs == 0) {
-               /* not set by user (this is default) */
-               if (piobufs > 144)
-                       kpiobufs = 32;
-               else
-                       kpiobufs = 16;
-       }
+       if (piobufs > 144)
+               defkbufs = 32 + dd->ipath_pioreserved;
        else
-               kpiobufs = ipath_kpiobufs;
+               defkbufs = 16 + dd->ipath_pioreserved;
 
-       if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) {
+       if (ipath_kpiobufs && (ipath_kpiobufs +
+               (uports * IPATH_MIN_USER_PORT_BUFCNT)) > piobufs) {
                int i = (int) piobufs -
                        (int) (uports * IPATH_MIN_USER_PORT_BUFCNT);
                if (i < 1)
                        i = 1;
                dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of "
                         "%d for kernel leaves too few for %d user ports "
-                        "(%d each); using %u\n", kpiobufs,
+                        "(%d each); using %u\n", ipath_kpiobufs,
                         piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i);
                /*
                 * shouldn't change ipath_kpiobufs, because could be
                 * different for different devices...
                 */
                kpiobufs = i;
-       }
+       } else if (ipath_kpiobufs)
+               kpiobufs = ipath_kpiobufs;
+       else
+               kpiobufs = defkbufs;
        dd->ipath_lastport_piobuf = piobufs - kpiobufs;
        dd->ipath_pbufsport =
                uports ? dd->ipath_lastport_piobuf / uports : 0;
-       val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports);
-       if (val32 > 0) {
-               ipath_dbg("allocating %u pbufs/port leaves %u unused, "
-                         "add to kernel\n", dd->ipath_pbufsport, val32);
-               dd->ipath_lastport_piobuf -= val32;
-               kpiobufs += val32;
-               ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n",
-                         dd->ipath_pbufsport, val32);
-       }
+       /* if not an even divisor, some user ports get extra buffers */
+       dd->ipath_ports_extrabuf = dd->ipath_lastport_piobuf -
+               (dd->ipath_pbufsport * uports);
+       if (dd->ipath_ports_extrabuf)
+               ipath_dbg("%u pbufs/port leaves some unused, add 1 buffer to "
+                       "ports <= %u\n", dd->ipath_pbufsport,
+                       dd->ipath_ports_extrabuf);
        dd->ipath_lastpioindex = 0;
        dd->ipath_lastpioindexl = dd->ipath_piobcnt2k;
-       ipath_chg_pioavailkernel(dd, 0, piobufs, 1);
+       /* ipath_pioavailshadow initialized earlier */
        ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u "
                   "each for %u user ports\n", kpiobufs,
                   piobufs, dd->ipath_pbufsport, uports);
-       if (dd->ipath_pioupd_thresh) {
-               if (dd->ipath_pbufsport < dd->ipath_pioupd_thresh)
-                       dd->ipath_pioupd_thresh = dd->ipath_pbufsport;
-               if (kpiobufs < dd->ipath_pioupd_thresh)
-                       dd->ipath_pioupd_thresh = kpiobufs;
-       }
-
        ret = dd->ipath_f_early_init(dd);
        if (ret) {
                ipath_dev_err(dd, "Early initialization failure\n");
                goto done;
        }
 
-       /*
-        * Cancel any possible active sends from early driver load.
-        * Follows early_init because some chips have to initialize
-        * PIO buffers in early_init to avoid false parity errors.
-        */
-       ipath_cancel_sends(dd, 0);
-
        /*
         * Early_init sets rcvhdrentsize and rcvhdrsize, so this must be
         * done after early_init.
@@ -836,6 +817,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
 
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr,
                         dd->ipath_pioavailregs_phys);
+
        /*
         * this is to detect s/w errors, which the h/w works around by
         * ignoring the low 6 bits of address, if it wasn't aligned.
@@ -862,12 +844,6 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
                         ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL);
 
-       spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
-       dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE;
-       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
-       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
-       spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
-
        /*
         * before error clears, since we expect serdes pll errors during
         * this, the first time after reset
@@ -940,6 +916,19 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
        else
                enable_chip(dd, reinit);
 
+       /* after enable_chip, so pioavailshadow setup */
+       ipath_chg_pioavailkernel(dd, 0, piobufs, 1);
+
+       /*
+        * Cancel any possible active sends from early driver load.
+        * Follows early_init because some chips have to initialize
+        * PIO buffers in early_init to avoid false parity errors.
+        * After enable and ipath_chg_pioavailkernel so we can safely
+        * enable pioavail updates and PIOENABLE; packets are now
+        * ready to go out.
+        */
+       ipath_cancel_sends(dd, 1);
+
        if (!reinit) {
                /*
                 * Used when we close a port, for DMA already in flight
index 1b58f4737c716e88629a465b34847a22e6e695b4..26900b3b7a4ee1bcef2fe064a1a8148900128fae 100644 (file)
 #include "ipath_verbs.h"
 #include "ipath_common.h"
 
-/*
- * clear (write) a pio buffer, to clear a parity error.   This routine
- * should only be called when in freeze mode, and the buffer should be
- * canceled afterwards.
- */
-static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum)
-{
-       u32 __iomem *pbuf;
-       u32 dwcnt; /* dword count to write */
-       if (pnum < dd->ipath_piobcnt2k) {
-               pbuf = (u32 __iomem *) (dd->ipath_pio2kbase + pnum *
-                       dd->ipath_palign);
-               dwcnt = dd->ipath_piosize2k >> 2;
-       }
-       else {
-               pbuf = (u32 __iomem *) (dd->ipath_pio4kbase +
-                       (pnum - dd->ipath_piobcnt2k) * dd->ipath_4kalign);
-               dwcnt = dd->ipath_piosize4k >> 2;
-       }
-       dev_info(&dd->pcidev->dev,
-               "Rewrite PIO buffer %u, to recover from parity error\n",
-               pnum);
-
-       /* no flush required, since already in freeze */
-       writel(dwcnt + 1, pbuf);
-       while (--dwcnt)
-               writel(0, pbuf++);
-}
 
 /*
  * Called when we might have an error that is specific to a particular
  * PIO buffer, and may need to cancel that buffer, so it can be re-used.
- * If rewrite is true, and bits are set in the sendbufferror registers,
- * we'll write to the buffer, for error recovery on parity errors.
  */
-void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
+void ipath_disarm_senderrbufs(struct ipath_devdata *dd)
 {
        u32 piobcnt;
        unsigned long sbuf[4];
@@ -109,11 +79,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
                }
 
                for (i = 0; i < piobcnt; i++)
-                       if (test_bit(i, sbuf)) {
-                               if (rewrite)
-                                       ipath_clrpiobuf(dd, i);
+                       if (test_bit(i, sbuf))
                                ipath_disarm_piobufs(dd, i, 1);
-                       }
                /* ignore armlaunch errs for a bit */
                dd->ipath_lastcancel = jiffies+3;
        }
@@ -164,7 +131,7 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs)
 {
        u64 ignore_this_time = 0;
 
-       ipath_disarm_senderrbufs(dd, 0);
+       ipath_disarm_senderrbufs(dd);
        if ((errs & E_SUM_LINK_PKTERRS) &&
            !(dd->ipath_flags & IPATH_LINKACTIVE)) {
                /*
@@ -909,8 +876,8 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
  * processes (causing armlaunch), send errors due to going into freeze mode,
  * etc., and try to avoid causing extra interrupts while doing so.
  * Forcibly update the in-memory pioavail register copies after cleanup
- * because the chip won't do it for anything changing while in freeze mode
- * (we don't want to wait for the next pio buffer state change).
+ * because the chip won't do it while in freeze mode (the register values
+ * themselves are kept correct).
  * Make sure that we don't lose any important interrupts by using the chip
  * feature that says that writing 0 to a bit in *clear that is set in
  * *status will cause an interrupt to be generated again (if allowed by
@@ -918,43 +885,22 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
  */
 void ipath_clear_freeze(struct ipath_devdata *dd)
 {
-       int i, im;
-       u64 val;
-
        /* disable error interrupts, to avoid confusion */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);
 
        /* also disable interrupts; errormask is sometimes overwriten */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);
 
-       /*
-        * clear all sends, because they have may been
-        * completed by usercode while in freeze mode, and
-        * therefore would not be sent, and eventually
-        * might cause the process to run out of bufs
-        */
-       ipath_cancel_sends(dd, 0);
+       ipath_cancel_sends(dd, 1);
+
+       /* clear the freeze, and be sure chip saw it */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
                         dd->ipath_control);
+       ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
 
-       /* ensure pio avail updates continue */
+       /* force in-memory update now we are out of freeze */
        ipath_force_pio_avail_update(dd);
 
-       /*
-        * We just enabled pioavailupdate, so dma copy is almost certainly
-        * not yet right, so read the registers directly.  Similar to init
-        */
-       for (i = 0; i < dd->ipath_pioavregs; i++) {
-               /* deal with 6110 chip bug */
-               im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
-                       i ^ 1 : i;
-               val = ipath_read_kreg64(dd, (0x1000 / sizeof(u64)) + im);
-               dd->ipath_pioavailregs_dma[i] = cpu_to_le64(val);
-               dd->ipath_pioavailshadow[i] = val |
-                       (~dd->ipath_pioavailkernel[i] <<
-                       INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT);
-       }
-
        /*
         * force new interrupt if any hwerr, error or interrupt bits are
         * still set, and clear "safe" send packet errors related to freeze
@@ -1312,10 +1258,8 @@ irqreturn_t ipath_intr(int irq, void *data)
                ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
                spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
-               if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA))
-                       handle_layer_pioavail(dd);
-               else
-                       ipath_dbg("unexpected BUFAVAIL intr\n");
+               /* always process; sdma verbs uses PIO for acks and VL15  */
+               handle_layer_pioavail(dd);
        }
 
        ret = IRQ_HANDLED;
index 202337ae90dc68621dc89feefe931dbb82982c37..02b24a340599525d9f423a74ac4ccf2f01d9e62d 100644 (file)
@@ -117,6 +117,10 @@ struct ipath_portdata {
        u16 port_subport_cnt;
        /* non-zero if port is being shared. */
        u16 port_subport_id;
+       /* number of pio bufs for this port (all procs, if shared) */
+       u32 port_piocnt;
+       /* first pio buffer for this port */
+       u32 port_pio_base;
        /* chip offset of PIO buffers for this port */
        u32 port_piobufs;
        /* how many alloc_pages() chunks in port_rcvegrbuf_pages */
@@ -384,6 +388,8 @@ struct ipath_devdata {
        u32 ipath_lastrpkts;
        /* pio bufs allocated per port */
        u32 ipath_pbufsport;
+       /* if remainder on bufs/port, ports < extrabuf get 1 extra */
+       u32 ipath_ports_extrabuf;
        u32 ipath_pioupd_thresh; /* update threshold, some chips */
        /*
         * number of ports configured as max; zero is set to number chip
@@ -1011,7 +1017,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *);
 int ipath_update_eeprom_log(struct ipath_devdata *dd);
 void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
 u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
-void ipath_disarm_senderrbufs(struct ipath_devdata *, int);
+void ipath_disarm_senderrbufs(struct ipath_devdata *);
 void ipath_force_pio_avail_update(struct ipath_devdata *);
 void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev);
 
index c405dfba5531329ae4324ee7690212640522a370..08b11b567614562e65a9ffc87e0270ff2a433edf 100644 (file)
@@ -1746,7 +1746,11 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
                qp->r_wrid_valid = 0;
                wc.wr_id = qp->r_wr_id;
                wc.status = IB_WC_SUCCESS;
-               wc.opcode = IB_WC_RECV;
+               if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) ||
+                   opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE))
+                       wc.opcode = IB_WC_RECV_RDMA_WITH_IMM;
+               else
+                       wc.opcode = IB_WC_RECV;
                wc.vendor_err = 0;
                wc.qp = &qp->ibqp;
                wc.src_qp = qp->remote_qpn;
index 8ac5c1d82ccdb9cdb49b1b01db264c38e9f04fd0..9e3fe61cbd08ea0f45bd9a988871e15d6ffd1baa 100644 (file)
@@ -481,9 +481,10 @@ done:
                wake_up(&qp->wait);
 }
 
-static void want_buffer(struct ipath_devdata *dd)
+static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp)
 {
-       if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) {
+       if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) ||
+               qp->ibqp.qp_type == IB_QPT_SMI) {
                unsigned long flags;
 
                spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
@@ -519,7 +520,7 @@ static void ipath_no_bufs_available(struct ipath_qp *qp,
        spin_lock_irqsave(&dev->pending_lock, flags);
        list_add_tail(&qp->piowait, &dev->piowait);
        spin_unlock_irqrestore(&dev->pending_lock, flags);
-       want_buffer(dev->dd);
+       want_buffer(dev->dd, qp);
        dev->n_piowait++;
 }
 
index 1974df7a9f789e6e19568876f59c9a4c5f5783ae..3697449c1ba4e7042d89f34ac334b66ff4872e2a 100644 (file)
@@ -308,13 +308,15 @@ static void sdma_abort_task(unsigned long opaque)
                spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 
                /*
-                * Don't restart sdma here. Wait until link is up to ACTIVE.
-                * VL15 MADs used to bring the link up use PIO, and multiple
-                * link transitions otherwise cause the sdma engine to be
+                * Don't restart sdma here (with the exception
+                * below). Wait until link is up to ACTIVE.  VL15 MADs
+                * used to bring the link up use PIO, and multiple link
+                * transitions otherwise cause the sdma engine to be
                 * stopped and started multiple times.
-                * The disable is done here, including the shadow, so the
-                * state is kept consistent.
-                * See ipath_restart_sdma() for the actual starting of sdma.
+                * The disable is done here, including the shadow,
+                * so the state is kept consistent.
+                * See ipath_restart_sdma() for the actual starting
+                * of sdma.
                 */
                spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
                dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE;
@@ -326,6 +328,13 @@ static void sdma_abort_task(unsigned long opaque)
                /* make sure I see next message */
                dd->ipath_sdma_abort_jiffies = 0;
 
+               /*
+                * Not everything that takes SDMA offline is a link
+                * status change.  If the link was up, restart SDMA.
+                */
+               if (dd->ipath_flags & IPATH_LINKACTIVE)
+                       ipath_restart_sdma(dd);
+
                goto done;
        }
 
@@ -427,7 +436,12 @@ int setup_sdma(struct ipath_devdata *dd)
                goto done;
        }
 
-       dd->ipath_sdma_status = 0;
+       /*
+        * Set initial status as if we had been up, then gone down.
+        * This lets initial start on transition to ACTIVE be the
+        * same as restart after link flap.
+        */
+       dd->ipath_sdma_status = IPATH_SDMA_ABORT_ABORTED;
        dd->ipath_sdma_abort_jiffies = 0;
        dd->ipath_sdma_generation = 0;
        dd->ipath_sdma_descq_tail = 0;
@@ -449,16 +463,19 @@ int setup_sdma(struct ipath_devdata *dd)
        ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmaheadaddr,
                         dd->ipath_sdma_head_phys);
 
-       /* Reserve all the former "kernel" piobufs */
-       n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - dd->ipath_pioreserved;
-       for (i = dd->ipath_lastport_piobuf; i < n; ++i) {
+       /*
+        * Reserve all the former "kernel" piobufs, using high number range
+        * so we get as many 4K buffers as possible
+        */
+       n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
+       i = dd->ipath_lastport_piobuf + dd->ipath_pioreserved;
+       ipath_chg_pioavailkernel(dd, i, n - i , 0);
+       for (; i < n; ++i) {
                unsigned word = i / 64;
                unsigned bit = i & 63;
                BUG_ON(word >= 3);
                senddmabufmask[word] |= 1ULL << bit;
        }
-       ipath_chg_pioavailkernel(dd, dd->ipath_lastport_piobuf,
-               n - dd->ipath_lastport_piobuf, 0);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask0,
                         senddmabufmask[0]);
        ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask1,
@@ -615,6 +632,9 @@ void ipath_restart_sdma(struct ipath_devdata *dd)
        ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
        spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
+       /* notify upper layers */
+       ipath_ib_piobufavail(dd->verbs_dev);
+
 bail:
        return;
 }
index e63927cce5b52180563bb4d03ffe2a41537959dc..5015cd2e57bd446c7c508ad22380a3f61c86ef52 100644 (file)
@@ -396,7 +396,6 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr)
 
        wqe = get_swqe_ptr(qp, qp->s_head);
        wqe->wr = *wr;
-       wqe->ssn = qp->s_ssn++;
        wqe->length = 0;
        if (wr->num_sge) {
                acc = wr->opcode >= IB_WR_RDMA_READ ?
@@ -422,6 +421,7 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr)
                        goto bail_inval;
        } else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu)
                goto bail_inval;
+       wqe->ssn = qp->s_ssn++;
        qp->s_head = next;
 
        ret = 0;
index 2f199c5c4a724320a8e517a5a37046d7d740923d..4521319b14067c22d576044c35bea72bcb2e3720 100644 (file)
@@ -246,7 +246,7 @@ err_mtt:
        if (context)
                ib_umem_release(cq->umem);
        else
-               mlx4_ib_free_cq_buf(dev, &cq->buf, entries);
+               mlx4_ib_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
 
 err_db:
        if (!context)
@@ -434,7 +434,7 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq)
                mlx4_ib_db_unmap_user(to_mucontext(cq->uobject->context), &mcq->db);
                ib_umem_release(mcq->umem);
        } else {
-               mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe + 1);
+               mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe);
                mlx4_db_free(dev->dev, &mcq->db);
        }
 
index 9044f8803532e035e264e2b166644b05d84563e4..ca126fc2b853c14a3d61f24e731f2f304ad9530d 100644 (file)
@@ -334,6 +334,7 @@ struct ipoib_dev_priv {
 #endif
        int     hca_caps;
        struct ipoib_ethtool_st ethtool;
+       struct timer_list poll_timer;
 };
 
 struct ipoib_ah {
@@ -404,6 +405,7 @@ extern struct workqueue_struct *ipoib_workqueue;
 
 int ipoib_poll(struct napi_struct *napi, int budget);
 void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
+void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr);
 
 struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
                                 struct ib_pd *pd, struct ib_ah_attr *attr);
index 97b815c1a3fc0988a33129e47ace54748d9d9dbb..f429bce24c20b9be303e75b6dc4ad1cf112a7663 100644 (file)
@@ -461,6 +461,26 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
        netif_rx_schedule(dev, &priv->napi);
 }
 
+static void drain_tx_cq(struct net_device *dev)
+{
+       struct ipoib_dev_priv *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->tx_lock, flags);
+       while (poll_tx(priv))
+               ; /* nothing */
+
+       if (netif_queue_stopped(dev))
+               mod_timer(&priv->poll_timer, jiffies + 1);
+
+       spin_unlock_irqrestore(&priv->tx_lock, flags);
+}
+
+void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr)
+{
+       drain_tx_cq((struct net_device *)dev_ptr);
+}
+
 static inline int post_send(struct ipoib_dev_priv *priv,
                            unsigned int wr_id,
                            struct ib_ah *address, u32 qpn,
@@ -555,12 +575,22 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
        else
                priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
 
+       if (++priv->tx_outstanding == ipoib_sendq_size) {
+               ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
+               if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
+                       ipoib_warn(priv, "request notify on send CQ failed\n");
+               netif_stop_queue(dev);
+       }
+
        if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
                               address->ah, qpn, tx_req, phead, hlen))) {
                ipoib_warn(priv, "post_send failed\n");
                ++dev->stats.tx_errors;
+               --priv->tx_outstanding;
                ipoib_dma_unmap_tx(priv->ca, tx_req);
                dev_kfree_skb_any(skb);
+               if (netif_queue_stopped(dev))
+                       netif_wake_queue(dev);
        } else {
                dev->trans_start = jiffies;
 
@@ -568,14 +598,11 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
                ++priv->tx_head;
                skb_orphan(skb);
 
-               if (++priv->tx_outstanding == ipoib_sendq_size) {
-                       ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
-                       netif_stop_queue(dev);
-               }
        }
 
        if (unlikely(priv->tx_outstanding > MAX_SEND_CQE))
-               poll_tx(priv);
+               while (poll_tx(priv))
+                       ; /* nothing */
 }
 
 static void __ipoib_reap_ah(struct net_device *dev)
@@ -609,6 +636,11 @@ void ipoib_reap_ah(struct work_struct *work)
                                   round_jiffies_relative(HZ));
 }
 
+static void ipoib_ib_tx_timer_func(unsigned long ctx)
+{
+       drain_tx_cq((struct net_device *)ctx);
+}
+
 int ipoib_ib_dev_open(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -645,6 +677,10 @@ int ipoib_ib_dev_open(struct net_device *dev)
        queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
                           round_jiffies_relative(HZ));
 
+       init_timer(&priv->poll_timer);
+       priv->poll_timer.function = ipoib_ib_tx_timer_func;
+       priv->poll_timer.data = (unsigned long)dev;
+
        set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
        return 0;
@@ -810,6 +846,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
        ipoib_dbg(priv, "All sends and receives done.\n");
 
 timeout:
+       del_timer_sync(&priv->poll_timer);
        qp_attr.qp_state = IB_QPS_RESET;
        if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
                ipoib_warn(priv, "Failed to modify QP to RESET state\n");
index c1e7ece1fd440ffd61efc2260ade377cc87df47e..8766d29ce3b783275d6b6753620cdc0291855186 100644 (file)
@@ -187,7 +187,8 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
                goto out_free_mr;
        }
 
-       priv->send_cq = ib_create_cq(priv->ca, NULL, NULL, dev, ipoib_sendq_size, 0);
+       priv->send_cq = ib_create_cq(priv->ca, ipoib_send_comp_handler, NULL,
+                                    dev, ipoib_sendq_size, 0);
        if (IS_ERR(priv->send_cq)) {
                printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name);
                goto out_free_recv_cq;
index 92b683411d5ab293cf27d34c0a9c07e1fafa2cf5..3ad8bd9f75436efd29fd3054a79e89a668219b4a 100644 (file)
@@ -14,7 +14,7 @@ if INPUT_MISC
 
 config INPUT_PCSPKR
        tristate "PC Speaker support"
-       depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+       depends on PCSPKR_PLATFORM
        depends on SND_PCSP=n
        help
          Say Y here if you want the standard PC Speaker to be used for
index 02b3ad8c082673efaf5e0ee39dd1365c08bae75f..edfedd9a166cef53a42d5c17846fe9adbb77bb21 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/hil.h>
+#include <linux/semaphore.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 3b4e13b9ce1b9ac7317335c49f7b5bed8f854524..f451c7351a9da1b0614e1e04412f65e07116a37c 100644 (file)
@@ -25,7 +25,7 @@
 #elif defined(__arm__)
 /* defined in include/asm-arm/arch-xxx/irqs.h */
 #include <asm/irq.h>
-#elif defined(CONFIG_SUPERH64)
+#elif defined(CONFIG_SH_CAYMAN)
 #include <asm/irq.h>
 #else
 # define I8042_KBD_IRQ 1
index 877be9922c3d24de4480d77dc25f017e86548092..15906d005b05de9f6371f75b6ca5b92617c0f4a3 100644 (file)
@@ -405,7 +405,8 @@ hysdn_procconf_init(void)
                sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
                if ((card->procconf = (void *) proc_create(conf_name,
                                                S_IFREG | S_IRUGO | S_IWUSR,
-                                               hysdn_proc_entry)) != NULL) {
+                                               hysdn_proc_entry,
+                                               &conf_fops)) != NULL) {
                        hysdn_proclog_init(card);       /* init the log file entry */
                }
                card = card->next;      /* next entry */
index 2bc9bf7e88e5e8f03a62347a346a1fc2cfd2c747..8080249957afb6d747631674d32cdc287319f96c 100644 (file)
@@ -85,27 +85,34 @@ static unsigned desc_size(const struct lguest_device_desc *desc)
                + desc->config_len;
 }
 
-/* This tests (and acknowleges) a feature bit. */
-static bool lg_feature(struct virtio_device *vdev, unsigned fbit)
+/* This gets the device's feature bits. */
+static u32 lg_get_features(struct virtio_device *vdev)
 {
+       unsigned int i;
+       u32 features = 0;
        struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-       u8 *features;
-
-       /* Obviously if they ask for a feature off the end of our feature
-        * bitmap, it's not set. */
-       if (fbit / 8 > desc->feature_len)
-               return false;
-
-       /* The feature bitmap comes after the virtqueues. */
-       features = lg_features(desc);
-       if (!(features[fbit / 8] & (1 << (fbit % 8))))
-               return false;
-
-       /* We set the matching bit in the other half of the bitmap to tell the
-        * Host we want to use this feature.  We don't use this yet, but we
-        * could in future. */
-       features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8));
-       return true;
+       u8 *in_features = lg_features(desc);
+
+       /* We do this the slow but generic way. */
+       for (i = 0; i < min(desc->feature_len * 8, 32); i++)
+               if (in_features[i / 8] & (1 << (i % 8)))
+                       features |= (1 << i);
+
+       return features;
+}
+
+static void lg_set_features(struct virtio_device *vdev, u32 features)
+{
+       unsigned int i;
+       struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+       /* Second half of bitmap is features we accept. */
+       u8 *out_features = lg_features(desc) + desc->feature_len;
+
+       memset(out_features, 0, desc->feature_len);
+       for (i = 0; i < min(desc->feature_len * 8, 32); i++) {
+               if (features & (1 << i))
+                       out_features[i / 8] |= (1 << (i % 8));
+       }
 }
 
 /* Once they've found a field, getting a copy of it is easy. */
@@ -137,20 +144,26 @@ static u8 lg_get_status(struct virtio_device *vdev)
        return to_lgdev(vdev)->desc->status;
 }
 
+/* To notify on status updates, we (ab)use the NOTIFY hypercall, with the
+ * descriptor address of the device.  A zero status means "reset". */
+static void set_status(struct virtio_device *vdev, u8 status)
+{
+       unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices;
+
+       /* We set the status. */
+       to_lgdev(vdev)->desc->status = status;
+       hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
+}
+
 static void lg_set_status(struct virtio_device *vdev, u8 status)
 {
        BUG_ON(!status);
-       to_lgdev(vdev)->desc->status = status;
+       set_status(vdev, status);
 }
 
-/* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor
- * address of the device.  The Host will zero the status and all the
- * features. */
 static void lg_reset(struct virtio_device *vdev)
 {
-       unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices;
-
-       hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
+       set_status(vdev, 0);
 }
 
 /*
@@ -286,7 +299,8 @@ static void lg_del_vq(struct virtqueue *vq)
 
 /* The ops structure which hooks everything together. */
 static struct virtio_config_ops lguest_config_ops = {
-       .feature = lg_feature,
+       .get_features = lg_get_features,
+       .set_features = lg_set_features,
        .get = lg_get,
        .set = lg_set,
        .get_status = lg_get_status,
index 645e6e040bfbeab46bad83b52f9bdf42a310d788..e73a000473cc524cd16d9773da390047d362751e 100644 (file)
@@ -102,7 +102,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
 static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
 {
        /* We have a limited number the number of CPUs in the lguest struct. */
-       if (id >= NR_CPUS)
+       if (id >= ARRAY_SIZE(cpu->lg->cpus))
                return -EINVAL;
 
        /* Set up this CPU's id, and pointer back to the lguest struct. */
@@ -251,8 +251,6 @@ static ssize_t write(struct file *file, const char __user *in,
                if (!lg || (cpu_id >= lg->nr_cpus))
                        return -EINVAL;
                cpu = &lg->cpus[cpu_id];
-               if (!cpu)
-                       return -EINVAL;
 
                /* Once the Guest is dead, you can only read() why it died. */
                if (lg->dead)
index 20978205cd02e2033e789eee8952495b982f6b33..b8b9e44f7f4ee9e478ebe07f45ae58ac6ae9a24b 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/device.h>
 #include <linux/kthread.h>
 #include <linux/platform_device.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 #ifdef CONFIG_PPC
@@ -102,7 +102,7 @@ static struct adb_handler {
 } adb_handler[16];
 
 /*
- * The adb_handler_sem mutex protects all accesses to the original_address
+ * The adb_handler_mutex mutex protects all accesses to the original_address
  * and handler_id fields of adb_handler[i] for all i, and changes to the
  * handler field.
  * Accesses to the handler field are protected by the adb_handler_lock
@@ -110,7 +110,7 @@ static struct adb_handler {
  * time adb_unregister returns, we know that the old handler isn't being
  * called.
  */
-static DECLARE_MUTEX(adb_handler_sem);
+static DEFINE_MUTEX(adb_handler_mutex);
 static DEFINE_RWLOCK(adb_handler_lock);
 
 #if 0
@@ -355,7 +355,7 @@ do_adb_reset_bus(void)
                msleep(500);
        }
 
-       down(&adb_handler_sem);
+       mutex_lock(&adb_handler_mutex);
        write_lock_irq(&adb_handler_lock);
        memset(adb_handler, 0, sizeof(adb_handler));
        write_unlock_irq(&adb_handler_lock);
@@ -376,7 +376,7 @@ do_adb_reset_bus(void)
                if (adb_controller->autopoll)
                        adb_controller->autopoll(autopoll_devs);
        }
-       up(&adb_handler_sem);
+       mutex_unlock(&adb_handler_mutex);
 
        blocking_notifier_call_chain(&adb_client_list,
                ADB_MSG_POST_RESET, NULL);
@@ -454,7 +454,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids,
 {
        int i;
 
-       down(&adb_handler_sem);
+       mutex_lock(&adb_handler_mutex);
        ids->nids = 0;
        for (i = 1; i < 16; i++) {
                if ((adb_handler[i].original_address == default_id) &&
@@ -472,7 +472,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids,
                        ids->id[ids->nids++] = i;
                }
        }
-       up(&adb_handler_sem);
+       mutex_unlock(&adb_handler_mutex);
        return ids->nids;
 }
 
@@ -481,7 +481,7 @@ adb_unregister(int index)
 {
        int ret = -ENODEV;
 
-       down(&adb_handler_sem);
+       mutex_lock(&adb_handler_mutex);
        write_lock_irq(&adb_handler_lock);
        if (adb_handler[index].handler) {
                while(adb_handler[index].busy) {
@@ -493,7 +493,7 @@ adb_unregister(int index)
                adb_handler[index].handler = NULL;
        }
        write_unlock_irq(&adb_handler_lock);
-       up(&adb_handler_sem);
+       mutex_unlock(&adb_handler_mutex);
        return ret;
 }
 
@@ -557,19 +557,19 @@ adb_try_handler_change(int address, int new_id)
 {
        int ret;
 
-       down(&adb_handler_sem);
+       mutex_lock(&adb_handler_mutex);
        ret = try_handler_change(address, new_id);
-       up(&adb_handler_sem);
+       mutex_unlock(&adb_handler_mutex);
        return ret;
 }
 
 int
 adb_get_infos(int address, int *original_address, int *handler_id)
 {
-       down(&adb_handler_sem);
+       mutex_lock(&adb_handler_mutex);
        *original_address = adb_handler[address].original_address;
        *handler_id = adb_handler[address].handler_id;
-       up(&adb_handler_sem);
+       mutex_unlock(&adb_handler_mutex);
 
        return (*original_address != 0);
 }
@@ -628,10 +628,10 @@ do_adb_query(struct adb_request *req)
        case ADB_QUERY_GETDEVINFO:
                if (req->nbytes < 3)
                        break;
-               down(&adb_handler_sem);
+               mutex_lock(&adb_handler_mutex);
                req->reply[0] = adb_handler[req->data[2]].original_address;
                req->reply[1] = adb_handler[req->data[2]].handler_id;
-               up(&adb_handler_sem);
+               mutex_unlock(&adb_handler_mutex);
                req->complete = 1;
                req->reply_len = 2;
                adb_write_done(req);
index 1e0a69a5e8150664c7240c9793f76a8563a63687..ddfb426a9abd01a57996e23afbad9db0c2e3d93e 100644 (file)
 #include <linux/kmod.h>
 #include <linux/i2c.h>
 #include <linux/kthread.h>
+#include <linux/mutex.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -169,7 +170,7 @@ static int                          rackmac;
 static s32                             dimm_output_clamp;
 static int                             fcu_rpm_shift;
 static int                             fcu_tickle_ticks;
-static DECLARE_MUTEX(driver_lock);
+static DEFINE_MUTEX(driver_lock);
 
 /*
  * We have 3 types of CPU PID control. One is "split" old style control
@@ -729,9 +730,9 @@ static void fetch_cpu_pumps_minmax(void)
 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)       \
 {                                                              \
        ssize_t r;                                              \
-       down(&driver_lock);                                     \
+       mutex_lock(&driver_lock);                                       \
        r = sprintf(buf, "%d.%03d", FIX32TOPRINT(data));        \
-       up(&driver_lock);                                       \
+       mutex_unlock(&driver_lock);                                     \
        return r;                                               \
 }
 #define BUILD_SHOW_FUNC_INT(name, data)                                \
@@ -1803,11 +1804,11 @@ static int main_control_loop(void *x)
 {
        DBG("main_control_loop started\n");
 
-       down(&driver_lock);
+       mutex_lock(&driver_lock);
 
        if (start_fcu() < 0) {
                printk(KERN_ERR "kfand: failed to start FCU\n");
-               up(&driver_lock);
+               mutex_unlock(&driver_lock);
                goto out;
        }
 
@@ -1822,14 +1823,14 @@ static int main_control_loop(void *x)
 
        fcu_tickle_ticks = FCU_TICKLE_TICKS;
 
-       up(&driver_lock);
+       mutex_unlock(&driver_lock);
 
        while (state == state_attached) {
                unsigned long elapsed, start;
 
                start = jiffies;
 
-               down(&driver_lock);
+               mutex_lock(&driver_lock);
 
                /* Tickle the FCU just in case */
                if (--fcu_tickle_ticks < 0) {
@@ -1861,7 +1862,7 @@ static int main_control_loop(void *x)
                        do_monitor_slots(&slots_state);
                else
                        do_monitor_drives(&drives_state);
-               up(&driver_lock);
+               mutex_unlock(&driver_lock);
 
                if (critical_state == 1) {
                        printk(KERN_WARNING "Temperature control detected a critical condition\n");
@@ -2019,13 +2020,13 @@ static void detach_fcu(void)
  */
 static int therm_pm72_attach(struct i2c_adapter *adapter)
 {
-       down(&driver_lock);
+       mutex_lock(&driver_lock);
 
        /* Check state */
        if (state == state_detached)
                state = state_attaching;
        if (state != state_attaching) {
-               up(&driver_lock);
+               mutex_unlock(&driver_lock);
                return 0;
        }
 
@@ -2054,7 +2055,7 @@ static int therm_pm72_attach(struct i2c_adapter *adapter)
                state = state_attached;
                start_control_loops();
        }
-       up(&driver_lock);
+       mutex_unlock(&driver_lock);
 
        return 0;
 }
@@ -2065,16 +2066,16 @@ static int therm_pm72_attach(struct i2c_adapter *adapter)
  */
 static int therm_pm72_detach(struct i2c_adapter *adapter)
 {
-       down(&driver_lock);
+       mutex_lock(&driver_lock);
 
        if (state != state_detached)
                state = state_detaching;
 
        /* Stop control loops if any */
        DBG("stopping control loops\n");
-       up(&driver_lock);
+       mutex_unlock(&driver_lock);
        stop_control_loops();
-       down(&driver_lock);
+       mutex_lock(&driver_lock);
 
        if (u3_0 != NULL && !strcmp(adapter->name, "u3 0")) {
                DBG("lost U3-0, disposing control loops\n");
@@ -2090,7 +2091,7 @@ static int therm_pm72_detach(struct i2c_adapter *adapter)
        if (u3_0 == NULL && u3_1 == NULL)
                state = state_detached;
 
-       up(&driver_lock);
+       mutex_unlock(&driver_lock);
 
        return 0;
 }
index 797918d0e59cb5888c8b5852f9f6e863ed7a3f1e..7f2be4baaedab9cec03e721a5733e864d10016bb 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/prom.h>
 #include <asm/smu.h>
 #include <asm/pmac_low_i2c.h>
@@ -36,7 +36,7 @@
 struct wf_sat {
        int                     nr;
        atomic_t                refcnt;
-       struct semaphore        mutex;
+       struct mutex            mutex;
        unsigned long           last_read; /* jiffies when cache last updated */
        u8                      cache[16];
        struct i2c_client       i2c;
@@ -163,7 +163,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value)
        if (sat->i2c.adapter == NULL)
                return -ENODEV;
 
-       down(&sat->mutex);
+       mutex_lock(&sat->mutex);
        if (time_after(jiffies, (sat->last_read + MAX_AGE))) {
                err = wf_sat_read_cache(sat);
                if (err)
@@ -182,7 +182,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value)
        err = 0;
 
  fail:
-       up(&sat->mutex);
+       mutex_unlock(&sat->mutex);
        return err;
 }
 
@@ -233,7 +233,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
        sat->nr = -1;
        sat->node = of_node_get(dev);
        atomic_set(&sat->refcnt, 0);
-       init_MUTEX(&sat->mutex);
+       mutex_init(&sat->mutex);
        sat->i2c.addr = (addr >> 1) & 0x7f;
        sat->i2c.adapter = adapter;
        sat->i2c.driver = &wf_sat_driver;
index 5938fa9629221145e6b4249d4996ca6c67e08516..faf3d89129799bc8157fa891c0176d985528c189 100644 (file)
@@ -886,7 +886,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
         */
        raid10_find_phys(conf, r10_bio);
  retry_write:
-       blocked_rdev = 0;
+       blocked_rdev = NULL;
        rcu_read_lock();
        for (i = 0;  i < conf->copies; i++) {
                int d = r10_bio->devs[i].devnum;
index 087eee0cb80913fabc692187eed59e981c5eb95e..ee0ea9183080fd3e333302eb4512803b6d9f26b1 100644 (file)
@@ -2369,8 +2369,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
 
        /* complete a check operation */
        if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
-           clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
-           clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+               clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
+               clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
                if (s->failed == 0) {
                        if (sh->ops.zero_sum_result == 0)
                                /* parity is correct (on disc,
@@ -2400,16 +2400,6 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                        canceled_check = 1; /* STRIPE_INSYNC is not set */
        }
 
-       /* check if we can clear a parity disk reconstruct */
-       if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
-               test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-
-               clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
-       }
-
        /* start a new check operation if there are no failures, the stripe is
         * not insync, and a repair is not in flight
         */
@@ -2424,6 +2414,17 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                }
        }
 
+       /* check if we can clear a parity disk reconstruct */
+       if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
+           test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
+
+               clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
+               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
+               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
+               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
+       }
+
+
        /* Wait for check parity and compute block operations to complete
         * before write-back.  If a failure occurred while the check operation
         * was in flight we need to cycle this stripe through handle_stripe
index 73f742c7e818428f1965d880a3c442e71154a957..cc11c4c0e7e7afaf585e3866c0119a0601275164 100644 (file)
@@ -2,6 +2,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
+obj-y := common/
+
 obj-$(CONFIG_VIDEO_MEDIA) += common/
 
 # Since hybrid devices are here, should be compiled if DVB and/or V4L
index 8f5ed9b4bf8327df434285194730f888d2a83a8b..3f55d47bc4b962706a7595803124796195b9c2da 100644 (file)
@@ -613,7 +613,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
        }
 
        cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
-       if (cx == 0) {
+       if (!cx) {
                spin_unlock(&cx18_cards_lock);
                return -ENOMEM;
        }
index a0baf2d0ba7f307bade2c320716ce08b9b143d18..48e1a01718ec37390f72fa8ed731bfaa0d16bc78 100644 (file)
@@ -1634,7 +1634,7 @@ static int saa7134_s_fmt_overlay(struct file *file, void *priv,
        struct saa7134_fh *fh = priv;
        struct saa7134_dev *dev = fh->dev;
        int err;
-       unsigned int flags;
+       unsigned long flags;
 
        if (saa7134_no_overlay > 0) {
                printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
index e57a646057785eb51dd331febc4db1772284204c..8f0100f67a91ea21bec97b6f708d337c18da1428 100644 (file)
@@ -885,12 +885,19 @@ static int __exit tcm825x_remove(struct i2c_client *client)
        return 0;
 }
 
+static const struct i2c_device_id tcm825x_id[] = {
+       { "tcm825x", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tcm825x_id);
+
 static struct i2c_driver tcm825x_i2c_driver = {
        .driver = {
                .name = TCM825X_NAME,
        },
        .probe  = tcm825x_probe,
        .remove = __exit_p(tcm825x_remove),
+       .id_table = tcm825x_id,
 };
 
 static struct tcm825x_sensor tcm825x = {
index f1db54202deaebb36138b119279bdf18424644aa..28ab9f9d760a29aa0317a9ee4eda54a78f2da854 100644 (file)
@@ -168,6 +168,11 @@ static int tlv320aic23b_remove(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id tlv320aic23b_id[] = {
+       { "tlv320aic23b", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
        .name = "tlv320aic23b",
@@ -175,4 +180,5 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
        .command = tlv320aic23b_command,
        .probe = tlv320aic23b_probe,
        .remove = tlv320aic23b_remove,
+       .id_table = tlv320aic23b_id,
 };
index 6f9945b04e1f2bcd676f0ed8dc910994b29ed300..c77914d99d15c5972c94e9763a08b5789098e90a 100644 (file)
@@ -1505,7 +1505,8 @@ static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
        }
 
        /* fill required data structures */
-       strcpy(client->name, desc->name);
+       if (!id)
+               strlcpy(client->name, desc->name, I2C_NAME_SIZE);
        chip->type = desc-chiplist;
        chip->shadow.count = desc->registers+1;
        chip->prevmode = -1;
@@ -1830,6 +1831,15 @@ static int chip_legacy_probe(struct i2c_adapter *adap)
        return 0;
 }
 
+/* This driver supports many devices and the idea is to let the driver
+   detect which device is present. So rather than listing all supported
+   devices here, we pretend to support a single, fake device type. */
+static const struct i2c_device_id chip_id[] = {
+       { "tvaudio", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, chip_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
        .name = "tvaudio",
        .driverid = I2C_DRIVERID_TVAUDIO,
@@ -1837,6 +1847,7 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
        .probe = chip_probe,
        .remove = chip_remove,
        .legacy_probe = chip_legacy_probe,
+       .id_table = chip_id,
 };
 
 /*
index 30a1af857c7a9345d254d118ea756acc84559fb4..fa394104339ccb8a9e45161f4d3ee1a5c900125d 100644 (file)
@@ -47,6 +47,7 @@
  *       to test the HW NMI watchdog
  * F## = Break at do_fork for ## iterations
  * S## = Break at sys_open for ## iterations
+ * I## = Run the single step test ## iterations
  *
  * NOTE: that the do_fork and sys_open tests are mutually exclusive.
  *
@@ -375,7 +376,7 @@ static void emul_sstep_get(char *arg)
                break;
        case 1:
                /* set breakpoint */
-               break_helper("Z0", 0, sstep_addr);
+               break_helper("Z0", NULL, sstep_addr);
                break;
        case 2:
                /* Continue */
@@ -383,7 +384,7 @@ static void emul_sstep_get(char *arg)
                break;
        case 3:
                /* Clear breakpoint */
-               break_helper("z0", 0, sstep_addr);
+               break_helper("z0", NULL, sstep_addr);
                break;
        default:
                eprintk("kgdbts: ERROR failed sstep get emulation\n");
@@ -465,11 +466,11 @@ static struct test_struct sw_breakpoint_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+       { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs },
        { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
        { "D", "OK" }, /* Detach */
-       { "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+       { "D", "OK", NULL,  got_break }, /* On success we made it here */
        { "", "" },
 };
 
@@ -499,14 +500,14 @@ static struct test_struct singlestep_break_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+       { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs }, /* Write registers */
        { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
        { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-       { "g", "kgdbts_break_test", 0, check_single_step },
+       { "g", "kgdbts_break_test", NULL, check_single_step },
        { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+       { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs }, /* Write registers */
        { "D", "OK" }, /* Remove all breakpoints and continues */
        { "", "" },
@@ -520,14 +521,14 @@ static struct test_struct do_fork_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "do_fork", 0, check_and_rewind_pc }, /* check location */
+       { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
        { "write", "OK", write_regs }, /* Write registers */
        { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
        { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-       { "g", "do_fork", 0, check_single_step },
+       { "g", "do_fork", NULL, check_single_step },
        { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
        { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
-       { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
+       { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
        { "", "" },
 };
 
@@ -538,14 +539,14 @@ static struct test_struct sys_open_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "sys_open", 0, check_and_rewind_pc }, /* check location */
+       { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
        { "write", "OK", write_regs }, /* Write registers */
        { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
        { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-       { "g", "sys_open", 0, check_single_step },
+       { "g", "sys_open", NULL, check_single_step },
        { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
        { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
-       { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
+       { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
        { "", "" },
 };
 
@@ -556,11 +557,11 @@ static struct test_struct hw_breakpoint_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */
        { "c", "T0*", }, /* Continue */
-       { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+       { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs },
        { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */
        { "D", "OK" }, /* Detach */
-       { "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+       { "D", "OK", NULL,  got_break }, /* On success we made it here */
        { "", "" },
 };
 
@@ -570,12 +571,12 @@ static struct test_struct hw_breakpoint_test[] = {
 static struct test_struct hw_write_break_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */
-       { "c", "T0*", 0, got_break }, /* Continue */
-       { "g", "silent", 0, check_and_rewind_pc },
+       { "c", "T0*", NULL, got_break }, /* Continue */
+       { "g", "silent", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs },
        { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */
        { "D", "OK" }, /* Detach */
-       { "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+       { "D", "OK", NULL,  got_break }, /* On success we made it here */
        { "", "" },
 };
 
@@ -585,12 +586,12 @@ static struct test_struct hw_write_break_test[] = {
 static struct test_struct hw_access_break_test[] = {
        { "?", "S0*" }, /* Clear break points */
        { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */
-       { "c", "T0*", 0, got_break }, /* Continue */
-       { "g", "silent", 0, check_and_rewind_pc },
+       { "c", "T0*", NULL, got_break }, /* Continue */
+       { "g", "silent", NULL, check_and_rewind_pc },
        { "write", "OK", write_regs },
        { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */
        { "D", "OK" }, /* Detach */
-       { "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+       { "D", "OK", NULL,  got_break }, /* On success we made it here */
        { "", "" },
 };
 
@@ -599,9 +600,9 @@ static struct test_struct hw_access_break_test[] = {
  */
 static struct test_struct nmi_sleep_test[] = {
        { "?", "S0*" }, /* Clear break points */
-       { "c", "T0*", 0, got_break }, /* Continue */
+       { "c", "T0*", NULL, got_break }, /* Continue */
        { "D", "OK" }, /* Detach */
-       { "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+       { "D", "OK", NULL,  got_break }, /* On success we made it here */
        { "", "" },
 };
 
@@ -874,18 +875,23 @@ static void kgdbts_run_tests(void)
 {
        char *ptr;
        int fork_test = 0;
-       int sys_open_test = 0;
+       int do_sys_open_test = 0;
+       int sstep_test = 1000;
        int nmi_sleep = 0;
+       int i;
 
        ptr = strstr(config, "F");
        if (ptr)
-               fork_test = simple_strtol(ptr+1, NULL, 10);
+               fork_test = simple_strtol(ptr + 1, NULL, 10);
        ptr = strstr(config, "S");
        if (ptr)
-               sys_open_test = simple_strtol(ptr+1, NULL, 10);
+               do_sys_open_test = simple_strtol(ptr + 1, NULL, 10);
        ptr = strstr(config, "N");
        if (ptr)
                nmi_sleep = simple_strtol(ptr+1, NULL, 10);
+       ptr = strstr(config, "I");
+       if (ptr)
+               sstep_test = simple_strtol(ptr+1, NULL, 10);
 
        /* required internal KGDB tests */
        v1printk("kgdbts:RUN plant and detach test\n");
@@ -894,8 +900,13 @@ static void kgdbts_run_tests(void)
        run_breakpoint_test(0);
        v1printk("kgdbts:RUN bad memory access test\n");
        run_bad_read_test();
-       v1printk("kgdbts:RUN singlestep breakpoint test\n");
-       run_singlestep_break_test();
+       v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test);
+       for (i = 0; i < sstep_test; i++) {
+               run_singlestep_break_test();
+               if (i % 100 == 0)
+                       v1printk("kgdbts:RUN singlestep [%i/%i]\n",
+                                i, sstep_test);
+       }
 
        /* ===Optional tests=== */
 
@@ -922,7 +933,7 @@ static void kgdbts_run_tests(void)
                repeat_test = fork_test;
                printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n",
                        repeat_test);
-               kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
+               kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
                run_do_fork_test();
                return;
        }
@@ -931,11 +942,11 @@ static void kgdbts_run_tests(void)
         * executed because a kernel thread will be spawned at the very
         * end to unregister the debug hooks.
         */
-       if (sys_open_test) {
-               repeat_test = sys_open_test;
+       if (do_sys_open_test) {
+               repeat_test = do_sys_open_test;
                printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n",
                        repeat_test);
-               kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
+               kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
                run_sys_open_test();
                return;
        }
index 5515234be86ab952d79d3165a9e1d96a7cbb004b..03a87a307e321f0ac2ae3dffd2a16cef7baa03f5 100644 (file)
@@ -157,215 +157,136 @@ struct xpc_msg {
 /*
  * Define the return values and values passed to user's callout functions.
  * (It is important to add new value codes at the end just preceding
- * xpcUnknownReason, which must have the highest numerical value.)
+ * xpUnknownReason, which must have the highest numerical value.)
  */
-enum xpc_retval {
-       xpcSuccess = 0,
+enum xp_retval {
+       xpSuccess = 0,
 
-       xpcNotConnected,        /*  1: channel is not connected */
-       xpcConnected,           /*  2: channel connected (opened) */
-       xpcRETIRED1,            /*  3: (formerly xpcDisconnected) */
+       xpNotConnected,         /*  1: channel is not connected */
+       xpConnected,            /*  2: channel connected (opened) */
+       xpRETIRED1,             /*  3: (formerly xpDisconnected) */
 
-       xpcMsgReceived,         /*  4: message received */
-       xpcMsgDelivered,        /*  5: message delivered and acknowledged */
+       xpMsgReceived,          /*  4: message received */
+       xpMsgDelivered,         /*  5: message delivered and acknowledged */
 
-       xpcRETIRED2,            /*  6: (formerly xpcTransferFailed) */
+       xpRETIRED2,             /*  6: (formerly xpTransferFailed) */
 
-       xpcNoWait,              /*  7: operation would require wait */
-       xpcRetry,               /*  8: retry operation */
-       xpcTimeout,             /*  9: timeout in xpc_allocate_msg_wait() */
-       xpcInterrupted,         /* 10: interrupted wait */
+       xpNoWait,               /*  7: operation would require wait */
+       xpRetry,                /*  8: retry operation */
+       xpTimeout,              /*  9: timeout in xpc_allocate_msg_wait() */
+       xpInterrupted,          /* 10: interrupted wait */
 
-       xpcUnequalMsgSizes,     /* 11: message size disparity between sides */
-       xpcInvalidAddress,      /* 12: invalid address */
+       xpUnequalMsgSizes,      /* 11: message size disparity between sides */
+       xpInvalidAddress,       /* 12: invalid address */
 
-       xpcNoMemory,            /* 13: no memory available for XPC structures */
-       xpcLackOfResources,     /* 14: insufficient resources for operation */
-       xpcUnregistered,        /* 15: channel is not registered */
-       xpcAlreadyRegistered,   /* 16: channel is already registered */
+       xpNoMemory,             /* 13: no memory available for XPC structures */
+       xpLackOfResources,      /* 14: insufficient resources for operation */
+       xpUnregistered,         /* 15: channel is not registered */
+       xpAlreadyRegistered,    /* 16: channel is already registered */
 
-       xpcPartitionDown,       /* 17: remote partition is down */
-       xpcNotLoaded,           /* 18: XPC module is not loaded */
-       xpcUnloading,           /* 19: this side is unloading XPC module */
+       xpPartitionDown,        /* 17: remote partition is down */
+       xpNotLoaded,            /* 18: XPC module is not loaded */
+       xpUnloading,            /* 19: this side is unloading XPC module */
 
-       xpcBadMagic,            /* 20: XPC MAGIC string not found */
+       xpBadMagic,             /* 20: XPC MAGIC string not found */
 
-       xpcReactivating,        /* 21: remote partition was reactivated */
+       xpReactivating,         /* 21: remote partition was reactivated */
 
-       xpcUnregistering,       /* 22: this side is unregistering channel */
-       xpcOtherUnregistering,  /* 23: other side is unregistering channel */
+       xpUnregistering,        /* 22: this side is unregistering channel */
+       xpOtherUnregistering,   /* 23: other side is unregistering channel */
 
-       xpcCloneKThread,        /* 24: cloning kernel thread */
-       xpcCloneKThreadFailed,  /* 25: cloning kernel thread failed */
+       xpCloneKThread,         /* 24: cloning kernel thread */
+       xpCloneKThreadFailed,   /* 25: cloning kernel thread failed */
 
-       xpcNoHeartbeat,         /* 26: remote partition has no heartbeat */
+       xpNoHeartbeat,          /* 26: remote partition has no heartbeat */
 
-       xpcPioReadError,        /* 27: PIO read error */
-       xpcPhysAddrRegFailed,   /* 28: registration of phys addr range failed */
+       xpPioReadError,         /* 27: PIO read error */
+       xpPhysAddrRegFailed,    /* 28: registration of phys addr range failed */
 
-       xpcBteDirectoryError,   /* 29: maps to BTEFAIL_DIR */
-       xpcBtePoisonError,      /* 30: maps to BTEFAIL_POISON */
-       xpcBteWriteError,       /* 31: maps to BTEFAIL_WERR */
-       xpcBteAccessError,      /* 32: maps to BTEFAIL_ACCESS */
-       xpcBtePWriteError,      /* 33: maps to BTEFAIL_PWERR */
-       xpcBtePReadError,       /* 34: maps to BTEFAIL_PRERR */
-       xpcBteTimeOutError,     /* 35: maps to BTEFAIL_TOUT */
-       xpcBteXtalkError,       /* 36: maps to BTEFAIL_XTERR */
-       xpcBteNotAvailable,     /* 37: maps to BTEFAIL_NOTAVAIL */
-       xpcBteUnmappedError,    /* 38: unmapped BTEFAIL_ error */
+       xpRETIRED3,             /* 29: (formerly xpBteDirectoryError) */
+       xpRETIRED4,             /* 30: (formerly xpBtePoisonError) */
+       xpRETIRED5,             /* 31: (formerly xpBteWriteError) */
+       xpRETIRED6,             /* 32: (formerly xpBteAccessError) */
+       xpRETIRED7,             /* 33: (formerly xpBtePWriteError) */
+       xpRETIRED8,             /* 34: (formerly xpBtePReadError) */
+       xpRETIRED9,             /* 35: (formerly xpBteTimeOutError) */
+       xpRETIRED10,            /* 36: (formerly xpBteXtalkError) */
+       xpRETIRED11,            /* 37: (formerly xpBteNotAvailable) */
+       xpRETIRED12,            /* 38: (formerly xpBteUnmappedError) */
 
-       xpcBadVersion,          /* 39: bad version number */
-       xpcVarsNotSet,          /* 40: the XPC variables are not set up */
-       xpcNoRsvdPageAddr,      /* 41: unable to get rsvd page's phys addr */
-       xpcInvalidPartid,       /* 42: invalid partition ID */
-       xpcLocalPartid,         /* 43: local partition ID */
+       xpBadVersion,           /* 39: bad version number */
+       xpVarsNotSet,           /* 40: the XPC variables are not set up */
+       xpNoRsvdPageAddr,       /* 41: unable to get rsvd page's phys addr */
+       xpInvalidPartid,        /* 42: invalid partition ID */
+       xpLocalPartid,          /* 43: local partition ID */
 
-       xpcOtherGoingDown,      /* 44: other side going down, reason unknown */
-       xpcSystemGoingDown,     /* 45: system is going down, reason unknown */
-       xpcSystemHalt,          /* 46: system is being halted */
-       xpcSystemReboot,        /* 47: system is being rebooted */
-       xpcSystemPoweroff,      /* 48: system is being powered off */
+       xpOtherGoingDown,       /* 44: other side going down, reason unknown */
+       xpSystemGoingDown,      /* 45: system is going down, reason unknown */
+       xpSystemHalt,           /* 46: system is being halted */
+       xpSystemReboot,         /* 47: system is being rebooted */
+       xpSystemPoweroff,       /* 48: system is being powered off */
 
-       xpcDisconnecting,       /* 49: channel disconnecting (closing) */
+       xpDisconnecting,        /* 49: channel disconnecting (closing) */
 
-       xpcOpenCloseError,      /* 50: channel open/close protocol error */
+       xpOpenCloseError,       /* 50: channel open/close protocol error */
 
-       xpcDisconnected,        /* 51: channel disconnected (closed) */
+       xpDisconnected,         /* 51: channel disconnected (closed) */
 
-       xpcBteSh2Start,         /* 52: BTE CRB timeout */
+       xpBteCopyError,         /* 52: bte_copy() returned error */
 
-                               /* 53: 0x1 BTE Error Response Short */
-       xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT,
-
-                               /* 54: 0x2 BTE Error Response Long */
-       xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG,
-
-                               /* 56: 0x4 BTE Error Response DSB */
-       xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP,
-
-                               /* 60: 0x8 BTE Error Response Access */
-       xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS,
-
-                               /* 68: 0x10 BTE Error CRB timeout */
-       xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO,
-
-                               /* 84: 0x20 BTE Error NACK limit */
-       xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT,
-
-                               /* 115: BTE end */
-       xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL,
-
-       xpcUnknownReason        /* 116: unknown reason - must be last in enum */
+       xpUnknownReason         /* 53: unknown reason - must be last in enum */
 };
 
 /*
- * Define the callout function types used by XPC to update the user on
- * connection activity and state changes (via the user function registered by
- * xpc_connect()) and to notify them of messages received and delivered (via
- * the user function registered by xpc_send_notify()).
- *
- * The two function types are xpc_channel_func and xpc_notify_func and
- * both share the following arguments, with the exception of "data", which
- * only xpc_channel_func has.
+ * Define the callout function type used by XPC to update the user on
+ * connection activity and state changes via the user function registered
+ * by xpc_connect().
  *
  * Arguments:
  *
- *     reason - reason code. (See following table.)
+ *     reason - reason code.
  *     partid - partition ID associated with condition.
  *     ch_number - channel # associated with condition.
- *     data - pointer to optional data. (See following table.)
+ *     data - pointer to optional data.
  *     key - pointer to optional user-defined value provided as the "key"
- *           argument to xpc_connect() or xpc_send_notify().
+ *           argument to xpc_connect().
  *
- * In the following table the "Optional Data" column applies to callouts made
- * to functions registered by xpc_connect(). A "NA" in that column indicates
- * that this reason code can be passed to functions registered by
- * xpc_send_notify() (i.e. they don't have data arguments).
+ * A reason code of xpConnected indicates that a connection has been
+ * established to the specified partition on the specified channel. The data
+ * argument indicates the max number of entries allowed in the message queue.
  *
- * Also, the first three reason codes in the following table indicate
- * success, whereas the others indicate failure. When a failure reason code
- * is received, one can assume that the channel is not connected.
+ * A reason code of xpMsgReceived indicates that a XPC message arrived from
+ * the specified partition on the specified channel. The data argument
+ * specifies the address of the message's payload. The user must call
+ * xpc_received() when finished with the payload.
  *
- *
- * Reason Code          | Cause                          | Optional Data
- * =====================+================================+=====================
- * xpcConnected         | connection has been established| max #of entries
- *                      | to the specified partition on  | allowed in message
- *                      | the specified channel          | queue
- * ---------------------+--------------------------------+---------------------
- * xpcMsgReceived       | an XPC message arrived from    | address of payload
- *                      | the specified partition on the |
- *                      | specified channel              | [the user must call
- *                      |                                | xpc_received() when
- *                      |                                | finished with the
- *                      |                                | payload]
- * ---------------------+--------------------------------+---------------------
- * xpcMsgDelivered      | notification that the message  | NA
- *                      | was delivered to the intended  |
- *                      | recipient and that they have   |
- *                      | acknowledged its receipt by    |
- *                      | calling xpc_received()         |
- * =====================+================================+=====================
- * xpcUnequalMsgSizes   | can't connect to the specified | NULL
- *                      | partition on the specified     |
- *                      | channel because of mismatched  |
- *                      | message sizes                  |
- * ---------------------+--------------------------------+---------------------
- * xpcNoMemory          | insufficient memory avaiable   | NULL
- *                      | to allocate message queue      |
- * ---------------------+--------------------------------+---------------------
- * xpcLackOfResources   | lack of resources to create    | NULL
- *                      | the necessary kthreads to      |
- *                      | support the channel            |
- * ---------------------+--------------------------------+---------------------
- * xpcUnregistering     | this side's user has           | NULL or NA
- *                      | unregistered by calling        |
- *                      | xpc_disconnect()               |
- * ---------------------+--------------------------------+---------------------
- * xpcOtherUnregistering| the other side's user has      | NULL or NA
- *                      | unregistered by calling        |
- *                      | xpc_disconnect()               |
- * ---------------------+--------------------------------+---------------------
- * xpcNoHeartbeat       | the other side's XPC is no     | NULL or NA
- *                      | longer heartbeating            |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcUnloading         | this side's XPC module is      | NULL or NA
- *                      | being unloaded                 |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcOtherUnloading    | the other side's XPC module is | NULL or NA
- *                      | is being unloaded              |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcPioReadError      | xp_nofault_PIOR() returned an  | NULL or NA
- *                      | error while sending an IPI     |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcInvalidAddress    | the address either received or | NULL or NA
- *                      | sent by the specified partition|
- *                      | is invalid                     |
- * ---------------------+--------------------------------+---------------------
- * xpcBteNotAvailable   | attempt to pull data from the  | NULL or NA
- * xpcBtePoisonError    | specified partition over the   |
- * xpcBteWriteError     | specified channel via a        |
- * xpcBteAccessError    | bte_copy() failed              |
- * xpcBteTimeOutError   |                                |
- * xpcBteXtalkError     |                                |
- * xpcBteDirectoryError |                                |
- * xpcBteGenericError   |                                |
- * xpcBteUnmappedError  |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcUnknownReason     | the specified channel to the   | NULL or NA
- *                      | specified partition was        |
- *                      | unavailable for unknown reasons|
- * =====================+================================+=====================
+ * All other reason codes indicate failure. The data argmument is NULL.
+ * When a failure reason code is received, one can assume that the channel
+ * is not connected.
  */
-
-typedef void (*xpc_channel_func) (enum xpc_retval reason, partid_t partid,
+typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
                                  int ch_number, void *data, void *key);
 
-typedef void (*xpc_notify_func) (enum xpc_retval reason, partid_t partid,
+/*
+ * Define the callout function type used by XPC to notify the user of
+ * messages received and delivered via the user function registered by
+ * xpc_send_notify().
+ *
+ * Arguments:
+ *
+ *     reason - reason code.
+ *     partid - partition ID associated with condition.
+ *     ch_number - channel # associated with condition.
+ *     key - pointer to optional user-defined value provided as the "key"
+ *           argument to xpc_send_notify().
+ *
+ * A reason code of xpMsgDelivered indicates that the message was delivered
+ * to the intended recipient and that they have acknowledged its receipt by
+ * calling xpc_received().
+ *
+ * All other reason codes indicate failure.
+ */
+typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
                                 int ch_number, void *key);
 
 /*
@@ -401,57 +322,57 @@ struct xpc_registration {
 struct xpc_interface {
        void (*connect) (int);
        void (*disconnect) (int);
-       enum xpc_retval (*allocate) (partid_t, int, u32, void **);
-       enum xpc_retval (*send) (partid_t, int, void *);
-       enum xpc_retval (*send_notify) (partid_t, int, void *,
+       enum xp_retval (*allocate) (short, int, u32, void **);
+       enum xp_retval (*send) (short, int, void *);
+       enum xp_retval (*send_notify) (short, int, void *,
                                        xpc_notify_func, void *);
-       void (*received) (partid_t, int, void *);
-       enum xpc_retval (*partid_to_nasids) (partid_t, void *);
+       void (*received) (short, int, void *);
+       enum xp_retval (*partid_to_nasids) (short, void *);
 };
 
 extern struct xpc_interface xpc_interface;
 
 extern void xpc_set_interface(void (*)(int),
                              void (*)(int),
-                             enum xpc_retval (*)(partid_t, int, u32, void **),
-                             enum xpc_retval (*)(partid_t, int, void *),
-                             enum xpc_retval (*)(partid_t, int, void *,
+                             enum xp_retval (*)(short, int, u32, void **),
+                             enum xp_retval (*)(short, int, void *),
+                             enum xp_retval (*)(short, int, void *,
                                                  xpc_notify_func, void *),
-                             void (*)(partid_t, int, void *),
-                             enum xpc_retval (*)(partid_t, void *));
+                             void (*)(short, int, void *),
+                             enum xp_retval (*)(short, void *));
 extern void xpc_clear_interface(void);
 
-extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
+extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
                                   u16, u32, u32);
 extern void xpc_disconnect(int);
 
-static inline enum xpc_retval
-xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+static inline enum xp_retval
+xpc_allocate(short partid, int ch_number, u32 flags, void **payload)
 {
        return xpc_interface.allocate(partid, ch_number, flags, payload);
 }
 
-static inline enum xpc_retval
-xpc_send(partid_t partid, int ch_number, void *payload)
+static inline enum xp_retval
+xpc_send(short partid, int ch_number, void *payload)
 {
        return xpc_interface.send(partid, ch_number, payload);
 }
 
-static inline enum xpc_retval
-xpc_send_notify(partid_t partid, int ch_number, void *payload,
+static inline enum xp_retval
+xpc_send_notify(short partid, int ch_number, void *payload,
                xpc_notify_func func, void *key)
 {
        return xpc_interface.send_notify(partid, ch_number, payload, func, key);
 }
 
 static inline void
-xpc_received(partid_t partid, int ch_number, void *payload)
+xpc_received(short partid, int ch_number, void *payload)
 {
        return xpc_interface.received(partid, ch_number, payload);
 }
 
-static inline enum xpc_retval
-xpc_partid_to_nasids(partid_t partid, void *nasids)
+static inline enum xp_retval
+xpc_partid_to_nasids(short partid, void *nasids)
 {
        return xpc_interface.partid_to_nasids(partid, nasids);
 }
index 1fbf99bae963a8cd49008b26bbbb81c0790ee6d1..196480b691a11c216e8601e61fdae213cd3d8bab 100644 (file)
@@ -42,21 +42,21 @@ EXPORT_SYMBOL_GPL(xpc_registrations);
 /*
  * Initialize the XPC interface to indicate that XPC isn't loaded.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_notloaded(void)
 {
-       return xpcNotLoaded;
+       return xpNotLoaded;
 }
 
 struct xpc_interface xpc_interface = {
        (void (*)(int))xpc_notloaded,
        (void (*)(int))xpc_notloaded,
-       (enum xpc_retval(*)(partid_t, int, u32, void **))xpc_notloaded,
-       (enum xpc_retval(*)(partid_t, int, void *))xpc_notloaded,
-       (enum xpc_retval(*)(partid_t, int, void *, xpc_notify_func, void *))
+       (enum xp_retval(*)(short, int, u32, void **))xpc_notloaded,
+       (enum xp_retval(*)(short, int, void *))xpc_notloaded,
+       (enum xp_retval(*)(short, int, void *, xpc_notify_func, void *))
            xpc_notloaded,
-       (void (*)(partid_t, int, void *))xpc_notloaded,
-       (enum xpc_retval(*)(partid_t, void *))xpc_notloaded
+       (void (*)(short, int, void *))xpc_notloaded,
+       (enum xp_retval(*)(short, void *))xpc_notloaded
 };
 EXPORT_SYMBOL_GPL(xpc_interface);
 
@@ -66,12 +66,12 @@ EXPORT_SYMBOL_GPL(xpc_interface);
 void
 xpc_set_interface(void (*connect) (int),
                  void (*disconnect) (int),
-                 enum xpc_retval (*allocate) (partid_t, int, u32, void **),
-                 enum xpc_retval (*send) (partid_t, int, void *),
-                 enum xpc_retval (*send_notify) (partid_t, int, void *,
+                 enum xp_retval (*allocate) (short, int, u32, void **),
+                 enum xp_retval (*send) (short, int, void *),
+                 enum xp_retval (*send_notify) (short, int, void *,
                                                  xpc_notify_func, void *),
-                 void (*received) (partid_t, int, void *),
-                 enum xpc_retval (*partid_to_nasids) (partid_t, void *))
+                 void (*received) (short, int, void *),
+                 enum xp_retval (*partid_to_nasids) (short, void *))
 {
        xpc_interface.connect = connect;
        xpc_interface.disconnect = disconnect;
@@ -91,16 +91,16 @@ xpc_clear_interface(void)
 {
        xpc_interface.connect = (void (*)(int))xpc_notloaded;
        xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
-       xpc_interface.allocate = (enum xpc_retval(*)(partid_t, int, u32,
+       xpc_interface.allocate = (enum xp_retval(*)(short, int, u32,
                                                     void **))xpc_notloaded;
-       xpc_interface.send = (enum xpc_retval(*)(partid_t, int, void *))
+       xpc_interface.send = (enum xp_retval(*)(short, int, void *))
            xpc_notloaded;
-       xpc_interface.send_notify = (enum xpc_retval(*)(partid_t, int, void *,
+       xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *,
                                                        xpc_notify_func,
                                                        void *))xpc_notloaded;
-       xpc_interface.received = (void (*)(partid_t, int, void *))
+       xpc_interface.received = (void (*)(short, int, void *))
            xpc_notloaded;
-       xpc_interface.partid_to_nasids = (enum xpc_retval(*)(partid_t, void *))
+       xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
            xpc_notloaded;
 }
 EXPORT_SYMBOL_GPL(xpc_clear_interface);
@@ -123,13 +123,13 @@ EXPORT_SYMBOL_GPL(xpc_clear_interface);
  *     nentries - max #of XPC message entries a message queue can contain.
  *                The actual number, which is determined when a connection
  *                is established and may be less then requested, will be
- *                passed to the user via the xpcConnected callout.
+ *                passed to the user via the xpConnected callout.
  *     assigned_limit - max number of kthreads allowed to be processing
  *                      messages (per connection) at any given instant.
  *     idle_limit - max number of kthreads allowed to be idle at any given
  *                  instant.
  */
-enum xpc_retval
+enum xp_retval
 xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
            u16 nentries, u32 assigned_limit, u32 idle_limit)
 {
@@ -143,12 +143,12 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
        registration = &xpc_registrations[ch_number];
 
        if (mutex_lock_interruptible(&registration->mutex) != 0)
-               return xpcInterrupted;
+               return xpInterrupted;
 
        /* if XPC_CHANNEL_REGISTERED(ch_number) */
        if (registration->func != NULL) {
                mutex_unlock(&registration->mutex);
-               return xpcAlreadyRegistered;
+               return xpAlreadyRegistered;
        }
 
        /* register the channel for connection */
@@ -163,7 +163,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
 
        xpc_interface.connect(ch_number);
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 EXPORT_SYMBOL_GPL(xpc_connect);
 
index 9eb6d4a3269cc584f427dde437b380a7b727718d..11ac267ed68fcca68a47c5e09647e55e525d5a5c 100644 (file)
@@ -172,13 +172,13 @@ struct xpc_vars {
                        (_version >= _XPC_VERSION(3, 1))
 
 static inline int
-xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
+xpc_hb_allowed(short partid, struct xpc_vars *vars)
 {
        return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
 }
 
 static inline void
-xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_allow_hb(short partid, struct xpc_vars *vars)
 {
        u64 old_mask, new_mask;
 
@@ -190,7 +190,7 @@ xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
 }
 
 static inline void
-xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_disallow_hb(short partid, struct xpc_vars *vars)
 {
        u64 old_mask, new_mask;
 
@@ -408,11 +408,11 @@ struct xpc_notify {
  *     messages.
  */
 struct xpc_channel {
-       partid_t partid;        /* ID of remote partition connected */
+       short partid;           /* ID of remote partition connected */
        spinlock_t lock;        /* lock for updating this structure */
        u32 flags;              /* general flags */
 
-       enum xpc_retval reason; /* reason why channel is disconnect'g */
+       enum xp_retval reason;  /* reason why channel is disconnect'g */
        int reason_line;        /* line# disconnect initiated from */
 
        u16 number;             /* channel # */
@@ -522,7 +522,7 @@ struct xpc_partition {
        spinlock_t act_lock;    /* protect updating of act_state */
        u8 act_state;           /* from XPC HB viewpoint */
        u8 remote_vars_version; /* version# of partition's vars */
-       enum xpc_retval reason; /* reason partition is deactivating */
+       enum xp_retval reason;  /* reason partition is deactivating */
        int reason_line;        /* line# deactivation initiated from */
        int reactivate_nasid;   /* nasid in partition to reactivate */
 
@@ -615,7 +615,7 @@ struct xpc_partition {
 /* interval in seconds to print 'waiting disengagement' messages */
 #define XPC_DISENGAGE_PRINTMSG_INTERVAL                10
 
-#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
+#define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
 
 /* found in xp_main.c */
 extern struct xpc_registration xpc_registrations[];
@@ -646,31 +646,31 @@ extern void xpc_allow_IPI_ops(void);
 extern void xpc_restrict_IPI_ops(void);
 extern int xpc_identify_act_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
-extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
+extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
 extern void xpc_discovery(void);
 extern void xpc_check_remote_hb(void);
 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
-                                    enum xpc_retval);
-extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
+                                    enum xp_retval);
+extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
 
 /* found in xpc_channel.c */
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
-extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
-extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
-extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
-                                               xpc_notify_func, void *);
-extern void xpc_initiate_received(partid_t, int, void *);
-extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
-extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
+extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
+extern enum xp_retval xpc_initiate_send(short, int, void *);
+extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
+                                              xpc_notify_func, void *);
+extern void xpc_initiate_received(short, int, void *);
+extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
+extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
 extern void xpc_process_channel_activity(struct xpc_partition *);
 extern void xpc_connected_callout(struct xpc_channel *);
 extern void xpc_deliver_msg(struct xpc_channel *);
 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
-                                  enum xpc_retval, unsigned long *);
-extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
-extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
+                                  enum xp_retval, unsigned long *);
+extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
+extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 extern void xpc_teardown_infrastructure(struct xpc_partition *);
 
 static inline void
@@ -901,7 +901,7 @@ xpc_IPI_receive(AMO_t *amo)
        return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
 }
 
-static inline enum xpc_retval
+static inline enum xp_retval
 xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
 {
        int ret = 0;
@@ -923,7 +923,7 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
 
        local_irq_restore(irq_flags);
 
-       return ((ret == 0) ? xpcSuccess : xpcPioReadError);
+       return ((ret == 0) ? xpSuccess : xpPioReadError);
 }
 
 /*
@@ -992,7 +992,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
                    unsigned long *irq_flags)
 {
        struct xpc_partition *part = &xpc_partitions[ch->partid];
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        if (likely(part->act_state != XPC_P_DEACTIVATING)) {
                ret = xpc_IPI_send(part->remote_IPI_amo_va,
@@ -1001,7 +1001,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
                                   part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
                dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
                        ipi_flag_string, ch->partid, ch->number, ret);
-               if (unlikely(ret != xpcSuccess)) {
+               if (unlikely(ret != xpSuccess)) {
                        if (irq_flags != NULL)
                                spin_unlock_irqrestore(&ch->lock, *irq_flags);
                        XPC_DEACTIVATE_PARTITION(part, ret);
@@ -1123,41 +1123,10 @@ xpc_IPI_init(int index)
        return amo;
 }
 
-static inline enum xpc_retval
+static inline enum xp_retval
 xpc_map_bte_errors(bte_result_t error)
 {
-       if (error == BTE_SUCCESS)
-               return xpcSuccess;
-
-       if (is_shub2()) {
-               if (BTE_VALID_SH2_ERROR(error))
-                       return xpcBteSh2Start + error;
-               return xpcBteUnmappedError;
-       }
-       switch (error) {
-       case BTE_SUCCESS:
-               return xpcSuccess;
-       case BTEFAIL_DIR:
-               return xpcBteDirectoryError;
-       case BTEFAIL_POISON:
-               return xpcBtePoisonError;
-       case BTEFAIL_WERR:
-               return xpcBteWriteError;
-       case BTEFAIL_ACCESS:
-               return xpcBteAccessError;
-       case BTEFAIL_PWERR:
-               return xpcBtePWriteError;
-       case BTEFAIL_PRERR:
-               return xpcBtePReadError;
-       case BTEFAIL_TOUT:
-               return xpcBteTimeOutError;
-       case BTEFAIL_XTERR:
-               return xpcBteXtalkError;
-       case BTEFAIL_NOTAVAIL:
-               return xpcBteNotAvailable;
-       default:
-               return xpcBteUnmappedError;
-       }
+       return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
 }
 
 /*
index bfcb9ea968e9e15aee9cf31c63fac58f8193adef..9c90c2d55c081172dc5ebcc9dbaa0ff15f20b888 100644 (file)
@@ -53,7 +53,7 @@ xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
  * Set up the initial values for the XPartition Communication channels.
  */
 static void
-xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
+xpc_initialize_channels(struct xpc_partition *part, short partid)
 {
        int ch_number;
        struct xpc_channel *ch;
@@ -90,12 +90,12 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
  * Setup the infrastructure necessary to support XPartition Communication
  * between the specified remote partition and the local one.
  */
-enum xpc_retval
+enum xp_retval
 xpc_setup_infrastructure(struct xpc_partition *part)
 {
        int ret, cpuid;
        struct timer_list *timer;
-       partid_t partid = XPC_PARTID(part);
+       short partid = XPC_PARTID(part);
 
        /*
         * Zero out MOST of the entry for this partition. Only the fields
@@ -114,7 +114,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                                 GFP_KERNEL);
        if (part->channels == NULL) {
                dev_err(xpc_chan, "can't get memory for channels\n");
-               return xpcNoMemory;
+               return xpNoMemory;
        }
 
        part->nchannels = XPC_NCHANNELS;
@@ -129,7 +129,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                part->channels = NULL;
                dev_err(xpc_chan, "can't get memory for local get/put "
                        "values\n");
-               return xpcNoMemory;
+               return xpNoMemory;
        }
 
        part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
@@ -143,7 +143,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                part->local_GPs = NULL;
                kfree(part->channels);
                part->channels = NULL;
-               return xpcNoMemory;
+               return xpNoMemory;
        }
 
        /* allocate all the required open and close args */
@@ -159,7 +159,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                part->local_GPs = NULL;
                kfree(part->channels);
                part->channels = NULL;
-               return xpcNoMemory;
+               return xpNoMemory;
        }
 
        part->remote_openclose_args =
@@ -175,7 +175,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                part->local_GPs = NULL;
                kfree(part->channels);
                part->channels = NULL;
-               return xpcNoMemory;
+               return xpNoMemory;
        }
 
        xpc_initialize_channels(part, partid);
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
                part->local_GPs = NULL;
                kfree(part->channels);
                part->channels = NULL;
-               return xpcLackOfResources;
+               return xpLackOfResources;
        }
 
        /* Setup a timer to check for dropped IPIs */
@@ -243,7 +243,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
        xpc_vars_part[partid].nchannels = part->nchannels;
        xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -254,7 +254,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
  * dst must be a cacheline aligned virtual address on this partition.
  * cnt must be an cacheline sized
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
                           const void *src, size_t cnt)
 {
@@ -270,7 +270,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
        bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt,
                              (BTE_NORMAL | BTE_WACQUIRE), NULL);
        if (bte_ret == BTE_SUCCESS)
-               return xpcSuccess;
+               return xpSuccess;
 
        dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
                XPC_PARTID(part), bte_ret);
@@ -282,7 +282,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
  * Pull the remote per partition specific variables from the specified
  * partition.
  */
-enum xpc_retval
+enum xp_retval
 xpc_pull_remote_vars_part(struct xpc_partition *part)
 {
        u8 buffer[L1_CACHE_BYTES * 2];
@@ -290,8 +290,8 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
            (struct xpc_vars_part *)L1_CACHE_ALIGN((u64)buffer);
        struct xpc_vars_part *pulled_entry;
        u64 remote_entry_cacheline_pa, remote_entry_pa;
-       partid_t partid = XPC_PARTID(part);
-       enum xpc_retval ret;
+       short partid = XPC_PARTID(part);
+       enum xp_retval ret;
 
        /* pull the cacheline that contains the variables we're interested in */
 
@@ -311,7 +311,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
        ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline,
                                         (void *)remote_entry_cacheline_pa,
                                         L1_CACHE_BYTES);
-       if (ret != xpcSuccess) {
+       if (ret != xpSuccess) {
                dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
                        "partition %d, ret=%d\n", partid, ret);
                return ret;
@@ -326,11 +326,11 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
                        dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
                                "partition %d has bad magic value (=0x%lx)\n",
                                partid, sn_partition_id, pulled_entry->magic);
-                       return xpcBadMagic;
+                       return xpBadMagic;
                }
 
                /* they've not been initialized yet */
-               return xpcRetry;
+               return xpRetry;
        }
 
        if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
@@ -344,7 +344,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
                        dev_err(xpc_chan, "partition %d's XPC vars_part for "
                                "partition %d are not valid\n", partid,
                                sn_partition_id);
-                       return xpcInvalidAddress;
+                       return xpInvalidAddress;
                }
 
                /* the variables we imported look to be valid */
@@ -366,9 +366,9 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
        }
 
        if (pulled_entry->magic == XPC_VP_MAGIC1)
-               return xpcRetry;
+               return xpRetry;
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -379,7 +379,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
 {
        unsigned long irq_flags;
        u64 IPI_amo;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        /*
         * See if there are any IPI flags to be handled.
@@ -398,7 +398,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
                                                 (void *)part->
                                                 remote_openclose_args_pa,
                                                 XPC_OPENCLOSE_ARGS_SIZE);
-               if (ret != xpcSuccess) {
+               if (ret != xpSuccess) {
                        XPC_DEACTIVATE_PARTITION(part, ret);
 
                        dev_dbg(xpc_chan, "failed to pull openclose args from "
@@ -414,7 +414,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
                ret = xpc_pull_remote_cachelines(part, part->remote_GPs,
                                                 (void *)part->remote_GPs_pa,
                                                 XPC_GP_SIZE);
-               if (ret != xpcSuccess) {
+               if (ret != xpSuccess) {
                        XPC_DEACTIVATE_PARTITION(part, ret);
 
                        dev_dbg(xpc_chan, "failed to pull GPs from partition "
@@ -431,7 +431,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
 /*
  * Allocate the local message queue and the notify queue.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_local_msgqueue(struct xpc_channel *ch)
 {
        unsigned long irq_flags;
@@ -464,18 +464,18 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
                        ch->local_nentries = nentries;
                }
                spin_unlock_irqrestore(&ch->lock, irq_flags);
-               return xpcSuccess;
+               return xpSuccess;
        }
 
        dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
                "queue, partid=%d, channel=%d\n", ch->partid, ch->number);
-       return xpcNoMemory;
+       return xpNoMemory;
 }
 
 /*
  * Allocate the cached remote message queue.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
 {
        unsigned long irq_flags;
@@ -502,12 +502,12 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
                        ch->remote_nentries = nentries;
                }
                spin_unlock_irqrestore(&ch->lock, irq_flags);
-               return xpcSuccess;
+               return xpSuccess;
        }
 
        dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
                "partid=%d, channel=%d\n", ch->partid, ch->number);
-       return xpcNoMemory;
+       return xpNoMemory;
 }
 
 /*
@@ -515,20 +515,20 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
  *
  * Note: Assumes all of the channel sizes are filled in.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msgqueues(struct xpc_channel *ch)
 {
        unsigned long irq_flags;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        DBUG_ON(ch->flags & XPC_C_SETUP);
 
        ret = xpc_allocate_local_msgqueue(ch);
-       if (ret != xpcSuccess)
+       if (ret != xpSuccess)
                return ret;
 
        ret = xpc_allocate_remote_msgqueue(ch);
-       if (ret != xpcSuccess) {
+       if (ret != xpSuccess) {
                kfree(ch->local_msgqueue_base);
                ch->local_msgqueue = NULL;
                kfree(ch->notify_queue);
@@ -540,7 +540,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
        ch->flags |= XPC_C_SETUP;
        spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -552,7 +552,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
 static void
 xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
 {
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        DBUG_ON(!spin_is_locked(&ch->lock));
 
@@ -568,7 +568,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
                ret = xpc_allocate_msgqueues(ch);
                spin_lock_irqsave(&ch->lock, *irq_flags);
 
-               if (ret != xpcSuccess)
+               if (ret != xpSuccess)
                        XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
 
                if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
@@ -603,7 +603,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
  * Notify those who wanted to be notified upon delivery of their message.
  */
 static void
-xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
+xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
 {
        struct xpc_notify *notify;
        u8 notify_type;
@@ -748,7 +748,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 
        if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
                spin_unlock_irqrestore(&ch->lock, *irq_flags);
-               xpc_disconnect_callout(ch, xpcDisconnected);
+               xpc_disconnect_callout(ch, xpDisconnected);
                spin_lock_irqsave(&ch->lock, *irq_flags);
        }
 
@@ -791,7 +791,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
        struct xpc_openclose_args *args =
            &part->remote_openclose_args[ch_number];
        struct xpc_channel *ch = &part->channels[ch_number];
-       enum xpc_retval reason;
+       enum xp_retval reason;
 
        spin_lock_irqsave(&ch->lock, irq_flags);
 
@@ -871,10 +871,10 @@ again:
 
                if (!(ch->flags & XPC_C_DISCONNECTING)) {
                        reason = args->reason;
-                       if (reason <= xpcSuccess || reason > xpcUnknownReason)
-                               reason = xpcUnknownReason;
-                       else if (reason == xpcUnregistering)
-                               reason = xpcOtherUnregistering;
+                       if (reason <= xpSuccess || reason > xpUnknownReason)
+                               reason = xpUnknownReason;
+                       else if (reason == xpUnregistering)
+                               reason = xpOtherUnregistering;
 
                        XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
 
@@ -961,7 +961,7 @@ again:
 
                if (ch->flags & XPC_C_OPENREQUEST) {
                        if (args->msg_size != ch->msg_size) {
-                               XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+                               XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
                                                       &irq_flags);
                                spin_unlock_irqrestore(&ch->lock, irq_flags);
                                return;
@@ -991,7 +991,7 @@ again:
                        return;
                }
                if (!(ch->flags & XPC_C_OPENREQUEST)) {
-                       XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError,
+                       XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
                                               &irq_flags);
                        spin_unlock_irqrestore(&ch->lock, irq_flags);
                        return;
@@ -1042,18 +1042,18 @@ again:
 /*
  * Attempt to establish a channel connection to a remote partition.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_connect_channel(struct xpc_channel *ch)
 {
        unsigned long irq_flags;
        struct xpc_registration *registration = &xpc_registrations[ch->number];
 
        if (mutex_trylock(&registration->mutex) == 0)
-               return xpcRetry;
+               return xpRetry;
 
        if (!XPC_CHANNEL_REGISTERED(ch->number)) {
                mutex_unlock(&registration->mutex);
-               return xpcUnregistered;
+               return xpUnregistered;
        }
 
        spin_lock_irqsave(&ch->lock, irq_flags);
@@ -1095,10 +1095,10 @@ xpc_connect_channel(struct xpc_channel *ch)
                         * the channel lock as needed.
                         */
                        mutex_unlock(&registration->mutex);
-                       XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+                       XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
                                               &irq_flags);
                        spin_unlock_irqrestore(&ch->lock, irq_flags);
-                       return xpcUnequalMsgSizes;
+                       return xpUnequalMsgSizes;
                }
        } else {
                ch->msg_size = registration->msg_size;
@@ -1120,7 +1120,7 @@ xpc_connect_channel(struct xpc_channel *ch)
 
        spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -1203,7 +1203,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
                         * Notify senders that messages sent have been
                         * received and delivered by the other side.
                         */
-                       xpc_notify_senders(ch, xpcMsgDelivered,
+                       xpc_notify_senders(ch, xpMsgDelivered,
                                           ch->remote_GP.get);
                }
 
@@ -1335,7 +1335,7 @@ xpc_process_channel_activity(struct xpc_partition *part)
  * at the same time.
  */
 void
-xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
+xpc_partition_going_down(struct xpc_partition *part, enum xp_retval reason)
 {
        unsigned long irq_flags;
        int ch_number;
@@ -1375,7 +1375,7 @@ xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
 void
 xpc_teardown_infrastructure(struct xpc_partition *part)
 {
-       partid_t partid = XPC_PARTID(part);
+       short partid = XPC_PARTID(part);
 
        /*
         * We start off by making this partition inaccessible to local
@@ -1428,7 +1428,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part)
 void
 xpc_initiate_connect(int ch_number)
 {
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
        struct xpc_channel *ch;
 
@@ -1456,13 +1456,13 @@ xpc_connected_callout(struct xpc_channel *ch)
        /* let the registerer know that a connection has been established */
 
        if (ch->func != NULL) {
-               dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, "
+               dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, "
                        "partid=%d, channel=%d\n", ch->partid, ch->number);
 
-               ch->func(xpcConnected, ch->partid, ch->number,
+               ch->func(xpConnected, ch->partid, ch->number,
                         (void *)(u64)ch->local_nentries, ch->key);
 
-               dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
+               dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, "
                        "partid=%d, channel=%d\n", ch->partid, ch->number);
        }
 }
@@ -1484,7 +1484,7 @@ void
 xpc_initiate_disconnect(int ch_number)
 {
        unsigned long irq_flags;
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
        struct xpc_channel *ch;
 
@@ -1503,7 +1503,7 @@ xpc_initiate_disconnect(int ch_number)
                        if (!(ch->flags & XPC_C_DISCONNECTED)) {
                                ch->flags |= XPC_C_WDISCONNECT;
 
-                               XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
+                               XPC_DISCONNECT_CHANNEL(ch, xpUnregistering,
                                                       &irq_flags);
                        }
 
@@ -1528,7 +1528,7 @@ xpc_initiate_disconnect(int ch_number)
  */
 void
 xpc_disconnect_channel(const int line, struct xpc_channel *ch,
-                      enum xpc_retval reason, unsigned long *irq_flags)
+                      enum xp_retval reason, unsigned long *irq_flags)
 {
        u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
 
@@ -1563,7 +1563,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
 
        } else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
                   !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
-               /* start a kthread that will do the xpcDisconnecting callout */
+               /* start a kthread that will do the xpDisconnecting callout */
                xpc_create_kthreads(ch, 1, 1);
        }
 
@@ -1575,7 +1575,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
 }
 
 void
-xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
+xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason)
 {
        /*
         * Let the channel's registerer know that the channel is being
@@ -1598,13 +1598,13 @@ xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
  * Wait for a message entry to become available for the specified channel,
  * but don't wait any longer than 1 jiffy.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msg_wait(struct xpc_channel *ch)
 {
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        if (ch->flags & XPC_C_DISCONNECTING) {
-               DBUG_ON(ch->reason == xpcInterrupted);
+               DBUG_ON(ch->reason == xpInterrupted);
                return ch->reason;
        }
 
@@ -1614,11 +1614,11 @@ xpc_allocate_msg_wait(struct xpc_channel *ch)
 
        if (ch->flags & XPC_C_DISCONNECTING) {
                ret = ch->reason;
-               DBUG_ON(ch->reason == xpcInterrupted);
+               DBUG_ON(ch->reason == xpInterrupted);
        } else if (ret == 0) {
-               ret = xpcTimeout;
+               ret = xpTimeout;
        } else {
-               ret = xpcInterrupted;
+               ret = xpInterrupted;
        }
 
        return ret;
@@ -1628,12 +1628,12 @@ xpc_allocate_msg_wait(struct xpc_channel *ch)
  * Allocate an entry for a message from the message queue associated with the
  * specified channel.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
                 struct xpc_msg **address_of_msg)
 {
        struct xpc_msg *msg;
-       enum xpc_retval ret;
+       enum xp_retval ret;
        s64 put;
 
        /* this reference will be dropped in xpc_send_msg() */
@@ -1645,7 +1645,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
        }
        if (!(ch->flags & XPC_C_CONNECTED)) {
                xpc_msgqueue_deref(ch);
-               return xpcNotConnected;
+               return xpNotConnected;
        }
 
        /*
@@ -1653,7 +1653,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
         * If none are available, we'll make sure that we grab the latest
         * GP values.
         */
-       ret = xpcTimeout;
+       ret = xpTimeout;
 
        while (1) {
 
@@ -1683,16 +1683,16 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
                 * that will cause the IPI handler to fetch the latest
                 * GP values as if an IPI was sent by the other side.
                 */
-               if (ret == xpcTimeout)
+               if (ret == xpTimeout)
                        xpc_IPI_send_local_msgrequest(ch);
 
                if (flags & XPC_NOWAIT) {
                        xpc_msgqueue_deref(ch);
-                       return xpcNoWait;
+                       return xpNoWait;
                }
 
                ret = xpc_allocate_msg_wait(ch);
-               if (ret != xpcInterrupted && ret != xpcTimeout) {
+               if (ret != xpInterrupted && ret != xpTimeout) {
                        xpc_msgqueue_deref(ch);
                        return ret;
                }
@@ -1711,7 +1711,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
 
        *address_of_msg = msg;
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -1727,11 +1727,11 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
  *     payload - address of the allocated payload area pointer (filled in on
  *               return) in which the user-defined message is constructed.
  */
-enum xpc_retval
-xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+enum xp_retval
+xpc_initiate_allocate(short partid, int ch_number, u32 flags, void **payload)
 {
        struct xpc_partition *part = &xpc_partitions[partid];
-       enum xpc_retval ret = xpcUnknownReason;
+       enum xp_retval ret = xpUnknownReason;
        struct xpc_msg *msg = NULL;
 
        DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
@@ -1814,11 +1814,11 @@ xpc_send_msgs(struct xpc_channel *ch, s64 initial_put)
  * local message queue's Put value and sends an IPI to the partition the
  * message is being sent to.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
             xpc_notify_func func, void *key)
 {
-       enum xpc_retval ret = xpcSuccess;
+       enum xp_retval ret = xpSuccess;
        struct xpc_notify *notify = notify;
        s64 put, msg_number = msg->number;
 
@@ -1908,12 +1908,12 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
  *     payload - pointer to the payload area allocated via
  *                     xpc_initiate_allocate().
  */
-enum xpc_retval
-xpc_initiate_send(partid_t partid, int ch_number, void *payload)
+enum xp_retval
+xpc_initiate_send(short partid, int ch_number, void *payload)
 {
        struct xpc_partition *part = &xpc_partitions[partid];
        struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
                partid, ch_number);
@@ -1957,13 +1957,13 @@ xpc_initiate_send(partid_t partid, int ch_number, void *payload)
  *               receipt. THIS FUNCTION MUST BE NON-BLOCKING.
  *     key - user-defined key to be passed to the function when it's called.
  */
-enum xpc_retval
-xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload,
+enum xp_retval
+xpc_initiate_send_notify(short partid, int ch_number, void *payload,
                         xpc_notify_func func, void *key)
 {
        struct xpc_partition *part = &xpc_partitions[partid];
        struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
                partid, ch_number);
@@ -1985,7 +1985,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
        struct xpc_msg *remote_msg, *msg;
        u32 msg_index, nmsgs;
        u64 msg_offset;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
                /* we were interrupted by a signal */
@@ -2012,7 +2012,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
 
                ret = xpc_pull_remote_cachelines(part, msg, remote_msg,
                                                 nmsgs * ch->msg_size);
-               if (ret != xpcSuccess) {
+               if (ret != xpSuccess) {
 
                        dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
                                " msg %ld from partition %d, channel=%d, "
@@ -2112,7 +2112,7 @@ xpc_deliver_msg(struct xpc_channel *ch)
                                ch->number);
 
                        /* deliver the message to its intended recipient */
-                       ch->func(xpcMsgReceived, ch->partid, ch->number,
+                       ch->func(xpMsgReceived, ch->partid, ch->number,
                                 &msg->payload, ch->key);
 
                        dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
@@ -2203,7 +2203,7 @@ xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
  *                     xpc_initiate_allocate().
  */
 void
-xpc_initiate_received(partid_t partid, int ch_number, void *payload)
+xpc_initiate_received(short partid, int ch_number, void *payload)
 {
        struct xpc_partition *part = &xpc_partitions[partid];
        struct xpc_channel *ch;
index f673ba90eb0eb2ab68187e00b723431f15d90389..08256ed0d9a6ffdf42ada557d715d88925d6cbbc 100644 (file)
@@ -315,13 +315,13 @@ xpc_initiate_discovery(void *ignore)
  * the XPC per partition variables from the remote partition and waiting for
  * the remote partition to pull ours.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_make_first_contact(struct xpc_partition *part)
 {
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
-       while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) {
-               if (ret != xpcRetry) {
+       while ((ret = xpc_pull_remote_vars_part(part)) != xpSuccess) {
+               if (ret != xpRetry) {
                        XPC_DEACTIVATE_PARTITION(part, ret);
                        return ret;
                }
@@ -406,7 +406,7 @@ xpc_partition_up(struct xpc_partition *part)
 
        dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part));
 
-       if (xpc_setup_infrastructure(part) != xpcSuccess)
+       if (xpc_setup_infrastructure(part) != xpSuccess)
                return;
 
        /*
@@ -418,7 +418,7 @@ xpc_partition_up(struct xpc_partition *part)
 
        (void)xpc_part_ref(part);       /* this will always succeed */
 
-       if (xpc_make_first_contact(part) == xpcSuccess)
+       if (xpc_make_first_contact(part) == xpSuccess)
                xpc_channel_mgr(part);
 
        xpc_part_deref(part);
@@ -429,7 +429,7 @@ xpc_partition_up(struct xpc_partition *part)
 static int
 xpc_activating(void *__partid)
 {
-       partid_t partid = (u64)__partid;
+       short partid = (u64)__partid;
        struct xpc_partition *part = &xpc_partitions[partid];
        unsigned long irq_flags;
 
@@ -470,7 +470,7 @@ xpc_activating(void *__partid)
 
                spin_lock_irqsave(&part->act_lock, irq_flags);
                part->act_state = XPC_P_INACTIVE;
-               XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__);
+               XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__);
                spin_unlock_irqrestore(&part->act_lock, irq_flags);
                part->remote_rp_pa = 0;
                return 0;
@@ -488,7 +488,7 @@ xpc_activating(void *__partid)
        xpc_disallow_hb(partid, xpc_vars);
        xpc_mark_partition_inactive(part);
 
-       if (part->reason == xpcReactivating) {
+       if (part->reason == xpReactivating) {
                /* interrupting ourselves results in activating partition */
                xpc_IPI_send_reactivate(part);
        }
@@ -499,7 +499,7 @@ xpc_activating(void *__partid)
 void
 xpc_activate_partition(struct xpc_partition *part)
 {
-       partid_t partid = XPC_PARTID(part);
+       short partid = XPC_PARTID(part);
        unsigned long irq_flags;
        struct task_struct *kthread;
 
@@ -508,7 +508,7 @@ xpc_activate_partition(struct xpc_partition *part)
        DBUG_ON(part->act_state != XPC_P_INACTIVE);
 
        part->act_state = XPC_P_ACTIVATION_REQ;
-       XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
+       XPC_SET_REASON(part, xpCloneKThread, __LINE__);
 
        spin_unlock_irqrestore(&part->act_lock, irq_flags);
 
@@ -517,7 +517,7 @@ xpc_activate_partition(struct xpc_partition *part)
        if (IS_ERR(kthread)) {
                spin_lock_irqsave(&part->act_lock, irq_flags);
                part->act_state = XPC_P_INACTIVE;
-               XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+               XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__);
                spin_unlock_irqrestore(&part->act_lock, irq_flags);
        }
 }
@@ -541,7 +541,7 @@ xpc_activate_partition(struct xpc_partition *part)
 irqreturn_t
 xpc_notify_IRQ_handler(int irq, void *dev_id)
 {
-       partid_t partid = (partid_t) (u64)dev_id;
+       short partid = (short)(u64)dev_id;
        struct xpc_partition *part = &xpc_partitions[partid];
 
        DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
@@ -643,7 +643,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
 static int
 xpc_kthread_start(void *args)
 {
-       partid_t partid = XPC_UNPACK_ARG1(args);
+       short partid = XPC_UNPACK_ARG1(args);
        u16 ch_number = XPC_UNPACK_ARG2(args);
        struct xpc_partition *part = &xpc_partitions[partid];
        struct xpc_channel *ch;
@@ -696,7 +696,7 @@ xpc_kthread_start(void *args)
                ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
                spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-               xpc_disconnect_callout(ch, xpcDisconnecting);
+               xpc_disconnect_callout(ch, xpDisconnecting);
 
                spin_lock_irqsave(&ch->lock, irq_flags);
                ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
@@ -776,7 +776,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
                         * then we'll deadlock if all other kthreads assigned
                         * to this channel are blocked in the channel's
                         * registerer, because the only thing that will unblock
-                        * them is the xpcDisconnecting callout that this
+                        * them is the xpDisconnecting callout that this
                         * failed kthread_run() would have made.
                         */
 
@@ -796,7 +796,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
                                 * to function.
                                 */
                                spin_lock_irqsave(&ch->lock, irq_flags);
-                               XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
+                               XPC_DISCONNECT_CHANNEL(ch, xpLackOfResources,
                                                       &irq_flags);
                                spin_unlock_irqrestore(&ch->lock, irq_flags);
                        }
@@ -809,7 +809,7 @@ void
 xpc_disconnect_wait(int ch_number)
 {
        unsigned long irq_flags;
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
        struct xpc_channel *ch;
        int wakeup_channel_mgr;
@@ -857,9 +857,9 @@ xpc_disconnect_wait(int ch_number)
 }
 
 static void
-xpc_do_exit(enum xpc_retval reason)
+xpc_do_exit(enum xp_retval reason)
 {
-       partid_t partid;
+       short partid;
        int active_part_count, printed_waiting_msg = 0;
        struct xpc_partition *part;
        unsigned long printmsg_time, disengage_request_timeout = 0;
@@ -955,7 +955,7 @@ xpc_do_exit(enum xpc_retval reason)
        del_timer_sync(&xpc_hb_timer);
        DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
 
-       if (reason == xpcUnloading) {
+       if (reason == xpUnloading) {
                /* take ourselves off of the reboot_notifier_list */
                (void)unregister_reboot_notifier(&xpc_reboot_notifier);
 
@@ -981,20 +981,20 @@ xpc_do_exit(enum xpc_retval reason)
 static int
 xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
 {
-       enum xpc_retval reason;
+       enum xp_retval reason;
 
        switch (event) {
        case SYS_RESTART:
-               reason = xpcSystemReboot;
+               reason = xpSystemReboot;
                break;
        case SYS_HALT:
-               reason = xpcSystemHalt;
+               reason = xpSystemHalt;
                break;
        case SYS_POWER_OFF:
-               reason = xpcSystemPoweroff;
+               reason = xpSystemPoweroff;
                break;
        default:
-               reason = xpcSystemGoingDown;
+               reason = xpSystemGoingDown;
        }
 
        xpc_do_exit(reason);
@@ -1008,7 +1008,7 @@ static void
 xpc_die_disengage(void)
 {
        struct xpc_partition *part;
-       partid_t partid;
+       short partid;
        unsigned long engaged;
        long time, printmsg_time, disengage_request_timeout;
 
@@ -1124,7 +1124,7 @@ int __init
 xpc_init(void)
 {
        int ret;
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
        struct task_struct *kthread;
        size_t buf_size;
@@ -1279,7 +1279,7 @@ xpc_init(void)
                /* mark this new thread as a non-starter */
                complete(&xpc_discovery_exited);
 
-               xpc_do_exit(xpcUnloading);
+               xpc_do_exit(xpUnloading);
                return -EBUSY;
        }
 
@@ -1297,7 +1297,7 @@ module_init(xpc_init);
 void __exit
 xpc_exit(void)
 {
-       xpc_do_exit(xpcUnloading);
+       xpc_do_exit(xpUnloading);
 }
 
 module_exit(xpc_exit);
index acd3fd4285d7c954c824286a804c48c6a75d39ce..7dd4b5812c422e844b399a1cb5624833cb0f5eb3 100644 (file)
@@ -403,7 +403,7 @@ xpc_check_remote_hb(void)
 {
        struct xpc_vars *remote_vars;
        struct xpc_partition *part;
-       partid_t partid;
+       short partid;
        bte_result_t bres;
 
        remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
@@ -444,7 +444,7 @@ xpc_check_remote_hb(void)
                     (remote_vars->heartbeat_offline == 0)) ||
                    !xpc_hb_allowed(sn_partition_id, remote_vars)) {
 
-                       XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
+                       XPC_DEACTIVATE_PARTITION(part, xpNoHeartbeat);
                        continue;
                }
 
@@ -459,7 +459,7 @@ xpc_check_remote_hb(void)
  * is large enough to contain a copy of their reserved page header and
  * part_nasids mask.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
                  struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
 {
@@ -469,7 +469,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
 
        *remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
        if (*remote_rp_pa == 0)
-               return xpcNoRsvdPageAddr;
+               return xpNoRsvdPageAddr;
 
        /* pull over the reserved page header and part_nasids mask */
        bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp,
@@ -489,18 +489,18 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
 
        if (remote_rp->partid < 1 ||
            remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
-               return xpcInvalidPartid;
+               return xpInvalidPartid;
        }
 
        if (remote_rp->partid == sn_partition_id)
-               return xpcLocalPartid;
+               return xpLocalPartid;
 
        if (XPC_VERSION_MAJOR(remote_rp->version) !=
            XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
-               return xpcBadVersion;
+               return xpBadVersion;
        }
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -509,13 +509,13 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
  * remote_vars points to a buffer that is cacheline aligned for BTE copies and
  * assumed to be of size XPC_RP_VARS_SIZE.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
 {
        int bres;
 
        if (remote_vars_pa == 0)
-               return xpcVarsNotSet;
+               return xpVarsNotSet;
 
        /* pull over the cross partition variables */
        bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE,
@@ -525,10 +525,10 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
 
        if (XPC_VERSION_MAJOR(remote_vars->version) !=
            XPC_VERSION_MAJOR(XPC_V_VERSION)) {
-               return xpcBadVersion;
+               return xpBadVersion;
        }
 
-       return xpcSuccess;
+       return xpSuccess;
 }
 
 /*
@@ -604,16 +604,16 @@ xpc_identify_act_IRQ_req(int nasid)
        int reactivate = 0;
        int stamp_diff;
        struct timespec remote_rp_stamp = { 0, 0 };
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        /* pull over the reserved page structure */
 
        remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer;
 
        ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
-       if (ret != xpcSuccess) {
+       if (ret != xpSuccess) {
                dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
                         "which sent interrupt, reason=%d\n", nasid, ret);
                return;
@@ -632,7 +632,7 @@ xpc_identify_act_IRQ_req(int nasid)
        remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
 
        ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
-       if (ret != xpcSuccess) {
+       if (ret != xpSuccess) {
 
                dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
                         "which sent interrupt, reason=%d\n", nasid, ret);
@@ -699,7 +699,7 @@ xpc_identify_act_IRQ_req(int nasid)
                                          &remote_rp_stamp, remote_rp_pa,
                                          remote_vars_pa, remote_vars);
                part->reactivate_nasid = nasid;
-               XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+               XPC_DEACTIVATE_PARTITION(part, xpReactivating);
                return;
        }
 
@@ -754,11 +754,11 @@ xpc_identify_act_IRQ_req(int nasid)
 
        if (reactivate) {
                part->reactivate_nasid = nasid;
-               XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+               XPC_DEACTIVATE_PARTITION(part, xpReactivating);
 
        } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
                   xpc_partition_disengage_requested(1UL << partid)) {
-               XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
+               XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
        }
 }
 
@@ -825,7 +825,7 @@ xpc_identify_act_IRQ_sender(void)
 int
 xpc_partition_disengaged(struct xpc_partition *part)
 {
-       partid_t partid = XPC_PARTID(part);
+       short partid = XPC_PARTID(part);
        int disengaged;
 
        disengaged = (xpc_partition_engaged(1UL << partid) == 0);
@@ -870,20 +870,20 @@ xpc_partition_disengaged(struct xpc_partition *part)
 /*
  * Mark specified partition as active.
  */
-enum xpc_retval
+enum xp_retval
 xpc_mark_partition_active(struct xpc_partition *part)
 {
        unsigned long irq_flags;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
 
        spin_lock_irqsave(&part->act_lock, irq_flags);
        if (part->act_state == XPC_P_ACTIVATING) {
                part->act_state = XPC_P_ACTIVE;
-               ret = xpcSuccess;
+               ret = xpSuccess;
        } else {
-               DBUG_ON(part->reason == xpcSuccess);
+               DBUG_ON(part->reason == xpSuccess);
                ret = part->reason;
        }
        spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -896,7 +896,7 @@ xpc_mark_partition_active(struct xpc_partition *part)
  */
 void
 xpc_deactivate_partition(const int line, struct xpc_partition *part,
-                        enum xpc_retval reason)
+                        enum xp_retval reason)
 {
        unsigned long irq_flags;
 
@@ -905,15 +905,15 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
        if (part->act_state == XPC_P_INACTIVE) {
                XPC_SET_REASON(part, reason, line);
                spin_unlock_irqrestore(&part->act_lock, irq_flags);
-               if (reason == xpcReactivating) {
+               if (reason == xpReactivating) {
                        /* we interrupt ourselves to reactivate partition */
                        xpc_IPI_send_reactivate(part);
                }
                return;
        }
        if (part->act_state == XPC_P_DEACTIVATING) {
-               if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
-                   reason == xpcReactivating) {
+               if ((part->reason == xpUnloading && reason != xpUnloading) ||
+                   reason == xpReactivating) {
                        XPC_SET_REASON(part, reason, line);
                }
                spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -982,10 +982,10 @@ xpc_discovery(void)
        int max_regions;
        int nasid;
        struct xpc_rsvd_page *rp;
-       partid_t partid;
+       short partid;
        struct xpc_partition *part;
        u64 *discovered_nasids;
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
                                                  xp_nasid_mask_bytes,
@@ -1063,12 +1063,12 @@ xpc_discovery(void)
 
                        ret = xpc_get_remote_rp(nasid, discovered_nasids,
                                                remote_rp, &remote_rp_pa);
-                       if (ret != xpcSuccess) {
+                       if (ret != xpSuccess) {
                                dev_dbg(xpc_part, "unable to get reserved page "
                                        "from nasid %d, reason=%d\n", nasid,
                                        ret);
 
-                               if (ret == xpcLocalPartid)
+                               if (ret == xpLocalPartid)
                                        break;
 
                                continue;
@@ -1082,7 +1082,7 @@ xpc_discovery(void)
                        /* pull over the cross partition variables */
 
                        ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
-                       if (ret != xpcSuccess) {
+                       if (ret != xpSuccess) {
                                dev_dbg(xpc_part, "unable to get XPC variables "
                                        "from nasid %d, reason=%d\n", nasid,
                                        ret);
@@ -1116,7 +1116,7 @@ xpc_discovery(void)
                                        "register xp_addr region 0x%016lx\n",
                                        partid, remote_vars->amos_page_pa);
 
-                               XPC_SET_REASON(part, xpcPhysAddrRegFailed,
+                               XPC_SET_REASON(part, xpPhysAddrRegFailed,
                                               __LINE__);
                                break;
                        }
@@ -1151,8 +1151,8 @@ xpc_discovery(void)
  * Given a partid, get the nasids owned by that partition from the
  * remote partition's reserved page.
  */
-enum xpc_retval
-xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
+enum xp_retval
+xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
 {
        struct xpc_partition *part;
        u64 part_nasid_pa;
@@ -1160,7 +1160,7 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
 
        part = &xpc_partitions[partid];
        if (part->remote_rp_pa == 0)
-               return xpcPartitionDown;
+               return xpPartitionDown;
 
        memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
 
index a9543c65814d82d1560c211e9f00958c7d95c5c3..822dc8e8d7f0662b9f37d2aa50d2c7b4eb0d4a95 100644 (file)
@@ -166,7 +166,7 @@ struct device *xpnet = &xpnet_dbg_subname;
  * Packet was recevied by XPC and forwarded to us.
  */
 static void
-xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
+xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 {
        struct sk_buff *skb;
        bte_result_t bret;
@@ -282,7 +282,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
  * state or message reception on a connection.
  */
 static void
-xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
+xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
                          void *data, void *key)
 {
        long bp;
@@ -291,13 +291,13 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
        DBUG_ON(channel != XPC_NET_CHANNEL);
 
        switch (reason) {
-       case xpcMsgReceived:    /* message received */
+       case xpMsgReceived:     /* message received */
                DBUG_ON(data == NULL);
 
                xpnet_receive(partid, channel, (struct xpnet_message *)data);
                break;
 
-       case xpcConnected:      /* connection completed to a partition */
+       case xpConnected:       /* connection completed to a partition */
                spin_lock_bh(&xpnet_broadcast_lock);
                xpnet_broadcast_partitions |= 1UL << (partid - 1);
                bp = xpnet_broadcast_partitions;
@@ -330,7 +330,7 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
 static int
 xpnet_dev_open(struct net_device *dev)
 {
-       enum xpc_retval ret;
+       enum xp_retval ret;
 
        dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
                "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
@@ -340,7 +340,7 @@ xpnet_dev_open(struct net_device *dev)
        ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
                          XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
                          XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
-       if (ret != xpcSuccess) {
+       if (ret != xpSuccess) {
                dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
                        "ret=%d\n", dev->name, ret);
 
@@ -407,7 +407,7 @@ xpnet_dev_get_stats(struct net_device *dev)
  * release the skb and then release our pending message structure.
  */
 static void
-xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel,
+xpnet_send_completed(enum xp_retval reason, short partid, int channel,
                     void *__qm)
 {
        struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm;
@@ -439,12 +439,12 @@ static int
 xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct xpnet_pending_msg *queued_msg;
-       enum xpc_retval ret;
+       enum xp_retval ret;
        struct xpnet_message *msg;
        u64 start_addr, end_addr;
        long dp;
        u8 second_mac_octet;
-       partid_t dest_partid;
+       short dest_partid;
        struct xpnet_dev_private *priv;
        u16 embedded_bytes;
 
@@ -528,7 +528,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
                                   XPC_NOWAIT, (void **)&msg);
-               if (unlikely(ret != xpcSuccess))
+               if (unlikely(ret != xpSuccess))
                        continue;
 
                msg->embedded_bytes = embedded_bytes;
@@ -557,7 +557,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
                                      xpnet_send_completed, queued_msg);
-               if (unlikely(ret != xpcSuccess)) {
+               if (unlikely(ret != xpSuccess)) {
                        atomic_dec(&queued_msg->use_count);
                        continue;
                }
index 626ac083f4e09c294c4d465dd3c85e886082867d..da5fecad74d9a79152076730981a36d35cfe3bed 100644 (file)
@@ -425,7 +425,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        host->cclk = host->mclk;
                } else {
                        clk = host->mclk / (2 * ios->clock) - 1;
-                       if (clk > 256)
+                       if (clk >= 256)
                                clk = 255;
                        host->cclk = host->mclk / (2 * (clk + 1));
                }
@@ -512,6 +512,18 @@ static int mmci_probe(struct amba_device *dev, void *id)
 
        host->plat = plat;
        host->mclk = clk_get_rate(host->clk);
+       /*
+        * According to the spec, mclk is max 100 MHz,
+        * so we try to adjust the clock down to this,
+        * (if possible).
+        */
+       if (host->mclk > 100000000) {
+               ret = clk_set_rate(host->clk, 100000000);
+               if (ret < 0)
+                       goto clk_disable;
+               host->mclk = clk_get_rate(host->clk);
+               DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+       }
        host->mmc = mmc;
        host->base = ioremap(dev->res.start, SZ_4K);
        if (!host->base) {
index 7fb02e177a3d13cd4b3439486b8dfb297bec2756..299118de8933e892c1953ac66856af7f12dd3a8e 100644 (file)
@@ -187,7 +187,7 @@ struct sdhci_host {
        struct mmc_request      *mrq;           /* Current request */
        struct mmc_command      *cmd;           /* Current command */
        struct mmc_data         *data;          /* Current data request */
-       int                     data_early:1;   /* Data finished before cmd */
+       unsigned int            data_early:1;   /* Data finished before cmd */
 
        struct scatterlist      *cur_sg;        /* We're working on this */
        int                     num_sg;         /* Entries left */
index e812df607a5c9aef596e96c4800881cb2df15967..fcd1aeccdf9393d0780da7ff83c94d8f32e1af62 100644 (file)
@@ -82,9 +82,8 @@ static struct mtd_info *cfi_intelext_setup (struct mtd_info *);
 static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **);
 
 static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
-                    size_t *retlen, u_char **mtdbuf);
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
-                       size_t len);
+                    size_t *retlen, void **virt, resource_size_t *phys);
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
 
 static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
@@ -1240,7 +1239,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
        return ret;
 }
 
-static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
+               size_t *retlen, void **virt, resource_size_t *phys)
 {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
@@ -1257,8 +1257,10 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
        chipnum = (from >> cfi->chipshift);
        ofs = from - (chipnum << cfi->chipshift);
 
-       *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
+       *virt = map->virt + cfi->chips[chipnum].start + ofs;
        *retlen = 0;
+       if (phys)
+               *phys = map->phys + cfi->chips[chipnum].start + ofs;
 
        while (len) {
                unsigned long thislen;
@@ -1291,7 +1293,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
        return 0;
 }
 
-static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
index bf485ff49457303cc3307655d266085ff23ea098..0399be178620ab67be22917e12595118fc3211f0 100644 (file)
@@ -48,18 +48,21 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
-               size_t *retlen, u_char **mtdbuf)
+               size_t *retlen, void **virt, resource_size_t *phys)
 {
        if (from + len > mtd->size)
                return -EINVAL;
 
-       *mtdbuf = mtd->priv + from;
+       /* can we return a physical address with this driver? */
+       if (phys)
+               return -EINVAL;
+
+       *virt = mtd->priv + from;
        *retlen = len;
        return 0;
 }
 
-static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
-               size_t len)
+static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
index 5f960182da957eaa8c4a12295fe93b66677e4287..c7987b1c5e01db083f237fa26b1c48d963a77a7d 100644 (file)
@@ -57,20 +57,21 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
-               size_t *retlen, u_char **mtdbuf)
+               size_t *retlen, void **virt, resource_size_t *phys)
 {
-       u_char *start = mtd->priv;
-
        if (from + len > mtd->size)
                return -EINVAL;
 
-       *mtdbuf = start + from;
+       /* can we return a physical address with this driver? */
+       if (phys)
+               return -EINVAL;
+
+       *virt = mtd->priv + from;
        *retlen = len;
        return 0;
 }
 
-static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
-               size_t len)
+static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
index 7060a0895ce26fd95bf67f2cdc85418bfbc0078e..bc99817490649572ced4f09e01ec2606c252a854 100644 (file)
@@ -134,7 +134,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
        eoff_lo = end & (priv->asize - 1);
        soff_lo = instr->addr & (priv->asize - 1);
 
-       pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
+       pmc551_point(mtd, instr->addr, instr->len, &retlen,
+                    (void **)&ptr, NULL);
 
        if (soff_hi == eoff_hi || mtd->size == priv->asize) {
                /* The whole thing fits within one access, so just one shot
@@ -154,7 +155,8 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
                        }
                        soff_hi += priv->asize;
                        pmc551_point(mtd, (priv->base_map0 | soff_hi),
-                                    priv->asize, &retlen, &ptr);
+                                    priv->asize, &retlen,
+                                    (void **)&ptr, NULL);
                }
                memset(ptr, 0xff, eoff_lo);
        }
@@ -170,7 +172,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
-                       size_t * retlen, u_char ** mtdbuf)
+                       size_t *retlen, void **virt, resource_size_t *phys)
 {
        struct mypriv *priv = mtd->priv;
        u32 soff_hi;
@@ -188,6 +190,10 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
                return -EINVAL;
        }
 
+       /* can we return a physical address with this driver? */
+       if (phys)
+               return -EINVAL;
+
        soff_hi = from & ~(priv->asize - 1);
        soff_lo = from & (priv->asize - 1);
 
@@ -198,13 +204,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
                priv->curr_map0 = soff_hi;
        }
 
-       *mtdbuf = priv->start + soff_lo;
+       *virt = priv->start + soff_lo;
        *retlen = len;
        return 0;
 }
 
-static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
-                          size_t len)
+static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 #ifdef CONFIG_MTD_PMC551_DEBUG
        printk(KERN_DEBUG "pmc551_unpoint()\n");
@@ -242,7 +247,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
        soff_lo = from & (priv->asize - 1);
        eoff_lo = end & (priv->asize - 1);
 
-       pmc551_point(mtd, from, len, retlen, &ptr);
+       pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL);
 
        if (soff_hi == eoff_hi) {
                /* The whole thing fits within one access, so just one shot
@@ -263,7 +268,8 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
                                goto out;
                        }
                        soff_hi += priv->asize;
-                       pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
+                       pmc551_point(mtd, soff_hi, priv->asize, retlen,
+                                    (void **)&ptr, NULL);
                }
                memcpy(copyto, ptr, eoff_lo);
                copyto += eoff_lo;
@@ -308,7 +314,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
        soff_lo = to & (priv->asize - 1);
        eoff_lo = end & (priv->asize - 1);
 
-       pmc551_point(mtd, to, len, retlen, &ptr);
+       pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL);
 
        if (soff_hi == eoff_hi) {
                /* The whole thing fits within one access, so just one shot
@@ -329,7 +335,8 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
                                goto out;
                        }
                        soff_hi += priv->asize;
-                       pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
+                       pmc551_point(mtd, soff_hi, priv->asize, retlen,
+                                    (void **)&ptr, NULL);
                }
                memcpy(ptr, copyfrom, eoff_lo);
                copyfrom += eoff_lo;
index d293add1857cfba358a033ff0247e7c755ef42c1..cb86db746f28c91f552462696b10d5c99f23c07d 100644 (file)
@@ -76,8 +76,9 @@ static char *map;
 static slram_mtd_list_t *slram_mtdlist = NULL;
 
 static int slram_erase(struct mtd_info *, struct erase_info *);
-static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **);
-static void slram_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
+static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
+               resource_size_t *);
+static void slram_unpoint(struct mtd_info *, loff_t, size_t);
 static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 
@@ -104,19 +105,23 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
 }
 
 static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
-               size_t *retlen, u_char **mtdbuf)
+               size_t *retlen, void **virt, resource_size_t *phys)
 {
        slram_priv_t *priv = mtd->priv;
 
+       /* can we return a physical address with this driver? */
+       if (phys)
+               return -EINVAL;
+
        if (from + len > mtd->size)
                return -EINVAL;
 
-       *mtdbuf = priv->start + from;
+       *virt = priv->start + from;
        *retlen = len;
        return(0);
 }
 
-static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 }
 
index 1bd69aa9e22acd2905a28e0e5c76d27d0bd00c94..17bc87a43ff415d151125673b1cda275c4d7b28d 100644 (file)
@@ -374,7 +374,7 @@ config MTD_REDWOOD
 
 config MTD_SOLUTIONENGINE
        tristate "CFI Flash device mapped on Hitachi SolutionEngine"
-       depends on SUPERH && MTD_CFI && MTD_REDBOOT_PARTS
+       depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
        help
          This enables access to the flash chips on the Hitachi SolutionEngine and
          similar boards. Say 'Y' if you are building a kernel for such a board.
@@ -480,13 +480,6 @@ config MTD_H720X
          This enables access to the flash chips on the Hynix evaluation boards.
          If you have such a board, say 'Y'.
 
-config MTD_MPC1211
-       tristate "CFI Flash device mapped on Interface MPC-1211"
-       depends on SH_MPC1211 && MTD_CFI
-       help
-         This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
-         If you have such a board, say 'Y'.
-
 config MTD_OMAP_NOR
        tristate "TI OMAP board mappings"
        depends on MTD_CFI && ARCH_OMAP
index a9cbe80f99a0d909eec2f89e109dfd53a7365a50..957fb5f70f5efdc592f18df82a0a43c09e2c6b27 100644 (file)
@@ -58,7 +58,6 @@ obj-$(CONFIG_MTD_WALNUT)        += walnut.o
 obj-$(CONFIG_MTD_H720X)                += h720x-flash.o
 obj-$(CONFIG_MTD_SBC8240)      += sbc8240.o
 obj-$(CONFIG_MTD_NOR_TOTO)     += omap-toto-flash.o
-obj-$(CONFIG_MTD_MPC1211)      += mpc1211.o
 obj-$(CONFIG_MTD_IXP4XX)       += ixp4xx.o
 obj-$(CONFIG_MTD_IXP2000)      += ixp2000.o
 obj-$(CONFIG_MTD_WRSBC8260)    += wr_sbc82xx_flash.o
diff --git a/drivers/mtd/maps/mpc1211.c b/drivers/mtd/maps/mpc1211.c
deleted file mode 100644 (file)
index 45a00fa..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Flash on MPC-1211
- *
- * $Id: mpc1211.c,v 1.4 2004/09/16 23:27:13 gleixner Exp $
- *
- * (C) 2002 Interface, Saito.K & Jeanne
- *
- * GPL'd
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-static struct mtd_info *flash_mtd;
-static struct mtd_partition *parsed_parts;
-
-struct map_info mpc1211_flash_map = {
-       .name           = "MPC-1211 FLASH",
-       .size           = 0x80000,
-       .bankwidth      = 1,
-};
-
-static struct mtd_partition mpc1211_partitions[] = {
-       {
-               .name   = "IPL & ETH-BOOT",
-               .offset = 0x00000000,
-               .size   = 0x10000,
-       },
-       {
-               .name   = "Flash FS",
-               .offset = 0x00010000,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-static int __init init_mpc1211_maps(void)
-{
-       int nr_parts;
-
-       mpc1211_flash_map.phys = 0;
-       mpc1211_flash_map.virt = (void __iomem *)P2SEGADDR(0);
-
-       simple_map_init(&mpc1211_flash_map);
-
-       printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
-       flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map);
-       if (!flash_mtd) {
-               printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
-               return -ENXIO;
-       }
-       printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff);
-       flash_mtd->module = THIS_MODULE;
-
-       parsed_parts = mpc1211_partitions;
-       nr_parts = ARRAY_SIZE(mpc1211_partitions);
-
-       add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
-       return 0;
-}
-
-static void __exit cleanup_mpc1211_maps(void)
-{
-       if (parsed_parts)
-               del_mtd_partitions(flash_mtd);
-       else
-               del_mtd_device(flash_mtd);
-       map_destroy(flash_mtd);
-}
-
-module_init(init_mpc1211_maps);
-module_exit(cleanup_mpc1211_maps);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Saito.K & Jeanne <ksaito@interface.co.jp>");
-MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface");
index 14ffb1a9302a51e8dc2271f7311116b1f7b635f3..c42f4b83f686dc0235f699b75a2dd457f4f53218 100644 (file)
@@ -40,10 +40,12 @@ struct mtd_partition uclinux_romfs[] = {
 /****************************************************************************/
 
 int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
-       size_t *retlen, u_char **mtdbuf)
+       size_t *retlen, void **virt, resource_size_t *phys)
 {
        struct map_info *map = mtd->priv;
-       *mtdbuf = (u_char *) (map->virt + ((int) from));
+       *virt = map->virt + from;
+       if (phys)
+               *phys = map->phys + from;
        *retlen = len;
        return(0);
 }
index c66902df3171aef08e1066fde0157992f456ffdc..07c701169344266e907ce92ee2068c2a8ad6881d 100644 (file)
@@ -68,7 +68,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
 }
 
 static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
-                       size_t *retlen, u_char **buf)
+                       size_t *retlen, void **virt, resource_size_t *phys)
 {
        struct mtd_part *part = PART(mtd);
        if (from >= mtd->size)
@@ -76,14 +76,14 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
        else if (from + len > mtd->size)
                len = mtd->size - from;
        return part->master->point (part->master, from + part->offset,
-                                   len, retlen, buf);
+                                   len, retlen, virt, phys);
 }
 
-static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
        struct mtd_part *part = PART(mtd);
 
-       part->master->unpoint (part->master, addr, from + part->offset, len);
+       part->master->unpoint(part->master, from + part->offset, len);
 }
 
 static int part_read_oob(struct mtd_info *mtd, loff_t from,
index 414ceaecdb3a2058bbba13def192553ed40ce29f..0adb287027a249409062c5ba6a46cadc717f50a8 100644 (file)
@@ -93,6 +93,24 @@ struct at91_nand_host {
        void __iomem            *ecc;
 };
 
+/*
+ * Enable NAND.
+ */
+static void at91_nand_enable(struct at91_nand_host *host)
+{
+       if (host->board->enable_pin)
+               at91_set_gpio_value(host->board->enable_pin, 0);
+}
+
+/*
+ * Disable NAND.
+ */
+static void at91_nand_disable(struct at91_nand_host *host)
+{
+       if (host->board->enable_pin)
+               at91_set_gpio_value(host->board->enable_pin, 1);
+}
+
 /*
  * Hardware specific access to control-lines
  */
@@ -101,11 +119,11 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
        struct nand_chip *nand_chip = mtd->priv;
        struct at91_nand_host *host = nand_chip->priv;
 
-       if (host->board->enable_pin && (ctrl & NAND_CTRL_CHANGE)) {
+       if (ctrl & NAND_CTRL_CHANGE) {
                if (ctrl & NAND_NCE)
-                       at91_set_gpio_value(host->board->enable_pin, 0);
+                       at91_nand_enable(host);
                else
-                       at91_set_gpio_value(host->board->enable_pin, 1);
+                       at91_nand_disable(host);
        }
        if (cmd == NAND_CMD_NONE)
                return;
@@ -127,24 +145,6 @@ static int at91_nand_device_ready(struct mtd_info *mtd)
        return at91_get_gpio_value(host->board->rdy_pin);
 }
 
-/*
- * Enable NAND.
- */
-static void at91_nand_enable(struct at91_nand_host *host)
-{
-       if (host->board->enable_pin)
-               at91_set_gpio_value(host->board->enable_pin, 0);
-}
-
-/*
- * Disable NAND.
- */
-static void at91_nand_disable(struct at91_nand_host *host)
-{
-       if (host->board->enable_pin)
-               at91_set_gpio_value(host->board->enable_pin, 1);
-}
-
 /*
  * write oob for small pages
  */
index d7a3ea88eddb562be4f632387d30776da84f4ef7..32a4f17d35fc5f1387ca232bc7100761cc7bcafe 100644 (file)
 #define        FEC_MAX_PORTS   1
 #endif
 
+#if defined(CONFIG_FADS) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_M5272)
+#define HAVE_mii_link_interrupt
+#endif
+
 /*
  * Define the fixed address of the FEC hardware.
  */
@@ -205,7 +209,10 @@ struct fec_enet_private {
        cbd_t   *cur_rx, *cur_tx;               /* The next free ring entry */
        cbd_t   *dirty_tx;      /* The ring entries to be free()ed. */
        uint    tx_full;
-       spinlock_t lock;
+       /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
+       spinlock_t hw_lock;
+       /* hold while accessing the mii_list_t() elements */
+       spinlock_t mii_lock;
 
        uint    phy_id;
        uint    phy_id_done;
@@ -309,6 +316,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        volatile fec_t  *fecp;
        volatile cbd_t  *bdp;
        unsigned short  status;
+       unsigned long flags;
 
        fep = netdev_priv(dev);
        fecp = (volatile fec_t*)dev->base_addr;
@@ -318,6 +326,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                return 1;
        }
 
+       spin_lock_irqsave(&fep->hw_lock, flags);
        /* Fill in a Tx ring entry */
        bdp = fep->cur_tx;
 
@@ -328,6 +337,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                 * This should not happen, since dev->tbusy should be set.
                 */
                printk("%s: tx queue full!.\n", dev->name);
+               spin_unlock_irqrestore(&fep->hw_lock, flags);
                return 1;
        }
 #endif
@@ -366,8 +376,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        flush_dcache_range((unsigned long)skb->data,
                           (unsigned long)skb->data + skb->len);
 
-       spin_lock_irq(&fep->lock);
-
        /* Send it on its way.  Tell FEC it's ready, interrupt when done,
         * it's the last BD of the frame, and to put the CRC on the end.
         */
@@ -396,7 +404,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        fep->cur_tx = (cbd_t *)bdp;
 
-       spin_unlock_irq(&fep->lock);
+       spin_unlock_irqrestore(&fep->hw_lock, flags);
 
        return 0;
 }
@@ -454,19 +462,20 @@ fec_enet_interrupt(int irq, void * dev_id)
        struct  net_device *dev = dev_id;
        volatile fec_t  *fecp;
        uint    int_events;
-       int handled = 0;
+       irqreturn_t ret = IRQ_NONE;
 
        fecp = (volatile fec_t*)dev->base_addr;
 
        /* Get the interrupt events that caused us to be here.
        */
-       while ((int_events = fecp->fec_ievent) != 0) {
+       do {
+               int_events = fecp->fec_ievent;
                fecp->fec_ievent = int_events;
 
                /* Handle receive event in its own function.
                 */
                if (int_events & FEC_ENET_RXF) {
-                       handled = 1;
+                       ret = IRQ_HANDLED;
                        fec_enet_rx(dev);
                }
 
@@ -475,17 +484,18 @@ fec_enet_interrupt(int irq, void * dev_id)
                   them as part of the transmit process.
                */
                if (int_events & FEC_ENET_TXF) {
-                       handled = 1;
+                       ret = IRQ_HANDLED;
                        fec_enet_tx(dev);
                }
 
                if (int_events & FEC_ENET_MII) {
-                       handled = 1;
+                       ret = IRQ_HANDLED;
                        fec_enet_mii(dev);
                }
 
-       }
-       return IRQ_RETVAL(handled);
+       } while (int_events);
+
+       return ret;
 }
 
 
@@ -498,7 +508,7 @@ fec_enet_tx(struct net_device *dev)
        struct  sk_buff *skb;
 
        fep = netdev_priv(dev);
-       spin_lock(&fep->lock);
+       spin_lock_irq(&fep->hw_lock);
        bdp = fep->dirty_tx;
 
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
@@ -557,7 +567,7 @@ fec_enet_tx(struct net_device *dev)
                }
        }
        fep->dirty_tx = (cbd_t *)bdp;
-       spin_unlock(&fep->lock);
+       spin_unlock_irq(&fep->hw_lock);
 }
 
 
@@ -584,6 +594,8 @@ fec_enet_rx(struct net_device *dev)
        fep = netdev_priv(dev);
        fecp = (volatile fec_t*)dev->base_addr;
 
+       spin_lock_irq(&fep->hw_lock);
+
        /* First, grab all of the stats for the incoming packet.
         * These get messed up if we get called due to a busy condition.
         */
@@ -689,6 +701,8 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
         */
        fecp->fec_r_des_active = 0;
 #endif
+
+       spin_unlock_irq(&fep->hw_lock);
 }
 
 
@@ -702,11 +716,11 @@ fec_enet_mii(struct net_device *dev)
        uint            mii_reg;
 
        fep = netdev_priv(dev);
+       spin_lock_irq(&fep->mii_lock);
+
        ep = fep->hwp;
        mii_reg = ep->fec_mii_data;
 
-       spin_lock(&fep->lock);
-
        if ((mip = mii_head) == NULL) {
                printk("MII and no head!\n");
                goto unlock;
@@ -723,7 +737,7 @@ fec_enet_mii(struct net_device *dev)
                ep->fec_mii_data = mip->mii_regval;
 
 unlock:
-       spin_unlock(&fep->lock);
+       spin_unlock_irq(&fep->mii_lock);
 }
 
 static int
@@ -737,12 +751,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
        /* Add PHY address to register command.
        */
        fep = netdev_priv(dev);
-       regval |= fep->phy_addr << 23;
+       spin_lock_irqsave(&fep->mii_lock, flags);
 
+       regval |= fep->phy_addr << 23;
        retval = 0;
 
-       spin_lock_irqsave(&fep->lock,flags);
-
        if ((mip = mii_free) != NULL) {
                mii_free = mip->mii_next;
                mip->mii_regval = regval;
@@ -759,9 +772,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                retval = 1;
        }
 
-       spin_unlock_irqrestore(&fep->lock,flags);
-
-       return(retval);
+       spin_unlock_irqrestore(&fep->mii_lock, flags);
+       return retval;
 }
 
 static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
@@ -1222,7 +1234,7 @@ static phy_info_t const * const phy_info[] = {
 };
 
 /* ------------------------------------------------------------------------- */
-#if !defined(CONFIG_M532x)
+#ifdef HAVE_mii_link_interrupt
 #ifdef CONFIG_RPXCLASSIC
 static void
 mii_link_interrupt(void *dev_id);
@@ -1362,18 +1374,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
                unsigned short irq;
        } *idp, id[] = {
                { "fec(TXF)", 23 },
-               { "fec(TXB)", 24 },
-               { "fec(TXFIFO)", 25 },
-               { "fec(TXCR)", 26 },
                { "fec(RXF)", 27 },
-               { "fec(RXB)", 28 },
                { "fec(MII)", 29 },
-               { "fec(LC)", 30 },
-               { "fec(HBERR)", 31 },
-               { "fec(GRA)", 32 },
-               { "fec(EBERR)", 33 },
-               { "fec(BABT)", 34 },
-               { "fec(BABR)", 35 },
                { NULL },
        };
 
@@ -1533,18 +1535,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
                unsigned short irq;
        } *idp, id[] = {
                { "fec(TXF)", 23 },
-               { "fec(TXB)", 24 },
-               { "fec(TXFIFO)", 25 },
-               { "fec(TXCR)", 26 },
                { "fec(RXF)", 27 },
-               { "fec(RXB)", 28 },
                { "fec(MII)", 29 },
-               { "fec(LC)", 30 },
-               { "fec(HBERR)", 31 },
-               { "fec(GRA)", 32 },
-               { "fec(EBERR)", 33 },
-               { "fec(BABT)", 34 },
-               { "fec(BABR)", 35 },
                { NULL },
        };
 
@@ -1660,18 +1652,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
                unsigned short irq;
        } *idp, id[] = {
            { "fec(TXF)", 36 },
-           { "fec(TXB)", 37 },
-           { "fec(TXFIFO)", 38 },
-           { "fec(TXCR)", 39 },
            { "fec(RXF)", 40 },
-           { "fec(RXB)", 41 },
            { "fec(MII)", 42 },
-           { "fec(LC)", 43 },
-           { "fec(HBERR)", 44 },
-           { "fec(GRA)", 45 },
-           { "fec(EBERR)", 46 },
-           { "fec(BABT)", 47 },
-           { "fec(BABR)", 48 },
            { NULL },
        };
 
@@ -2126,6 +2108,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 
 /* This interrupt occurs when the PHY detects a link change.
 */
+#ifdef HAVE_mii_link_interrupt
 #ifdef CONFIG_RPXCLASSIC
 static void
 mii_link_interrupt(void *dev_id)
@@ -2148,6 +2131,7 @@ mii_link_interrupt(int irq, void * dev_id)
 
        return IRQ_HANDLED;
 }
+#endif
 
 static int
 fec_enet_open(struct net_device *dev)
@@ -2243,13 +2227,13 @@ static void set_multicast_list(struct net_device *dev)
                        /* Catch all multicast addresses, so set the
                         * filter to all 1's.
                         */
-                       ep->fec_hash_table_high = 0xffffffff;
-                       ep->fec_hash_table_low = 0xffffffff;
+                       ep->fec_grp_hash_table_high = 0xffffffff;
+                       ep->fec_grp_hash_table_low = 0xffffffff;
                } else {
                        /* Clear filter and add the addresses in hash register.
                        */
-                       ep->fec_hash_table_high = 0;
-                       ep->fec_hash_table_low = 0;
+                       ep->fec_grp_hash_table_high = 0;
+                       ep->fec_grp_hash_table_low = 0;
 
                        dmi = dev->mc_list;
 
@@ -2280,9 +2264,9 @@ static void set_multicast_list(struct net_device *dev)
                                hash = (crc >> (32 - HASH_BITS)) & 0x3f;
 
                                if (hash > 31)
-                                       ep->fec_hash_table_high |= 1 << (hash - 32);
+                                       ep->fec_grp_hash_table_high |= 1 << (hash - 32);
                                else
-                                       ep->fec_hash_table_low |= 1 << hash;
+                                       ep->fec_grp_hash_table_low |= 1 << hash;
                        }
                }
        }
@@ -2332,6 +2316,9 @@ int __init fec_enet_init(struct net_device *dev)
                return -ENOMEM;
        }
 
+       spin_lock_init(&fep->hw_lock);
+       spin_lock_init(&fep->mii_lock);
+
        /* Create an Ethernet device instance.
        */
        fecp = (volatile fec_t *) fec_hw[index];
@@ -2430,11 +2417,15 @@ int __init fec_enet_init(struct net_device *dev)
        */
        fec_request_intrs(dev);
 
-       fecp->fec_hash_table_high = 0;
-       fecp->fec_hash_table_low = 0;
+       fecp->fec_grp_hash_table_high = 0;
+       fecp->fec_grp_hash_table_low = 0;
        fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
        fecp->fec_ecntrl = 2;
        fecp->fec_r_des_active = 0;
+#ifndef CONFIG_M5272
+       fecp->fec_hash_table_high = 0;
+       fecp->fec_hash_table_low = 0;
+#endif
 
        dev->base_addr = (unsigned long)fecp;
 
@@ -2455,8 +2446,7 @@ int __init fec_enet_init(struct net_device *dev)
 
        /* Clear and enable interrupts */
        fecp->fec_ievent = 0xffc00000;
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-               FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
 
        /* Queue up command to detect the PHY and initialize the
         * remainder of the interface.
@@ -2500,8 +2490,8 @@ fec_restart(struct net_device *dev, int duplex)
 
        /* Reset all multicast.
        */
-       fecp->fec_hash_table_high = 0;
-       fecp->fec_hash_table_low = 0;
+       fecp->fec_grp_hash_table_high = 0;
+       fecp->fec_grp_hash_table_low = 0;
 
        /* Set maximum receive buffer size.
        */
@@ -2583,8 +2573,7 @@ fec_restart(struct net_device *dev, int duplex)
 
        /* Enable interrupts we wish to service.
        */
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-               FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
 }
 
 static void
@@ -2624,7 +2613,7 @@ fec_stop(struct net_device *dev)
 static int __init fec_enet_module_init(void)
 {
        struct net_device *dev;
-       int i, j, err;
+       int i, err;
        DECLARE_MAC_BUF(mac);
 
        printk("FEC ENET Version 0.2\n");
index 1d421606984fd4925e0a058ffb6bbc57e1332b06..292719daceff0e8060aa7ae6ddef7fda0a0bcf31 100644 (file)
@@ -88,8 +88,8 @@ typedef struct fec {
        unsigned long   fec_reserved7[158];
        unsigned long   fec_addr_low;           /* Low 32bits MAC address */
        unsigned long   fec_addr_high;          /* High 16bits MAC address */
-       unsigned long   fec_hash_table_high;    /* High 32bits hash table */
-       unsigned long   fec_hash_table_low;     /* Low 32bits hash table */
+       unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
+       unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
        unsigned long   fec_r_des_start;        /* Receive descriptor ring */
        unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
        unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
index d21b7ab64bd13224fc96e5b53a3c47a83285b50b..5f9c42e7a7f153e4fda0d8f5c0c6720bd429047e 100644 (file)
 
 #define DRIVER_NAME "mpc52xx-fec"
 
+#define FEC5200_PHYADDR_NONE   (-1)
+#define FEC5200_PHYADDR_7WIRE  (-2)
+
+/* Private driver data structure */
+struct mpc52xx_fec_priv {
+       int duplex;
+       int speed;
+       int r_irq;
+       int t_irq;
+       struct mpc52xx_fec __iomem *fec;
+       struct bcom_task *rx_dmatsk;
+       struct bcom_task *tx_dmatsk;
+       spinlock_t lock;
+       int msg_enable;
+
+       /* MDIO link details */
+       int phy_addr;
+       unsigned int phy_speed;
+       struct phy_device *phydev;
+       enum phy_state link;
+};
+
+
 static irqreturn_t mpc52xx_fec_interrupt(int, void *);
 static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *);
 static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *);
@@ -223,7 +246,7 @@ static int mpc52xx_fec_phy_start(struct net_device *dev)
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
        int err;
 
-       if (!priv->has_phy)
+       if (priv->phy_addr < 0)
                return 0;
 
        err = mpc52xx_fec_init_phy(dev);
@@ -243,7 +266,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev)
 {
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 
-       if (!priv->has_phy)
+       if (!priv->phydev)
                return;
 
        phy_disconnect(priv->phydev);
@@ -255,7 +278,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev)
 static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
                struct mii_ioctl_data *mii_data, int cmd)
 {
-       if (!priv->has_phy)
+       if (!priv->phydev)
                return -ENOTSUPP;
 
        return phy_mii_ioctl(priv->phydev, mii_data, cmd);
@@ -265,7 +288,7 @@ static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
 {
        struct mpc52xx_fec __iomem *fec = priv->fec;
 
-       if (!priv->has_phy)
+       if (priv->phydev)
                return;
 
        out_be32(&fec->mii_speed, priv->phy_speed);
@@ -704,7 +727,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
        rcntrl = FEC_RX_BUFFER_SIZE << 16;      /* max frame length */
        rcntrl |= FEC_RCNTRL_FCE;
 
-       if (priv->has_phy)
+       if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
                rcntrl |= FEC_RCNTRL_MII_MODE;
 
        if (priv->duplex == DUPLEX_FULL)
@@ -864,7 +887,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        struct net_device *ndev;
        struct mpc52xx_fec_priv *priv = NULL;
        struct resource mem;
-       const phandle *ph;
+       struct device_node *phy_node;
+       const phandle *phy_handle;
+       const u32 *prop;
+       int prop_size;
 
        phys_addr_t rx_fifo;
        phys_addr_t tx_fifo;
@@ -948,26 +974,37 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
                mpc52xx_fec_get_paddr(ndev, ndev->dev_addr);
 
        priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT);
-       priv->duplex = DUPLEX_FULL;
-
-       /* is the phy present in device tree? */
-       ph = of_get_property(op->node, "phy-handle", NULL);
-       if (ph) {
-               const unsigned int *prop;
-               struct device_node *phy_dn;
-               priv->has_phy = 1;
 
-               phy_dn = of_find_node_by_phandle(*ph);
-               prop = of_get_property(phy_dn, "reg", NULL);
-               priv->phy_addr = *prop;
+       /*
+        * Link mode configuration
+        */
 
-               of_node_put(phy_dn);
+       /* Start with safe defaults for link connection */
+       priv->phy_addr = FEC5200_PHYADDR_NONE;
+       priv->speed = 100;
+       priv->duplex = DUPLEX_HALF;
+       priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
+
+       /* the 7-wire property means don't use MII mode */
+       if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
+               priv->phy_addr = FEC5200_PHYADDR_7WIRE;
+
+       /* The current speed preconfigures the speed of the MII link */
+       prop = of_get_property(op->node, "current-speed", &prop_size);
+       if (prop && (prop_size >= sizeof(u32) * 2)) {
+               priv->speed = prop[0];
+               priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
+       }
 
-               /* Phy speed */
-               priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
-       } else {
-               dev_info(&ndev->dev, "can't find \"phy-handle\" in device"
-                               " tree, using 7-wire mode\n");
+       /* If there is a phy handle, setup link to that phy */
+       phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
+       if (phy_handle && (prop_size >= sizeof(phandle))) {
+               phy_node = of_find_node_by_phandle(*phy_handle);
+               prop = of_get_property(phy_node, "reg", &prop_size);
+               if (prop && (prop_size >= sizeof(u32)))
+                       if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
+                               priv->phy_addr = *prop;
+               of_node_put(phy_node);
        }
 
        /* Hardware init */
@@ -982,6 +1019,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        if (rv < 0)
                goto probe_error;
 
+       /* Now report the link setup */
+       switch (priv->phy_addr) {
+        case FEC5200_PHYADDR_NONE:
+               dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
+                        priv->speed, priv->duplex ? 'F' : 'H');
+               break;
+        case FEC5200_PHYADDR_7WIRE:
+               dev_info(&ndev->dev, "using 7-wire PHY mode\n");
+               break;
+        default:
+               dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
+                        priv->phy_addr);
+       }
+
        /* We're done ! */
        dev_set_drvdata(&op->dev, ndev);
 
index 8b1f75397b9a0fbd70c2a8d657ae042296004984..a227a525bdbb61e168a7fa47ab55e4118ab65eb0 100644 (file)
 
 #define FEC_WATCHDOG_TIMEOUT   ((400*HZ)/1000)
 
-struct mpc52xx_fec_priv {
-       int duplex;
-       int r_irq;
-       int t_irq;
-       struct mpc52xx_fec __iomem *fec;
-       struct bcom_task *rx_dmatsk;
-       struct bcom_task *tx_dmatsk;
-       spinlock_t lock;
-       int msg_enable;
-
-       int has_phy;
-       unsigned int phy_speed;
-       unsigned int phy_addr;
-       struct phy_device *phydev;
-       enum phy_state link;
-       int speed;
-};
-
-
 /* ======================================================================== */
 /* Hardware register sets & bits                                            */
 /* ======================================================================== */
index cb46446b2691b88a7db70ce08a482f9a09696e5a..03a9abcce5240bbe53be4783e25584b010dcd68b 100644 (file)
@@ -551,7 +551,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
        u64 mtt_seg;
        int err = -ENOMEM;
 
-       if (page_shift < 12 || page_shift >= 32)
+       if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32)
                return -EINVAL;
 
        /* All MTTs must fit in the same page */
index 6f245cfb662419f3f173a65073d873f4195768db..dc6f097062df3cb385d296cabfde169f54081bf4 100644 (file)
@@ -1380,6 +1380,10 @@ static const struct usb_device_id        products [] = {
        // Buffalo LUA-U2-KTX
        USB_DEVICE (0x0411, 0x003d),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Buffalo LUA-U2-GT 10/100/1000
+       USB_DEVICE (0x0411, 0x006e),
+       .driver_info =  (unsigned long) &ax88178_info,
 }, {
        // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
        USB_DEVICE (0x6189, 0x182d),
index 555b70c8b8635226a1fa295c7334d5d70c34f939..f926b5ab3d09291f2146ebd3928bc385503fb04e 100644 (file)
@@ -41,6 +41,9 @@ struct virtnet_info
        struct net_device *dev;
        struct napi_struct napi;
 
+       /* The skb we couldn't send because buffers were full. */
+       struct sk_buff *last_xmit_skb;
+
        /* Number of input buffers, and max we've ever had. */
        unsigned int num, max;
 
@@ -142,10 +145,10 @@ drop:
 static void try_fill_recv(struct virtnet_info *vi)
 {
        struct sk_buff *skb;
-       struct scatterlist sg[1+MAX_SKB_FRAGS];
+       struct scatterlist sg[2+MAX_SKB_FRAGS];
        int num, err;
 
-       sg_init_table(sg, 1+MAX_SKB_FRAGS);
+       sg_init_table(sg, 2+MAX_SKB_FRAGS);
        for (;;) {
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
                if (unlikely(!skb))
@@ -221,23 +224,22 @@ static void free_old_xmit_skbs(struct virtnet_info *vi)
        while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) {
                pr_debug("Sent skb %p\n", skb);
                __skb_unlink(skb, &vi->send);
-               vi->dev->stats.tx_bytes += len;
+               vi->dev->stats.tx_bytes += skb->len;
                vi->dev->stats.tx_packets++;
                kfree_skb(skb);
        }
 }
 
-static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
 {
-       struct virtnet_info *vi = netdev_priv(dev);
-       int num, err;
-       struct scatterlist sg[1+MAX_SKB_FRAGS];
+       int num;
+       struct scatterlist sg[2+MAX_SKB_FRAGS];
        struct virtio_net_hdr *hdr;
        const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
 
-       sg_init_table(sg, 1+MAX_SKB_FRAGS);
+       sg_init_table(sg, 2+MAX_SKB_FRAGS);
 
-       pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb,
+       pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb,
                 dest[0], dest[1], dest[2],
                 dest[3], dest[4], dest[5]);
 
@@ -272,30 +274,51 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        vnet_hdr_to_sg(sg, skb);
        num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
-       __skb_queue_head(&vi->send, skb);
+
+       return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
+}
+
+static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct virtnet_info *vi = netdev_priv(dev);
 
 again:
        /* Free up any pending old buffers before queueing new ones. */
        free_old_xmit_skbs(vi);
-       err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
-       if (err) {
-               pr_debug("%s: virtio not prepared to send\n", dev->name);
-               netif_stop_queue(dev);
-
-               /* Activate callback for using skbs: if this returns false it
-                * means some were used in the meantime. */
-               if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) {
-                       vi->svq->vq_ops->disable_cb(vi->svq);
-                       netif_start_queue(dev);
-                       goto again;
+
+       /* If we has a buffer left over from last time, send it now. */
+       if (vi->last_xmit_skb) {
+               if (xmit_skb(vi, vi->last_xmit_skb) != 0) {
+                       /* Drop this skb: we only queue one. */
+                       vi->dev->stats.tx_dropped++;
+                       kfree_skb(skb);
+                       goto stop_queue;
                }
-               __skb_unlink(skb, &vi->send);
+               vi->last_xmit_skb = NULL;
+       }
 
-               return NETDEV_TX_BUSY;
+       /* Put new one in send queue and do transmit */
+       __skb_queue_head(&vi->send, skb);
+       if (xmit_skb(vi, skb) != 0) {
+               vi->last_xmit_skb = skb;
+               goto stop_queue;
        }
+done:
        vi->svq->vq_ops->kick(vi->svq);
-
-       return 0;
+       return NETDEV_TX_OK;
+
+stop_queue:
+       pr_debug("%s: virtio not prepared to send\n", dev->name);
+       netif_stop_queue(dev);
+
+       /* Activate callback for using skbs: if this returns false it
+        * means some were used in the meantime. */
+       if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) {
+               vi->svq->vq_ops->disable_cb(vi->svq);
+               netif_start_queue(dev);
+               goto again;
+       }
+       goto done;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -355,17 +378,26 @@ static int virtnet_probe(struct virtio_device *vdev)
        SET_NETDEV_DEV(dev, &vdev->dev);
 
        /* Do we support "hardware" checksums? */
-       if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) {
+       if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
                /* This opens up the world of extra features. */
                dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
-               if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) {
+               if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
                        dev->features |= NETIF_F_TSO | NETIF_F_UFO
                                | NETIF_F_TSO_ECN | NETIF_F_TSO6;
                }
+               /* Individual feature bits: what can host handle? */
+               if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
+                       dev->features |= NETIF_F_TSO;
+               if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
+                       dev->features |= NETIF_F_TSO6;
+               if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
+                       dev->features |= NETIF_F_TSO_ECN;
+               if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+                       dev->features |= NETIF_F_UFO;
        }
 
        /* Configuration may specify what MAC to use.  Otherwise random. */
-       if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) {
+       if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
                vdev->config->get(vdev,
                                  offsetof(struct virtio_net_config, mac),
                                  dev->dev_addr, dev->addr_len);
@@ -454,7 +486,15 @@ static struct virtio_device_id id_table[] = {
        { 0 },
 };
 
+static unsigned int features[] = {
+       VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
+       VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
+       VIRTIO_NET_F_HOST_ECN,
+};
+
 static struct virtio_driver virtio_net = {
+       .feature_table = features,
+       .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table =     id_table,
index 5dd23c93497db90163365b84a7e62917571cd122..883af891ebfb4c54d19daff25495af0a063734f4 100644 (file)
@@ -2611,7 +2611,7 @@ static int strip_open(struct tty_struct *tty)
         * We need a write method.
         */
 
-       if (tty->ops->write == NULL)
+       if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
                return -EOPNOTSUPP;
 
        /*
index 1fd8bb7657024c2629858940fc050a35fc3acab7..66c0fd21894b155e9db690b65a86bfddffca29c4 100644 (file)
@@ -49,7 +49,7 @@
 
 #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
 
-#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
 
 #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
 
@@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
 
 #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
 {\
-       unsigned long start_time = jiffies;\
+       cycles_t start_time = get_cycles();\
        while (1) {\
                sts = op (iommu->reg + offset);\
                if (cond)\
                        break;\
-               if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
+               if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
                        panic("DMAR hardware is malfunctioning\n");\
                cpu_relax();\
        }\
index 72f7476930c857ffa20a4c323dff3af6bf7c9baa..9d6fc8e6285d0c557a5e1778e468f49066ff4da5 100644 (file)
 #include <linux/pci-acpi.h>
 #include "pci.h"
 
-static u32 ctrlset_buf[3] = {0, 0, 0};
-static u32 global_ctrlsets = 0;
+struct acpi_osc_data {
+       acpi_handle handle;
+       u32 ctrlset_buf[3];
+       u32 global_ctrlsets;
+       struct list_head sibiling;
+};
+static LIST_HEAD(acpi_osc_data_list);
+
+static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
+{
+       struct acpi_osc_data *data;
+
+       list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
+               if (data->handle == handle)
+                       return data;
+       }
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return NULL;
+       INIT_LIST_HEAD(&data->sibiling);
+       data->handle = handle;
+       list_add_tail(&data->sibiling, &acpi_osc_data_list);
+       return data;
+}
+
 static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
 
 static acpi_status  
@@ -37,8 +60,27 @@ acpi_query_osc (
        union acpi_object       *out_obj;
        u32                     osc_dw0;
        acpi_status *ret_status = (acpi_status *)retval;
+       struct acpi_osc_data *osc_data;
+       u32 flags = (unsigned long)context, temp;
+       acpi_handle tmp;
+
+       status = acpi_get_handle(handle, "_OSC", &tmp);
+       if (ACPI_FAILURE(status))
+               return status;
+
+       osc_data = acpi_get_osc_data(handle);
+       if (!osc_data) {
+               printk(KERN_ERR "acpi osc data array is full\n");
+               return AE_ERROR;
+       }
+
+       osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
+
+       /* do _OSC query for all possible controls */
+       temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE];
+       osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+       osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
 
-       
        /* Setting up input parameters */
        input.count = 4;
        input.pointer = in_params;
@@ -51,13 +93,11 @@ acpi_query_osc (
        in_params[2].integer.value      = 3;
        in_params[3].type               = ACPI_TYPE_BUFFER;
        in_params[3].buffer.length      = 12;
-       in_params[3].buffer.pointer     = (u8 *)context;
+       in_params[3].buffer.pointer     = (u8 *)osc_data->ctrlset_buf;
 
        status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-       if (ACPI_FAILURE (status)) {
-               *ret_status = status;
-               return status;
-       }
+       if (ACPI_FAILURE(status))
+               goto out_nofree;
        out_obj = output.pointer;
 
        if (out_obj->type != ACPI_TYPE_BUFFER) {
@@ -76,7 +116,8 @@ acpi_query_osc (
                        printk(KERN_DEBUG "_OSC invalid revision\n"); 
                if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
                        /* Update Global Control Set */
-                       global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
+                       osc_data->global_ctrlsets =
+                               *((u32 *)(out_obj->buffer.pointer + 8));
                        status = AE_OK;
                        goto query_osc_out;
                }
@@ -85,12 +126,21 @@ acpi_query_osc (
        }
 
        /* Update Global Control Set */
-       global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
+       osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
        status = AE_OK;
 
 query_osc_out:
        kfree(output.pointer);
+out_nofree:
        *ret_status = status;
+
+       osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
+       osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp;
+       if (ACPI_FAILURE(status)) {
+               /* no osc support at all */
+               osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
+       }
+
        return status;
 }
 
@@ -165,28 +215,15 @@ run_osc_out:
  **/
 acpi_status __pci_osc_support_set(u32 flags, const char *hid)
 {
-       u32 temp;
-       acpi_status retval;
+       acpi_status retval = AE_NOT_FOUND;
 
        if (!(flags & OSC_SUPPORT_MASKS)) {
                return AE_TYPE;
        }
-       ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
-
-       /* do _OSC query for all possible controls */
-       temp = ctrlset_buf[OSC_CONTROL_TYPE];
-       ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-       ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
        acpi_get_devices(hid,
                        acpi_query_osc,
-                       ctrlset_buf,
+                       (void *)(unsigned long)flags,
                        (void **) &retval );
-       ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
-       ctrlset_buf[OSC_CONTROL_TYPE] = temp;
-       if (ACPI_FAILURE(retval)) {
-               /* no osc support at all */
-               ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
-       }
        return AE_OK;
 }
 
@@ -201,19 +238,31 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
 {
        acpi_status     status;
        u32             ctrlset;
+       acpi_handle tmp;
+       struct acpi_osc_data *osc_data;
+
+       status = acpi_get_handle(handle, "_OSC", &tmp);
+       if (ACPI_FAILURE(status))
+               return status;
+
+       osc_data = acpi_get_osc_data(handle);
+       if (!osc_data) {
+               printk(KERN_ERR "acpi osc data array is full\n");
+               return AE_ERROR;
+       }
 
        ctrlset = (flags & OSC_CONTROL_MASKS);
        if (!ctrlset) {
                return AE_TYPE;
        }
-       if (ctrlset_buf[OSC_SUPPORT_TYPE] && 
-               ((global_ctrlsets & ctrlset) != ctrlset)) {
+       if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] &&
+               ((osc_data->global_ctrlsets & ctrlset) != ctrlset)) {
                return AE_SUPPORT;
        }
-       ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
-       status = acpi_run_osc(handle, ctrlset_buf);
+       osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
+       status = acpi_run_osc(handle, osc_data->ctrlset_buf);
        if (ACPI_FAILURE (status)) {
-               ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
+               osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
        }
        
        return status;
index 4a55bf380957fd5142f0dd0a8dfa9c39af6d73e8..3706ce7972dddc0c389f828a3ec0c4635d1d8efe 100644 (file)
@@ -842,13 +842,25 @@ static void set_pcie_port_type(struct pci_dev *pdev)
  * reading the dword at 0x100 which must either be 0 or a valid extended
  * capability header.
  */
-int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix)
+int pci_cfg_space_size_ext(struct pci_dev *dev)
 {
-       int pos;
        u32 status;
 
-       if (!check_exp_pcix)
-               goto skip;
+       if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
+               goto fail;
+       if (status == 0xffffffff)
+               goto fail;
+
+       return PCI_CFG_SPACE_EXP_SIZE;
+
+ fail:
+       return PCI_CFG_SPACE_SIZE;
+}
+
+int pci_cfg_space_size(struct pci_dev *dev)
+{
+       int pos;
+       u32 status;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
        if (!pos) {
@@ -861,23 +873,12 @@ int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix)
                        goto fail;
        }
 
- skip:
-       if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
-               goto fail;
-       if (status == 0xffffffff)
-               goto fail;
-
-       return PCI_CFG_SPACE_EXP_SIZE;
+       return pci_cfg_space_size_ext(dev);
 
  fail:
        return PCI_CFG_SPACE_SIZE;
 }
 
-int pci_cfg_space_size(struct pci_dev *dev)
-{
-       return pci_cfg_space_size_ext(dev, 1);
-}
-
 static void pci_release_bus_bridge_dev(struct device *dev)
 {
        kfree(dev);
index afd914ebe2153aeca5bb78be50dcfed26c7d2603..f2d9c770f51acd834550e506dcff3fea17086922 100644 (file)
@@ -1826,6 +1826,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {
index 74e051535d6c0419cad92901dabb9c0737929deb..c78d77fd7e3bcea2a7a448c979130be99f609f0e 100644 (file)
@@ -194,7 +194,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s
                                default:
                                        pwr |= SET_VCC_VPP(0,0,sock);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n",
-                                                       __FUNCTION__,
+                                                       __func__,
                                                        state->Vcc,
                                                        state->Vpp);
                                        break;
@@ -215,7 +215,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s
                                default:
                                        pwr |= SET_VCC_VPP(0,0,sock);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n",
-                                                       __FUNCTION__,
+                                                       __func__,
                                                        state->Vcc,
                                                        state->Vpp);
                                        break;
@@ -224,7 +224,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s
                default: /* what's this ? */
                        pwr |= SET_VCC_VPP(0,0,sock);
                        printk(KERN_ERR "%s: bad Vcc %d\n",
-                                       __FUNCTION__, state->Vcc);
+                                       __func__, state->Vcc);
                        break;
        }
 
index b693367d38cdbb3d907e14b1dd8275fed044ffe3..75e8f8505e47230156103ccb784a606ed43b8698 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/notifier.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
@@ -71,7 +72,7 @@ extern struct au1000_pcmcia_socket au1000_pcmcia_socket[];
 u32 *pcmcia_base_vaddrs[2];
 extern const unsigned long mips_io_port_base;
 
-DECLARE_MUTEX(pcmcia_sockets_lock);
+static DEFINE_MUTEX(pcmcia_sockets_lock);
 
 static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
        au1x_board_init,
@@ -472,7 +473,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
        struct skt_dev_info *sinfo = dev_get_drvdata(dev);
        int i;
 
-       down(&pcmcia_sockets_lock);
+       mutex_lock(&pcmcia_sockets_lock);
        dev_set_drvdata(dev, NULL);
 
        for (i = 0; i < sinfo->nskt; i++) {
@@ -488,7 +489,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
        }
 
        kfree(sinfo);
-       up(&pcmcia_sockets_lock);
+       mutex_unlock(&pcmcia_sockets_lock);
        return 0;
 }
 
@@ -501,13 +502,13 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
 {
        int i, ret = -ENODEV;
 
-       down(&pcmcia_sockets_lock);
+       mutex_lock(&pcmcia_sockets_lock);
        for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
                ret = au1x00_pcmcia_hw_init[i](dev);
                if (ret == 0)
                        break;
        }
-       up(&pcmcia_sockets_lock);
+       mutex_unlock(&pcmcia_sockets_lock);
        return ret;
 }
 
index 86c0808d6a057920bfe07412cf1e73c9efff7c2a..157e41423a0a5390e42bb5106eccc5be489fb16f 100644 (file)
@@ -244,7 +244,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
                                                        configure->sock);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-                                                       __FUNCTION__, 
+                                                       __func__,
                                                        configure->vcc, 
                                                        configure->vpp);
                                        break;
@@ -272,7 +272,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
                                                        configure->sock);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-                                                       __FUNCTION__, 
+                                                       __func__,
                                                        configure->vcc, 
                                                        configure->vpp);
                                        break;
@@ -300,7 +300,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
                                                        configure->sock);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-                                                       __FUNCTION__, 
+                                                       __func__,
                                                        configure->vcc, 
                                                        configure->vpp);
                                        break;
@@ -309,7 +309,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                default: /* what's this ? */
                        pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock);
                        printk(KERN_ERR "%s: bad Vcc %d\n", 
-                                       __FUNCTION__, configure->vcc);
+                                       __func__, configure->vcc);
                        break;
        }
 
@@ -353,7 +353,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                                default:
                                        pcr |= SET_VCC_VPP(0,0);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-                                                       __FUNCTION__, 
+                                                       __func__,
                                                        configure->vcc, 
                                                        configure->vpp);
                                        break;
@@ -374,7 +374,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                                default:
                                        pcr |= SET_VCC_VPP(0,0);
                                        printk("%s: bad Vcc/Vpp (%d:%d)\n", 
-                                                       __FUNCTION__, 
+                                                       __func__,
                                                        configure->vcc, 
                                                        configure->vpp);
                                        break;
@@ -383,7 +383,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
                default: /* what's this ? */
                        pcr |= SET_VCC_VPP(0,0);
                        printk(KERN_ERR "%s: bad Vcc %d\n", 
-                                       __FUNCTION__, configure->vcc);
+                                       __func__, configure->vcc);
                        break;
        }
 
index ce9d5c44a7b5a8253dc8d553f20b9a246cf38830..c78ed53475107c7371b503aa68c6d6ff96c6c4e6 100644 (file)
@@ -56,7 +56,7 @@
 #define PCMCIA_IRQ             AU1000_GPIO_4
 
 #if 0
-#define DEBUG(x,args...)       printk(__FUNCTION__ ": " x,##args)
+#define DEBUG(x, args...)      printk(__func__ ": " x, ##args)
 #else
 #define DEBUG(x,args...)
 #endif
index 714baaeb6da1257a264c903b4b36d67570c15486..fb2f38dc92c560de378ddab5b688657e82d8661a 100644 (file)
@@ -209,7 +209,7 @@ static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
        }
 }
 
-int cb_alloc(struct pcmcia_socket * s)
+int __ref cb_alloc(struct pcmcia_socket * s)
 {
        struct pci_bus *bus = s->cb_dev->subordinate;
        struct pci_dev *dev;
index 5a85871f5ee919ff3bdb18f10be8715132b037de..e40775443d04c73233735c61b0802eaa4936a751 100644 (file)
@@ -1520,7 +1520,7 @@ static void pcmcia_bus_remove_socket(struct device *dev,
 
 
 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
-static struct class_interface pcmcia_bus_interface = {
+static struct class_interface pcmcia_bus_interface __refdata = {
        .class = &pcmcia_socket_class,
        .add_dev = &pcmcia_bus_add_socket,
        .remove_dev = &pcmcia_bus_remove_socket,
index e54ecc580d9ed328cc887cb843ab58542d5f5b34..e13618656ff7ee7807618c9a52e0398334e04505 100644 (file)
@@ -53,7 +53,7 @@ static int i82092aa_socket_resume (struct pci_dev *dev)
 }
 #endif
 
-static struct pci_driver i82092aa_pci_drv = {
+static struct pci_driver i82092aa_pci_driver = {
        .name           = "i82092aa",
        .id_table       = i82092aa_pci_ids,
        .probe          = i82092aa_pci_probe,
@@ -714,13 +714,13 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_
 
 static int i82092aa_module_init(void)
 {
-       return pci_register_driver(&i82092aa_pci_drv);
+       return pci_register_driver(&i82092aa_pci_driver);
 }
 
 static void i82092aa_module_exit(void)
 {
        enter("i82092aa_module_exit");
-       pci_unregister_driver(&i82092aa_pci_drv);
+       pci_unregister_driver(&i82092aa_pci_driver);
        if (sockets[0].io_base>0)
                         release_region(sockets[0].io_base, 2);
        leave("i82092aa_module_exit");
index bb6db3a582b2292d1dbe7777e87c545a4b00d737..46314b420765e6dffc63d3a5f4ce31241e3bccf6 100644 (file)
@@ -153,7 +153,7 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
 
 static int omap_cf_ss_suspend(struct pcmcia_socket *s)
 {
-       pr_debug("%s: %s\n", driver_name, __FUNCTION__);
+       pr_debug("%s: %s\n", driver_name, __func__);
        return omap_cf_set_socket(s, &dead_socket);
 }
 
index abc10fe49bd85889fa813aba43c703eeacba4678..8bed1dab903983e4f5d8a11f238b59567931cec0 100644 (file)
@@ -778,7 +778,7 @@ static struct pci_device_id pd6729_pci_ids[] = {
 };
 MODULE_DEVICE_TABLE(pci, pd6729_pci_ids);
 
-static struct pci_driver pd6729_pci_drv = {
+static struct pci_driver pd6729_pci_driver = {
        .name           = "pd6729",
        .id_table       = pd6729_pci_ids,
        .probe          = pd6729_pci_probe,
@@ -791,12 +791,12 @@ static struct pci_driver pd6729_pci_drv = {
 
 static int pd6729_module_init(void)
 {
-       return pci_register_driver(&pd6729_pci_drv);
+       return pci_register_driver(&pd6729_pci_driver);
 }
 
 static void pd6729_module_exit(void)
 {
-       pci_unregister_driver(&pd6729_pci_drv);
+       pci_unregister_driver(&pd6729_pci_driver);
 }
 
 module_init(pd6729_module_init);
index 4a05802213c8bdae09138a359bb92ec025d41d2f..881ec8a8e3896bf969213bcc9433d4b9b9a95e3a 100644 (file)
@@ -87,7 +87,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
                default:
                        printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __FUNCTION__, state->Vcc);
+                              __func__, state->Vcc);
                        ret = -1;
                }
 
@@ -104,7 +104,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                pa_dwr_set |= GPIO_A0;
                        else {
                                printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-                                      __FUNCTION__, state->Vpp);
+                                      __func__, state->Vpp);
                                ret = -1;
                                break;
                        }
@@ -128,14 +128,14 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
                default:
                        printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __FUNCTION__, state->Vcc);
+                              __func__, state->Vcc);
                        ret = -1;
                        break;
                }
 
                if (state->Vpp != state->Vcc && state->Vpp != 0) {
                        printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-                              __FUNCTION__, state->Vpp);
+                              __func__, state->Vpp);
                        ret = -1;
                        break;
                }
index 6fa5eaaab8afcf4188fd27f04bb95aa9c5746d16..145b85e0f02c10a84690d6aa0ccf8dd64bc39304 100644 (file)
@@ -99,7 +99,7 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        case 50: power |= MST_PCMCIA_PWR_VCC_50; break;
        default:
                 printk(KERN_ERR "%s(): bad Vcc %u\n",
-                                __FUNCTION__, state->Vcc);
+                                __func__, state->Vcc);
                 ret = -1;
        }
 
@@ -111,7 +111,7 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                          power |= MST_PCMCIA_PWR_VPP_VCC;
                  } else {
                          printk(KERN_ERR "%s(): bad Vpp %u\n",
-                                         __FUNCTION__, state->Vpp);
+                                         __func__, state->Vpp);
                          ret = -1;
                  }
        }
index a8d1007077213c96cdc6fe02b7c75d7b198fcde3..0fcf763b9175a077768d6e85b9a933e24ef52967 100644 (file)
@@ -1045,7 +1045,7 @@ static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
                device_remove_file(dev, *attr);
 }
 
-static struct class_interface pccard_rsrc_interface = {
+static struct class_interface pccard_rsrc_interface __refdata = {
        .class = &pcmcia_socket_class,
        .add_dev = &pccard_sysfs_add_rsrc,
        .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
index 7c57fdd3c8d77ae03985175243c72f1f42bf5ba7..ce133ce81c107c30670e5542777a1ec8c44ede87 100644 (file)
@@ -66,14 +66,14 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat
 
        case 50:
                printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
-                       __FUNCTION__);
+                       __func__);
 
        case 33:  /* Can only apply 3.3V to the CF slot. */
                mask = ASSABET_BCR_CF_PWR;
                break;
 
        default:
-               printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
+               printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__,
                        state->Vcc);
                return -1;
        }
index 62bfc7566ec2a927396bbe48f993b5502fd63d16..607c3f326eca493809022e9c72232cdaddf7a2b8 100644 (file)
@@ -82,14 +82,14 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
        case 0:
                if ((state->Vcc != 0) &&
                    (state->Vcc != badge4_pcmvcc)) {
-                       complain_about_jumpering(__FUNCTION__, "pcmvcc",
+                       complain_about_jumpering(__func__, "pcmvcc",
                                                 badge4_pcmvcc, state->Vcc);
                        // Apply power regardless of the jumpering.
                        // return -1;
                }
                if ((state->Vpp != 0) &&
                    (state->Vpp != badge4_pcmvpp)) {
-                       complain_about_jumpering(__FUNCTION__, "pcmvpp",
+                       complain_about_jumpering(__func__, "pcmvpp",
                                                 badge4_pcmvpp, state->Vpp);
                        return -1;
                }
@@ -98,7 +98,7 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
        case 1:
                if ((state->Vcc != 0) &&
                    (state->Vcc != badge4_cfvcc)) {
-                       complain_about_jumpering(__FUNCTION__, "cfvcc",
+                       complain_about_jumpering(__func__, "cfvcc",
                                                 badge4_cfvcc, state->Vcc);
                        return -1;
                }
@@ -143,7 +143,7 @@ int pcmcia_badge4_init(struct device *dev)
        if (machine_is_badge4()) {
                printk(KERN_INFO
                       "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
-                      __FUNCTION__,
+                      __func__,
                       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
 
                ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2);
index 549a1529fe35800e9c6034a6a4940dcf3460caab..7c3951a2675dd2c5ba8ff3b0194a8ac865294a7d 100644 (file)
@@ -63,7 +63,7 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
        default:
                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                       __FUNCTION__, state->Vcc);
+                       __func__, state->Vcc);
                return -1;
        }
 
index 6284c35dabc687f6ee1fc5afbf89bda6276ffd46..2167e6714d2dcbee063097e92fbee4411c1fbfe6 100644 (file)
@@ -42,7 +42,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
-printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
+printk("%s(): config socket %d vcc %d vpp %d\n", __func__,
        skt->nr, state->Vcc, state->Vpp);
 
   switch (skt->nr) {
@@ -74,7 +74,7 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
 
   if (state->Vpp != state->Vcc && state->Vpp != 0) {
     printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
-          __FUNCTION__, state->Vpp);
+          __func__, state->Vpp);
     return -1;
   }
 
index 5bc9e9532b9d78f48f00ecd94fdcd5211118bd46..687492fcd5b44254913edd61508c83099e467232 100644 (file)
@@ -59,7 +59,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
                        ncr_set = NCR_A0VPP;
                else {
                        printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-                              __FUNCTION__, state->Vpp);
+                              __func__, state->Vpp);
                        return -1;
                }
                break;
@@ -71,7 +71,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
 
                if (state->Vpp != state->Vcc && state->Vpp != 0) {
                        printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-                              __FUNCTION__, state->Vpp);
+                              __func__, state->Vpp);
                        return -1;
                }
                break;
index 9456f5478d09251178534d354a947ffd38032be3..494912fccc0d27dd4cafd93247cc82c4fd3ad52a 100644 (file)
@@ -73,19 +73,19 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 {
        switch (state->Vcc) {
        case 0: /* power off */
-               printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __FUNCTION__);
+               printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__);
                break;
        case 50:
-               printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __FUNCTION__);
+               printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__);
        case 33:
                break;
        default:
                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                      __FUNCTION__, state->Vcc);
+                      __func__, state->Vcc);
                return -1;
        }
 
-       printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __FUNCTION__);
+       printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__);
        
        /* Silently ignore Vpp, output enable, speaker enable. */
 
index 04d6f7f75f7806b6ea8fc66f4bc34b4163bbb3c3..42567de894b942916e3dbfeafe1015f4896adb8d 100644 (file)
@@ -90,7 +90,7 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
        default:
                printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                       __FUNCTION__, state->Vcc);
+                       __func__, state->Vcc);
                clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
                local_irq_restore(flags);
                return -1;
index aa7779d89752681a05e5d10d0aa76c19ff08a648..420a77540f412758979e72b300d7aeac1801b145 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
+#include <linux/mutex.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/spinlock.h>
@@ -353,7 +354,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
                (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
 
        if (map->map >= MAX_IO_WIN) {
-               printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+               printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
                       map->map);
                return -1;
        }
@@ -578,7 +579,7 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
 
 
 LIST_HEAD(soc_pcmcia_sockets);
-DECLARE_MUTEX(soc_pcmcia_sockets_lock);
+static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
 static const char *skt_names[] = {
        "PCMCIA socket 0",
@@ -601,11 +602,11 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
        struct cpufreq_freqs *freqs = data;
        int ret = 0;
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
        list_for_each_entry(skt, &soc_pcmcia_sockets, node)
                if ( skt->ops->frequency_change )
                        ret += skt->ops->frequency_change(skt, val, freqs);
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
 
        return ret;
 }
@@ -642,7 +643,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        struct soc_pcmcia_socket *skt;
        int ret, i;
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
 
        sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
        if (!sinfo) {
@@ -782,7 +783,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        kfree(sinfo);
 
  out:
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
        return ret;
 }
 
@@ -793,7 +794,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
 
        dev_set_drvdata(dev, NULL);
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
        for (i = 0; i < sinfo->nskt; i++) {
                struct soc_pcmcia_socket *skt = &sinfo->skt[i];
 
@@ -818,7 +819,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
        if (list_empty(&soc_pcmcia_sockets))
                soc_pcmcia_cpufreq_unregister();
 
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
 
        kfree(sinfo);
 
index 6f14126889b3457e6c8d7055e9994918e594b793..1edc1da9d3537b208c3af78e8de487e752477f91 100644 (file)
@@ -133,7 +133,6 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_
 
 
 extern struct list_head soc_pcmcia_sockets;
-extern struct semaphore soc_pcmcia_sockets_lock;
 
 extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
 extern int soc_common_drv_pcmcia_remove(struct device *dev);
index 5d9301de17786bd35613e4eecda23ef48f5c35d6..5695a79f3a5262fe3701752a41cce19b43fff937 100644 (file)
@@ -424,7 +424,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
                                start = simple_strtoul(buf, &buf, 0);
                                pnp_res = pnp_add_irq_resource(dev, start, 0);
                                if (pnp_res)
-                                       nirq++;
+                                       pnp_res->index = nirq++;
                                continue;
                        }
                        if (!strnicmp(buf, "dma", 3)) {
index 2e2c457a0fea8e8849f51e4e8d9e4bd36e6be28d..5ff9a4c0447ec8052e0de9a433255051826e1298 100644 (file)
@@ -591,7 +591,8 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
        p[1] = map & 0xff;
        p[2] = (map >> 8) & 0xff;
 
-       dev_dbg(&dev->dev, "  encode irq %d\n", res->start);
+       dev_dbg(&dev->dev, "  encode irq %llu\n",
+               (unsigned long long)res->start);
 }
 
 static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
@@ -602,7 +603,8 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
        map = 1 << res->start;
        p[1] = map & 0xff;
 
-       dev_dbg(&dev->dev, "  encode dma %d\n", res->start);
+       dev_dbg(&dev->dev, "  encode dma %llu\n",
+               (unsigned long long)res->start);
 }
 
 static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
index c8aa55b81fd86458f7c5dbcdcbc486a81c8cb5a7..82810b7bff9ccbf7b2dd183f7e49e4036239ff66 100644 (file)
@@ -209,6 +209,12 @@ static int pda_power_probe(struct platform_device *pdev)
 
        pdata = pdev->dev.platform_data;
 
+       if (pdata->init) {
+               ret = pdata->init(dev);
+               if (ret < 0)
+                       goto init_failed;
+       }
+
        update_status();
        update_charger();
 
@@ -298,6 +304,9 @@ ac_irq_failed:
        if (pdata->is_ac_online)
                power_supply_unregister(&pda_psy_ac);
 ac_supply_failed:
+       if (pdata->exit)
+               pdata->exit(dev);
+init_failed:
 wrongid:
        return ret;
 }
@@ -318,6 +327,8 @@ static int pda_power_remove(struct platform_device *pdev)
                power_supply_unregister(&pda_psy_usb);
        if (pdata->is_ac_online)
                power_supply_unregister(&pda_psy_ac);
+       if (pdata->exit)
+               pdata->exit(dev);
 
        return 0;
 }
index 60a8cf3a0431f870c2b9a87d8466d77fc17ffc4a..9346a862f1f2609bd5bdf834357c65d0bf24803e 100644 (file)
@@ -159,7 +159,7 @@ static int __init pmu_bat_init(void)
                if (!pbat)
                        break;
 
-               sprintf(pbat->name, "PMU battery %d", i);
+               sprintf(pbat->name, "PMU_battery_%d", i);
                pbat->bat.name = pbat->name;
                pbat->bat.properties = pmu_bat_props;
                pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props);
index 6c9592ce49961e6a145463392f2c0523a5569cf6..85edf945ab86a9a3f9c5c93d1484794f0b1acc93 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
+#include <asm/time.h>
 #include <asm/ps3.h>
 #include <asm/lv1call.h>
 #include <asm/cell-pmu.h>
index 7605453b74fd965506e164a0990387aecafa2029..f17513dd9d4ba4a340effd9cb63f5fa6e1a04eeb 100644 (file)
@@ -184,10 +184,7 @@ enum ps3_sys_manager_next_op {
 
 /**
  * enum ps3_sys_manager_wake_source - Next-op wakeup source (bit position mask).
- * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button, IR
- * controller, and bluetooth controller.
- * @PS3_SM_WAKE_RTC:
- * @PS3_SM_WAKE_RTC_ERROR:
+ * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button.
  * @PS3_SM_WAKE_W_O_L: Ether or wireless LAN.
  * @PS3_SM_WAKE_P_O_R: Power on reset.
  *
@@ -200,8 +197,6 @@ enum ps3_sys_manager_next_op {
 enum ps3_sys_manager_wake_source {
        /* version 3 */
        PS3_SM_WAKE_DEFAULT   = 0,
-       PS3_SM_WAKE_RTC       = 0x00000040,
-       PS3_SM_WAKE_RTC_ERROR = 0x00000080,
        PS3_SM_WAKE_W_O_L     = 0x00000400,
        PS3_SM_WAKE_P_O_R     = 0x80000000,
 };
index a83a40b3ebaaf9ad67b08c97a52a481645a0f4fa..0f0d27d1c4ca366916b7958798ac44570681f679 100644 (file)
@@ -184,7 +184,7 @@ ds1511_wdog_disable(void)
 static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
 {
        u8 mon, day, dow, hrs, min, sec, yrs, cen;
-       unsigned int flags;
+       unsigned long flags;
 
        /*
         * won't have to change this for a while
@@ -247,7 +247,7 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
 static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
 {
        unsigned int century;
-       unsigned int flags;
+       unsigned long flags;
 
        spin_lock_irqsave(&ds1511_lock, flags);
        rtc_disable_update();
index ba795a4db1e97289829c3c69dbee613fa2720a25..9f996ec881ce90dbf2a97cef5ecb73e090d634c7 100644 (file)
@@ -51,7 +51,7 @@ EXPORT_SYMBOL(rtc_year_days);
  */
 void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
 {
-       register int days, month, year;
+       unsigned int days, month, year;
 
        days = time / 86400;
        time -= days * 86400;
index 316bfaa80872195badfeda9ec87de81265d77d96..a3e0880b38fb2cdb0116b4168664566fdab84ab4 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/i2c.h>
@@ -803,6 +804,7 @@ static int m41t80_probe(struct i2c_client *client,
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
        if (clientdata->features & M41T80_FEATURE_HT) {
+               save_client = client;
                rc = misc_register(&wdt_dev);
                if (rc)
                        goto exit;
@@ -811,7 +813,6 @@ static int m41t80_probe(struct i2c_client *client,
                        misc_deregister(&wdt_dev);
                        goto exit;
                }
-               save_client = client;
        }
 #endif
        return 0;
index 29f47bacfc77b5503086473f858fb1cc6124f33e..a6fa1f2f2ca6b59726ab099e46a698b4e26cae2d 100644 (file)
@@ -227,7 +227,7 @@ static int s35390a_probe(struct i2c_client *client,
        /* This chip uses multiple addresses, use dummy devices for them */
        for (i = 1; i < 8; ++i) {
                s35390a->client[i] = i2c_new_dummy(client->adapter,
-                                       client->addr + i, "rtc-s35390a");
+                                       client->addr + i);
                if (!s35390a->client[i]) {
                        dev_err(&client->dev, "Address %02x unavailable\n",
                                                client->addr + i);
index 110699bb478751ac619b1e0a6869059dc99318a8..1f88e9e914ec97d41c139519ab6e2e34c77ea4e2 100644 (file)
@@ -616,7 +616,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
                goto err_badres;
        }
 
-       rtc->regbase = (void __iomem *)rtc->res->start;
+       rtc->regbase = ioremap_nocache(rtc->res->start, rtc->regsize);
        if (unlikely(!rtc->regbase)) {
                ret = -EINVAL;
                goto err_badmap;
@@ -626,7 +626,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
                                           &sh_rtc_ops, THIS_MODULE);
        if (IS_ERR(rtc->rtc_dev)) {
                ret = PTR_ERR(rtc->rtc_dev);
-               goto err_badmap;
+               goto err_unmap;
        }
 
        rtc->capabilities = RTC_DEF_CAPABILITIES;
@@ -653,7 +653,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
                dev_err(&pdev->dev,
                        "request period IRQ failed with %d, IRQ %d\n", ret,
                        rtc->periodic_irq);
-               goto err_badmap;
+               goto err_unmap;
        }
 
        ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
@@ -663,7 +663,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
                        "request carry IRQ failed with %d, IRQ %d\n", ret,
                        rtc->carry_irq);
                free_irq(rtc->periodic_irq, rtc);
-               goto err_badmap;
+               goto err_unmap;
        }
 
        ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
@@ -674,7 +674,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
                        rtc->alarm_irq);
                free_irq(rtc->carry_irq, rtc);
                free_irq(rtc->periodic_irq, rtc);
-               goto err_badmap;
+               goto err_unmap;
        }
 
        tmp = readb(rtc->regbase + RCR1);
@@ -684,6 +684,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 
        return 0;
 
+err_unmap:
+       iounmap(rtc->regbase);
 err_badmap:
        release_resource(rtc->res);
 err_badres:
@@ -708,6 +710,8 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
 
        release_resource(rtc->res);
 
+       iounmap(rtc->regbase);
+
        platform_set_drvdata(pdev, NULL);
 
        kfree(rtc);
index c1f2adefad410287fe170ae77a8baa47a8611187..5043150019ac0788e91d4a42ee1d49955c99d527 100644 (file)
@@ -965,8 +965,7 @@ tty3270_write_room(struct tty_struct *tty)
  * Insert character into the screen at the current position with the
  * current color and highlight. This function does NOT do cursor movement.
  */
-static int
-tty3270_put_character(struct tty3270 *tp, char ch)
+static void tty3270_put_character(struct tty3270 *tp, char ch)
 {
        struct tty3270_line *line;
        struct tty3270_cell *cell;
@@ -986,7 +985,6 @@ tty3270_put_character(struct tty3270 *tp, char ch)
        cell->character = tp->view.ascebc[(unsigned int) ch];
        cell->highlight = tp->highlight;
        cell->f_color = tp->f_color;
-       return 1;
 }
 
 /*
@@ -1612,16 +1610,15 @@ tty3270_write(struct tty_struct * tty,
 /*
  * Put single characters to the ttys character buffer
  */
-static void
-tty3270_put_char(struct tty_struct *tty, unsigned char ch)
+static int tty3270_put_char(struct tty_struct *tty, unsigned char ch)
 {
        struct tty3270 *tp;
 
        tp = tty->driver_data;
-       if (!tp)
-               return;
-       if (tp->char_count < TTY3270_CHAR_BUF_SIZE)
-               tp->char_buf[tp->char_count++] = ch;
+       if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE)
+               return 0;
+       tp->char_buf[tp->char_count++] = ch;
+       return 1;
 }
 
 /*
index 40ef948fcb3a5e9b2441bacb6a78fd65f9a693cf..9c21b8f43f9b70ab8b559d9a880bfb160d73ec01 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <asm/cio.h>
 #include <asm/uaccess.h>
+#include <asm/cio.h>
 
 #include "blacklist.h"
 #include "cio.h"
@@ -43,164 +44,169 @@ typedef enum {add, free} range_action;
  * Function: blacklist_range
  * (Un-)blacklist the devices from-to
  */
-static void
-blacklist_range (range_action action, unsigned int from, unsigned int to,
-                unsigned int ssid)
+static int blacklist_range(range_action action, unsigned int from_ssid,
+                          unsigned int to_ssid, unsigned int from,
+                          unsigned int to, int msgtrigger)
 {
-       if (!to)
-               to = from;
-
-       if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) {
-               printk (KERN_WARNING "cio: Invalid blacklist range "
-                       "0.%x.%04x to 0.%x.%04x, skipping\n",
-                       ssid, from, ssid, to);
-               return;
+       if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) {
+               if (msgtrigger)
+                       printk(KERN_WARNING "cio: Invalid cio_ignore range "
+                              "0.%x.%04x-0.%x.%04x\n", from_ssid, from,
+                              to_ssid, to);
+               return 1;
        }
-       for (; from <= to; from++) {
+
+       while ((from_ssid < to_ssid) || ((from_ssid == to_ssid) &&
+              (from <= to))) {
                if (action == add)
-                       set_bit (from, bl_dev[ssid]);
+                       set_bit(from, bl_dev[from_ssid]);
                else
-                       clear_bit (from, bl_dev[ssid]);
+                       clear_bit(from, bl_dev[from_ssid]);
+               from++;
+               if (from > __MAX_SUBCHANNEL) {
+                       from_ssid++;
+                       from = 0;
+               }
        }
+
+       return 0;
 }
 
-/*
- * Function: blacklist_busid
- * Get devno/busid from given string.
- * Shamelessly grabbed from dasd_devmap.c.
- */
-static int
-blacklist_busid(char **str, int *id0, int *ssid, int *devno)
+static int pure_hex(char **cp, unsigned int *val, int min_digit,
+                   int max_digit, int max_val)
 {
-       int val, old_style;
-       char *sav;
+       int diff;
+       unsigned int value;
 
-       sav = *str;
+       diff = 0;
+       *val = 0;
 
-       /* check for leading '0x' */
-       old_style = 0;
-       if ((*str)[0] == '0' && (*str)[1] == 'x') {
-               *str += 2;
-               old_style = 1;
-       }
-       if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
-               goto confused;
-       val = simple_strtoul(*str, str, 16);
-       if (old_style || (*str)[0] != '.') {
-               *id0 = *ssid = 0;
-               if (val < 0 || val > 0xffff)
-                       goto confused;
-               *devno = val;
-               if ((*str)[0] != ',' && (*str)[0] != '-' &&
-                   (*str)[0] != '\n' && (*str)[0] != '\0')
-                       goto confused;
-               return 0;
+       while (isxdigit(**cp) && (diff <= max_digit)) {
+
+               if (isdigit(**cp))
+                       value = **cp - '0';
+               else
+                       value = tolower(**cp) - 'a' + 10;
+               *val = *val * 16 + value;
+               (*cp)++;
+               diff++;
        }
-       /* New style x.y.z busid */
-       if (val < 0 || val > 0xff)
-               goto confused;
-       *id0 = val;
-       (*str)++;
-       if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
-               goto confused;
-       val = simple_strtoul(*str, str, 16);
-       if (val < 0 || val > 0xff || (*str)++[0] != '.')
-               goto confused;
-       *ssid = val;
-       if (!isxdigit((*str)[0]))       /* We require at least one hex digit */
-               goto confused;
-       val = simple_strtoul(*str, str, 16);
-       if (val < 0 || val > 0xffff)
-               goto confused;
-       *devno = val;
-       if ((*str)[0] != ',' && (*str)[0] != '-' &&
-           (*str)[0] != '\n' && (*str)[0] != '\0')
-               goto confused;
+
+       if ((diff < min_digit) || (diff > max_digit) || (*val > max_val))
+               return 1;
+
        return 0;
-confused:
-       strsep(str, ",\n");
-       printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav);
-       return 1;
 }
 
-static int
-blacklist_parse_parameters (char *str, range_action action)
+static int parse_busid(char *str, int *cssid, int *ssid, int *devno,
+                      int msgtrigger)
 {
-       int from, to, from_id0, to_id0, from_ssid, to_ssid;
-
-       while (*str != 0 && *str != '\n') {
-               range_action ra = action;
-               while(*str == ',')
-                       str++;
-               if (*str == '!') {
-                       ra = !action;
-                       ++str;
+       char *str_work;
+       int val, rc, ret;
+
+       rc = 1;
+
+       if (*str == '\0')
+               goto out;
+
+       /* old style */
+       str_work = str;
+       val = simple_strtoul(str, &str_work, 16);
+
+       if (*str_work == '\0') {
+               if (val <= __MAX_SUBCHANNEL) {
+                       *devno = val;
+                       *ssid = 0;
+                       *cssid = 0;
+                       rc = 0;
                }
+               goto out;
+       }
 
-               /*
-                * Since we have to parse the proc commands and the
-                * kernel arguments we have to check four cases
-                */
-               if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 ||
-                   strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) {
-                       int j;
-
-                       str += 3;
-                       for (j=0; j <= __MAX_SSID; j++)
-                               blacklist_range(ra, 0, __MAX_SUBCHANNEL, j);
-               } else {
-                       int rc;
+       /* new style */
+       str_work = str;
+       ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID);
+       if (ret || (str_work[0] != '.'))
+               goto out;
+       str_work++;
+       ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID);
+       if (ret || (str_work[0] != '.'))
+               goto out;
+       str_work++;
+       ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL);
+       if (ret || (str_work[0] != '\0'))
+               goto out;
+
+       rc = 0;
+out:
+       if (rc && msgtrigger)
+               printk(KERN_WARNING "cio: Invalid cio_ignore device '%s'\n",
+                      str);
+
+       return rc;
+}
 
-                       rc = blacklist_busid(&str, &from_id0,
-                                            &from_ssid, &from);
-                       if (rc)
-                               continue;
-                       to = from;
-                       to_id0 = from_id0;
-                       to_ssid = from_ssid;
-                       if (*str == '-') {
-                               str++;
-                               rc = blacklist_busid(&str, &to_id0,
-                                                    &to_ssid, &to);
-                               if (rc)
-                                       continue;
-                       }
-                       if (*str == '-') {
-                               printk(KERN_WARNING "cio: invalid cio_ignore "
-                                       "parameter '%s'\n",
-                                       strsep(&str, ",\n"));
-                               continue;
-                       }
-                       if ((from_id0 != to_id0) ||
-                           (from_ssid != to_ssid)) {
-                               printk(KERN_WARNING "cio: invalid cio_ignore "
-                                      "range %x.%x.%04x-%x.%x.%04x\n",
-                                      from_id0, from_ssid, from,
-                                      to_id0, to_ssid, to);
-                               continue;
+static int blacklist_parse_parameters(char *str, range_action action,
+                                     int msgtrigger)
+{
+       int from_cssid, to_cssid, from_ssid, to_ssid, from, to;
+       int rc, totalrc;
+       char *parm;
+       range_action ra;
+
+       totalrc = 0;
+
+       while ((parm = strsep(&str, ","))) {
+               rc = 0;
+               ra = action;
+               if (*parm == '!') {
+                       if (ra == add)
+                               ra = free;
+                       else
+                               ra = add;
+                       parm++;
+               }
+               if (strcmp(parm, "all") == 0) {
+                       from_cssid = 0;
+                       from_ssid = 0;
+                       from = 0;
+                       to_cssid = __MAX_CSSID;
+                       to_ssid = __MAX_SSID;
+                       to = __MAX_SUBCHANNEL;
+               } else {
+                       rc = parse_busid(strsep(&parm, "-"), &from_cssid,
+                                        &from_ssid, &from, msgtrigger);
+                       if (!rc) {
+                               if (parm != NULL)
+                                       rc = parse_busid(parm, &to_cssid,
+                                                        &to_ssid, &to,
+                                                        msgtrigger);
+                               else {
+                                       to_cssid = from_cssid;
+                                       to_ssid = from_ssid;
+                                       to = from;
+                               }
                        }
-                       blacklist_range (ra, from, to, to_ssid);
                }
+               if (!rc) {
+                       rc = blacklist_range(ra, from_ssid, to_ssid, from, to,
+                                            msgtrigger);
+                       if (rc)
+                               totalrc = 1;
+               } else
+                       totalrc = 1;
        }
-       return 1;
+
+       return totalrc;
 }
 
-/* Parsing the commandline for blacklist parameters, e.g. to blacklist
- * bus ids 0.0.1234, 0.0.1235 and 0.0.1236, you could use any of:
- * - cio_ignore=1234-1236
- * - cio_ignore=0x1234-0x1235,1236
- * - cio_ignore=0x1234,1235-1236
- * - cio_ignore=1236 cio_ignore=1234-0x1236
- * - cio_ignore=1234 cio_ignore=1236 cio_ignore=0x1235
- * - cio_ignore=0.0.1234-0.0.1236
- * - cio_ignore=0.0.1234,0x1235,1236
- * - ...
- */
 static int __init
 blacklist_setup (char *str)
 {
        CIO_MSG_EVENT(6, "Reading blacklist parameters\n");
-       return blacklist_parse_parameters (str, add);
+       if (blacklist_parse_parameters(str, add, 1))
+               return 0;
+       return 1;
 }
 
 __setup ("cio_ignore=", blacklist_setup);
@@ -224,27 +230,23 @@ is_blacklisted (int ssid, int devno)
  * Function: blacklist_parse_proc_parameters
  * parse the stuff which is piped to /proc/cio_ignore
  */
-static void
-blacklist_parse_proc_parameters (char *buf)
+static int blacklist_parse_proc_parameters(char *buf)
 {
-       if (strncmp (buf, "free ", 5) == 0) {
-               blacklist_parse_parameters (buf + 5, free);
-       } else if (strncmp (buf, "add ", 4) == 0) {
-               /* 
-                * We don't need to check for known devices since
-                * css_probe_device will handle this correctly. 
-                */
-               blacklist_parse_parameters (buf + 4, add);
-       } else {
-               printk (KERN_WARNING "cio: cio_ignore: Parse error; \n"
-                       KERN_WARNING "try using 'free all|<devno-range>,"
-                                    "<devno-range>,...'\n"
-                       KERN_WARNING "or 'add <devno-range>,"
-                                    "<devno-range>,...'\n");
-               return;
-       }
+       int rc;
+       char *parm;
+
+       parm = strsep(&buf, " ");
+
+       if (strcmp("free", parm) == 0)
+               rc = blacklist_parse_parameters(buf, free, 0);
+       else if (strcmp("add", parm) == 0)
+               rc = blacklist_parse_parameters(buf, add, 0);
+       else
+               return 1;
 
        css_schedule_reprobe();
+
+       return rc;
 }
 
 /* Iterator struct for all devices. */
@@ -328,6 +330,8 @@ cio_ignore_write(struct file *file, const char __user *user_buf,
                 size_t user_len, loff_t *offset)
 {
        char *buf;
+       size_t i;
+       ssize_t rc, ret;
 
        if (*offset)
                return -EINVAL;
@@ -336,16 +340,27 @@ cio_ignore_write(struct file *file, const char __user *user_buf,
        buf = vmalloc (user_len + 1); /* maybe better use the stack? */
        if (buf == NULL)
                return -ENOMEM;
+       memset(buf, 0, user_len + 1);
+
        if (strncpy_from_user (buf, user_buf, user_len) < 0) {
-               vfree (buf);
-               return -EFAULT;
+               rc = -EFAULT;
+               goto out_free;
        }
-       buf[user_len] = '\0';
 
-       blacklist_parse_proc_parameters (buf);
+       i = user_len - 1;
+       while ((i >= 0) && (isspace(buf[i]) || (buf[i] == 0))) {
+               buf[i] = '\0';
+               i--;
+       }
+       ret = blacklist_parse_proc_parameters(buf);
+       if (ret)
+               rc = -EINVAL;
+       else
+               rc = user_len;
 
+out_free:
        vfree (buf);
-       return user_len;
+       return rc;
 }
 
 static const struct seq_operations cio_ignore_proc_seq_ops = {
index 08a578161306e1088f4fe6786ea85b518cfd7a12..82c6a2d451284424c40fc14791736f642ef80934 100644 (file)
@@ -39,23 +39,6 @@ debug_info_t *cio_debug_msg_id;
 debug_info_t *cio_debug_trace_id;
 debug_info_t *cio_debug_crw_id;
 
-int cio_show_msg;
-
-static int __init
-cio_setup (char *parm)
-{
-       if (!strcmp (parm, "yes"))
-               cio_show_msg = 1;
-       else if (!strcmp (parm, "no"))
-               cio_show_msg = 0;
-       else
-               printk(KERN_ERR "cio: cio_setup: "
-                      "invalid cio_msg parameter '%s'", parm);
-       return 1;
-}
-
-__setup ("cio_msg=", cio_setup);
-
 /*
  * Function: cio_debug_init
  * Initializes three debug logs for common I/O:
@@ -166,7 +149,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
 
        stsch (sch->schid, &sch->schib);
 
-       CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
+       CIO_MSG_EVENT(2, "cio_start: 'not oper' status for "
                      "subchannel 0.%x.%04x!\n", sch->schid.ssid,
                      sch->schid.sch_no);
        sprintf(dbf_text, "no%s", sch->dev.bus_id);
@@ -567,10 +550,9 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
         * ... just being curious we check for non I/O subchannels
         */
        if (sch->st != 0) {
-               CIO_DEBUG(KERN_INFO, 0,
-                         "Subchannel 0.%x.%04x reports "
-                         "non-I/O subchannel type %04X\n",
-                         sch->schid.ssid, sch->schid.sch_no, sch->st);
+               CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports "
+                             "non-I/O subchannel type %04X\n",
+                             sch->schid.ssid, sch->schid.sch_no, sch->st);
                /* We stop here for non-io subchannels. */
                err = sch->st;
                goto out;
@@ -588,7 +570,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
                 * This device must not be known to Linux. So we simply
                 * say that there is no device and return ENODEV.
                 */
-               CIO_MSG_EVENT(4, "Blacklisted device detected "
+               CIO_MSG_EVENT(6, "Blacklisted device detected "
                              "at devno %04X, subchannel set %x\n",
                              sch->schib.pmcw.dev, sch->schid.ssid);
                err = -ENODEV;
@@ -601,12 +583,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
        sch->lpm = sch->schib.pmcw.pam & sch->opm;
        sch->isc = 3;
 
-       CIO_DEBUG(KERN_INFO, 0,
-                 "Detected device %04x on subchannel 0.%x.%04X"
-                 " - PIM = %02X, PAM = %02X, POM = %02X\n",
-                 sch->schib.pmcw.dev, sch->schid.ssid,
-                 sch->schid.sch_no, sch->schib.pmcw.pim,
-                 sch->schib.pmcw.pam, sch->schib.pmcw.pom);
+       CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X "
+                     "- PIM = %02X, PAM = %02X, POM = %02X\n",
+                     sch->schib.pmcw.dev, sch->schid.ssid,
+                     sch->schid.sch_no, sch->schib.pmcw.pim,
+                     sch->schib.pmcw.pam, sch->schib.pmcw.pom);
 
        /*
         * We now have to initially ...
index 3c75412904dc495eade9f6627b148adc730e6e82..6e933aebe01308e2882f45f0320c72a9612e133d 100644 (file)
@@ -118,6 +118,4 @@ extern void *cio_get_console_priv(void);
 #define cio_get_console_priv() NULL
 #endif
 
-extern int cio_show_msg;
-
 #endif
index d7429ef6c666c1c56a4fa8b2ab05e04cc69901cf..e64e8278c42e9979af1d35fb57c685be02327731 100644 (file)
@@ -31,10 +31,4 @@ static inline void CIO_HEX_EVENT(int level, void *data, int length)
        }
 }
 
-#define CIO_DEBUG(printk_level, event_level, msg...) do {      \
-               if (cio_show_msg)                               \
-                       printk(printk_level "cio: " msg);       \
-               CIO_MSG_EVENT(event_level, msg);                \
-       } while (0)
-
 #endif
index 595e327d2f76cc4f47d7f7682fb7e99e88647c3e..a76956512b2d41963a0bd89ddba91a69f7b2553a 100644 (file)
@@ -570,7 +570,7 @@ static void reprobe_all(struct work_struct *unused)
 {
        int ret;
 
-       CIO_MSG_EVENT(2, "reprobe start\n");
+       CIO_MSG_EVENT(4, "reprobe start\n");
 
        need_reprobe = 0;
        /* Make sure initial subchannel scan is done. */
@@ -578,7 +578,7 @@ static void reprobe_all(struct work_struct *unused)
                   atomic_read(&ccw_device_init_count) == 0);
        ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
 
-       CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
+       CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
                      need_reprobe);
 }
 
index abfd601d237a1a07c9aa852e671a8bde507f6cc4..e22813db74a2b6bb81d2d0e1e27ec64acde946e2 100644 (file)
@@ -341,7 +341,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
                rc = device_schedule_callback(&cdev->dev,
                                              ccw_device_remove_orphan_cb);
                if (rc)
-                       CIO_MSG_EVENT(2, "Couldn't unregister orphan "
+                       CIO_MSG_EVENT(0, "Couldn't unregister orphan "
                                      "0.%x.%04x\n",
                                      cdev->private->dev_id.ssid,
                                      cdev->private->dev_id.devno);
@@ -351,7 +351,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
        rc = device_schedule_callback(cdev->dev.parent,
                                      ccw_device_remove_sch_cb);
        if (rc)
-               CIO_MSG_EVENT(2, "Couldn't unregister disconnected device "
+               CIO_MSG_EVENT(0, "Couldn't unregister disconnected device "
                              "0.%x.%04x\n",
                              cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno);
@@ -397,7 +397,7 @@ int ccw_device_set_offline(struct ccw_device *cdev)
        if (ret == 0)
                wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
        else {
-               CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+               CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
                              "device 0.%x.%04x\n",
                              ret, cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno);
@@ -433,7 +433,7 @@ int ccw_device_set_online(struct ccw_device *cdev)
        if (ret == 0)
                wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
        else {
-               CIO_MSG_EVENT(2, "ccw_device_online returned %d, "
+               CIO_MSG_EVENT(0, "ccw_device_online returned %d, "
                              "device 0.%x.%04x\n",
                              ret, cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno);
@@ -451,7 +451,7 @@ int ccw_device_set_online(struct ccw_device *cdev)
        if (ret == 0)
                wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
        else
-               CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+               CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
                              "device 0.%x.%04x\n",
                              ret, cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno);
@@ -803,7 +803,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch,
        other_sch = to_subchannel(get_device(cdev->dev.parent));
        ret = device_move(&cdev->dev, &sch->dev);
        if (ret) {
-               CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed "
+               CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
                              "(ret=%d)!\n", cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno, ret);
                put_device(&other_sch->dev);
@@ -933,7 +933,7 @@ io_subchannel_register(struct work_struct *work)
                        ret = device_reprobe(&cdev->dev);
                        if (ret)
                                /* We can't do much here. */
-                               CIO_MSG_EVENT(2, "device_reprobe() returned"
+                               CIO_MSG_EVENT(0, "device_reprobe() returned"
                                              " %d for 0.%x.%04x\n", ret,
                                              cdev->private->dev_id.ssid,
                                              cdev->private->dev_id.devno);
@@ -1086,7 +1086,7 @@ static void ccw_device_move_to_sch(struct work_struct *work)
        rc = device_move(&cdev->dev, &sch->dev);
        mutex_unlock(&sch->reg_mutex);
        if (rc) {
-               CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel "
+               CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
                              "0.%x.%04x failed (ret=%d)!\n",
                              cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno, sch->schid.ssid,
@@ -1446,8 +1446,7 @@ ccw_device_remove (struct device *dev)
                        wait_event(cdev->private->wait_q,
                                   dev_fsm_final_state(cdev));
                else
-                       //FIXME: we can't fail!
-                       CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+                       CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
                                      "device 0.%x.%04x\n",
                                      ret, cdev->private->dev_id.ssid,
                                      cdev->private->dev_id.devno);
@@ -1524,7 +1523,7 @@ static int recovery_check(struct device *dev, void *data)
        spin_lock_irq(cdev->ccwlock);
        switch (cdev->private->state) {
        case DEV_STATE_DISCONNECTED:
-               CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n",
+               CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n",
                              cdev->private->dev_id.ssid,
                              cdev->private->dev_id.devno);
                dev_fsm_event(cdev, DEV_EVENT_VERIFY);
@@ -1554,7 +1553,7 @@ static void recovery_work_func(struct work_struct *unused)
                }
                spin_unlock_irq(&recovery_lock);
        } else
-               CIO_MSG_EVENT(2, "recovery: end\n");
+               CIO_MSG_EVENT(4, "recovery: end\n");
 }
 
 static DECLARE_WORK(recovery_work, recovery_work_func);
@@ -1572,7 +1571,7 @@ void ccw_device_schedule_recovery(void)
 {
        unsigned long flags;
 
-       CIO_MSG_EVENT(2, "recovery: schedule\n");
+       CIO_MSG_EVENT(4, "recovery: schedule\n");
        spin_lock_irqsave(&recovery_lock, flags);
        if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) {
                recovery_phase = 0;
index 99403b0a97a7737a4865f72d41453048d1fb2600..e268d5a77c12633c4d80d5493add727229fe94fa 100644 (file)
@@ -322,10 +322,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
        same_dev = 0; /* Keep the compiler quiet... */
        switch (state) {
        case DEV_STATE_NOT_OPER:
-               CIO_DEBUG(KERN_WARNING, 2,
-                         "SenseID : unknown device %04x on subchannel "
-                         "0.%x.%04x\n", cdev->private->dev_id.devno,
-                         sch->schid.ssid, sch->schid.sch_no);
+               CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
+                             "subchannel 0.%x.%04x\n",
+                             cdev->private->dev_id.devno,
+                             sch->schid.ssid, sch->schid.sch_no);
                break;
        case DEV_STATE_OFFLINE:
                if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
@@ -348,20 +348,19 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
                        return;
                }
                /* Issue device info message. */
-               CIO_DEBUG(KERN_INFO, 2,
-                         "SenseID : device 0.%x.%04x reports: "
-                         "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
-                         "%04X/%02X\n",
-                         cdev->private->dev_id.ssid,
-                         cdev->private->dev_id.devno,
-                         cdev->id.cu_type, cdev->id.cu_model,
-                         cdev->id.dev_type, cdev->id.dev_model);
+               CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
+                             "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
+                             "%04X/%02X\n",
+                             cdev->private->dev_id.ssid,
+                             cdev->private->dev_id.devno,
+                             cdev->id.cu_type, cdev->id.cu_model,
+                             cdev->id.dev_type, cdev->id.dev_model);
                break;
        case DEV_STATE_BOXED:
-               CIO_DEBUG(KERN_WARNING, 2,
-                         "SenseID : boxed device %04x on subchannel "
-                         "0.%x.%04x\n", cdev->private->dev_id.devno,
-                         sch->schid.ssid, sch->schid.sch_no);
+               CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
+                             " subchannel 0.%x.%04x\n",
+                             cdev->private->dev_id.devno,
+                             sch->schid.ssid, sch->schid.sch_no);
                break;
        }
        cdev->private->state = state;
@@ -443,9 +442,8 @@ ccw_device_done(struct ccw_device *cdev, int state)
 
 
        if (state == DEV_STATE_BOXED)
-               CIO_DEBUG(KERN_WARNING, 2,
-                         "Boxed device %04x on subchannel %04x\n",
-                         cdev->private->dev_id.devno, sch->schid.sch_no);
+               CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
+                             cdev->private->dev_id.devno, sch->schid.sch_no);
 
        if (cdev->private->flags.donotify) {
                cdev->private->flags.donotify = 0;
@@ -900,7 +898,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
                        /* Basic sense hasn't started. Try again. */
                        ccw_device_do_sense(cdev, irb);
                else {
-                       CIO_MSG_EVENT(2, "Huh? 0.%x.%04x: unsolicited "
+                       CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited "
                                      "interrupt during w4sense...\n",
                                      cdev->private->dev_id.ssid,
                                      cdev->private->dev_id.devno);
@@ -1169,8 +1167,10 @@ ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event)
 static void
 ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
 {
-       CIO_MSG_EVENT(0, "dev_jumptable[%i][%i] == NULL\n",
-                     cdev->private->state, dev_event);
+       CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device "
+                     "0.%x.%04x\n", cdev->private->state, dev_event,
+                     cdev->private->dev_id.ssid,
+                     cdev->private->dev_id.devno);
        BUG();
 }
 
index dc4d87f77f6c4bbb45dd1e15fe9582c5cf3f474f..cba7020517edbaa300e5fd2cfc3b80d52380aea3 100644 (file)
@@ -214,7 +214,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
                 *     sense id information. So, for intervention required,
                 *     we use the "whack it until it talks" strategy...
                 */
-               CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel "
+               CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel "
                              "0.%x.%04x reports cmd reject\n",
                              cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no);
@@ -239,7 +239,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
 
                lpm = to_io_private(sch)->orb.lpm;
                if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0)
-                       CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x "
+                       CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x "
                                      "on subchannel 0.%x.%04x is "
                                      "'not operational'\n", lpm,
                                      cdev->private->dev_id.devno,
index c52449a1f9fce93f2af14456c88cb7dc7e390d96..ba559053402e341134af40565b8a571f4b3359d9 100644 (file)
@@ -79,7 +79,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
                        /* ret is 0, -EBUSY, -EACCES or -ENODEV */
                        if (ret != -EACCES)
                                return ret;
-                       CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
+                       CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel "
                                      "0.%x.%04x, lpm %02X, became 'not "
                                      "operational'\n",
                                      cdev->private->dev_id.devno,
@@ -159,7 +159,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
                u8 lpm;
 
                lpm = to_io_private(sch)->orb.lpm;
-               CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x,"
+               CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
                              cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, lpm);
@@ -275,7 +275,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
                        return ret;
        }
        /* PGID command failed on this path. */
-       CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
+       CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel "
                      "0.%x.%04x, lpm %02X, became 'not operational'\n",
                      cdev->private->dev_id.devno, sch->schid.ssid,
                      sch->schid.sch_no, cdev->private->imask);
@@ -317,7 +317,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
                        return ret;
        }
        /* nop command failed on this path. */
-       CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
+       CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel "
                      "0.%x.%04x, lpm %02X, became 'not operational'\n",
                      cdev->private->dev_id.devno, sch->schid.ssid,
                      sch->schid.sch_no, cdev->private->imask);
@@ -362,7 +362,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
                return -EAGAIN;
        }
        if (irb->scsw.cc == 3) {
-               CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x,"
+               CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
                              cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, cdev->private->imask);
@@ -391,7 +391,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
                return -ETIME;
        }
        if (irb->scsw.cc == 3) {
-               CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
+               CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
                              cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, cdev->private->imask);
index 4d4b54277c43d2554e81f4cf5207ed8e3107995b..5080f343ad7482ebac5addfc19768ac5adfeeae2 100644 (file)
@@ -48,10 +48,11 @@ s390_collect_crw_info(void *param)
        int ccode;
        struct semaphore *sem;
        unsigned int chain;
+       int ignore;
 
        sem = (struct semaphore *)param;
 repeat:
-       down_interruptible(sem);
+       ignore = down_interruptible(sem);
        chain = 0;
        while (1) {
                if (unlikely(chain > 1)) {
index 37b85c67b11dcb2404d0f59eafa021d096f47588..c8bad675dbd1717992c6c1db287415fa4e40b933 100644 (file)
@@ -1055,7 +1055,7 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
                                rec->scsi_result = scsi_cmnd->result;
                                rec->scsi_cmnd = (unsigned long)scsi_cmnd;
                                rec->scsi_serial = scsi_cmnd->serial_number;
-                               memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd,
+                               memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
                                        min((int)scsi_cmnd->cmd_len,
                                                ZFCP_DBF_SCSI_OPCODE));
                                rec->scsi_retries = scsi_cmnd->retries;
index 9af2330f07a21c0019b0df6d5495427ae4ba38b3..b2ea4ea051f582009a9dace7d8f6a77109271f0c 100644 (file)
@@ -4014,7 +4014,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
                ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n",
                               scpnt->result);
                ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
-                             (void *) &scpnt->cmnd, scpnt->cmd_len);
+                             scpnt->cmnd, scpnt->cmd_len);
 
                ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n",
                               fcp_rsp_iu->fcp_sns_len);
index 4fab0c23814c90dda8bf55b85e6242c6dbc07d96..b87037ec9805502a52cd4655f6d40a96847d3b66 100644 (file)
@@ -41,7 +41,7 @@
 #define BPP_DELAY 100
 
 static const unsigned  BPP_MAJOR = LP_MAJOR;
-static const chardev_name = "bpp";
+static const char *bpp_dev_name = "bpp";
 
 /* When switching from compatibility to a mode where I can read, try
    the following mode first. */
index f4c4fe90240abdbf995d4c2f8afe0ef9b87374b4..f5a9addb7050d243ea1a5ebd71689b565b2d0214 100644 (file)
@@ -599,7 +599,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
                        (struct NCR_700_command_slot *)SCp->host_scribble;
                
                dma_unmap_single(hostdata->dev, slot->pCmd,
-                                sizeof(SCp->cmnd), DMA_TO_DEVICE);
+                                MAX_COMMAND_SIZE, DMA_TO_DEVICE);
                if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
                        char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
 #ifdef NCR_700_DEBUG
@@ -1004,7 +1004,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                                 * here */
                                NCR_700_unmap(hostdata, SCp, slot);
                                dma_unmap_single(hostdata->dev, slot->pCmd,
-                                                sizeof(SCp->cmnd),
+                                                MAX_COMMAND_SIZE,
                                                 DMA_TO_DEVICE);
 
                                cmnd[0] = REQUEST_SENSE;
@@ -1901,7 +1901,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
        }
        slot->resume_offset = 0;
        slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd,
-                                   sizeof(SCp->cmnd), DMA_TO_DEVICE);
+                                   MAX_COMMAND_SIZE, DMA_TO_DEVICE);
        NCR_700_start_command(SCp);
        return 0;
 }
index 99c57b0c1d540c5d8e7d63138ebd76bc7dc4db4f..81ccbd7f9e34d4d4405ea3982952a608b09f8aa9 100644 (file)
@@ -504,10 +504,9 @@ config SCSI_AIC7XXX_OLD
 source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
 source "drivers/scsi/aic94xx/Kconfig"
 
-# All the I2O code and drivers do not seem to be 64bit safe.
 config SCSI_DPT_I2O
        tristate "Adaptec I2O RAID support "
-       depends on !64BIT && SCSI && PCI && VIRT_TO_BUS
+       depends on SCSI && PCI && VIRT_TO_BUS
        help
          This driver supports all of Adaptec's I2O based RAID controllers as 
          well as the DPT SmartRaid V cards.  This is an Adaptec maintained
@@ -1680,6 +1679,7 @@ config MAC_SCSI
 config SCSI_MAC_ESP
        tristate "Macintosh NCR53c9[46] SCSI"
        depends on MAC && SCSI
+       select SCSI_SPI_ATTRS
        help
          This is the NCR 53c9x SCSI controller found on most of the 68040
          based Macintoshes.
index 792b2e807bf32a6151a38e3c2690e2a33c272f90..ced3eebe252c17164c1b7fe1ab01d82251341f1f 100644 (file)
@@ -895,7 +895,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
        } else {
                scb->tag_msg = 0;       /* No tag support               */
        }
-       memcpy(&scb->cdb[0], &cmd->cmnd, scb->cdb_len);
+       memcpy(scb->cdb, cmd->cmnd, scb->cdb_len);
 }
 
 /**
index 460d4024c46c4c8118cb841d7c5107f69ed0ef29..aa4e77c252735c593e523ae4a9f516045b674733 100644 (file)
@@ -498,6 +498,11 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
                    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
                    (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
                        fsa_dev_ptr->valid = 1;
+                       /* sense_key holds the current state of the spin-up */
+                       if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
+                               fsa_dev_ptr->sense_data.sense_key = NOT_READY;
+                       else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY)
+                               fsa_dev_ptr->sense_data.sense_key = NO_SENSE;
                        fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol);
                        fsa_dev_ptr->size
                          = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
@@ -1509,20 +1514,35 @@ static void io_callback(void *context, struct fib * fibptr)
        scsi_dma_unmap(scsicmd);
 
        readreply = (struct aac_read_reply *)fib_data(fibptr);
-       if (le32_to_cpu(readreply->status) == ST_OK)
-               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-       else {
+       switch (le32_to_cpu(readreply->status)) {
+       case ST_OK:
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                       SAM_STAT_GOOD;
+               dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
+               break;
+       case ST_NOT_READY:
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                       SAM_STAT_CHECK_CONDITION;
+               set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
+                 SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
+               memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+                      min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+                            SCSI_SENSE_BUFFERSIZE));
+               break;
+       default:
 #ifdef AAC_DETAILED_STATUS_INFO
                printk(KERN_WARNING "io_callback: io failed, status = %d\n",
                  le32_to_cpu(readreply->status));
 #endif
-               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                       SAM_STAT_CHECK_CONDITION;
                set_sense(&dev->fsa_dev[cid].sense_data,
                  HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
                  ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
                memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
                       min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
                             SCSI_SENSE_BUFFERSIZE));
+               break;
        }
        aac_fib_complete(fibptr);
        aac_fib_free(fibptr);
@@ -1863,6 +1883,84 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
+static void aac_start_stop_callback(void *context, struct fib *fibptr)
+{
+       struct scsi_cmnd *scsicmd = context;
+
+       if (!aac_valid_context(scsicmd, fibptr))
+               return;
+
+       BUG_ON(fibptr == NULL);
+
+       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
+       scsicmd->scsi_done(scsicmd);
+}
+
+static int aac_start_stop(struct scsi_cmnd *scsicmd)
+{
+       int status;
+       struct fib *cmd_fibcontext;
+       struct aac_power_management *pmcmd;
+       struct scsi_device *sdev = scsicmd->device;
+       struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
+
+       if (!(aac->supplement_adapter_info.SupportedOptions2 &
+             AAC_OPTION_POWER_MANAGEMENT)) {
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                                 SAM_STAT_GOOD;
+               scsicmd->scsi_done(scsicmd);
+               return 0;
+       }
+
+       if (aac->in_reset)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
+       /*
+        *      Allocate and initialize a Fib
+        */
+       cmd_fibcontext = aac_fib_alloc(aac);
+       if (!cmd_fibcontext)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
+       aac_fib_init(cmd_fibcontext);
+
+       pmcmd = fib_data(cmd_fibcontext);
+       pmcmd->command = cpu_to_le32(VM_ContainerConfig);
+       pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT);
+       /* Eject bit ignored, not relevant */
+       pmcmd->sub = (scsicmd->cmnd[4] & 1) ?
+               cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT);
+       pmcmd->cid = cpu_to_le32(sdev_id(sdev));
+       pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
+               cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
+
+       /*
+        *      Now send the Fib to the adapter
+        */
+       status = aac_fib_send(ContainerCommand,
+                 cmd_fibcontext,
+                 sizeof(struct aac_power_management),
+                 FsaNormal,
+                 0, 1,
+                 (fib_callback)aac_start_stop_callback,
+                 (void *)scsicmd);
+
+       /*
+        *      Check that the command queued to the controller
+        */
+       if (status == -EINPROGRESS) {
+               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+               return 0;
+       }
+
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
+       return SCSI_MLQUEUE_HOST_BUSY;
+}
+
 /**
  *     aac_scsi_cmd()          -       Process SCSI command
  *     @scsicmd:               SCSI command block
@@ -1899,7 +1997,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                         *      If the target container doesn't exist, it may have
                         *      been newly created
                         */
-                       if ((fsa_dev_ptr[cid].valid & 1) == 0) {
+                       if (((fsa_dev_ptr[cid].valid & 1) == 0) ||
+                         (fsa_dev_ptr[cid].sense_data.sense_key ==
+                          NOT_READY)) {
                                switch (scsicmd->cmnd[0]) {
                                case SERVICE_ACTION_IN:
                                        if (!(dev->raw_io_interface) ||
@@ -2091,8 +2191,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
                /* Do not cache partition table for arrays */
                scsicmd->device->removable = 1;
-
-               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                 SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
 
                return 0;
@@ -2187,15 +2287,32 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
         *      These commands are all No-Ops
         */
        case TEST_UNIT_READY:
+               if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
+                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+                               SAM_STAT_CHECK_CONDITION;
+                       set_sense(&dev->fsa_dev[cid].sense_data,
+                                 NOT_READY, SENCODE_BECOMING_READY,
+                                 ASENCODE_BECOMING_READY, 0, 0);
+                       memcpy(scsicmd->sense_buffer,
+                              &dev->fsa_dev[cid].sense_data,
+                              min_t(size_t,
+                                    sizeof(dev->fsa_dev[cid].sense_data),
+                                    SCSI_SENSE_BUFFERSIZE));
+                       scsicmd->scsi_done(scsicmd);
+                       return 0;
+               }
+               /* FALLTHRU */
        case RESERVE:
        case RELEASE:
        case REZERO_UNIT:
        case REASSIGN_BLOCKS:
        case SEEK_10:
-       case START_STOP:
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
                return 0;
+
+       case START_STOP:
+               return aac_start_stop(scsicmd);
        }
 
        switch (scsicmd->cmnd[0])
index 113ca9c8934c775e05164f9ab302645bd9c15d53..73916adb8f80f21d587cf1fbe499a14252c042fb 100644 (file)
@@ -12,7 +12,7 @@
  *----------------------------------------------------------------------------*/
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2455
+# define AAC_DRIVER_BUILD 2456
 # define AAC_DRIVER_BRANCH "-ms"
 #endif
 #define MAXIMUM_NUM_CONTAINERS 32
@@ -34,8 +34,8 @@
 #define CONTAINER_TO_ID(cont)          (cont)
 #define CONTAINER_TO_LUN(cont)         (0)
 
-#define aac_phys_to_logical(x)  (x+1)
-#define aac_logical_to_phys(x)  (x?x-1:0)
+#define aac_phys_to_logical(x)  ((x)+1)
+#define aac_logical_to_phys(x)  ((x)?(x)-1:0)
 
 /* #define AAC_DETAILED_STATUS_INFO */
 
@@ -424,6 +424,8 @@ struct aac_init
         */
        __le32  InitFlags;      /* flags for supported features */
 #define INITFLAGS_NEW_COMM_SUPPORTED   0x00000001
+#define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010
+#define INITFLAGS_DRIVER_SUPPORTS_PM   0x00000020
        __le32  MaxIoCommands;  /* max outstanding commands */
        __le32  MaxIoSize;      /* largest I/O command */
        __le32  MaxFibSize;     /* largest FIB to adapter */
@@ -867,8 +869,10 @@ struct aac_supplement_adapter_info
 };
 #define AAC_FEATURE_FALCON     cpu_to_le32(0x00000010)
 #define AAC_FEATURE_JBOD       cpu_to_le32(0x08000000)
-#define AAC_OPTION_MU_RESET    cpu_to_le32(0x00000001)
-#define AAC_OPTION_IGNORE_RESET        cpu_to_le32(0x00000002)
+/* SupportedOptions2 */
+#define AAC_OPTION_MU_RESET            cpu_to_le32(0x00000001)
+#define AAC_OPTION_IGNORE_RESET                cpu_to_le32(0x00000002)
+#define AAC_OPTION_POWER_MANAGEMENT    cpu_to_le32(0x00000004)
 #define AAC_SIS_VERSION_V3     3
 #define AAC_SIS_SLOT_UNKNOWN   0xFF
 
@@ -1148,6 +1152,7 @@ struct aac_dev
 #define                ST_DQUOT        69
 #define                ST_STALE        70
 #define                ST_REMOTE       71
+#define                ST_NOT_READY    72
 #define                ST_BADHANDLE    10001
 #define                ST_NOT_SYNC     10002
 #define                ST_BAD_COOKIE   10003
@@ -1269,6 +1274,18 @@ struct aac_synchronize_reply {
        u8              data[16];
 };
 
+#define CT_POWER_MANAGEMENT    245
+#define CT_PM_START_UNIT       2
+#define CT_PM_STOP_UNIT                3
+#define CT_PM_UNIT_IMMEDIATE   1
+struct aac_power_management {
+       __le32          command;        /* VM_ContainerConfig */
+       __le32          type;           /* CT_POWER_MANAGEMENT */
+       __le32          sub;            /* CT_PM_* */
+       __le32          cid;
+       __le32          parm;           /* CT_PM_sub_* */
+};
+
 #define CT_PAUSE_IO    65
 #define CT_RELEASE_IO  66
 struct aac_pause {
@@ -1536,6 +1553,7 @@ struct aac_mntent {
 #define FSCS_NOTCLEAN  0x0001  /* fsck is necessary before mounting */
 #define FSCS_READONLY  0x0002  /* possible result of broken mirror */
 #define FSCS_HIDDEN    0x0004  /* should be ignored - set during a clear */
+#define FSCS_NOT_READY 0x0008  /* Array spinning up to fulfil request */
 
 struct aac_query_mount {
        __le32          command;
index 294a802450be2efafe4cb0381b9c01c88920aa79..cbac063551073c4db0a0401d05281e7844b72320 100644 (file)
@@ -97,6 +97,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
                init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
                dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
        }
+       init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
+                                      INITFLAGS_DRIVER_SUPPORTS_PM);
        init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
        init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
        init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
index ef67816a6fe5940211247e96e1299343e3f4a298..289304aab690d065e0e65dbb11ede16b87f7f808 100644 (file)
@@ -515,7 +515,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
                                }
                                udelay(5);
                        }
-               } else if (down_interruptible(&fibptr->event_wait) == 0) {
+               } else if (down_interruptible(&fibptr->event_wait)) {
                        fibptr->done = 2;
                        up(&fibptr->event_wait);
                }
@@ -906,15 +906,22 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                case AifEnAddJBOD:
                case AifEnDeleteJBOD:
                        container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
-                       if ((container >> 28))
+                       if ((container >> 28)) {
+                               container = (u32)-1;
                                break;
+                       }
                        channel = (container >> 24) & 0xF;
-                       if (channel >= dev->maximum_num_channels)
+                       if (channel >= dev->maximum_num_channels) {
+                               container = (u32)-1;
                                break;
+                       }
                        id = container & 0xFFFF;
-                       if (id >= dev->maximum_num_physicals)
+                       if (id >= dev->maximum_num_physicals) {
+                               container = (u32)-1;
                                break;
+                       }
                        lun = (container >> 16) & 0xFF;
+                       container = (u32)-1;
                        channel = aac_phys_to_logical(channel);
                        device_config_needed =
                          (((__le32 *)aifcmd->data)[0] ==
@@ -933,13 +940,18 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                        case EM_DRIVE_REMOVAL:
                                container = le32_to_cpu(
                                        ((__le32 *)aifcmd->data)[2]);
-                               if ((container >> 28))
+                               if ((container >> 28)) {
+                                       container = (u32)-1;
                                        break;
+                               }
                                channel = (container >> 24) & 0xF;
-                               if (channel >= dev->maximum_num_channels)
+                               if (channel >= dev->maximum_num_channels) {
+                                       container = (u32)-1;
                                        break;
+                               }
                                id = container & 0xFFFF;
                                lun = (container >> 16) & 0xFF;
+                               container = (u32)-1;
                                if (id >= dev->maximum_num_physicals) {
                                        /* legacy dev_t ? */
                                        if ((0x2000 <= id) || lun || channel ||
@@ -1025,9 +1037,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                break;
        }
 
+       container = 0;
+retry_next:
        if (device_config_needed == NOTHING)
-       for (container = 0; container < dev->maximum_num_containers;
-           ++container) {
+       for (; container < dev->maximum_num_containers; ++container) {
                if ((dev->fsa_dev[container].config_waiting_on == 0) &&
                        (dev->fsa_dev[container].config_needed != NOTHING) &&
                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) {
@@ -1110,6 +1123,11 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
        }
        if (device_config_needed == ADD)
                scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
+       if (channel == CONTAINER_CHANNEL) {
+               container++;
+               device_config_needed = NOTHING;
+               goto retry_next;
+       }
 }
 
 static int _aac_reset_adapter(struct aac_dev *aac, int forced)
index c109f63f827940e275c886e462280bca459c0997..1f7c83607f84729a918c640e83a67daf9e45643e 100644 (file)
@@ -401,6 +401,8 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
 static int aac_slave_configure(struct scsi_device *sdev)
 {
        struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
+       if (aac->jbod && (sdev->type == TYPE_DISK))
+               sdev->removable = 1;
        if ((sdev->type == TYPE_DISK) &&
                        (sdev_channel(sdev) != CONTAINER_CHANNEL) &&
                        (!aac->jbod || sdev->inq_periph_qual) &&
@@ -809,6 +811,12 @@ static ssize_t aac_show_flags(struct device *cdev,
                                "SAI_READ_CAPACITY_16\n");
        if (dev->jbod)
                len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n");
+       if (dev->supplement_adapter_info.SupportedOptions2 &
+               AAC_OPTION_POWER_MANAGEMENT)
+               len += snprintf(buf + len, PAGE_SIZE - len,
+                               "SUPPORTED_POWER_MANAGEMENT\n");
+       if (dev->msi)
+               len += snprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n");
        return len;
 }
 
@@ -1106,7 +1114,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        aac->pdev = pdev;
        aac->name = aac_driver_template.name;
        aac->id = shost->unique_id;
-       aac->cardtype =  index;
+       aac->cardtype = index;
        INIT_LIST_HEAD(&aac->entry);
 
        aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
@@ -1146,19 +1154,19 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
                goto out_deinit;
 
        /*
-        * Lets override negotiations and drop the maximum SG limit to 34
-        */
+        * Lets override negotiations and drop the maximum SG limit to 34
+        */
        if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
                        (shost->sg_tablesize > 34)) {
                shost->sg_tablesize = 34;
                shost->max_sectors = (shost->sg_tablesize * 8) + 112;
-       }
+       }
 
-       if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
+       if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
                        (shost->sg_tablesize > 17)) {
                shost->sg_tablesize = 17;
                shost->max_sectors = (shost->sg_tablesize * 8) + 112;
-       }
+       }
 
        error = pci_set_dma_max_seg_size(pdev,
                (aac->adapter_info.options & AAC_OPT_NEW_COMM) ?
@@ -1174,7 +1182,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        else
                aac->printf_enabled = 0;
 
-       /*
+       /*
         * max channel will be the physical channels plus 1 virtual channel
         * all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
         * physical channels are address by their actual physical number+1
index f5215fd4b73d30bac4603dd7deab26adccb11971..1dca1775f4b14554213fc366b89433e78f2af11c 100644 (file)
@@ -3830,7 +3830,7 @@ static int __init aha152x_init(void)
                        iounmap(p);
                }
                if (!ok && setup_count == 0)
-                       return 0;
+                       return -ENODEV;
 
                printk(KERN_INFO "aha152x: BIOS test: passed, ");
 #else
@@ -3909,14 +3909,14 @@ static int __init aha152x_init(void)
 #endif
        }
 
-       return 1;
+       return 0;
 }
 
 static void __exit aha152x_exit(void)
 {
-       struct aha152x_hostdata *hd;
+       struct aha152x_hostdata *hd, *tmp;
 
-       list_for_each_entry(hd, &aha152x_host_list, host_list) {
+       list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
                struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
 
                aha152x_release(shost);
index 90f5e0a6f2e3f77fbe024850a3de235589bb1ccb..2a730c470f6265abf3d1add4bf77bb8eb4280b96 100644 (file)
@@ -529,10 +529,10 @@ static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
 /* The first entry, 0, is used for dynamic ids, the rest for devices
  * we know about.
  */
-static struct asd_pcidev_struct {
+static const struct asd_pcidev_struct {
        const char * name;
        int (*setup)(struct asd_ha_struct *asd_ha);
-} asd_pcidev_data[] = {
+} asd_pcidev_data[] __devinitconst = {
        /* Id 0 is used for dynamic ids. */
        { .name  = "Adaptec AIC-94xx SAS/SATA Host Adapter",
          .setup = asd_aic9410_setup
@@ -735,7 +735,7 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
 static int __devinit asd_pci_probe(struct pci_dev *dev,
                                   const struct pci_device_id *id)
 {
-       struct asd_pcidev_struct *asd_dev;
+       const struct asd_pcidev_struct *asd_dev;
        unsigned asd_id = (unsigned) id->driver_data;
        struct asd_ha_struct *asd_ha;
        struct Scsi_Host *shost;
index 403a7f2d8f9b21a92fbd2b687560b06e71e5db99..9785d7384199f8c457b346354b73455b8b509151 100644 (file)
@@ -28,7 +28,6 @@
 #define SERVICE_ACTION_OUT_12 0xa9
 #define SERVICE_ACTION_IN_16 0x9e
 #define SERVICE_ACTION_OUT_16 0x9f
-#define VARIABLE_LENGTH_CMD 0x7f
 
 
 
@@ -210,7 +209,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
        cdb0 = cdbp[0];
        switch(cdb0) {
        case VARIABLE_LENGTH_CMD:
-               len = cdbp[7] + 8;
+               len = scsi_varlen_cdb_length(cdbp);
                if (len < 10) {
                        printk("short variable length command, "
                               "len=%d ext_len=%d", len, cdb_len);
@@ -300,7 +299,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
        cdb0 = cdbp[0];
        switch(cdb0) {
        case VARIABLE_LENGTH_CMD:
-               len = cdbp[7] + 8;
+               len = scsi_varlen_cdb_length(cdbp);
                if (len < 10) {
                        printk("short opcode=0x%x command, len=%d "
                               "ext_len=%d", cdb0, len, cdb_len);
@@ -335,10 +334,7 @@ void __scsi_print_command(unsigned char *cdb)
        int k, len;
 
        print_opcode_name(cdb, 0);
-       if (VARIABLE_LENGTH_CMD == cdb[0])
-               len = cdb[7] + 8;
-       else
-               len = COMMAND_SIZE(cdb[0]);
+       len = scsi_command_size(cdb);
        /* print out all bytes in cdb */
        for (k = 0; k < len; ++k) 
                printk(" %02x", cdb[k]);
index cc784e8f6e9d04fef20a29b83bb1cfdec02b3ad2..f60236721e0ddef2074fdd3b08538a3ba1acc67f 100644 (file)
@@ -89,7 +89,7 @@ typedef struct {
        int      njobs;            /* # of jobs sent to HA            */
        int      qdepth;           /* Controller queue depth.         */
        int      wakebase;         /* mpx wakeup base index.          */
-       uLONG    SGsize;           /* Scatter/Gather list size.       */
+       uINT     SGsize;           /* Scatter/Gather list size.       */
        unsigned heads;            /* heads for drives on cntlr.      */
        unsigned sectors;          /* sectors for drives on cntlr.    */
        uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
@@ -97,8 +97,8 @@ typedef struct {
        char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
        uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
        uCHAR    eataVersion;      /* EATA Version                    */
-       uLONG    cpLength;         /* EATA Command Packet Length      */
-       uLONG    spLength;         /* EATA Status Packet Length       */
+       uINT     cpLength;         /* EATA Command Packet Length      */
+       uINT     spLength;         /* EATA Status Packet Length       */
        uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */
        uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
        uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
@@ -107,23 +107,23 @@ typedef struct {
 typedef struct {
        uSHORT length;          // Remaining length of this
        uSHORT drvrHBAnum;      // Relative HBA # used by the driver
-       uLONG baseAddr;         // Base I/O address
+       uINT baseAddr;          // Base I/O address
        uSHORT blinkState;      // Blink LED state (0=Not in blink LED)
        uCHAR pciBusNum;        // PCI Bus # (Optional)
        uCHAR pciDeviceNum;     // PCI Device # (Optional)
        uSHORT hbaFlags;        // Miscellaneous HBA flags
        uSHORT Interrupt;       // Interrupt set for this device.
 #   if (defined(_DPT_ARC))
-       uLONG baseLength;
+       uINT baseLength;
        ADAPTER_OBJECT *AdapterObject;
        LARGE_INTEGER DmaLogicalAddress;
        PVOID DmaVirtualAddress;
        LARGE_INTEGER ReplyLogicalAddress;
        PVOID ReplyVirtualAddress;
 #   else
-       uLONG reserved1;        // Reserved for future expansion
-       uLONG reserved2;        // Reserved for future expansion
-       uLONG reserved3;        // Reserved for future expansion
+       uINT reserved1;         // Reserved for future expansion
+       uINT reserved2;         // Reserved for future expansion
+       uINT reserved3;         // Reserved for future expansion
 #   endif
 } drvrHBAinfo_S;
 
index 94bc894d1200f255d6ef98a3ec74f4c27a8b1a0a..72c8992fdf21e089f5c25b6dfd2c42d507c0eb3c 100644 (file)
 /* to make sure we are talking the same size under all OS's     */
 typedef unsigned char sigBYTE;
 typedef unsigned short sigWORD;
-#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
-typedef uint32_t sigLONG;
-#else
-typedef unsigned long sigLONG;
-#endif
+typedef unsigned int sigINT;
 
 /*
  * use sigWORDLittleEndian for:
@@ -300,7 +296,7 @@ typedef struct dpt_sig {
     sigBYTE dsFiletype;          /* type of file */
     sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
     sigBYTE dsOEM;               /* OEM file was created for */
-    sigLONG dsOS;                /* which Operating systems */
+    sigINT  dsOS;                /* which Operating systems */
     sigWORD dsCapabilities;      /* RAID levels, etc. */
     sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
     sigWORD dsAdapterSupp;       /* DPT adapter families supported */
index d23b70c8c768c3cc9ad782175496cbebc1c7436c..a90c4cb8ea8b29cb29abf267a1b74d5baf64ca35 100644 (file)
    uCHAR        smartROMRevision;
    uSHORT       flags;                  /* See bit definitions above */
    uSHORT       conventionalMemSize;    /* in KB */
-   uLONG        extendedMemSize;        /* in KB */
-   uLONG        osType;                 /* Same as DPTSIG's definition */
+   uINT         extendedMemSize;        /* in KB */
+   uINT         osType;                 /* Same as DPTSIG's definition */
    uCHAR        osMajorVersion;
    uCHAR        osMinorVersion;         /* The OS version */
    uCHAR        osRevision;
index ac92ac143b46783bc9df6323bcfee84680189e8f..8508816f303d08144fb8377da3c5c780ae7c5a9e 100644 (file)
 /*#define DEBUG 1 */
 /*#define UARTDELAY 1 */
 
-/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
-   high pages. Keep the macro around because of the broken unmerged ia64 tree */
-
-#define ADDR32 (0)
-
 #include <linux/module.h>
 
 MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
@@ -108,27 +103,28 @@ static dpt_sig_S DPTI_sig = {
 
 static DEFINE_MUTEX(adpt_configuration_lock);
 
-static struct i2o_sys_tbl *sys_tbl = NULL;
-static int sys_tbl_ind = 0;
-static int sys_tbl_len = 0;
+static struct i2o_sys_tbl *sys_tbl;
+static dma_addr_t sys_tbl_pa;
+static int sys_tbl_ind;
+static int sys_tbl_len;
 
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
 
+static struct class *adpt_sysfs_class;
+
+#ifdef CONFIG_COMPAT
+static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long);
+#endif
+
 static const struct file_operations adpt_fops = {
        .ioctl          = adpt_ioctl,
        .open           = adpt_open,
-       .release        = adpt_close
-};
-
-#ifdef REBOOT_NOTIFIER
-static struct notifier_block adpt_reboot_notifier =
-{
-        adpt_reboot_event,
-        NULL,
-        0
-};
+       .release        = adpt_close,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = compat_adpt_ioctl,
 #endif
+};
 
 /* Structures and definitions for synchronous message posting.
  * See adpt_i2o_post_wait() for description
@@ -151,6 +147,21 @@ static DEFINE_SPINLOCK(adpt_post_wait_lock);
  *============================================================================
  */
 
+static inline int dpt_dma64(adpt_hba *pHba)
+{
+       return (sizeof(dma_addr_t) > 4 && (pHba)->dma64);
+}
+
+static inline u32 dma_high(dma_addr_t addr)
+{
+       return upper_32_bits(addr);
+}
+
+static inline u32 dma_low(dma_addr_t addr)
+{
+       return (u32)addr;
+}
+
 static u8 adpt_read_blink_led(adpt_hba* host)
 {
        if (host->FwDebugBLEDflag_P) {
@@ -178,8 +189,6 @@ static int adpt_detect(struct scsi_host_template* sht)
        struct pci_dev *pDev = NULL;
        adpt_hba* pHba;
 
-       adpt_init();
-
        PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
         /* search for all Adatpec I2O RAID cards */
@@ -247,13 +256,29 @@ rebuild_sys_tab:
                adpt_inquiry(pHba);
        }
 
+       adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
+       if (IS_ERR(adpt_sysfs_class)) {
+               printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n");
+               adpt_sysfs_class = NULL;
+       }
+
        for (pHba = hba_chain; pHba; pHba = pHba->next) {
-               if( adpt_scsi_register(pHba,sht) < 0){
+               if (adpt_scsi_host_alloc(pHba, sht) < 0){
                        adpt_i2o_delete_hba(pHba);
                        continue;
                }
                pHba->initialized = TRUE;
                pHba->state &= ~DPTI_STATE_RESET;
+               if (adpt_sysfs_class) {
+                       struct device *dev = device_create(adpt_sysfs_class,
+                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit),
+                               "dpti%d", pHba->unit);
+                       if (IS_ERR(dev)) {
+                               printk(KERN_WARNING"dpti%d: unable to "
+                                       "create device in dpt_i2o class\n",
+                                       pHba->unit);
+                       }
+               }
        }
 
        // Register our control device node
@@ -282,7 +307,7 @@ static int adpt_release(struct Scsi_Host *host)
 
 static void adpt_inquiry(adpt_hba* pHba)
 {
-       u32 msg[14]; 
+       u32 msg[17]; 
        u32 *mptr;
        u32 *lenptr;
        int direction;
@@ -290,11 +315,12 @@ static void adpt_inquiry(adpt_hba* pHba)
        u32 len;
        u32 reqlen;
        u8* buf;
+       dma_addr_t addr;
        u8  scb[16];
        s32 rcode;
 
        memset(msg, 0, sizeof(msg));
-       buf = kmalloc(80,GFP_KERNEL|ADDR32);
+       buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL);
        if(!buf){
                printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
                return;
@@ -305,7 +331,10 @@ static void adpt_inquiry(adpt_hba* pHba)
        direction = 0x00000000; 
        scsidir  =0x40000000;   // DATA IN  (iop<--dev)
 
-       reqlen = 14;            // SINGLE SGE
+       if (dpt_dma64(pHba))
+               reqlen = 17;            // SINGLE SGE, 64 bit
+       else
+               reqlen = 14;            // SINGLE SGE, 32 bit
        /* Stick the headers on */
        msg[0] = reqlen<<16 | SGL_OFFSET_12;
        msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
@@ -338,8 +367,16 @@ static void adpt_inquiry(adpt_hba* pHba)
 
        /* Now fill in the SGList and command */
        *lenptr = len;
-       *mptr++ = 0xD0000000|direction|len;
-       *mptr++ = virt_to_bus(buf);
+       if (dpt_dma64(pHba)) {
+               *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */
+               *mptr++ = 1 << PAGE_SHIFT;
+               *mptr++ = 0xD0000000|direction|len;
+               *mptr++ = dma_low(addr);
+               *mptr++ = dma_high(addr);
+       } else {
+               *mptr++ = 0xD0000000|direction|len;
+               *mptr++ = addr;
+       }
 
        // Send it on it's way
        rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
@@ -347,7 +384,7 @@ static void adpt_inquiry(adpt_hba* pHba)
                sprintf(pHba->detail, "Adaptec I2O RAID");
                printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
                if (rcode != -ETIME && rcode != -EINTR)
-                       kfree(buf);
+                       dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
        } else {
                memset(pHba->detail, 0, sizeof(pHba->detail));
                memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
@@ -356,7 +393,7 @@ static void adpt_inquiry(adpt_hba* pHba)
                memcpy(&(pHba->detail[40]), " FW: ", 4);
                memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
                pHba->detail[48] = '\0';        /* precautionary */
-               kfree(buf);
+               dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
        }
        adpt_i2o_status_get(pHba);
        return ;
@@ -632,6 +669,91 @@ stop_output:
        return len;
 }
 
+/*
+ *     Turn a struct scsi_cmnd * into a unique 32 bit 'context'.
+ */
+static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd)
+{
+       return (u32)cmd->serial_number;
+}
+
+/*
+ *     Go from a u32 'context' to a struct scsi_cmnd * .
+ *     This could probably be made more efficient.
+ */
+static struct scsi_cmnd *
+       adpt_cmd_from_context(adpt_hba * pHba, u32 context)
+{
+       struct scsi_cmnd * cmd;
+       struct scsi_device * d;
+
+       if (context == 0)
+               return NULL;
+
+       spin_unlock(pHba->host->host_lock);
+       shost_for_each_device(d, pHba->host) {
+               unsigned long flags;
+               spin_lock_irqsave(&d->list_lock, flags);
+               list_for_each_entry(cmd, &d->cmd_list, list) {
+                       if (((u32)cmd->serial_number == context)) {
+                               spin_unlock_irqrestore(&d->list_lock, flags);
+                               scsi_device_put(d);
+                               spin_lock(pHba->host->host_lock);
+                               return cmd;
+                       }
+               }
+               spin_unlock_irqrestore(&d->list_lock, flags);
+       }
+       spin_lock(pHba->host->host_lock);
+
+       return NULL;
+}
+
+/*
+ *     Turn a pointer to ioctl reply data into an u32 'context'
+ */
+static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply)
+{
+#if BITS_PER_LONG == 32
+       return (u32)(unsigned long)reply;
+#else
+       ulong flags = 0;
+       u32 nr, i;
+
+       spin_lock_irqsave(pHba->host->host_lock, flags);
+       nr = ARRAY_SIZE(pHba->ioctl_reply_context);
+       for (i = 0; i < nr; i++) {
+               if (pHba->ioctl_reply_context[i] == NULL) {
+                       pHba->ioctl_reply_context[i] = reply;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(pHba->host->host_lock, flags);
+       if (i >= nr) {
+               kfree (reply);
+               printk(KERN_WARNING"%s: Too many outstanding "
+                               "ioctl commands\n", pHba->name);
+               return (u32)-1;
+       }
+
+       return i;
+#endif
+}
+
+/*
+ *     Go from an u32 'context' to a pointer to ioctl reply data.
+ */
+static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context)
+{
+#if BITS_PER_LONG == 32
+       return (void *)(unsigned long)context;
+#else
+       void *p = pHba->ioctl_reply_context[context];
+       pHba->ioctl_reply_context[context] = NULL;
+
+       return p;
+#endif
+}
 
 /*===========================================================================
  * Error Handling routines
@@ -660,7 +782,7 @@ static int adpt_abort(struct scsi_cmnd * cmd)
        msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
        msg[2] = 0;
        msg[3]= 0; 
-       msg[4] = (u32)cmd;
+       msg[4] = adpt_cmd_to_context(cmd);
        if (pHba->host)
                spin_lock_irq(pHba->host->host_lock);
        rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
@@ -861,27 +983,6 @@ static void adpt_i2o_sys_shutdown(void)
         printk(KERN_INFO "Adaptec I2O controllers down.\n");
 }
 
-/*
- * reboot/shutdown notification.
- *
- * - Quiesce each IOP in the system
- *
- */
-
-#ifdef REBOOT_NOTIFIER
-static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
-{
-
-        if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
-                 return NOTIFY_DONE;
-
-        adpt_i2o_sys_shutdown();
-
-        return NOTIFY_DONE;
-}
-#endif
-
-
 static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
 {
 
@@ -893,6 +994,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
        u32 hba_map1_area_size = 0;
        void __iomem *base_addr_virt = NULL;
        void __iomem *msg_addr_virt = NULL;
+       int dma64 = 0;
 
        int raptorFlag = FALSE;
 
@@ -906,9 +1008,21 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
        }
 
        pci_set_master(pDev);
-       if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
+
+       /*
+        *      See if we should enable dma64 mode.
+        */
+       if (sizeof(dma_addr_t) > 4 &&
+           pci_set_dma_mask(pDev, DMA_64BIT_MASK) == 0) {
+               if (dma_get_required_mask(&pDev->dev) > DMA_32BIT_MASK)
+                       dma64 = 1;
+       }
+       if (!dma64 && pci_set_dma_mask(pDev, DMA_32BIT_MASK) != 0)
                return -EINVAL;
 
+       /* adapter only supports message blocks below 4GB */
+       pci_set_consistent_dma_mask(pDev, DMA_32BIT_MASK);
+
        base_addr0_phys = pci_resource_start(pDev,0);
        hba_map0_area_size = pci_resource_len(pDev,0);
 
@@ -929,6 +1043,25 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
                raptorFlag = TRUE;
        }
 
+#if BITS_PER_LONG == 64
+       /*
+        *      The original Adaptec 64 bit driver has this comment here:
+        *      "x86_64 machines need more optimal mappings"
+        *
+        *      I assume some HBAs report ridiculously large mappings
+        *      and we need to limit them on platforms with IOMMUs.
+        */
+       if (raptorFlag == TRUE) {
+               if (hba_map0_area_size > 128)
+                       hba_map0_area_size = 128;
+               if (hba_map1_area_size > 524288)
+                       hba_map1_area_size = 524288;
+       } else {
+               if (hba_map0_area_size > 524288)
+                       hba_map0_area_size = 524288;
+       }
+#endif
+
        base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
        if (!base_addr_virt) {
                pci_release_regions(pDev);
@@ -991,16 +1124,22 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
        pHba->state = DPTI_STATE_RESET;
        pHba->pDev = pDev;
        pHba->devices = NULL;
+       pHba->dma64 = dma64;
 
        // Initializing the spinlocks
        spin_lock_init(&pHba->state_lock);
        spin_lock_init(&adpt_post_wait_lock);
 
        if(raptorFlag == 0){
-               printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", 
-                       hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
+               printk(KERN_INFO "Adaptec I2O RAID controller"
+                                " %d at %p size=%x irq=%d%s\n", 
+                       hba_count-1, base_addr_virt,
+                       hba_map0_area_size, pDev->irq,
+                       dma64 ? " (64-bit DMA)" : "");
        } else {
-               printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
+               printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d%s\n",
+                       hba_count-1, pDev->irq,
+                       dma64 ? " (64-bit DMA)" : "");
                printk(KERN_INFO"     BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
                printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
        }
@@ -1053,10 +1192,26 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
        if(pHba->msg_addr_virt != pHba->base_addr_virt){
                iounmap(pHba->msg_addr_virt);
        }
-       kfree(pHba->hrt);
-       kfree(pHba->lct);
-       kfree(pHba->status_block);
-       kfree(pHba->reply_pool);
+       if(pHba->FwDebugBuffer_P)
+               iounmap(pHba->FwDebugBuffer_P);
+       if(pHba->hrt) {
+               dma_free_coherent(&pHba->pDev->dev,
+                       pHba->hrt->num_entries * pHba->hrt->entry_len << 2,
+                       pHba->hrt, pHba->hrt_pa);
+       }
+       if(pHba->lct) {
+               dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
+                       pHba->lct, pHba->lct_pa);
+       }
+       if(pHba->status_block) {
+               dma_free_coherent(&pHba->pDev->dev, sizeof(i2o_status_block),
+                       pHba->status_block, pHba->status_block_pa);
+       }
+       if(pHba->reply_pool) {
+               dma_free_coherent(&pHba->pDev->dev,
+                       pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+                       pHba->reply_pool, pHba->reply_pool_pa);
+       }
 
        for(d = pHba->devices; d ; d = next){
                next = d->next;
@@ -1075,23 +1230,19 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
        pci_dev_put(pHba->pDev);
        kfree(pHba);
 
+       if (adpt_sysfs_class)
+               device_destroy(adpt_sysfs_class,
+                               MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+
        if(hba_count <= 0){
                unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
+               if (adpt_sysfs_class) {
+                       class_destroy(adpt_sysfs_class);
+                       adpt_sysfs_class = NULL;
+               }
        }
 }
 
-
-static int adpt_init(void)
-{
-       printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-#ifdef REBOOT_NOTIFIER
-       register_reboot_notifier(&adpt_reboot_notifier);
-#endif
-
-       return 0;
-}
-
-
 static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
 {
        struct adpt_device* d;
@@ -1283,6 +1434,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
 {
        u32 msg[8];
        u8* status;
+       dma_addr_t addr;
        u32 m = EMPTY_QUEUE ;
        ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
 
@@ -1305,12 +1457,13 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                schedule_timeout_uninterruptible(1);
        } while (m == EMPTY_QUEUE);
 
-       status = kzalloc(4, GFP_KERNEL|ADDR32);
+       status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
        if(status == NULL) {
                adpt_send_nop(pHba, m);
                printk(KERN_ERR"IOP reset failed - no free memory.\n");
                return -ENOMEM;
        }
+       memset(status,0,4);
 
        msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
        msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -1318,8 +1471,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
        msg[3]=0;
        msg[4]=0;
        msg[5]=0;
-       msg[6]=virt_to_bus(status);
-       msg[7]=0;     
+       msg[6]=dma_low(addr);
+       msg[7]=dma_high(addr);
 
        memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
        wmb();
@@ -1329,7 +1482,10 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
        while(*status == 0){
                if(time_after(jiffies,timeout)){
                        printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
-                       kfree(status);
+                       /* We lose 4 bytes of "status" here, but we cannot
+                          free these because controller may awake and corrupt
+                          those bytes at any time */
+                       /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
                        return -ETIMEDOUT;
                }
                rmb();
@@ -1348,6 +1504,10 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                        }
                        if(time_after(jiffies,timeout)){
                                printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+                               /* We lose 4 bytes of "status" here, but we
+                                  cannot free these because controller may
+                                  awake and corrupt those bytes at any time */
+                               /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
                                return -ETIMEDOUT;
                        }
                        schedule_timeout_uninterruptible(1);
@@ -1364,7 +1524,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                PDEBUG("%s: Reset completed.\n", pHba->name);
        }
 
-       kfree(status);
+       dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
 #ifdef UARTDELAY
        // This delay is to allow someone attached to the card through the debug UART to 
        // set up the dump levels that they want before the rest of the initialization sequence
@@ -1636,6 +1796,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
        u32 i = 0;
        u32 rcode = 0;
        void *p = NULL;
+       dma_addr_t addr;
        ulong flags = 0;
 
        memset(&msg, 0, MAX_MESSAGE_SIZE*4);
@@ -1668,10 +1829,13 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
        }
        sg_offset = (msg[0]>>4)&0xf;
        msg[2] = 0x40000000; // IOCTL context
-       msg[3] = (u32)reply;
+       msg[3] = adpt_ioctl_to_context(pHba, reply);
+       if (msg[3] == (u32)-1)
+               return -EBUSY;
+
        memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
        if(sg_offset) {
-               // TODO 64bit fix
+               // TODO add 64 bit API
                struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
                sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
                if (sg_count > pHba->sg_tablesize){
@@ -1690,7 +1854,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
                        }
                        sg_size = sg[i].flag_count & 0xffffff;      
                        /* Allocate memory for the transfer */
-                       p = kmalloc(sg_size, GFP_KERNEL|ADDR32);
+                       p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL);
                        if(!p) {
                                printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
                                                pHba->name,sg_size,i,sg_count);
@@ -1700,15 +1864,15 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
                        sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
                        /* Copy in the user's SG buffer if necessary */
                        if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
-                               // TODO 64bit fix
-                               if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) {
+                               // sg_simple_element API is 32 bit
+                               if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) {
                                        printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
                                        rcode = -EFAULT;
                                        goto cleanup;
                                }
                        }
-                       //TODO 64bit fix
-                       sg[i].addr_bus = (u32)virt_to_bus(p);
+                       /* sg_simple_element API is 32 bit, but addr < 4GB */
+                       sg[i].addr_bus = addr;
                }
        }
 
@@ -1736,7 +1900,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
        if(sg_offset) {
        /* Copy back the Scatter Gather buffers back to user space */
                u32 j;
-               // TODO 64bit fix
+               // TODO add 64 bit API
                struct sg_simple_element* sg;
                int sg_size;
 
@@ -1756,14 +1920,14 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
                }
                sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
 
-               // TODO 64bit fix
+               // TODO add 64 bit API
                sg       = (struct sg_simple_element*)(msg + sg_offset);
                for (j = 0; j < sg_count; j++) {
                        /* Copy out the SG list to user's buffer if necessary */
                        if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
                                sg_size = sg[j].flag_count & 0xffffff; 
-                               // TODO 64bit fix
-                               if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) {
+                               // sg_simple_element API is 32 bit
+                               if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) {
                                        printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
                                        rcode = -EFAULT;
                                        goto cleanup;
@@ -1787,56 +1951,22 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
 
 
 cleanup:
-       if (rcode != -ETIME && rcode != -EINTR)
+       if (rcode != -ETIME && rcode != -EINTR) {
+               struct sg_simple_element *sg =
+                               (struct sg_simple_element*) (msg +sg_offset);
                kfree (reply);
-       while(sg_index) {
-               if(sg_list[--sg_index]) {
-                       if (rcode != -ETIME && rcode != -EINTR)
-                               kfree(sg_list[sg_index]);
+               while(sg_index) {
+                       if(sg_list[--sg_index]) {
+                               dma_free_coherent(&pHba->pDev->dev,
+                                       sg[sg_index].flag_count & 0xffffff,
+                                       sg_list[sg_index],
+                                       sg[sg_index].addr_bus);
+                       }
                }
        }
        return rcode;
 }
 
-
-/*
- * This routine returns information about the system.  This does not effect
- * any logic and if the info is wrong - it doesn't matter.
- */
-
-/* Get all the info we can not get from kernel services */
-static int adpt_system_info(void __user *buffer)
-{
-       sysInfo_S si;
-
-       memset(&si, 0, sizeof(si));
-
-       si.osType = OS_LINUX;
-       si.osMajorVersion = 0;
-       si.osMinorVersion = 0;
-       si.osRevision = 0;
-       si.busType = SI_PCI_BUS;
-       si.processorFamily = DPTI_sig.dsProcessorFamily;
-
-#if defined __i386__ 
-       adpt_i386_info(&si);
-#elif defined (__ia64__)
-       adpt_ia64_info(&si);
-#elif defined(__sparc__)
-       adpt_sparc_info(&si);
-#elif defined (__alpha__)
-       adpt_alpha_info(&si);
-#else
-       si.processorType = 0xff ;
-#endif
-       if(copy_to_user(buffer, &si, sizeof(si))){
-               printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si)
 {
@@ -1847,7 +1977,6 @@ static void adpt_ia64_info(sysInfo_S* si)
 }
 #endif
 
-
 #if defined __sparc__ 
 static void adpt_sparc_info(sysInfo_S* si)
 {
@@ -1857,7 +1986,6 @@ static void adpt_sparc_info(sysInfo_S* si)
        si->processorType = PROC_ULTRASPARC;
 }
 #endif
-
 #if defined __alpha__ 
 static void adpt_alpha_info(sysInfo_S* si)
 {
@@ -1869,7 +1997,6 @@ static void adpt_alpha_info(sysInfo_S* si)
 #endif
 
 #if defined __i386__
-
 static void adpt_i386_info(sysInfo_S* si)
 {
        // This is all the info we need for now
@@ -1890,9 +2017,45 @@ static void adpt_i386_info(sysInfo_S* si)
                break;
        }
 }
+#endif
 
+/*
+ * This routine returns information about the system.  This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void __user *buffer)
+{
+       sysInfo_S si;
+
+       memset(&si, 0, sizeof(si));
+
+       si.osType = OS_LINUX;
+       si.osMajorVersion = 0;
+       si.osMinorVersion = 0;
+       si.osRevision = 0;
+       si.busType = SI_PCI_BUS;
+       si.processorFamily = DPTI_sig.dsProcessorFamily;
+
+#if defined __i386__
+       adpt_i386_info(&si);
+#elif defined (__ia64__)
+       adpt_ia64_info(&si);
+#elif defined(__sparc__)
+       adpt_sparc_info(&si);
+#elif defined (__alpha__)
+       adpt_alpha_info(&si);
+#else
+       si.processorType = 0xff ;
 #endif
+       if (copy_to_user(buffer, &si, sizeof(si))){
+               printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+               return -EFAULT;
+       }
 
+       return 0;
+}
 
 static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
              ulong arg)
@@ -1978,6 +2141,38 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
        return error;
 }
 
+#ifdef CONFIG_COMPAT
+static long compat_adpt_ioctl(struct file *file,
+                               unsigned int cmd, unsigned long arg)
+{
+       struct inode *inode;
+       long ret;
+       inode = file->f_dentry->d_inode;
+       lock_kernel();
+       switch(cmd) {
+               case DPT_SIGNATURE:
+               case I2OUSRCMD:
+               case DPT_CTRLINFO:
+               case DPT_SYSINFO:
+               case DPT_BLINKLED:
+               case I2ORESETCMD:
+               case I2ORESCANCMD:
+               case (DPT_TARGET_BUSY & 0xFFFF):
+               case DPT_TARGET_BUSY:
+                       ret = adpt_ioctl(inode, file, cmd, arg);
+                       break;
+               default:
+                       ret =  -ENOIOCTLCMD;
+       }
+       unlock_kernel();
+       return ret;
+}
+#endif
 
 static irqreturn_t adpt_isr(int irq, void *dev_id)
 {
@@ -2009,7 +2204,16 @@ static irqreturn_t adpt_isr(int irq, void *dev_id)
                                goto out;
                        }
                }
-               reply = bus_to_virt(m);
+               if (pHba->reply_pool_pa <= m &&
+                   m < pHba->reply_pool_pa +
+                       (pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)) {
+                       reply = (u8 *)pHba->reply_pool +
+                                               (m - pHba->reply_pool_pa);
+               } else {
+                       /* Ick, we should *never* be here */
+                       printk(KERN_ERR "dpti: reply frame not from pool\n");
+                       reply = (u8 *)bus_to_virt(m);
+               }
 
                if (readl(reply) & MSG_FAIL) {
                        u32 old_m = readl(reply+28); 
@@ -2029,7 +2233,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id)
                } 
                context = readl(reply+8);
                if(context & 0x40000000){ // IOCTL
-                       void *p = (void *)readl(reply+12);
+                       void *p = adpt_ioctl_from_context(pHba, readl(reply+12));
                        if( p != NULL) {
                                memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
                        }
@@ -2043,15 +2247,17 @@ static irqreturn_t adpt_isr(int irq, void *dev_id)
                                status = I2O_POST_WAIT_OK;
                        }
                        if(!(context & 0x40000000)) {
-                               cmd = (struct scsi_cmnd*) readl(reply+12); 
+                               cmd = adpt_cmd_from_context(pHba,
+                                                       readl(reply+12));
                                if(cmd != NULL) {
                                        printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
                                }
                        }
                        adpt_i2o_post_wait_complete(context, status);
                } else { // SCSI message
-                       cmd = (struct scsi_cmnd*) readl(reply+12); 
+                       cmd = adpt_cmd_from_context (pHba, readl(reply+12));
                        if(cmd != NULL){
+                               scsi_dma_unmap(cmd);
                                if(cmd->serial_number != 0) { // If not timedout
                                        adpt_i2o_to_scsi(reply, cmd);
                                }
@@ -2072,6 +2278,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        int i;
        u32 msg[MAX_MESSAGE_SIZE];
        u32* mptr;
+       u32* lptr;
        u32 *lenptr;
        int direction;
        int scsidir;
@@ -2079,6 +2286,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        u32 len;
        u32 reqlen;
        s32 rcode;
+       dma_addr_t addr;
 
        memset(msg, 0 , sizeof(msg));
        len = scsi_bufflen(cmd);
@@ -2118,7 +2326,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        // I2O_CMD_SCSI_EXEC
        msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
        msg[2] = 0;
-       msg[3] = (u32)cmd;      /* We want the SCSI control block back */
+       msg[3] = adpt_cmd_to_context(cmd);  /* Want SCSI control block back */
        // Our cards use the transaction context as the tag for queueing
        // Adaptec/DPT Private stuff 
        msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
@@ -2136,7 +2344,13 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        memcpy(mptr, cmd->cmnd, cmd->cmd_len);
        mptr+=4;
        lenptr=mptr++;          /* Remember me - fill in when we know */
-       reqlen = 14;            // SINGLE SGE
+       if (dpt_dma64(pHba)) {
+               reqlen = 16;            // SINGLE SGE
+               *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */
+               *mptr++ = 1 << PAGE_SHIFT;
+       } else {
+               reqlen = 14;            // SINGLE SGE
+       }
        /* Now fill in the SGList and command */
 
        nseg = scsi_dma_map(cmd);
@@ -2146,12 +2360,16 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
 
                len = 0;
                scsi_for_each_sg(cmd, sg, nseg, i) {
+                       lptr = mptr;
                        *mptr++ = direction|0x10000000|sg_dma_len(sg);
                        len+=sg_dma_len(sg);
-                       *mptr++ = sg_dma_address(sg);
+                       addr = sg_dma_address(sg);
+                       *mptr++ = dma_low(addr);
+                       if (dpt_dma64(pHba))
+                               *mptr++ = dma_high(addr);
                        /* Make this an end of list */
                        if (i == nseg - 1)
-                               mptr[-2] = direction|0xD0000000|sg_dma_len(sg);
+                               *lptr = direction|0xD0000000|sg_dma_len(sg);
                }
                reqlen = mptr - msg;
                *lenptr = len;
@@ -2177,13 +2395,13 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
 }
 
 
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
+static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht)
 {
-       struct Scsi_Host *host = NULL;
+       struct Scsi_Host *host;
 
-       host = scsi_register(sht, sizeof(adpt_hba*));
+       host = scsi_host_alloc(sht, sizeof(adpt_hba*));
        if (host == NULL) {
-               printk ("%s: scsi_register returned NULL\n",pHba->name);
+               printk("%s: scsi_host_alloc returned NULL\n", pHba->name);
                return -1;
        }
        host->hostdata[0] = (unsigned long)pHba;
@@ -2200,7 +2418,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
        host->max_lun = 256;
        host->max_channel = pHba->top_scsi_channel + 1;
        host->cmd_per_lun = 1;
-       host->unique_id = (uint) pHba;
+       host->unique_id = (u32)sys_tbl_pa + pHba->unit;
        host->sg_tablesize = pHba->sg_tablesize;
        host->can_queue = pHba->post_fifo_size;
 
@@ -2640,11 +2858,10 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
 static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 {
        u8 *status;
+       dma_addr_t addr;
        u32 __iomem *msg = NULL;
        int i;
        ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
-       u32* ptr;
-       u32 outbound_frame;  // This had to be a 32 bit address
        u32 m;
 
        do {
@@ -2663,13 +2880,14 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 
        msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
 
-       status = kzalloc(4, GFP_KERNEL|ADDR32);
+       status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
        if (!status) {
                adpt_send_nop(pHba, m);
                printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
                        pHba->name);
                return -ENOMEM;
        }
+       memset(status, 0, 4);
 
        writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
        writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
@@ -2678,7 +2896,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
        writel(4096, &msg[4]);          /* Host page frame size */
        writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);   /* Outbound msg frame size and Initcode */
        writel(0xD0000004, &msg[6]);            /* Simple SG LE, EOB */
-       writel(virt_to_bus(status), &msg[7]);
+       writel((u32)addr, &msg[7]);
 
        writel(m, pHba->post_port);
        wmb();
@@ -2693,6 +2911,10 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
                rmb();
                if(time_after(jiffies,timeout)){
                        printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
+                       /* We lose 4 bytes of "status" here, but we
+                          cannot free these because controller may
+                          awake and corrupt those bytes at any time */
+                       /* dma_free_coherent(&pHba->pDev->dev, 4, status, addr); */
                        return -ETIMEDOUT;
                }
                schedule_timeout_uninterruptible(1);
@@ -2701,25 +2923,30 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
        // If the command was successful, fill the fifo with our reply
        // message packets
        if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
-               kfree(status);
+               dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
                return -2;
        }
-       kfree(status);
+       dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
 
-       kfree(pHba->reply_pool);
+       if(pHba->reply_pool != NULL) {
+               dma_free_coherent(&pHba->pDev->dev,
+                       pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+                       pHba->reply_pool, pHba->reply_pool_pa);
+       }
 
-       pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+       pHba->reply_pool = dma_alloc_coherent(&pHba->pDev->dev,
+                               pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+                               &pHba->reply_pool_pa, GFP_KERNEL);
        if (!pHba->reply_pool) {
                printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
                return -ENOMEM;
        }
+       memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
 
-       ptr = pHba->reply_pool;
        for(i = 0; i < pHba->reply_fifo_size; i++) {
-               outbound_frame = (u32)virt_to_bus(ptr);
-               writel(outbound_frame, pHba->reply_port);
+               writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4),
+                       pHba->reply_port);
                wmb();
-               ptr +=  REPLY_FRAME_SIZE;
        }
        adpt_i2o_status_get(pHba);
        return 0;
@@ -2743,11 +2970,11 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
        u32 m;
        u32 __iomem *msg;
        u8 *status_block=NULL;
-       ulong status_block_bus;
 
        if(pHba->status_block == NULL) {
-               pHba->status_block = (i2o_status_block*)
-                       kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
+               pHba->status_block = dma_alloc_coherent(&pHba->pDev->dev,
+                                       sizeof(i2o_status_block),
+                                       &pHba->status_block_pa, GFP_KERNEL);
                if(pHba->status_block == NULL) {
                        printk(KERN_ERR
                        "dpti%d: Get Status Block failed; Out of memory. \n", 
@@ -2757,7 +2984,6 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
        }
        memset(pHba->status_block, 0, sizeof(i2o_status_block));
        status_block = (u8*)(pHba->status_block);
-       status_block_bus = virt_to_bus(pHba->status_block);
        timeout = jiffies+TMOUT_GETSTATUS*HZ;
        do {
                rmb();
@@ -2782,8 +3008,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
        writel(0, &msg[3]);
        writel(0, &msg[4]);
        writel(0, &msg[5]);
-       writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
-       writel(0, &msg[7]);
+       writel( dma_low(pHba->status_block_pa), &msg[6]);
+       writel( dma_high(pHba->status_block_pa), &msg[7]);
        writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
 
        //post message
@@ -2812,7 +3038,17 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
        }
 
        // Calculate the Scatter Gather list size
-       pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
+       if (dpt_dma64(pHba)) {
+               pHba->sg_tablesize
+                 = ((pHba->status_block->inbound_frame_size * 4
+                 - 14 * sizeof(u32))
+                 / (sizeof(struct sg_simple_element) + sizeof(u32)));
+       } else {
+               pHba->sg_tablesize
+                 = ((pHba->status_block->inbound_frame_size * 4
+                 - 12 * sizeof(u32))
+                 / sizeof(struct sg_simple_element));
+       }
        if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
                pHba->sg_tablesize = SG_LIST_ELEMENTS;
        }
@@ -2863,7 +3099,9 @@ static int adpt_i2o_lct_get(adpt_hba* pHba)
        }
        do {
                if (pHba->lct == NULL) {
-                       pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
+                       pHba->lct = dma_alloc_coherent(&pHba->pDev->dev,
+                                       pHba->lct_size, &pHba->lct_pa,
+                                       GFP_KERNEL);
                        if(pHba->lct == NULL) {
                                printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
                                        pHba->name);
@@ -2879,7 +3117,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba)
                msg[4] = 0xFFFFFFFF;    /* All devices */
                msg[5] = 0x00000000;    /* Report now */
                msg[6] = 0xD0000000|pHba->lct_size;
-               msg[7] = virt_to_bus(pHba->lct);
+               msg[7] = (u32)pHba->lct_pa;
 
                if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
                        printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
@@ -2890,7 +3128,8 @@ static int adpt_i2o_lct_get(adpt_hba* pHba)
 
                if ((pHba->lct->table_size << 2) > pHba->lct_size) {
                        pHba->lct_size = pHba->lct->table_size << 2;
-                       kfree(pHba->lct);
+                       dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
+                                       pHba->lct, pHba->lct_pa);
                        pHba->lct = NULL;
                }
        } while (pHba->lct == NULL);
@@ -2901,13 +3140,19 @@ static int adpt_i2o_lct_get(adpt_hba* pHba)
        // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
        if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
                pHba->FwDebugBufferSize = buf[1];
-               pHba->FwDebugBuffer_P    = pHba->base_addr_virt + buf[0];
-               pHba->FwDebugFlags_P     = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET;
-               pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
-               pHba->FwDebugBLEDflag_P  = pHba->FwDebugBLEDvalue_P + 1;
-               pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET;
-               pHba->FwDebugBuffer_P += buf[2]; 
-               pHba->FwDebugFlags = 0;
+               pHba->FwDebugBuffer_P = ioremap(pHba->base_addr_phys + buf[0],
+                                               pHba->FwDebugBufferSize);
+               if (pHba->FwDebugBuffer_P) {
+                       pHba->FwDebugFlags_P     = pHba->FwDebugBuffer_P +
+                                                       FW_DEBUG_FLAGS_OFFSET;
+                       pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P +
+                                                       FW_DEBUG_BLED_OFFSET;
+                       pHba->FwDebugBLEDflag_P  = pHba->FwDebugBLEDvalue_P + 1;
+                       pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P +
+                                               FW_DEBUG_STR_LENGTH_OFFSET;
+                       pHba->FwDebugBuffer_P += buf[2]; 
+                       pHba->FwDebugFlags = 0;
+               }
        }
 
        return 0;
@@ -2915,25 +3160,30 @@ static int adpt_i2o_lct_get(adpt_hba* pHba)
 
 static int adpt_i2o_build_sys_table(void)
 {
-       adpt_hba* pHba = NULL;
+       adpt_hba* pHba = hba_chain;
        int count = 0;
 
+       if (sys_tbl)
+               dma_free_coherent(&pHba->pDev->dev, sys_tbl_len,
+                                       sys_tbl, sys_tbl_pa);
+
        sys_tbl_len = sizeof(struct i2o_sys_tbl) +      // Header + IOPs
                                (hba_count) * sizeof(struct i2o_sys_tbl_entry);
 
-       kfree(sys_tbl);
-
-       sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+       sys_tbl = dma_alloc_coherent(&pHba->pDev->dev,
+                               sys_tbl_len, &sys_tbl_pa, GFP_KERNEL);
        if (!sys_tbl) {
                printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");     
                return -ENOMEM;
        }
+       memset(sys_tbl, 0, sys_tbl_len);
 
        sys_tbl->num_entries = hba_count;
        sys_tbl->version = I2OVERSION;
        sys_tbl->change_ind = sys_tbl_ind++;
 
        for(pHba = hba_chain; pHba; pHba = pHba->next) {
+               u64 addr;
                // Get updated Status Block so we have the latest information
                if (adpt_i2o_status_get(pHba)) {
                        sys_tbl->num_entries--;
@@ -2949,8 +3199,9 @@ static int adpt_i2o_build_sys_table(void)
                sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
                sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
                sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
-               sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
-               sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
+               addr = pHba->base_addr_phys + 0x40;
+               sys_tbl->iops[count].inbound_low = dma_low(addr);
+               sys_tbl->iops[count].inbound_high = dma_high(addr);
 
                count++;
        }
@@ -3086,7 +3337,8 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
 
        do {
                if (pHba->hrt == NULL) {
-                       pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
+                       pHba->hrt = dma_alloc_coherent(&pHba->pDev->dev,
+                                       size, &pHba->hrt_pa, GFP_KERNEL);
                        if (pHba->hrt == NULL) {
                                printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
                                return -ENOMEM;
@@ -3098,7 +3350,7 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
                msg[2]= 0;
                msg[3]= 0;
                msg[4]= (0xD0000000 | size);    /* Simple transaction */
-               msg[5]= virt_to_bus(pHba->hrt);   /* Dump it here */
+               msg[5]= (u32)pHba->hrt_pa;      /* Dump it here */
 
                if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
                        printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
@@ -3106,8 +3358,10 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
                }
 
                if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
-                       size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
-                       kfree(pHba->hrt);
+                       int newsize = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
+                       dma_free_coherent(&pHba->pDev->dev, size,
+                               pHba->hrt, pHba->hrt_pa);
+                       size = newsize;
                        pHba->hrt = NULL;
                }
        } while(pHba->hrt == NULL);
@@ -3121,33 +3375,54 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
                        int group, int field, void *buf, int buflen)
 {
        u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
-       u8 *resblk;
+       u8 *opblk_va;
+       dma_addr_t opblk_pa;
+       u8 *resblk_va;
+       dma_addr_t resblk_pa;
 
        int size;
 
        /* 8 bytes for header */
-       resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32);
-       if (resblk == NULL) {
+       resblk_va = dma_alloc_coherent(&pHba->pDev->dev,
+                       sizeof(u8) * (8 + buflen), &resblk_pa, GFP_KERNEL);
+       if (resblk_va == NULL) {
                printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name);
                return -ENOMEM;
        }
 
+       opblk_va = dma_alloc_coherent(&pHba->pDev->dev,
+                       sizeof(opblk), &opblk_pa, GFP_KERNEL);
+       if (opblk_va == NULL) {
+               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+                       resblk_va, resblk_pa);
+               printk(KERN_CRIT "%s: query operatio failed; Out of memory.\n",
+                       pHba->name);
+               return -ENOMEM;
+       }
        if (field == -1)                /* whole group */
                        opblk[4] = -1;
 
+       memcpy(opblk_va, opblk, sizeof(opblk));
        size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
-               opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen));
+               opblk_va, opblk_pa, sizeof(opblk),
+               resblk_va, resblk_pa, sizeof(u8)*(8+buflen));
+       dma_free_coherent(&pHba->pDev->dev, sizeof(opblk), opblk_va, opblk_pa);
        if (size == -ETIME) {
+               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+                                                       resblk_va, resblk_pa);
                printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
                return -ETIME;
        } else if (size == -EINTR) {
+               dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+                                                       resblk_va, resblk_pa);
                printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
                return -EINTR;
        }
                        
-       memcpy(buf, resblk+8, buflen);  /* cut off header */
+       memcpy(buf, resblk_va+8, buflen);  /* cut off header */
 
-       kfree(resblk);
+       dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+                                               resblk_va, resblk_pa);
        if (size < 0)
                return size;    
 
@@ -3164,10 +3439,11 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
  *     ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
  */
 static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-                 void *opblk, int oplen, void *resblk, int reslen)
+                 void *opblk_va,  dma_addr_t opblk_pa, int oplen,
+               void *resblk_va, dma_addr_t resblk_pa, int reslen)
 {
        u32 msg[9]; 
-       u32 *res = (u32 *)resblk;
+       u32 *res = (u32 *)resblk_va;
        int wait_status;
 
        msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
@@ -3176,12 +3452,12 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
        msg[3] = 0;
        msg[4] = 0;
        msg[5] = 0x54000000 | oplen;    /* OperationBlock */
-       msg[6] = virt_to_bus(opblk);
+       msg[6] = (u32)opblk_pa;
        msg[7] = 0xD0000000 | reslen;   /* ResultBlock */
-       msg[8] = virt_to_bus(resblk);
+       msg[8] = (u32)resblk_pa;
 
        if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
-               printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk);
+               printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk_va);
                return wait_status;     /* -DetailedStatus */
        }
 
@@ -3284,7 +3560,7 @@ static int adpt_i2o_systab_send(adpt_hba* pHba)
         * Private i/o space declaration  
         */
        msg[6] = 0x54000000 | sys_tbl_len;
-       msg[7] = virt_to_phys(sys_tbl);
+       msg[7] = (u32)sys_tbl_pa;
        msg[8] = 0x54000000 | 0;
        msg[9] = 0;
        msg[10] = 0xD4000000 | 0;
@@ -3323,11 +3599,10 @@ static static void adpt_delay(int millisec)
 #endif
 
 static struct scsi_host_template driver_template = {
+       .module                 = THIS_MODULE,
        .name                   = "dpt_i2o",
        .proc_name              = "dpt_i2o",
        .proc_info              = adpt_proc_info,
-       .detect                 = adpt_detect,
-       .release                = adpt_release,
        .info                   = adpt_info,
        .queuecommand           = adpt_queue,
        .eh_abort_handler       = adpt_abort,
@@ -3341,5 +3616,48 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
 };
-#include "scsi_module.c"
+
+static int __init adpt_init(void)
+{
+       int             error;
+       adpt_hba        *pHba, *next;
+
+       printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+
+       error = adpt_detect(&driver_template);
+       if (error < 0)
+               return error;
+       if (hba_chain == NULL)
+               return -ENODEV;
+
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               error = scsi_add_host(pHba->host, &pHba->pDev->dev);
+               if (error)
+                       goto fail;
+               scsi_scan_host(pHba->host);
+       }
+       return 0;
+fail:
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
+               scsi_remove_host(pHba->host);
+       }
+       return error;
+}
+
+static void __exit adpt_exit(void)
+{
+       adpt_hba        *pHba, *next;
+
+       for (pHba = hba_chain; pHba; pHba = pHba->next)
+               scsi_remove_host(pHba->host);
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
+               adpt_release(pHba->host);
+       }
+}
+
+module_init(adpt_init);
+module_exit(adpt_exit);
+
 MODULE_LICENSE("GPL");
index fd79068c586931b640eb2f1814b96eaa84bae76b..337746d460438417281d25c3aa9aec863f3e002d 100644 (file)
@@ -84,7 +84,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd);
 #define PCI_DPT_DEVICE_ID         (0xA501)     // DPT PCI I2O Device ID
 #define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)     
 
-//#define REBOOT_NOTIFIER 1
 /* Debugging macro from Linux Device Drivers - Rubini */
 #undef PDEBUG
 #ifdef DEBUG
@@ -229,14 +228,19 @@ typedef struct _adpt_hba {
        u32  post_fifo_size;
        u32  reply_fifo_size;
        u32* reply_pool;
+       dma_addr_t reply_pool_pa;
        u32  sg_tablesize;      // Scatter/Gather List Size.       
        u8  top_scsi_channel;
        u8  top_scsi_id;
        u8  top_scsi_lun;
+       u8  dma64;
 
        i2o_status_block* status_block;
+       dma_addr_t status_block_pa;
        i2o_hrt* hrt;
+       dma_addr_t hrt_pa;
        i2o_lct* lct;
+       dma_addr_t lct_pa;
        uint lct_size;
        struct i2o_device* devices;
        struct adpt_channel channel[MAX_CHANNEL];
@@ -249,6 +253,7 @@ typedef struct _adpt_hba {
        void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
        void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
        u32 FwDebugFlags;
+       u32 *ioctl_reply_context[4];
 } adpt_hba;
 
 struct sg_simple_element {
@@ -264,9 +269,6 @@ static void adpt_i2o_sys_shutdown(void);
 static int adpt_init(void);
 static int adpt_i2o_build_sys_table(void);
 static irqreturn_t adpt_isr(int irq, void *dev_id);
-#ifdef REBOOT_NOTIFIER
-static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
-#endif
 
 static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
 static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
@@ -275,7 +277,8 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
 static const char *adpt_i2o_get_class_name(int class);
 #endif
 static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-                 void *opblk, int oplen, void *resblk, int reslen);
+                 void *opblk, dma_addr_t opblk_pa, int oplen,
+                 void *resblk, dma_addr_t resblk_pa, int reslen);
 static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
 static int adpt_i2o_lct_get(adpt_hba* pHba);
 static int adpt_i2o_parse_lct(adpt_hba* pHba);
@@ -289,7 +292,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
 static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
 static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
 static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
+static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht);
 static s32 adpt_hba_reset(adpt_hba* pHba);
 static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
 static s32 adpt_rescan(adpt_hba* pHba);
@@ -313,19 +316,6 @@ static int adpt_close(struct inode *inode, struct file *file);
 static void adpt_delay(int millisec);
 #endif
 
-#if defined __ia64__ 
-static void adpt_ia64_info(sysInfo_S* si);
-#endif
-#if defined __sparc__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __alpha__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __i386__
-static void adpt_i386_info(sysInfo_S* si);
-#endif
-
 #define PRINT_BUFFER_SIZE     512
 
 #define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000    // Mask for debug flags
index c6d6e7c6559a6664008cbcf9fe75ae106577b476..46771d4c81bdcd8abeb8bad9b81bdd6430f5dfff 100644 (file)
@@ -465,7 +465,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
     scp->request = (struct request *)&wait;
     scp->timeout_per_command = timeout*HZ;
     scp->cmd_len = 12;
-    memcpy(scp->cmnd, cmnd, 12);
+    scp->cmnd = cmnd;
     cmndinfo.priority = IOCTL_PRI;
     cmndinfo.internal_cmd_str = gdtcmd;
     cmndinfo.internal_command = 1;
@@ -550,7 +550,6 @@ static int __init gdth_search_isa(ulong32 bios_adr)
 #endif /* CONFIG_ISA */
 
 #ifdef CONFIG_PCI
-static bool gdth_pci_registered;
 
 static bool gdth_search_vortex(ushort device)
 {
@@ -3724,6 +3723,8 @@ static void gdth_log_event(gdth_evt_data *dvr, char *buffer)
 }
 
 #ifdef GDTH_STATISTICS
+static unchar  gdth_timer_running;
+
 static void gdth_timeout(ulong data)
 {
     ulong32 i;
@@ -3731,7 +3732,10 @@ static void gdth_timeout(ulong data)
     gdth_ha_str *ha;
     ulong flags;
 
-    BUG_ON(list_empty(&gdth_instances));
+    if(unlikely(list_empty(&gdth_instances))) {
+           gdth_timer_running = 0;
+           return;
+    }
 
     ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -3751,6 +3755,22 @@ static void gdth_timeout(ulong data)
     add_timer(&gdth_timer);
     spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
+
+static void gdth_timer_init(void)
+{
+       if (gdth_timer_running)
+               return;
+       gdth_timer_running = 1;
+       TRACE2(("gdth_detect(): Initializing timer !\n"));
+       gdth_timer.expires = jiffies + HZ;
+       gdth_timer.data = 0L;
+       gdth_timer.function = gdth_timeout;
+       add_timer(&gdth_timer);
+}
+#else
+static inline void gdth_timer_init(void)
+{
+}
 #endif
 
 static void __init internal_setup(char *str,int *ints)
@@ -4735,6 +4755,7 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios)
        if (error)
                goto out_free_coal_stat;
        list_add_tail(&ha->list, &gdth_instances);
+       gdth_timer_init();
 
        scsi_scan_host(shp);
 
@@ -4865,6 +4886,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
        if (error)
                goto out_free_coal_stat;
        list_add_tail(&ha->list, &gdth_instances);
+       gdth_timer_init();
 
        scsi_scan_host(shp);
 
@@ -5011,6 +5033,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr,
        list_add_tail(&ha->list, &gdth_instances);
 
        pci_set_drvdata(ha->pdev, ha);
+       gdth_timer_init();
 
        scsi_scan_host(shp);
 
@@ -5110,6 +5133,7 @@ static int __init gdth_init(void)
        /* initializations */
        gdth_polling = TRUE;
        gdth_clear_events();
+       init_timer(&gdth_timer);
 
        /* As default we do not probe for EISA or ISA controllers */
        if (probe_eisa_isa) {
@@ -5132,23 +5156,17 @@ static int __init gdth_init(void)
 
 #ifdef CONFIG_PCI
        /* scanning for PCI controllers */
-       if (pci_register_driver(&gdth_pci_driver) == 0)
-               gdth_pci_registered = true;
+       if (pci_register_driver(&gdth_pci_driver)) {
+               gdth_ha_str *ha;
+
+               list_for_each_entry(ha, &gdth_instances, list)
+                       gdth_remove_one(ha);
+               return -ENODEV;
+       }
 #endif /* CONFIG_PCI */
 
        TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
 
-       if (list_empty(&gdth_instances))
-               return -ENODEV;
-
-#ifdef GDTH_STATISTICS
-       TRACE2(("gdth_detect(): Initializing timer !\n"));
-       init_timer(&gdth_timer);
-       gdth_timer.expires = jiffies + HZ;
-       gdth_timer.data = 0L;
-       gdth_timer.function = gdth_timeout;
-       add_timer(&gdth_timer);
-#endif
        major = register_chrdev(0,"gdth", &gdth_fops);
        register_reboot_notifier(&gdth_notifier);
        gdth_polling = FALSE;
@@ -5167,8 +5185,7 @@ static void __exit gdth_exit(void)
 #endif
 
 #ifdef CONFIG_PCI
-       if (gdth_pci_registered)
-               pci_unregister_driver(&gdth_pci_driver);
+       pci_unregister_driver(&gdth_pci_driver);
 #endif
 
        list_for_each_entry(ha, &gdth_instances, list)
index 5b7be1e9841c23da55fd007390c90bbd237ff79a..aaa48e0c8ed054a231c1c2a3d699371be32f4d41 100644 (file)
@@ -763,9 +763,9 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
                        scp,
                        host->host_no, scp->device->channel,
                        scp->device->id, scp->device->lun,
-                       *((u32 *)&scp->cmnd),
-                       *((u32 *)&scp->cmnd + 1),
-                       *((u32 *)&scp->cmnd + 2),
+                       ((u32 *)scp->cmnd)[0],
+                       ((u32 *)scp->cmnd)[1],
+                       ((u32 *)scp->cmnd)[2],
                        _req->index, _req->req_virt);
 
        scp->result = 0;
index 4a922c57125ef1403e074d32eb85309c84002e6d..ccfd8aca3765875cf7cf4711aba0aa8bfbb6fb09 100644 (file)
@@ -686,7 +686,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct)
        }
        
        if (cmnd) {
-               cmnd->result = rsp->status;
+               cmnd->result |= rsp->status;
                if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION)
                        memcpy(cmnd->sense_buffer,
                               rsp->data,
@@ -730,6 +730,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
        u16 lun = lun_from_dev(cmnd->device);
        u8 out_fmt, in_fmt;
 
+       cmnd->result = (DID_OK << 16);
        evt_struct = get_event_struct(&hostdata->pool);
        if (!evt_struct)
                return SCSI_MLQUEUE_HOST_BUSY;
@@ -738,7 +739,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
        srp_cmd = &evt_struct->iu.srp.cmd;
        memset(srp_cmd, 0x00, SRP_MAX_IU_LEN);
        srp_cmd->opcode = SRP_CMD;
-       memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd));
+       memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(srp_cmd->cdb));
        srp_cmd->lun = ((u64) lun) << 48;
 
        if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
@@ -1347,6 +1348,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
 
        del_timer(&evt_struct->timer);
 
+       if (crq->status != VIOSRP_OK && evt_struct->cmnd)
+               evt_struct->cmnd->result = DID_ERROR << 16;
        if (evt_struct->done)
                evt_struct->done(evt_struct);
        else
index 90f1a61283adaeb527f038a193b4e635776a1057..4c4aadb3e405fa9f4e8a2d8a1aa6cf4cf438daf9 100644 (file)
@@ -59,6 +59,15 @@ enum viosrp_crq_formats {
        VIOSRP_INLINE_FORMAT = 0x07
 };
 
+enum viosrp_crq_status {
+       VIOSRP_OK = 0x0,
+       VIOSRP_NONRECOVERABLE_ERR = 0x1,
+       VIOSRP_VIOLATES_MAX_XFER = 0x2,
+       VIOSRP_PARTNER_PANIC = 0x3,
+       VIOSRP_DEVICE_BUSY = 0x8,
+       VIOSRP_ADAPTER_FAIL = 0x10
+};
+
 struct viosrp_crq {
        u8 valid;               /* used by RPA */
        u8 format;              /* SCSI vs out-of-band */
index dbae3fdb85065c92819443b0046c3fc81e5785a6..e3f739776bada819eb566bb2f8fcd861b7256519 100644 (file)
@@ -2590,7 +2590,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
        cblk->hastat = 0;
        cblk->tastat = 0;
        /* Command the command */
-       memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len);
+       memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len);
 
        /* Set up tags */
        if (cmnd->device->tagged_supported) {   /* Tag Support                  */
index de5ae6a65029ffbd1efc31911ecf3d660e5f2320..999e91ea745139bba95caf0b9bd5224254ff9190 100644 (file)
@@ -2791,7 +2791,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev,
 
 static struct device_attribute ipr_ioa_state_attr = {
        .attr = {
-               .name =         "state",
+               .name =         "online_state",
                .mode =         S_IRUGO | S_IWUSR,
        },
        .show = ipr_show_adapter_state,
index 010c1b9b178cb5ae5ea0e9f54e3a631c210f0a7e..b43bf1d60dac8a5499922f8a66da15b3c26626d2 100644 (file)
@@ -730,7 +730,9 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                                if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
                                                   datalen))
                                        rc = ISCSI_ERR_CONN_FAILED;
-                       }
+                       } else
+                               mod_timer(&conn->transport_timer,
+                                         jiffies + conn->recv_timeout);
                        iscsi_free_mgmt_task(conn, mtask);
                        break;
                default:
@@ -1453,19 +1455,20 @@ static void iscsi_check_transport_timeouts(unsigned long data)
 {
        struct iscsi_conn *conn = (struct iscsi_conn *)data;
        struct iscsi_session *session = conn->session;
-       unsigned long timeout, next_timeout = 0, last_recv;
+       unsigned long recv_timeout, next_timeout = 0, last_recv;
 
        spin_lock(&session->lock);
        if (session->state != ISCSI_STATE_LOGGED_IN)
                goto done;
 
-       timeout = conn->recv_timeout;
-       if (!timeout)
+       recv_timeout = conn->recv_timeout;
+       if (!recv_timeout)
                goto done;
 
-       timeout *= HZ;
+       recv_timeout *= HZ;
        last_recv = conn->last_recv;
-       if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
+       if (conn->ping_mtask &&
+           time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
                           jiffies)) {
                iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
                                  "expired, last rx %lu, last ping %lu, "
@@ -1476,15 +1479,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
                return;
        }
 
-       if (time_before_eq(last_recv + timeout, jiffies)) {
-               if (time_before_eq(conn->last_ping, last_recv)) {
-                       /* send a ping to try to provoke some traffic */
-                       debug_scsi("Sending nopout as ping on conn %p\n", conn);
-                       iscsi_send_nopout(conn, NULL);
-               }
-               next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
+       if (time_before_eq(last_recv + recv_timeout, jiffies)) {
+               /* send a ping to try to provoke some traffic */
+               debug_scsi("Sending nopout as ping on conn %p\n", conn);
+               iscsi_send_nopout(conn, NULL);
+               next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
        } else
-               next_timeout = last_recv + timeout;
+               next_timeout = last_recv + recv_timeout;
 
        debug_scsi("Setting next tmo %lu\n", next_timeout);
        mod_timer(&conn->transport_timer, next_timeout);
index 820f91fb63ba55dcd4384e0fb4184744199d1deb..70a0f11f48b235d769b1efb088d1c9bd2c98f949 100644 (file)
@@ -3168,6 +3168,23 @@ megaraid_mbox_support_random_del(adapter_t *adapter)
        uint8_t         raw_mbox[sizeof(mbox_t)];
        int             rval;
 
+       /*
+        * Newer firmware on Dell CERC expect a different
+        * random deletion handling, so disable it.
+        */
+       if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI &&
+           adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 &&
+           adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+           adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH &&
+           (adapter->fw_version[0] > '6' ||
+            (adapter->fw_version[0] == '6' &&
+             adapter->fw_version[2] > '6') ||
+            (adapter->fw_version[0] == '6'
+             && adapter->fw_version[2] == '6'
+             && adapter->fw_version[3] > '1'))) {
+               con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n"));
+               return 0;
+       }
 
        mbox = (mbox_t *)raw_mbox;
 
index 626459d1e9021180c2af19e60576a85eeeb37772..c1d86d961a92df976c63da2dfa0cbd39d1babc52 100644 (file)
@@ -88,6 +88,7 @@
 #define PCI_SUBSYS_ID_PERC3_QC                         0x0471
 #define PCI_SUBSYS_ID_PERC3_DC                         0x0493
 #define PCI_SUBSYS_ID_PERC3_SC                         0x0475
+#define PCI_SUBSYS_ID_CERC_ATA100_4CH                  0x0511
 
 
 #define MBOX_MAX_SCSI_CMDS     128     // number of cmds reserved for kernel
index b937e9cddb2381608f2002320a18f82fc4729a55..7d84c8bbcf3fc1a55b8a9c04cbc65e2e05b33902 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.16-rc1
+ * Version     : v00.00.03.20-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
@@ -2650,12 +2650,13 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
        return;
 }
 
+#ifdef CONFIG_PM
 /**
  * megasas_suspend -   driver suspend entry point
  * @pdev:              PCI device structure
  * @state:             PCI power state to suspend routine
  */
-static int __devinit
+static int
 megasas_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct Scsi_Host *host;
@@ -2687,7 +2688,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
  * megasas_resume-      driver resume entry point
  * @pdev:               PCI device structure
  */
-static int __devinit
+static int
 megasas_resume(struct pci_dev *pdev)
 {
        int rval;
@@ -2782,12 +2783,16 @@ fail_ready_state:
 
        return -ENODEV;
 }
+#else
+#define megasas_suspend        NULL
+#define megasas_resume NULL
+#endif
 
 /**
  * megasas_detach_one -        PCI hot"un"plug entry point
  * @pdev:              PCI device structure
  */
-static void megasas_detach_one(struct pci_dev *pdev)
+static void __devexit megasas_detach_one(struct pci_dev *pdev)
 {
        int i;
        struct Scsi_Host *host;
index 3a997eb457bf84813212c046beb08e73a51774cc..b0c41e67170281428b5725437524826a7a10fd6f 100644 (file)
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.03.16-rc1"
-#define MEGASAS_RELDATE                                "Nov. 07, 2007"
-#define MEGASAS_EXT_VERSION                    "Thu. Nov. 07 10:09:32 PDT 2007"
+#define MEGASAS_VERSION                        "00.00.03.20-rc1"
+#define MEGASAS_RELDATE                        "March 10, 2008"
+#define MEGASAS_EXT_VERSION            "Mon. March 10 11:02:31 PDT 2008"
 
 /*
  * Device IDs
index e55b9037adb224286b4a2a0a1f0efd77a2b3b967..1dd70d7a4947c9a5f6ec41d5e46b3dc52a311f11 100644 (file)
@@ -2822,7 +2822,9 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
                dev_printk(KERN_DEBUG, &pdev->dev,
                        "phy[%d] Get Attached Address 0x%llX ,"
                        " SAS Address 0x%llX\n",
-                       i, phy->att_dev_sas_addr, phy->dev_sas_addr);
+                       i,
+                       (unsigned long long)phy->att_dev_sas_addr,
+                       (unsigned long long)phy->dev_sas_addr);
                dev_printk(KERN_DEBUG, &pdev->dev,
                        "Rate = %x , type = %d\n",
                        sas_phy->linkrate, phy->phy_type);
index ceab4f73caf1dfbaa953d91979ffedc937c7155f..c57c94c0ffd237f1d39b0cf6ea164e737ac11643 100644 (file)
@@ -8222,7 +8222,7 @@ static void process_waiting_list(struct ncb *np, int sts)
 #ifdef DEBUG_WAITING_LIST
        if (waiting_list) printk("%s: waiting_list=%lx processing sts=%d\n", ncr_name(np), (u_long) waiting_list, sts);
 #endif
-       while (wcmd = waiting_list) {
+       while ((wcmd = waiting_list) != NULL) {
                waiting_list = (struct scsi_cmnd *) wcmd->next_wcmd;
                wcmd->next_wcmd = NULL;
                if (sts == DID_OK) {
index 09ab3eac1c1abe9ac2e571e277cb3e1cfdfd4c8d..51e2f299dbbb11e60b0995ac4e5cca14c5a2c634 100644 (file)
@@ -2007,7 +2007,7 @@ qla1280_set_defaults(struct scsi_qla_host *ha)
                nv->bus[bus].config_2.req_ack_active_negation = 1;
                nv->bus[bus].config_2.data_line_active_negation = 1;
                nv->bus[bus].selection_timeout = 250;
-               nv->bus[bus].max_queue_depth = 256;
+               nv->bus[bus].max_queue_depth = 32;
 
                if (IS_ISP1040(ha)) {
                        nv->bus[bus].bus_reset_delay = 3;
@@ -2051,7 +2051,7 @@ qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
        status = qla1280_mailbox_command(ha, 0x0f, mb);
 
        /* Save Tag queuing enable flag. */
-       flag = (BIT_0 << target) & mb[0];
+       flag = (BIT_0 << target);
        if (nv->bus[bus].target[target].parameter.tag_queuing)
                ha->bus_settings[bus].qtag_enables |= flag;
 
@@ -2858,7 +2858,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 
        /* Load SCSI command packet. */
        pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
-       memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+       memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd));
        /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
 
        /* Set transfer direction. */
@@ -3127,7 +3127,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 
        /* Load SCSI command packet. */
        pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
-       memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+       memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd));
 
        /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
        /* Set transfer direction. */
index 12d69d7c85775475ce89de8fc6a6381ba4453809..110e776d1a078cbd24cfdb795f7fec16cf95f1c3 100644 (file)
@@ -78,15 +78,6 @@ static void scsi_done(struct scsi_cmnd *cmd);
 /* Do not call reset on error if we just did a reset within 15 sec. */
 #define MIN_RESET_PERIOD (15*HZ)
 
-/*
- * Macro to determine the size of SCSI command. This macro takes vendor
- * unique commands into account. SCSI commands in groups 6 and 7 are
- * vendor unique and we will depend upon the command length being
- * supplied correctly in cmd_len.
- */
-#define CDB_SIZE(cmd)  (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \
-                               COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len)
-
 /*
  * Note - the initial logging level can be set here to log events at boot time.
  * After the system is up, you may enable logging via the /proc interface.
@@ -469,6 +460,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
        cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask);
        if (!cmd) {
                scsi_put_host_cmd_pool(gfp_mask);
+               shost->cmd_pool = NULL;
                return -ENOMEM;
        }
        list_add(&cmd->list, &shost->free_list);
@@ -481,6 +473,13 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
  */
 void scsi_destroy_command_freelist(struct Scsi_Host *shost)
 {
+       /*
+        * If cmd_pool is NULL the free list was not initialized, so
+        * do not attempt to release resources.
+        */
+       if (!shost->cmd_pool)
+               return;
+
        while (!list_empty(&shost->free_list)) {
                struct scsi_cmnd *cmd;
 
@@ -701,9 +700,11 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
         * Before we queue this command, check if the command
         * length exceeds what the host adapter can handle.
         */
-       if (CDB_SIZE(cmd) > cmd->device->host->max_cmd_len) {
+       if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
                SCSI_LOG_MLQUEUE(3,
-                               printk("queuecommand : command too long.\n"));
+                       printk("queuecommand : command too long. "
+                              "cdb_size=%d host->max_cmd_len=%d\n",
+                              cmd->cmd_len, cmd->device->host->max_cmd_len));
                cmd->result = (DID_ABORT << 16);
 
                scsi_done(cmd);
index 1eaba6cd80f411735b390a984a3f61837e377432..eaf5a8add1ba1a9ba9e03d8aaa0969ffd41d2c58 100644 (file)
@@ -626,7 +626,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
  * @scmd:       SCSI command structure to hijack
  * @ses:        structure to save restore information
  * @cmnd:       CDB to send. Can be NULL if no new cmnd is needed
- * @cmnd_size:  size in bytes of @cmnd
+ * @cmnd_size:  size in bytes of @cmnd (must be <= BLK_MAX_CDB)
  * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
  *
  * This function is used to save a scsi command information before re-execution
@@ -648,12 +648,14 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
         * command.
         */
        ses->cmd_len = scmd->cmd_len;
-       memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd));
+       ses->cmnd = scmd->cmnd;
        ses->data_direction = scmd->sc_data_direction;
        ses->sdb = scmd->sdb;
        ses->next_rq = scmd->request->next_rq;
        ses->result = scmd->result;
 
+       scmd->cmnd = ses->eh_cmnd;
+       memset(scmd->cmnd, 0, BLK_MAX_CDB);
        memset(&scmd->sdb, 0, sizeof(scmd->sdb));
        scmd->request->next_rq = NULL;
 
@@ -665,14 +667,13 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
                scmd->sdb.table.sgl = &ses->sense_sgl;
                scmd->sc_data_direction = DMA_FROM_DEVICE;
                scmd->sdb.table.nents = 1;
-               memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
                scmd->cmnd[0] = REQUEST_SENSE;
                scmd->cmnd[4] = scmd->sdb.length;
                scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
        } else {
                scmd->sc_data_direction = DMA_NONE;
                if (cmnd) {
-                       memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
+                       BUG_ON(cmnd_size > BLK_MAX_CDB);
                        memcpy(scmd->cmnd, cmnd, cmnd_size);
                        scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
                }
@@ -705,7 +706,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
         * Restore original data
         */
        scmd->cmd_len = ses->cmd_len;
-       memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd));
+       scmd->cmnd = ses->cmnd;
        scmd->sc_data_direction = ses->data_direction;
        scmd->sdb = ses->sdb;
        scmd->request->next_rq = ses->next_rq;
@@ -1775,8 +1776,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
        scmd->request = &req;
        memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
 
-       memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
-    
+       scmd->cmnd = req.cmd;
+
        scmd->scsi_done         = scsi_reset_provider_done_command;
        memset(&scmd->sdb, 0, sizeof(scmd->sdb));
 
index d545ad1cf47a7f94c70369da8c1b6fb4dab0fe9d..a82d2fe80fb544da5afb86d835e6fbafb3a74533 100644 (file)
@@ -445,7 +445,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
        scsi_set_resid(cmd, 0);
        memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
        if (cmd->cmd_len == 0)
-               cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
+               cmd->cmd_len = scsi_command_size(cmd->cmnd);
 }
 
 void scsi_device_unbusy(struct scsi_device *sdev)
@@ -1094,6 +1094,8 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
        cmd->tag = req->tag;
        cmd->request = req;
 
+       cmd->cmnd = req->cmd;
+
        return cmd;
 }
 
@@ -1131,8 +1133,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
                req->buffer = NULL;
        }
 
-       BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
-       memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
        cmd->cmd_len = req->cmd_len;
        if (!req->data_len)
                cmd->sc_data_direction = DMA_NONE;
@@ -1169,6 +1169,7 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
        if (unlikely(!cmd))
                return BLKPREP_DEFER;
 
+       memset(cmd->cmnd, 0, BLK_MAX_CDB);
        return scsi_init_io(cmd, GFP_ATOMIC);
 }
 EXPORT_SYMBOL(scsi_setup_fs_cmnd);
index ee8496aa0336682eedc40879dfca871d6551ff3c..257e097c39afe708e2e5a4286948e0de246c5c92 100644 (file)
@@ -107,6 +107,8 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
        cmd->jiffies_at_alloc = jiffies;
        cmd->request = rq;
 
+       cmd->cmnd = rq->cmd;
+
        rq->special = cmd;
        rq->cmd_type = REQ_TYPE_SPECIAL;
        rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
index 640333b1e75c9b32565bfeab8721ef566fb903c4..329eb8780e74f4c2335137acdd181e92d8c6e863 100644 (file)
@@ -744,7 +744,8 @@ static int wait_on_busy(unsigned long iobase, unsigned int loop) {
 static int board_inquiry(unsigned int j) {
    struct mscp *cpp;
    dma_addr_t id_dma_addr;
-   unsigned int time, limit = 0;
+   unsigned int limit = 0;
+   unsigned long time;
 
    id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id,
                     sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL);
@@ -1392,7 +1393,8 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
 }
 
 static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) {
-   unsigned int i, j, time, k, c, limit = 0;
+   unsigned int i, j, k, c, limit = 0;
+   unsigned long time;
    int arg_done = FALSE;
    struct scsi_cmnd *SCpnt;
 
index ea41f26264580dfe7a5ab27a71d19103305b7bc9..a1ca9b7bf2d5862b7466fbdcee4f5099b882ac76 100644 (file)
@@ -2271,7 +2271,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
                }
 
                if (up->port.flags & UPF_IOREMAP) {
-                       up->port.membase = ioremap(up->port.mapbase, size);
+                       up->port.membase = ioremap_nocache(up->port.mapbase,
+                                                                       size);
                        if (!up->port.membase) {
                                release_mem_region(up->port.mapbase, size);
                                ret = -ENOMEM;
index cd898704ba4f66d5fba055d4e9d574e5125786cd..f279745e9fefe9f07114923d58ebaec052dda4cf 100644 (file)
@@ -153,7 +153,7 @@ static int __init parse_options(struct early_serial8250_device *device,
                        (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
                port->membase += port->mapbase & ~PAGE_MASK;
 #else
-               port->membase = ioremap(port->mapbase, 64);
+               port->membase = ioremap_nocache(port->mapbase, 64);
                if (!port->membase) {
                        printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
                                __func__,
index 6e57382b9137504b1d9fdbb669610b9c37052376..53fa19cf2f0636d6dd79d0918266243441bda31f 100644 (file)
@@ -86,7 +86,7 @@ setup_port(struct serial_private *priv, struct uart_port *port,
                len =  pci_resource_len(dev, bar);
 
                if (!priv->remapped_bar[bar])
-                       priv->remapped_bar[bar] = ioremap(base, len);
+                       priv->remapped_bar[bar] = ioremap_nocache(base, len);
                if (!priv->remapped_bar[bar])
                        return -ENOMEM;
 
@@ -270,7 +270,7 @@ static int pci_plx9050_init(struct pci_dev *dev)
        /*
         * enable/disable interrupts
         */
-       p = ioremap(pci_resource_start(dev, 0), 0x80);
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
        if (p == NULL)
                return -ENOMEM;
        writel(irq_config, p + 0x4c);
@@ -294,7 +294,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
        /*
         * disable interrupts
         */
-       p = ioremap(pci_resource_start(dev, 0), 0x80);
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
        if (p != NULL) {
                writel(0, p + 0x4c);
 
@@ -341,7 +341,8 @@ static int sbs_init(struct pci_dev *dev)
 {
        u8 __iomem *p;
 
-       p = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
+       p = ioremap_nocache(pci_resource_start(dev, 0),
+                                               pci_resource_len(dev, 0));
 
        if (p == NULL)
                return -ENOMEM;
@@ -365,7 +366,8 @@ static void __devexit sbs_exit(struct pci_dev *dev)
 {
        u8 __iomem *p;
 
-       p = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
+       p = ioremap_nocache(pci_resource_start(dev, 0),
+                                       pci_resource_len(dev, 0));
        /* FIXME: What if resource_len < OCT_REG_CR_OFF */
        if (p != NULL)
                writeb(0, p + OCT_REG_CR_OFF);
@@ -419,7 +421,7 @@ static int pci_siig10x_init(struct pci_dev *dev)
                break;
        }
 
-       p = ioremap(pci_resource_start(dev, 0), 0x80);
+       p = ioremap_nocache(pci_resource_start(dev, 0), 0x80);
        if (p == NULL)
                return -ENOMEM;
 
index 8a2f6a1baa74d5b09b31666dd46be9b7bca746c2..d6b4ead693b7b08f798bf12e9e6f09e81287af77 100644 (file)
@@ -65,9 +65,6 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
        struct circ_buf *xmit = &uart->port.info->xmit;
-#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA)
-       unsigned short ier;
-#endif
 
        while (!(UART_GET_LSR(uart) & TEMT))
                cpu_relax();
@@ -82,12 +79,8 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 #ifdef CONFIG_BF54x
        /* Clear TFI bit */
        UART_PUT_LSR(uart, TFI);
-       UART_CLEAR_IER(uart, ETBEI);
-#else
-       ier = UART_GET_IER(uart);
-       ier &= ~ETBEI;
-       UART_PUT_IER(uart, ier);
 #endif
+       UART_CLEAR_IER(uart, ETBEI);
 #endif
 }
 
@@ -102,14 +95,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
        if (uart->tx_done)
                bfin_serial_dma_tx_chars(uart);
 #else
-#ifdef CONFIG_BF54x
        UART_SET_IER(uart, ETBEI);
-#else
-       unsigned short ier;
-       ier = UART_GET_IER(uart);
-       ier |= ETBEI;
-       UART_PUT_IER(uart, ier);
-#endif
        bfin_serial_tx_chars(uart);
 #endif
 }
@@ -120,21 +106,10 @@ static void bfin_serial_start_tx(struct uart_port *port)
 static void bfin_serial_stop_rx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-#ifdef CONFIG_KGDB_UART
-       if (uart->port.line != CONFIG_KGDB_UART_PORT) {
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.line != CONFIG_KGDB_UART_PORT)
 #endif
-#ifdef CONFIG_BF54x
        UART_CLEAR_IER(uart, ERBFI);
-#else
-       unsigned short ier;
-
-       ier = UART_GET_IER(uart);
-       ier &= ~ERBFI;
-       UART_PUT_IER(uart, ier);
-#endif
-#ifdef CONFIG_KGDB_UART
-       }
-#endif
 }
 
 /*
@@ -161,10 +136,7 @@ void kgdb_put_debug_char(int chr)
                SSYNC();
        }
 
-#ifndef CONFIG_BF54x
-       UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-       SSYNC();
-#endif
+       UART_CLEAR_DLAB(uart);
        UART_PUT_CHAR(uart, (unsigned char)chr);
        SSYNC();
 }
@@ -183,10 +155,7 @@ int kgdb_get_debug_char(void)
        while(!(UART_GET_LSR(uart) & DR)) {
                SSYNC();
        }
-#ifndef CONFIG_BF54x
-       UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-       SSYNC();
-#endif
+       UART_CLEAR_DLAB(uart);
        chr = UART_GET_CHAR(uart);
        SSYNC();
 
@@ -208,9 +177,6 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
        struct tty_struct *tty = uart->port.info->tty;
        unsigned int status, ch, flg;
        static struct timeval anomaly_start = { .tv_sec = 0 };
-#ifdef CONFIG_KGDB_UART
-       struct pt_regs *regs = get_irq_regs();
-#endif
 
        status = UART_GET_LSR(uart);
        UART_CLEAR_LSR(uart);
@@ -220,6 +186,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 
 #ifdef CONFIG_KGDB_UART
        if (uart->port.line == CONFIG_KGDB_UART_PORT) {
+               struct pt_regs *regs = get_irq_regs();
                if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
                        kgdb_breakkey_pressed(regs);
                        return;
@@ -391,7 +358,6 @@ static void bfin_serial_do_work(struct work_struct *work)
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 {
        struct circ_buf *xmit = &uart->port.info->xmit;
-       unsigned short ier;
 
        uart->tx_done = 0;
 
@@ -429,13 +395,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
        set_dma_x_modify(uart->tx_dma_channel, 1);
        enable_dma(uart->tx_dma_channel);
 
-#ifdef CONFIG_BF54x
        UART_SET_IER(uart, ETBEI);
-#else
-       ier = UART_GET_IER(uart);
-       ier |= ETBEI;
-       UART_PUT_IER(uart, ier);
-#endif
 }
 
 static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
@@ -513,19 +473,12 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
 {
        struct bfin_serial_port *uart = dev_id;
        struct circ_buf *xmit = &uart->port.info->xmit;
-       unsigned short ier;
 
        spin_lock(&uart->port.lock);
        if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
                disable_dma(uart->tx_dma_channel);
                clear_dma_irqstat(uart->tx_dma_channel);
-#ifdef CONFIG_BF54x
                UART_CLEAR_IER(uart, ETBEI);
-#else
-               ier = UART_GET_IER(uart);
-               ier &= ~ETBEI;
-               UART_PUT_IER(uart, ier);
-#endif
                xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1);
                uart->port.icount.tx += uart->tx_count;
 
@@ -701,7 +654,6 @@ static int bfin_serial_startup(struct uart_port *port)
 # endif
        }
 
-
        if (request_irq
            (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED,
             "BFIN_UART_TX", uart)) {
@@ -710,11 +662,7 @@ static int bfin_serial_startup(struct uart_port *port)
                return -EBUSY;
        }
 #endif
-#ifdef CONFIG_BF54x
        UART_SET_IER(uart, ERBFI);
-#else
-       UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
-#endif
        return 0;
 }
 
@@ -810,26 +758,15 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
        UART_PUT_IER(uart, 0);
 #endif
 
-#ifndef CONFIG_BF54x
        /* Set DLAB in LCR to Access DLL and DLH */
-       val = UART_GET_LCR(uart);
-       val |= DLAB;
-       UART_PUT_LCR(uart, val);
-       SSYNC();
-#endif
+       UART_SET_DLAB(uart);
 
        UART_PUT_DLL(uart, quot & 0xFF);
-       SSYNC();
        UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
        SSYNC();
 
-#ifndef CONFIG_BF54x
        /* Clear DLAB in LCR to Access THR RBR IER */
-       val = UART_GET_LCR(uart);
-       val &= ~DLAB;
-       UART_PUT_LCR(uart, val);
-       SSYNC();
-#endif
+       UART_CLEAR_DLAB(uart);
 
        UART_PUT_LCR(uart, lcr);
 
@@ -992,8 +929,7 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
        status = UART_GET_IER(uart) & (ERBFI | ETBEI);
        if (status == (ERBFI | ETBEI)) {
                /* ok, the port was enabled */
-               unsigned short lcr, val;
-               unsigned short dlh, dll;
+               u16 lcr, dlh, dll;
 
                lcr = UART_GET_LCR(uart);
 
@@ -1010,22 +946,14 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
                        case 2: *bits = 7; break;
                        case 3: *bits = 8; break;
                }
-#ifndef CONFIG_BF54x
                /* Set DLAB in LCR to Access DLL and DLH */
-               val = UART_GET_LCR(uart);
-               val |= DLAB;
-               UART_PUT_LCR(uart, val);
-#endif
+               UART_SET_DLAB(uart);
 
                dll = UART_GET_DLL(uart);
                dlh = UART_GET_DLH(uart);
 
-#ifndef CONFIG_BF54x
                /* Clear DLAB in LCR to Access THR RBR IER */
-               val = UART_GET_LCR(uart);
-               val &= ~DLAB;
-               UART_PUT_LCR(uart, val);
-#endif
+               UART_CLEAR_DLAB(uart);
 
                *baud = get_sclk() / (16*(dll | dlh << 8));
        }
@@ -1290,11 +1218,7 @@ static int __init bfin_serial_init(void)
                request_irq(uart->port.irq, bfin_serial_rx_int,
                        IRQF_DISABLED, "BFIN_UART_RX", uart);
                pr_info("Request irq for kgdb uart port\n");
-#ifdef CONFIG_BF54x
                UART_SET_IER(uart, ERBFI);
-#else
-               UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
-#endif
                SSYNC();
                t.c_cflag = CS8|B57600;
                t.c_iflag = 0;
index f9fa237aa9496d7cdf88d4cd0589d8b8391ae351..3e0366eab412878258f993f16a0fc1804c401e8c 100644 (file)
@@ -3808,7 +3808,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
 
        shutdown(info);
        rs_flush_buffer(tty);
-       tty_ldisc_flush_buffer(tty);
+       tty_ldisc_flush(tty);
        tty->closing = 0;
        info->event = 0;
        info->tty = 0;
index 12c934a1f2742c88a7b80e1b3ed00588d73e521b..8871aaa3dba677350f519280a5d75b8ff915316d 100644 (file)
@@ -373,6 +373,7 @@ struct neo_uart_struct {
 #define PCI_DEVICE_NEO_2DB9PRI_PCI_NAME                "Neo 2 - DB9 Universal PCI - Powered Ring Indicator"
 #define PCI_DEVICE_NEO_2RJ45_PCI_NAME          "Neo 2 - RJ45 Universal PCI"
 #define PCI_DEVICE_NEO_2RJ45PRI_PCI_NAME       "Neo 2 - RJ45 Universal PCI - Powered Ring Indicator"
+#define PCIE_DEVICE_NEO_IBM_PCI_NAME           "Neo 4 - PCI Express - IBM"
 
 /*
  * Our Global Variables.
index 6767ee381cd1b4645056012ba3704c05177389a0..338cf8a08b436db85c1b9d11b10b2f868e93fd24 100644 (file)
@@ -82,7 +82,10 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* store the info for the board we've found */
        brd->boardnum = adapter_count++;
        brd->pci_dev = pdev;
-       brd->maxports = 2;
+       if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM)
+               brd->maxports = 4;
+       else
+               brd->maxports = 2;
 
        spin_lock_init(&brd->bd_lock);
        spin_lock_init(&brd->bd_intr_lock);
@@ -208,6 +211,7 @@ static struct pci_device_id jsm_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 },
        { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 },
        { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, jsm_pci_tbl);
index 7a3625f52a03b837551697cf2bc23b54bc488d32..efc971d9647b20b7d09f773ba21e12c3b6407437 100644 (file)
@@ -783,7 +783,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
                }
        }
 
+       spin_unlock(&port->lock);
        tty_flip_buffer_push(tty);
+       spin_lock(&port->lock);
 
        return psc_ops->raw_rx_rdy(port);
 }
index 1e2b9d826f69a5db2756e8eb477f2249587122e4..eab032733790d5524ac9f14e8596c1a5a62e462c 100644 (file)
@@ -556,7 +556,7 @@ static int uart_chars_in_buffer(struct tty_struct *tty)
 static void uart_flush_buffer(struct tty_struct *tty)
 {
        struct uart_state *state = tty->driver_data;
-       struct uart_port *port = state->port;
+       struct uart_port *port;
        unsigned long flags;
 
        /*
@@ -568,6 +568,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
                return;
        }
 
+       port = state->port;
        pr_debug("uart_flush_buffer(%d) called\n", tty->index);
 
        spin_lock_irqsave(&port->lock, flags);
index 969106187718d909e0aacb9478477296d43e04ae..8fdafc27fce8a3bccfcfb840d288c30d7a34857f 100644 (file)
 #include <linux/console.h>
 #include <linux/platform_device.h>
 #include <linux/serial_sci.h>
-
-#ifdef CONFIG_CPU_FREQ
 #include <linux/notifier.h>
 #include <linux/cpufreq.h>
-#endif
-
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <linux/clk.h>
 #include <linux/ctype.h>
+
+#ifdef CONFIG_SUPERH
 #include <asm/clock.h>
 #include <asm/sh_bios.h>
 #include <asm/kgdb.h>
@@ -80,7 +78,7 @@ struct sci_port {
        struct timer_list       break_timer;
        int                     break_flag;
 
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_SUPERH
        /* Port clock */
        struct clk              *clk;
 #endif
@@ -365,21 +363,19 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 {
        unsigned int fcr_val = 0;
+       unsigned short data;
 
-       if (cflag & CRTSCTS) {
-               fcr_val |= SCFCR_MCE;
-
-               ctrl_outw(0x0000, PORT_PSCR);
-       } else {
-               unsigned short data;
-
-               data = ctrl_inw(PORT_PSCR);
-               data &= 0x033f;
-               data |= 0x0400;
-               ctrl_outw(data, PORT_PSCR);
+       if (port->mapbase == 0xffe00000) {
+               data = ctrl_inw(PSCR);
+               data &= ~0x03cf;
+               if (cflag & CRTSCTS)
+                       fcr_val |= SCFCR_MCE;
+               else
+                       data |= 0x0340;
 
-               ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0);
+               ctrl_outw(data, PSCR);
        }
+       /* SCIF1 and SCIF2 should be setup by board code */
 
        sci_out(port, SCFCR, fcr_val);
 }
index fa8700a968fc4be01018a1a916e0660fed6e6530..eb84833233fd98e690a1f08831b6cacf42fe2289 100644 (file)
 # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-# define SCPDR0                        0xA405013E      /* 16 bit SCIF0 PSDR */
-# define SCSPTR0               SCPDR0
+# define PADR                  0xA4050120
+# define PSDR                  0xA405013e
+# define PWDR                  0xA4050166
+# define PSCR                  0xA405011E
 # define SCIF_ORER             0x0001  /* overrun error bit */
 # define SCSCR_INIT(port)      0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
-# define PORT_PSCR             0xA405011E
 #elif defined(CONFIG_CPU_SUBTYPE_SH7366)
 # define SCPDR0                        0xA405013E      /* 16 bit SCIF0 PSDR */
 # define SCSPTR0               SCPDR0
   unsigned int addr = port->mapbase + (offset);                        \
   if ((size) == 8) {                                           \
     ctrl_outb(value, addr);                                    \
-  } else {                                                     \
+  } else if ((size) == 16) {                                   \
     ctrl_outw(value, addr);                                    \
   }
 
@@ -451,7 +452,11 @@ SCIF_FNS(SCSPTR,                   0,  0, 0x24, 16)
 SCIF_FNS(SCLSR,                                0,  0, 0x28, 16)
 #else
 SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
+#if defined(CONFIG_CPU_SUBTYPE_SH7722)
+SCIF_FNS(SCSPTR,                        0,  0, 0, 0)
+#else
 SCIF_FNS(SCSPTR,                        0,  0, 0x20, 16)
+#endif
 SCIF_FNS(SCLSR,                         0,  0, 0x24, 16)
 #endif
 #endif
@@ -593,13 +598,25 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
        return 1;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
 static inline int sci_rxd_in(struct uart_port *port)
 {
        if (port->mapbase == 0xffe00000)
                return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
        return 1;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+       if (port->mapbase == 0xffe00000)
+               return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */
+       if (port->mapbase == 0xffe10000)
+               return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */
+       if (port->mapbase == 0xffe20000)
+               return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */
+
+       return 1;
+}
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723)
 static inline int sci_rxd_in(struct uart_port *port)
 {
index be0fe152891b762135ec1d72ff9a8cd200aea708..145c0281495d81e1c7c214ed5f61847da0555d0d 100644 (file)
@@ -392,7 +392,7 @@ static struct uart_ops sunhv_pops = {
 
 static struct uart_driver sunhv_reg = {
        .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
+       .driver_name            = "sunhv",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
index 543f93741e6f5e9b09e79fb9f40076554cc9cc1a..9ff5b38f3bee9e5ac3aedf0740c2bd4ca71bff9d 100644 (file)
@@ -826,7 +826,7 @@ static struct uart_ops sunsab_pops = {
 
 static struct uart_driver sunsab_reg = {
        .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
+       .driver_name            = "sunsab",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
index 4e2302d43ab163966234da9091b173b955a9c131..03806a9352092a7b952259ebae0019e23a53f3c2 100644 (file)
@@ -1173,7 +1173,7 @@ out:
 
 static struct uart_driver sunsu_reg = {
        .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
+       .driver_name            = "sunsu",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
index 90a20a152ebfe9ce0779b3ddba4682941ce9de4a..7e9fa5ef0eb72c3a90a51871c584ac134efd2ed2 100644 (file)
@@ -1023,7 +1023,7 @@ static struct uart_sunzilog_port *sunzilog_irq_chain;
 
 static struct uart_driver sunzilog_reg = {
        .owner          =       THIS_MODULE,
-       .driver_name    =       "ttyS",
+       .driver_name    =       "sunzilog",
        .dev_name       =       "ttyS",
        .major          =       TTY_MAJOR,
 };
index fae9e8f3d092ce6e34afcf4e89ed5cfc73f0d39f..66ec5d8808de83c5393fd0d35fb0d6352bc24161 100644 (file)
@@ -126,7 +126,6 @@ config SPI_MPC52xx_PSC
 config SPI_MPC83xx
        tristate "Freescale MPC83xx/QUICC Engine SPI controller"
        depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
-       select SPI_BITBANG
        help
          This enables using the Freescale MPC83xx and QUICC Engine SPI
          controllers in master mode.
index 654bb58be63099235c711e909e46c13fd4831c62..0c452c46ab0778bf3e1c5458dcec0c270a979016 100644 (file)
@@ -1567,7 +1567,7 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
        int status = 0;
 
        /* Enable the SSP clock */
-       clk_disable(ssp->clk);
+       clk_enable(ssp->clk);
 
        /* Start the queue running */
        status = start_queue(drv_data);
index a9ac1fdb30948c5eba8ff864d0ee156d8db7e247..7fea3cf4588a37fa89589c8931862e704a62f156 100644 (file)
@@ -608,6 +608,7 @@ static void pump_transfers(unsigned long data)
        u8 width;
        u16 cr, dma_width, dma_config;
        u32 tranf_success = 1;
+       u8 full_duplex = 0;
 
        /* Get current state information */
        message = drv_data->cur_msg;
@@ -658,6 +659,7 @@ static void pump_transfers(unsigned long data)
        }
 
        if (transfer->rx_buf != NULL) {
+               full_duplex = transfer->tx_buf != NULL;
                drv_data->rx = transfer->rx_buf;
                drv_data->rx_end = drv_data->rx + transfer->len;
                dev_dbg(&drv_data->pdev->dev, "rx_buf is %p, rx_end is %p\n",
@@ -740,7 +742,8 @@ static void pump_transfers(unsigned long data)
         * successful use different way to r/w according to
         * drv_data->cur_chip->enable_dma
         */
-       if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
+       if (!full_duplex && drv_data->cur_chip->enable_dma
+                               && drv_data->len > 6) {
 
                disable_dma(drv_data->dma_channel);
                clear_dma_irqstat(drv_data->dma_channel);
@@ -828,7 +831,7 @@ static void pump_transfers(unsigned long data)
                /* IO mode write then read */
                dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n");
 
-               if (drv_data->tx != NULL && drv_data->rx != NULL) {
+               if (full_duplex) {
                        /* full duplex mode */
                        BUG_ON((drv_data->tx_end - drv_data->tx) !=
                               (drv_data->rx_end - drv_data->rx));
index 189f706b9e4b98b517d939c8ece9ed6146121659..6832da6f7109c32a379c169b1943abd56ac6af99 100644 (file)
@@ -49,6 +49,7 @@ struct mpc83xx_spi_reg {
 #define        SPMODE_LEN(x)           ((x) << 20)
 #define        SPMODE_PM(x)            ((x) << 16)
 #define        SPMODE_OP               (1 << 14)
+#define        SPMODE_CG(x)            ((x) << 7)
 
 /*
  * Default for SPI Mode:
@@ -67,10 +68,6 @@ struct mpc83xx_spi_reg {
 
 /* SPI Controller driver's private data. */
 struct mpc83xx_spi {
-       /* bitbang has to be first */
-       struct spi_bitbang bitbang;
-       struct completion done;
-
        struct mpc83xx_spi_reg __iomem *base;
 
        /* rx & tx bufs from the spi_transfer */
@@ -82,7 +79,7 @@ struct mpc83xx_spi {
        u32(*get_tx) (struct mpc83xx_spi *);
 
        unsigned int count;
-       u32 irq;
+       int irq;
 
        unsigned nsecs;         /* (clock cycle time)/2 */
 
@@ -94,6 +91,25 @@ struct mpc83xx_spi {
 
        void (*activate_cs) (u8 cs, u8 polarity);
        void (*deactivate_cs) (u8 cs, u8 polarity);
+
+       u8 busy;
+
+       struct workqueue_struct *workqueue;
+       struct work_struct work;
+
+       struct list_head queue;
+       spinlock_t lock;
+
+       struct completion done;
+};
+
+struct spi_mpc83xx_cs {
+       /* functions to deal with different sized buffers */
+       void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
+       u32 (*get_tx) (struct mpc83xx_spi *);
+       u32 rx_shift;           /* RX data reg shift when in qe mode */
+       u32 tx_shift;           /* TX data reg shift when in qe mode */
+       u32 hw_mode;            /* Holds HW mode register settings */
 };
 
 static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
@@ -137,6 +153,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 {
        struct mpc83xx_spi *mpc83xx_spi;
        u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+       struct spi_mpc83xx_cs   *cs = spi->controller_state;
 
        mpc83xx_spi = spi_master_get_devdata(spi->master);
 
@@ -147,50 +164,26 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 
        if (value == BITBANG_CS_ACTIVE) {
                u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-               u32 len = spi->bits_per_word;
-               u8 pm;
 
-               if (len == 32)
-                       len = 0;
-               else
-                       len = len - 1;
-
-               /* mask out bits we are going to set */
-               regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
-                               | SPMODE_LEN(0xF) | SPMODE_DIV16
-                               | SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP);
-
-               if (spi->mode & SPI_CPHA)
-                       regval |= SPMODE_CP_BEGIN_EDGECLK;
-               if (spi->mode & SPI_CPOL)
-                       regval |= SPMODE_CI_INACTIVEHIGH;
-               if (!(spi->mode & SPI_LSB_FIRST))
-                       regval |= SPMODE_REV;
-               if (spi->mode & SPI_LOOP)
-                       regval |= SPMODE_LOOP;
-
-               regval |= SPMODE_LEN(len);
-
-               if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) {
-                       pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1;
-                       if (pm > 0x0f) {
-                               dev_err(&spi->dev, "Requested speed is too "
-                                       "low: %d Hz. Will use %d Hz instead.\n",
-                                       spi->max_speed_hz,
-                                       mpc83xx_spi->spibrg / 1024);
-                               pm = 0x0f;
-                       }
-                       regval |= SPMODE_PM(pm) | SPMODE_DIV16;
-               } else {
-                       pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4);
-                       if (pm)
-                               pm--;
-                       regval |= SPMODE_PM(pm);
+               mpc83xx_spi->rx_shift = cs->rx_shift;
+               mpc83xx_spi->tx_shift = cs->tx_shift;
+               mpc83xx_spi->get_rx = cs->get_rx;
+               mpc83xx_spi->get_tx = cs->get_tx;
+
+               if (cs->hw_mode != regval) {
+                       unsigned long flags;
+                       void *tmp_ptr = &mpc83xx_spi->base->mode;
+
+                       regval = cs->hw_mode;
+                       /* Turn off IRQs locally to minimize time that
+                        * SPI is disabled
+                        */
+                       local_irq_save(flags);
+                       /* Turn off SPI unit prior changing mode */
+                       mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
+                       mpc83xx_spi_write_reg(tmp_ptr, regval);
+                       local_irq_restore(flags);
                }
-
-               /* Turn off SPI unit prior changing mode */
-               mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-               mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
                if (mpc83xx_spi->activate_cs)
                        mpc83xx_spi->activate_cs(spi->chip_select, pol);
        }
@@ -201,8 +194,9 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 {
        struct mpc83xx_spi *mpc83xx_spi;
        u32 regval;
-       u8 bits_per_word;
+       u8 bits_per_word, pm;
        u32 hz;
+       struct spi_mpc83xx_cs   *cs = spi->controller_state;
 
        mpc83xx_spi = spi_master_get_devdata(spi->master);
 
@@ -223,61 +217,191 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
            || ((bits_per_word > 16) && (bits_per_word != 32)))
                return -EINVAL;
 
-       mpc83xx_spi->rx_shift = 0;
-       mpc83xx_spi->tx_shift = 0;
+       if (!hz)
+               hz = spi->max_speed_hz;
+
+       cs->rx_shift = 0;
+       cs->tx_shift = 0;
        if (bits_per_word <= 8) {
-               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
-               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+               cs->get_rx = mpc83xx_spi_rx_buf_u8;
+               cs->get_tx = mpc83xx_spi_tx_buf_u8;
                if (mpc83xx_spi->qe_mode) {
-                       mpc83xx_spi->rx_shift = 16;
-                       mpc83xx_spi->tx_shift = 24;
+                       cs->rx_shift = 16;
+                       cs->tx_shift = 24;
                }
        } else if (bits_per_word <= 16) {
-               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
-               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
+               cs->get_rx = mpc83xx_spi_rx_buf_u16;
+               cs->get_tx = mpc83xx_spi_tx_buf_u16;
                if (mpc83xx_spi->qe_mode) {
-                       mpc83xx_spi->rx_shift = 16;
-                       mpc83xx_spi->tx_shift = 16;
+                       cs->rx_shift = 16;
+                       cs->tx_shift = 16;
                }
        } else if (bits_per_word <= 32) {
-               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
-               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
+               cs->get_rx = mpc83xx_spi_rx_buf_u32;
+               cs->get_tx = mpc83xx_spi_tx_buf_u32;
        } else
                return -EINVAL;
 
        if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
-               mpc83xx_spi->tx_shift = 0;
+               cs->tx_shift = 0;
                if (bits_per_word <= 8)
-                       mpc83xx_spi->rx_shift = 8;
+                       cs->rx_shift = 8;
                else
-                       mpc83xx_spi->rx_shift = 0;
+                       cs->rx_shift = 0;
        }
 
-       /* nsecs = (clock period)/2 */
-       if (!hz)
-               hz = spi->max_speed_hz;
-       mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
-       if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
-               return -EINVAL;
+       mpc83xx_spi->rx_shift = cs->rx_shift;
+       mpc83xx_spi->tx_shift = cs->tx_shift;
+       mpc83xx_spi->get_rx = cs->get_rx;
+       mpc83xx_spi->get_tx = cs->get_tx;
 
        if (bits_per_word == 32)
                bits_per_word = 0;
        else
                bits_per_word = bits_per_word - 1;
 
-       regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-
        /* mask out bits we are going to set */
-       regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV);
-       regval |= SPMODE_LEN(bits_per_word);
-       if (!(spi->mode & SPI_LSB_FIRST))
-               regval |= SPMODE_REV;
+       cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16
+                                 | SPMODE_PM(0xF));
+
+       cs->hw_mode |= SPMODE_LEN(bits_per_word);
+
+       if ((mpc83xx_spi->spibrg / hz) >= 64) {
+               pm = mpc83xx_spi->spibrg / (hz * 64) - 1;
+               if (pm > 0x0f) {
+                       dev_err(&spi->dev, "Requested speed is too "
+                               "low: %d Hz. Will use %d Hz instead.\n",
+                               hz, mpc83xx_spi->spibrg / 1024);
+                       pm = 0x0f;
+               }
+               cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16;
+       } else {
+               pm = mpc83xx_spi->spibrg / (hz * 4);
+               if (pm)
+                       pm--;
+               cs->hw_mode |= SPMODE_PM(pm);
+       }
+       regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+       if (cs->hw_mode != regval) {
+               unsigned long flags;
+               void *tmp_ptr = &mpc83xx_spi->base->mode;
+
+               regval = cs->hw_mode;
+               /* Turn off IRQs locally to minimize time
+                * that SPI is disabled
+                */
+               local_irq_save(flags);
+               /* Turn off SPI unit prior changing mode */
+               mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
+               mpc83xx_spi_write_reg(tmp_ptr, regval);
+               local_irq_restore(flags);
+       }
+       return 0;
+}
 
-       /* Turn off SPI unit prior changing mode */
-       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+       struct mpc83xx_spi *mpc83xx_spi;
+       u32 word, len, bits_per_word;
 
-       return 0;
+       mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+       mpc83xx_spi->tx = t->tx_buf;
+       mpc83xx_spi->rx = t->rx_buf;
+       bits_per_word = spi->bits_per_word;
+       if (t->bits_per_word)
+               bits_per_word = t->bits_per_word;
+       len = t->len;
+       if (bits_per_word > 8)
+               len /= 2;
+       if (bits_per_word > 16)
+               len /= 2;
+       mpc83xx_spi->count = len;
+       INIT_COMPLETION(mpc83xx_spi->done);
+
+       /* enable rx ints */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+
+       /* transmit word */
+       word = mpc83xx_spi->get_tx(mpc83xx_spi);
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+
+       wait_for_completion(&mpc83xx_spi->done);
+
+       /* disable rx ints */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+
+       return mpc83xx_spi->count;
+}
+
+static void mpc83xx_spi_work(struct work_struct *work)
+{
+       struct mpc83xx_spi *mpc83xx_spi =
+               container_of(work, struct mpc83xx_spi, work);
+
+       spin_lock_irq(&mpc83xx_spi->lock);
+       mpc83xx_spi->busy = 1;
+       while (!list_empty(&mpc83xx_spi->queue)) {
+               struct spi_message *m;
+               struct spi_device *spi;
+               struct spi_transfer *t = NULL;
+               unsigned cs_change;
+               int status, nsecs = 50;
+
+               m = container_of(mpc83xx_spi->queue.next,
+                               struct spi_message, queue);
+               list_del_init(&m->queue);
+               spin_unlock_irq(&mpc83xx_spi->lock);
+
+               spi = m->spi;
+               cs_change = 1;
+               status = 0;
+               list_for_each_entry(t, &m->transfers, transfer_list) {
+                       if (t->bits_per_word || t->speed_hz) {
+                               /* Don't allow changes if CS is active */
+                               status = -EINVAL;
+
+                               if (cs_change)
+                                       status = mpc83xx_spi_setup_transfer(spi, t);
+                               if (status < 0)
+                                       break;
+                       }
+
+                       if (cs_change)
+                               mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
+                       cs_change = t->cs_change;
+                       if (t->len)
+                               status = mpc83xx_spi_bufs(spi, t);
+                       if (status) {
+                               status = -EMSGSIZE;
+                               break;
+                       }
+                       m->actual_length += t->len;
+
+                       if (t->delay_usecs)
+                               udelay(t->delay_usecs);
+
+                       if (cs_change) {
+                               ndelay(nsecs);
+                               mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+                               ndelay(nsecs);
+                       }
+               }
+
+               m->status = status;
+               m->complete(m->context);
+
+               if (status || !cs_change) {
+                       ndelay(nsecs);
+                       mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+               }
+
+               mpc83xx_spi_setup_transfer(spi, NULL);
+
+               spin_lock_irq(&mpc83xx_spi->lock);
+       }
+       mpc83xx_spi->busy = 0;
+       spin_unlock_irq(&mpc83xx_spi->lock);
 }
 
 /* the spi->mode bits understood by this driver: */
@@ -286,9 +410,10 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 
 static int mpc83xx_spi_setup(struct spi_device *spi)
 {
-       struct spi_bitbang *bitbang;
        struct mpc83xx_spi *mpc83xx_spi;
        int retval;
+       u32 hw_mode;
+       struct spi_mpc83xx_cs   *cs = spi->controller_state;
 
        if (spi->mode & ~MODEBITS) {
                dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
@@ -299,63 +424,56 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
        if (!spi->max_speed_hz)
                return -EINVAL;
 
-       bitbang = spi_master_get_devdata(spi->master);
+       if (!cs) {
+               cs = kzalloc(sizeof *cs, GFP_KERNEL);
+               if (!cs)
+                       return -ENOMEM;
+               spi->controller_state = cs;
+       }
        mpc83xx_spi = spi_master_get_devdata(spi->master);
 
        if (!spi->bits_per_word)
                spi->bits_per_word = 8;
 
+       hw_mode = cs->hw_mode; /* Save orginal settings */
+       cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+       /* mask out bits we are going to set */
+       cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
+                        | SPMODE_REV | SPMODE_LOOP);
+
+       if (spi->mode & SPI_CPHA)
+               cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
+       if (spi->mode & SPI_CPOL)
+               cs->hw_mode |= SPMODE_CI_INACTIVEHIGH;
+       if (!(spi->mode & SPI_LSB_FIRST))
+               cs->hw_mode |= SPMODE_REV;
+       if (spi->mode & SPI_LOOP)
+               cs->hw_mode |= SPMODE_LOOP;
+
        retval = mpc83xx_spi_setup_transfer(spi, NULL);
-       if (retval < 0)
+       if (retval < 0) {
+               cs->hw_mode = hw_mode; /* Restore settings */
                return retval;
+       }
 
-       dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
+       dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
                __func__, spi->mode & (SPI_CPOL | SPI_CPHA),
-               spi->bits_per_word, 2 * mpc83xx_spi->nsecs);
-
+               spi->bits_per_word, spi->max_speed_hz);
+#if 0 /* Don't think this is needed */
        /* NOTE we _need_ to call chipselect() early, ideally with adapter
         * setup, unless the hardware defaults cooperate to avoid confusion
         * between normal (active low) and inverted chipselects.
         */
 
        /* deselect chip (low or high) */
-       spin_lock(&bitbang->lock);
-       if (!bitbang->busy) {
-               bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
-               ndelay(mpc83xx_spi->nsecs);
-       }
-       spin_unlock(&bitbang->lock);
-
+       spin_lock(&mpc83xx_spi->lock);
+       if (!mpc83xx_spi->busy)
+               mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+       spin_unlock(&mpc83xx_spi->lock);
+#endif
        return 0;
 }
 
-static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
-{
-       struct mpc83xx_spi *mpc83xx_spi;
-       u32 word;
-
-       mpc83xx_spi = spi_master_get_devdata(spi->master);
-
-       mpc83xx_spi->tx = t->tx_buf;
-       mpc83xx_spi->rx = t->rx_buf;
-       mpc83xx_spi->count = t->len;
-       INIT_COMPLETION(mpc83xx_spi->done);
-
-       /* enable rx ints */
-       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
-
-       /* transmit word */
-       word = mpc83xx_spi->get_tx(mpc83xx_spi);
-       mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
-
-       wait_for_completion(&mpc83xx_spi->done);
-
-       /* disable rx ints */
-       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
-
-       return t->len - mpc83xx_spi->count;
-}
-
 irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
 {
        struct mpc83xx_spi *mpc83xx_spi = context_data;
@@ -395,6 +513,28 @@ irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
 
        return ret;
 }
+static int mpc83xx_spi_transfer(struct spi_device *spi,
+                               struct spi_message *m)
+{
+       struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+       unsigned long flags;
+
+       m->actual_length = 0;
+       m->status = -EINPROGRESS;
+
+       spin_lock_irqsave(&mpc83xx_spi->lock, flags);
+       list_add_tail(&m->queue, &mpc83xx_spi->queue);
+       queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
+       spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
+
+       return 0;
+}
+
+
+static void mpc83xx_spi_cleanup(struct spi_device *spi)
+{
+       kfree(spi->controller_state);
+}
 
 static int __init mpc83xx_spi_probe(struct platform_device *dev)
 {
@@ -426,11 +566,11 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
                ret = -ENODEV;
                goto free_master;
        }
+       master->setup = mpc83xx_spi_setup;
+       master->transfer = mpc83xx_spi_transfer;
+       master->cleanup = mpc83xx_spi_cleanup;
+
        mpc83xx_spi = spi_master_get_devdata(master);
-       mpc83xx_spi->bitbang.master = spi_master_get(master);
-       mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
-       mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
-       mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
        mpc83xx_spi->activate_cs = pdata->activate_cs;
        mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
        mpc83xx_spi->qe_mode = pdata->qe_mode;
@@ -445,7 +585,6 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
                mpc83xx_spi->tx_shift = 24;
        }
 
-       mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
        init_completion(&mpc83xx_spi->done);
 
        mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
@@ -483,11 +622,21 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
                regval |= SPMODE_OP;
 
        mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+       spin_lock_init(&mpc83xx_spi->lock);
+       init_completion(&mpc83xx_spi->done);
+       INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
+       INIT_LIST_HEAD(&mpc83xx_spi->queue);
 
-       ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
-
-       if (ret != 0)
+       mpc83xx_spi->workqueue = create_singlethread_workqueue(
+               master->dev.parent->bus_id);
+       if (mpc83xx_spi->workqueue == NULL) {
+               ret = -EBUSY;
                goto free_irq;
+       }
+
+       ret = spi_register_master(master);
+       if (ret < 0)
+               goto unreg_master;
 
        printk(KERN_INFO
               "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
@@ -495,6 +644,8 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
 
        return ret;
 
+unreg_master:
+       destroy_workqueue(mpc83xx_spi->workqueue);
 free_irq:
        free_irq(mpc83xx_spi->irq, mpc83xx_spi);
 unmap_io:
@@ -515,10 +666,12 @@ static int __exit mpc83xx_spi_remove(struct platform_device *dev)
        master = platform_get_drvdata(dev);
        mpc83xx_spi = spi_master_get_devdata(master);
 
-       spi_bitbang_stop(&mpc83xx_spi->bitbang);
+       flush_workqueue(mpc83xx_spi->workqueue);
+       destroy_workqueue(mpc83xx_spi->workqueue);
+       spi_unregister_master(master);
+
        free_irq(mpc83xx_spi->irq, mpc83xx_spi);
        iounmap(mpc83xx_spi->base);
-       spi_master_put(mpc83xx_spi->bitbang.master);
 
        return 0;
 }
index 34bfb7dd77642f8a14a82bbca20ef2a2ef752456..0885cc357a371552dc2190a6da682f98a652abdb 100644 (file)
@@ -125,10 +125,10 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi,
        /* is clk = pclk / (2 * (pre+1)), or is it
         *    clk = (pclk * 2) / ( pre + 1) */
 
-       div = (div / 2) - 1;
+       div /= 2;
 
-       if (div < 0)
-               div = 1;
+       if (div > 0)
+               div -= 1;
 
        if (div > 255)
                div = 255;
index 516a6400db432eb0ccb6e96d7af7d0a0a3d0bb82..a419c42e880e208f5eec222fff067a7bbe7424c3 100644 (file)
@@ -17,6 +17,8 @@ obj-$(CONFIG_USB_SL811_HCD)   += host/
 obj-$(CONFIG_USB_U132_HCD)     += host/
 obj-$(CONFIG_USB_R8A66597_HCD) += host/
 
+obj-$(CONFIG_USB_C67X00_HCD)   += c67x00/
+
 obj-$(CONFIG_USB_ACM)          += class/
 obj-$(CONFIG_USB_PRINTER)      += class/
 
index 86e64035edb01b04ec7439c1c450bad641a14085..be0b8daac9c7de2681191161415877cb3289961e 100644 (file)
@@ -19,7 +19,6 @@ if USB_ATM
 
 config USB_SPEEDTOUCH
        tristate "Speedtouch USB support"
-       depends on USB_ATM
        select FW_LOADER
        help
          Say Y here if you have an SpeedTouch USB or SpeedTouch 330
@@ -32,7 +31,6 @@ config USB_SPEEDTOUCH
 
 config USB_CXACRU
        tristate "Conexant AccessRunner USB support"
-       depends on USB_ATM
        select FW_LOADER
        help
          Say Y here if you have an ADSL USB modem based on the Conexant
@@ -45,7 +43,6 @@ config USB_CXACRU
 
 config USB_UEAGLEATM
        tristate "ADI 930 and eagle USB DSL modem"
-       depends on USB_ATM
        select FW_LOADER
        help
          Say Y here if you have an ADSL USB modem based on the ADI 930
@@ -58,7 +55,6 @@ config USB_UEAGLEATM
 
 config USB_XUSBATM
        tristate "Other USB DSL modem support"
-       depends on USB_ATM
        help
          Say Y here if you have a DSL USB modem not explicitly supported by
          another USB DSL drivers.  In order to use your modem you will need to
diff --git a/drivers/usb/c67x00/Makefile b/drivers/usb/c67x00/Makefile
new file mode 100644 (file)
index 0000000..868bc41
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for Cypress C67X00 USB Controller
+#
+
+ccflags-$(CONFIG_USB_DEBUG)            += -DDEBUG
+
+obj-$(CONFIG_USB_C67X00_HCD)           += c67x00.o
+
+c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
new file mode 100644 (file)
index 0000000..5633bc5
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * c67x00-drv.c: Cypress C67X00 USB Common infrastructure
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+/*
+ * This file implements the common infrastructure for using the c67x00.
+ * It is both the link between the platform configuration and subdrivers and
+ * the link between the common hardware parts and the subdrivers (e.g.
+ * interrupt handling).
+ *
+ * The c67x00 has 2 SIE's (serial interface engine) wich can be configured
+ * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG).
+ *
+ * Depending on the platform configuration, the SIE's are created and
+ * the corresponding subdriver is initialized (c67x00_probe_sie).
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/usb/c67x00.h>
+
+#include "c67x00.h"
+#include "c67x00-hcd.h"
+
+static void c67x00_probe_sie(struct c67x00_sie *sie,
+                            struct c67x00_device *dev, int sie_num)
+{
+       spin_lock_init(&sie->lock);
+       sie->dev = dev;
+       sie->sie_num = sie_num;
+       sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);
+
+       switch (sie->mode) {
+       case C67X00_SIE_HOST:
+               c67x00_hcd_probe(sie);
+               break;
+
+       case C67X00_SIE_UNUSED:
+               dev_info(sie_dev(sie),
+                        "Not using SIE %d as requested\n", sie->sie_num);
+               break;
+
+       default:
+               dev_err(sie_dev(sie),
+                       "Unsupported configuration: 0x%x for SIE %d\n",
+                       sie->mode, sie->sie_num);
+               break;
+       }
+}
+
+static void c67x00_remove_sie(struct c67x00_sie *sie)
+{
+       switch (sie->mode) {
+       case C67X00_SIE_HOST:
+               c67x00_hcd_remove(sie);
+               break;
+
+       default:
+               break;
+       }
+}
+
+static irqreturn_t c67x00_irq(int irq, void *__dev)
+{
+       struct c67x00_device *c67x00 = __dev;
+       struct c67x00_sie *sie;
+       u16 msg, int_status;
+       int i, count = 8;
+
+       int_status = c67x00_ll_hpi_status(c67x00);
+       if (!int_status)
+               return IRQ_NONE;
+
+       while (int_status != 0 && (count-- >= 0)) {
+               c67x00_ll_irq(c67x00, int_status);
+               for (i = 0; i < C67X00_SIES; i++) {
+                       sie = &c67x00->sie[i];
+                       msg = 0;
+                       if (int_status & SIEMSG_FLG(i))
+                               msg = c67x00_ll_fetch_siemsg(c67x00, i);
+                       if (sie->irq)
+                               sie->irq(sie, int_status, msg);
+               }
+               int_status = c67x00_ll_hpi_status(c67x00);
+       }
+
+       if (int_status)
+               dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! "
+                        "status = 0x%04x\n", int_status);
+
+       return IRQ_HANDLED;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit c67x00_drv_probe(struct platform_device *pdev)
+{
+       struct c67x00_device *c67x00;
+       struct c67x00_platform_data *pdata;
+       struct resource *res, *res2;
+       int ret, i;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res2)
+               return -ENODEV;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -ENODEV;
+
+       c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL);
+       if (!c67x00)
+               return -ENOMEM;
+
+       if (!request_mem_region(res->start, res->end - res->start + 1,
+                               pdev->name)) {
+               dev_err(&pdev->dev, "Memory region busy\n");
+               ret = -EBUSY;
+               goto request_mem_failed;
+       }
+       c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1);
+       if (!c67x00->hpi.base) {
+               dev_err(&pdev->dev, "Unable to map HPI registers\n");
+               ret = -EIO;
+               goto map_failed;
+       }
+
+       spin_lock_init(&c67x00->hpi.lock);
+       c67x00->hpi.regstep = pdata->hpi_regstep;
+       c67x00->pdata = pdev->dev.platform_data;
+       c67x00->pdev = pdev;
+
+       c67x00_ll_init(c67x00);
+       c67x00_ll_hpi_reg_init(c67x00);
+
+       ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot claim IRQ\n");
+               goto request_irq_failed;
+       }
+
+       ret = c67x00_ll_reset(c67x00);
+       if (ret) {
+               dev_err(&pdev->dev, "Device reset failed\n");
+               goto reset_failed;
+       }
+
+       for (i = 0; i < C67X00_SIES; i++)
+               c67x00_probe_sie(&c67x00->sie[i], c67x00, i);
+
+       platform_set_drvdata(pdev, c67x00);
+
+       return 0;
+
+ reset_failed:
+       free_irq(res2->start, c67x00);
+ request_irq_failed:
+       iounmap(c67x00->hpi.base);
+ map_failed:
+       release_mem_region(res->start, res->end - res->start + 1);
+ request_mem_failed:
+       kfree(c67x00);
+
+       return ret;
+}
+
+static int __devexit c67x00_drv_remove(struct platform_device *pdev)
+{
+       struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
+       struct resource *res;
+       int i;
+
+       for (i = 0; i < C67X00_SIES; i++)
+               c67x00_remove_sie(&c67x00->sie[i]);
+
+       c67x00_ll_release(c67x00);
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res)
+               free_irq(res->start, c67x00);
+
+       iounmap(c67x00->hpi.base);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res)
+               release_mem_region(res->start, res->end - res->start + 1);
+
+       kfree(c67x00);
+
+       return 0;
+}
+
+static struct platform_driver c67x00_driver = {
+       .probe  = c67x00_drv_probe,
+       .remove = __devexit_p(c67x00_drv_remove),
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "c67x00",
+       },
+};
+MODULE_ALIAS("platform:c67x00");
+
+static int __init c67x00_init(void)
+{
+       return platform_driver_register(&c67x00_driver);
+}
+
+static void __exit c67x00_exit(void)
+{
+       platform_driver_unregister(&c67x00_driver);
+}
+
+module_init(c67x00_init);
+module_exit(c67x00_exit);
+
+MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
+MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
new file mode 100644 (file)
index 0000000..a22b887
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * c67x00-hcd.c: Cypress C67X00 USB Host Controller Driver
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/usb.h>
+
+#include "c67x00.h"
+#include "c67x00-hcd.h"
+
+/* --------------------------------------------------------------------------
+ * Root Hub Support
+ */
+
+static __u8 c67x00_hub_des[] = {
+       0x09,                   /*  __u8  bLength; */
+       0x29,                   /*  __u8  bDescriptorType; Hub-descriptor */
+       0x02,                   /*  __u8  bNbrPorts; */
+       0x00,                   /* __u16  wHubCharacteristics; */
+       0x00,                   /*   (per-port OC, no power switching) */
+       0x32,                   /*  __u8  bPwrOn2pwrGood; 2ms */
+       0x00,                   /*  __u8  bHubContrCurrent; 0 mA */
+       0x00,                   /*  __u8  DeviceRemovable; ** 7 Ports max ** */
+       0xff,                   /*  __u8  PortPwrCtrlMask; ** 7 ports max ** */
+};
+
+static void c67x00_hub_reset_host_port(struct c67x00_sie *sie, int port)
+{
+       struct c67x00_hcd *c67x00 = sie->private_data;
+       unsigned long flags;
+
+       c67x00_ll_husb_reset(sie, port);
+
+       spin_lock_irqsave(&c67x00->lock, flags);
+       c67x00_ll_husb_reset_port(sie, port);
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+
+       c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT);
+}
+
+static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       struct c67x00_sie *sie = c67x00->sie;
+       u16 status;
+       int i;
+
+       *buf = 0;
+       status = c67x00_ll_usb_get_status(sie);
+       for (i = 0; i < C67X00_PORTS; i++)
+               if (status & PORT_CONNECT_CHANGE(i))
+                       *buf |= (1 << i);
+
+       /* bit 0 denotes hub change, b1..n port change */
+       *buf <<= 1;
+
+       return !!*buf;
+}
+
+static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+                             u16 wIndex, char *buf, u16 wLength)
+{
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       struct c67x00_sie *sie = c67x00->sie;
+       u16 status, usb_status;
+       int len = 0;
+       unsigned int port = wIndex-1;
+       u16 wPortChange, wPortStatus;
+
+       switch (typeReq) {
+
+       case GetHubStatus:
+               *(__le32 *) buf = cpu_to_le32(0);
+               len = 4;                /* hub power */
+               break;
+
+       case GetPortStatus:
+               if (wIndex > C67X00_PORTS)
+                       return -EPIPE;
+
+               status = c67x00_ll_usb_get_status(sie);
+               usb_status = c67x00_ll_get_usb_ctl(sie);
+
+               wPortChange = 0;
+               if (status & PORT_CONNECT_CHANGE(port))
+                       wPortChange |= USB_PORT_STAT_C_CONNECTION;
+
+               wPortStatus = USB_PORT_STAT_POWER;
+               if (!(status & PORT_SE0_STATUS(port)))
+                       wPortStatus |= USB_PORT_STAT_CONNECTION;
+               if (usb_status & LOW_SPEED_PORT(port)) {
+                       wPortStatus |= USB_PORT_STAT_LOW_SPEED;
+                       c67x00->low_speed_ports |= (1 << port);
+               } else
+                       c67x00->low_speed_ports &= ~(1 << port);
+
+               if (usb_status & SOF_EOP_EN(port))
+                       wPortStatus |= USB_PORT_STAT_ENABLE;
+
+               *(__le16 *) buf = cpu_to_le16(wPortStatus);
+               *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange);
+               len = 4;
+               break;
+
+       case SetHubFeature:     /* We don't implement these */
+       case ClearHubFeature:
+               switch (wValue) {
+               case C_HUB_OVER_CURRENT:
+               case C_HUB_LOCAL_POWER:
+                       len = 0;
+                       break;
+
+               default:
+                       return -EPIPE;
+               }
+               break;
+
+       case SetPortFeature:
+               if (wIndex > C67X00_PORTS)
+                       return -EPIPE;
+
+               switch (wValue) {
+               case USB_PORT_FEAT_SUSPEND:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "SetPortFeature %d (SUSPEND)\n", port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_RESET:
+                       c67x00_hub_reset_host_port(sie, port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_POWER:
+                       /* Power always enabled */
+                       len = 0;
+                       break;
+
+               default:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "%s: SetPortFeature %d (0x%04x) Error!\n",
+                               __func__, port, wValue);
+                       return -EPIPE;
+               }
+               break;
+
+       case ClearPortFeature:
+               if (wIndex > C67X00_PORTS)
+                       return -EPIPE;
+
+               switch (wValue) {
+               case USB_PORT_FEAT_ENABLE:
+                       /* Reset the port so that the c67x00 also notices the
+                        * disconnect */
+                       c67x00_hub_reset_host_port(sie, port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_C_ENABLE:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): C_ENABLE\n", port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_SUSPEND:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): SUSPEND\n", port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_C_SUSPEND:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): C_SUSPEND\n", port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_POWER:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): POWER\n", port);
+                       return -EPIPE;
+
+               case USB_PORT_FEAT_C_CONNECTION:
+                       c67x00_ll_usb_clear_status(sie,
+                                                  PORT_CONNECT_CHANGE(port));
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_C_OVER_CURRENT:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): OVER_CURRENT\n", port);
+                       len = 0;
+                       break;
+
+               case USB_PORT_FEAT_C_RESET:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "ClearPortFeature (%d): C_RESET\n", port);
+                       len = 0;
+                       break;
+
+               default:
+                       dev_dbg(c67x00_hcd_dev(c67x00),
+                               "%s: ClearPortFeature %d (0x%04x) Error!\n",
+                               __func__, port, wValue);
+                       return -EPIPE;
+               }
+               break;
+
+       case GetHubDescriptor:
+               len = min_t(unsigned int, sizeof(c67x00_hub_des), wLength);
+               memcpy(buf, c67x00_hub_des, len);
+               break;
+
+       default:
+               dev_dbg(c67x00_hcd_dev(c67x00), "%s: unknown\n", __func__);
+               return -EPIPE;
+       }
+
+       return 0;
+}
+
+/* ---------------------------------------------------------------------
+ * Main part of host controller driver
+ */
+
+/**
+ * c67x00_hcd_irq
+ *
+ * This function is called from the interrupt handler in c67x00-drv.c
+ */
+static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg)
+{
+       struct c67x00_hcd *c67x00 = sie->private_data;
+       struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00);
+
+       /* Handle sie message flags */
+       if (msg) {
+               if (msg & HUSB_TDListDone)
+                       c67x00_sched_kick(c67x00);
+               else
+                       dev_warn(c67x00_hcd_dev(c67x00),
+                                "Unknown SIE msg flag(s): 0x%04x\n", msg);
+       }
+
+       if (unlikely(hcd->state == HC_STATE_HALT))
+               return;
+
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+               return;
+
+       /* Handle Start of frame events */
+       if (int_status & SOFEOP_FLG(sie->sie_num)) {
+               c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG);
+               c67x00_sched_kick(c67x00);
+               set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+       }
+}
+
+/**
+ * c67x00_hcd_start: Host controller start hook
+ */
+static int c67x00_hcd_start(struct usb_hcd *hcd)
+{
+       hcd->uses_new_polling = 1;
+       hcd->state = HC_STATE_RUNNING;
+       hcd->poll_rh = 1;
+
+       return 0;
+}
+
+/**
+ * c67x00_hcd_stop: Host controller stop hook
+ */
+static void c67x00_hcd_stop(struct usb_hcd *hcd)
+{
+       /* Nothing to do */
+}
+
+static int c67x00_hcd_get_frame(struct usb_hcd *hcd)
+{
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       u16 temp_val;
+
+       dev_dbg(c67x00_hcd_dev(c67x00), "%s\n", __func__);
+       temp_val = c67x00_ll_husb_get_frame(c67x00->sie);
+       temp_val &= HOST_FRAME_MASK;
+       return temp_val ? (temp_val - 1) : HOST_FRAME_MASK;
+}
+
+static struct hc_driver c67x00_hc_driver = {
+       .description    = "c67x00-hcd",
+       .product_desc   = "Cypress C67X00 Host Controller",
+       .hcd_priv_size  = sizeof(struct c67x00_hcd),
+       .flags          = HCD_USB11 | HCD_MEMORY,
+
+       /*
+        * basic lifecycle operations
+        */
+       .start          = c67x00_hcd_start,
+       .stop           = c67x00_hcd_stop,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue    = c67x00_urb_enqueue,
+       .urb_dequeue    = c67x00_urb_dequeue,
+       .endpoint_disable = c67x00_endpoint_disable,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number = c67x00_hcd_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data = c67x00_hub_status_data,
+       .hub_control    = c67x00_hub_control,
+};
+
+/* ---------------------------------------------------------------------
+ * Setup/Teardown routines
+ */
+
+int c67x00_hcd_probe(struct c67x00_sie *sie)
+{
+       struct c67x00_hcd *c67x00;
+       struct usb_hcd *hcd;
+       unsigned long flags;
+       int retval;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       hcd = usb_create_hcd(&c67x00_hc_driver, sie_dev(sie), "c67x00_sie");
+       if (!hcd) {
+               retval = -ENOMEM;
+               goto err0;
+       }
+       c67x00 = hcd_to_c67x00_hcd(hcd);
+
+       spin_lock_init(&c67x00->lock);
+       c67x00->sie = sie;
+
+       INIT_LIST_HEAD(&c67x00->list[PIPE_ISOCHRONOUS]);
+       INIT_LIST_HEAD(&c67x00->list[PIPE_INTERRUPT]);
+       INIT_LIST_HEAD(&c67x00->list[PIPE_CONTROL]);
+       INIT_LIST_HEAD(&c67x00->list[PIPE_BULK]);
+       c67x00->urb_count = 0;
+       INIT_LIST_HEAD(&c67x00->td_list);
+       c67x00->td_base_addr = CY_HCD_BUF_ADDR + SIE_TD_OFFSET(sie->sie_num);
+       c67x00->buf_base_addr = CY_HCD_BUF_ADDR + SIE_BUF_OFFSET(sie->sie_num);
+       c67x00->max_frame_bw = MAX_FRAME_BW_STD;
+
+       c67x00_ll_husb_init_host_port(sie);
+
+       init_completion(&c67x00->endpoint_disable);
+       retval = c67x00_sched_start_scheduler(c67x00);
+       if (retval)
+               goto err1;
+
+       retval = usb_add_hcd(hcd, 0, 0);
+       if (retval) {
+               dev_dbg(sie_dev(sie), "%s: usb_add_hcd returned %d\n",
+                       __func__, retval);
+               goto err2;
+       }
+
+       spin_lock_irqsave(&sie->lock, flags);
+       sie->private_data = c67x00;
+       sie->irq = c67x00_hcd_irq;
+       spin_unlock_irqrestore(&sie->lock, flags);
+
+       return retval;
+
+ err2:
+       c67x00_sched_stop_scheduler(c67x00);
+ err1:
+       usb_put_hcd(hcd);
+ err0:
+       return retval;
+}
+
+/* may be called with controller, bus, and devices active */
+void c67x00_hcd_remove(struct c67x00_sie *sie)
+{
+       struct c67x00_hcd *c67x00 = sie->private_data;
+       struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00);
+
+       c67x00_sched_stop_scheduler(c67x00);
+       usb_remove_hcd(hcd);
+       usb_put_hcd(hcd);
+}
diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h
new file mode 100644 (file)
index 0000000..e8c6d94
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * c67x00-hcd.h: Cypress C67X00 USB HCD
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#ifndef _USB_C67X00_HCD_H
+#define _USB_C67X00_HCD_H
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "c67x00.h"
+
+/*
+ * The following parameters depend on the CPU speed, bus speed, ...
+ * These can be tuned for specific use cases, e.g. if isochronous transfers
+ * are very important, bandwith can be sacrificed to guarantee that the
+ * 1ms deadline will be met.
+ * If bulk transfers are important, the MAX_FRAME_BW can be increased,
+ * but some (or many) isochronous deadlines might not be met.
+ *
+ * The values are specified in bittime.
+ */
+
+/*
+ * The current implementation switches between _STD (default) and _ISO (when
+ * isochronous transfers are scheduled), in order to optimize the throughput
+ * in normal cicrumstances, but also provide good isochronous behaviour.
+ *
+ * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms
+ * frames; there are 12000 bit times per frame.
+ */
+
+#define TOTAL_FRAME_BW         12000
+#define DEFAULT_EOT            2250
+
+#define MAX_FRAME_BW_STD       (TOTAL_FRAME_BW - DEFAULT_EOT)
+#define MAX_FRAME_BW_ISO       2400
+
+/*
+ * Periodic transfers may only use 90% of the full frame, but as
+ * we currently don't even use 90% of the full frame, we may
+ * use the full usable time for periodic transfers.
+ */
+#define MAX_PERIODIC_BW(full_bw)       full_bw
+
+/* -------------------------------------------------------------------------- */
+
+struct c67x00_hcd {
+       spinlock_t lock;
+       struct c67x00_sie *sie;
+       unsigned int low_speed_ports;   /* bitmask of low speed ports */
+       unsigned int urb_count;
+       unsigned int urb_iso_count;
+
+       struct list_head list[4];       /* iso, int, ctrl, bulk */
+#if PIPE_BULK != 3
+#error "Sanity check failed, this code presumes PIPE_... to range from 0 to 3"
+#endif
+
+       /* USB bandwidth allocated to td_list */
+       int bandwidth_allocated;
+       /* USB bandwidth allocated for isoc/int transfer */
+       int periodic_bw_allocated;
+       struct list_head td_list;
+       int max_frame_bw;
+
+       u16 td_base_addr;
+       u16 buf_base_addr;
+       u16 next_td_addr;
+       u16 next_buf_addr;
+
+       struct tasklet_struct tasklet;
+
+       struct completion endpoint_disable;
+
+       u16 current_frame;
+       u16 last_frame;
+};
+
+static inline struct c67x00_hcd *hcd_to_c67x00_hcd(struct usb_hcd *hcd)
+{
+       return (struct c67x00_hcd *)(hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00)
+{
+       return container_of((void *)c67x00, struct usb_hcd, hcd_priv);
+}
+
+/* ---------------------------------------------------------------------
+ * Functions used by c67x00-drv
+ */
+
+int c67x00_hcd_probe(struct c67x00_sie *sie);
+void c67x00_hcd_remove(struct c67x00_sie *sie);
+
+/* ---------------------------------------------------------------------
+ * Transfer Descriptor scheduling functions
+ */
+int c67x00_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
+int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
+void c67x00_endpoint_disable(struct usb_hcd *hcd,
+                            struct usb_host_endpoint *ep);
+
+void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg);
+void c67x00_sched_kick(struct c67x00_hcd *c67x00);
+int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00);
+void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00);
+
+#define c67x00_hcd_dev(x)      (c67x00_hcd_to_hcd(x)->self.controller)
+
+#endif                         /* _USB_C67X00_HCD_H */
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
new file mode 100644 (file)
index 0000000..5100fbb
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#include <asm/byteorder.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/usb/c67x00.h>
+#include "c67x00.h"
+
+#define COMM_REGS 14
+
+struct c67x00_lcp_int_data {
+       u16 regs[COMM_REGS];
+};
+
+/* -------------------------------------------------------------------------- */
+/* Interface definitions */
+
+#define COMM_ACK                       0x0FED
+#define COMM_NAK                       0xDEAD
+
+#define COMM_RESET                     0xFA50
+#define COMM_EXEC_INT                  0xCE01
+#define COMM_INT_NUM                   0x01C2
+
+/* Registers 0 to COMM_REGS-1 */
+#define COMM_R(x)                      (0x01C4 + 2 * (x))
+
+#define HUSB_SIE_pCurrentTDPtr(x)      ((x) ? 0x01B2 : 0x01B0)
+#define HUSB_SIE_pTDListDone_Sem(x)    ((x) ? 0x01B8 : 0x01B6)
+#define HUSB_pEOT                      0x01B4
+
+/* Software interrupts */
+/* 114, 115: */
+#define HUSB_SIE_INIT_INT(x)           ((x) ? 0x0073 : 0x0072)
+#define HUSB_RESET_INT                 0x0074
+
+#define SUSB_INIT_INT                  0x0071
+#define SUSB_INIT_INT_LOC              (SUSB_INIT_INT * 2)
+
+/* -----------------------------------------------------------------------
+ * HPI implementation
+ *
+ * The c67x00 chip also support control via SPI or HSS serial
+ * interfaces.  However, this driver assumes that register access can
+ * be performed from IRQ context.  While this is a safe assuption with
+ * the HPI interface, it is not true for the serial interfaces.
+ */
+
+/* HPI registers */
+#define HPI_DATA       0
+#define HPI_MAILBOX    1
+#define HPI_ADDR       2
+#define HPI_STATUS     3
+
+static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg)
+{
+       return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep);
+}
+
+static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value)
+{
+       __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep);
+}
+
+static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg)
+{
+       hpi_write_reg(dev, HPI_ADDR, reg);
+       return hpi_read_reg(dev, HPI_DATA);
+}
+
+static u16 hpi_read_word(struct c67x00_device *dev, u16 reg)
+{
+       u16 value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       value = hpi_read_word_nolock(dev, reg);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+
+       return value;
+}
+
+static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value)
+{
+       hpi_write_reg(dev, HPI_ADDR, reg);
+       hpi_write_reg(dev, HPI_DATA, value);
+}
+
+static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       hpi_write_word_nolock(dev, reg, value);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+}
+
+/*
+ * Only data is little endian, addr has cpu endianess
+ */
+static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr,
+                                u16 *data, u16 count)
+{
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+
+       hpi_write_reg(dev, HPI_ADDR, addr);
+       for (i = 0; i < count; i++)
+               hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++));
+
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+}
+
+/*
+ * Only data is little endian, addr has cpu endianess
+ */
+static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr,
+                               u16 *data, u16 count)
+{
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       hpi_write_reg(dev, HPI_ADDR, addr);
+       for (i = 0; i < count; i++)
+               *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA));
+
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+}
+
+static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask)
+{
+       u16 value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       value = hpi_read_word_nolock(dev, reg);
+       hpi_write_word_nolock(dev, reg, value | mask);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+}
+
+static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask)
+{
+       u16 value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       value = hpi_read_word_nolock(dev, reg);
+       hpi_write_word_nolock(dev, reg, value & ~mask);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+}
+
+static u16 hpi_recv_mbox(struct c67x00_device *dev)
+{
+       u16 value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       value = hpi_read_reg(dev, HPI_MAILBOX);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+
+       return value;
+}
+
+static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       hpi_write_reg(dev, HPI_MAILBOX, value);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+
+       return value;
+}
+
+u16 c67x00_ll_hpi_status(struct c67x00_device *dev)
+{
+       u16 value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->hpi.lock, flags);
+       value = hpi_read_reg(dev, HPI_STATUS);
+       spin_unlock_irqrestore(&dev->hpi.lock, flags);
+
+       return value;
+}
+
+void c67x00_ll_hpi_reg_init(struct c67x00_device *dev)
+{
+       int i;
+
+       hpi_recv_mbox(dev);
+       c67x00_ll_hpi_status(dev);
+       hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0);
+
+       for (i = 0; i < C67X00_SIES; i++) {
+               hpi_write_word(dev, SIEMSG_REG(i), 0);
+               hpi_read_word(dev, SIEMSG_REG(i));
+       }
+}
+
+void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie)
+{
+       hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
+                    SOFEOP_TO_HPI_EN(sie->sie_num));
+}
+
+void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie)
+{
+       hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG,
+                      SOFEOP_TO_HPI_EN(sie->sie_num));
+}
+
+/* -------------------------------------------------------------------------- */
+/* Transactions */
+
+static inline u16 ll_recv_msg(struct c67x00_device *dev)
+{
+       u16 res;
+
+       res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ);
+       WARN_ON(!res);
+
+       return (res == 0) ? -EIO : 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/* General functions */
+
+u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num)
+{
+       u16 val;
+
+       val = hpi_read_word(dev, SIEMSG_REG(sie_num));
+       /* clear register to allow next message */
+       hpi_write_word(dev, SIEMSG_REG(sie_num), 0);
+
+       return val;
+}
+
+u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
+{
+       return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num));
+}
+
+/**
+ * c67x00_ll_usb_clear_status - clear the USB status bits
+ */
+void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits)
+{
+       hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits);
+}
+
+u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie)
+{
+       return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num));
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
+                               struct c67x00_lcp_int_data *data)
+{
+       int i, rc;
+
+       mutex_lock(&dev->hpi.lcp.mutex);
+       hpi_write_word(dev, COMM_INT_NUM, nr);
+       for (i = 0; i < COMM_REGS; i++)
+               hpi_write_word(dev, COMM_R(i), data->regs[i]);
+       hpi_send_mbox(dev, COMM_EXEC_INT);
+       rc = ll_recv_msg(dev);
+       mutex_unlock(&dev->hpi.lcp.mutex);
+
+       return rc;
+}
+
+/* -------------------------------------------------------------------------- */
+/* Host specific functions */
+
+void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value)
+{
+       mutex_lock(&dev->hpi.lcp.mutex);
+       hpi_write_word(dev, HUSB_pEOT, value);
+       mutex_unlock(&dev->hpi.lcp.mutex);
+}
+
+static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
+{
+       struct c67x00_device *dev = sie->dev;
+       struct c67x00_lcp_int_data data;
+       int rc;
+
+       rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data);
+       BUG_ON(rc); /* No return path for error code; crash spectacularly */
+}
+
+void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port)
+{
+       struct c67x00_device *dev = sie->dev;
+       struct c67x00_lcp_int_data data;
+       int rc;
+
+       data.regs[0] = 50;      /* Reset USB port for 50ms */
+       data.regs[1] = port | (sie->sie_num << 1);
+       rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data);
+       BUG_ON(rc); /* No return path for error code; crash spectacularly */
+}
+
+void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr)
+{
+       hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr);
+}
+
+u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie)
+{
+       return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num));
+}
+
+u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie)
+{
+       return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num));
+}
+
+void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie)
+{
+       /* Set port into host mode */
+       hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE);
+       c67x00_ll_husb_sie_init(sie);
+       /* Clear interrupts */
+       c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK);
+       /* Check */
+       if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
+               dev_warn(sie_dev(sie),
+                        "SIE %d not set to host mode\n", sie->sie_num);
+}
+
+void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port)
+{
+       /* Clear connect change */
+       c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port));
+
+       /* Enable interrupts */
+       hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
+                    SOFEOP_TO_CPU_EN(sie->sie_num));
+       hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num),
+                    SOF_EOP_IRQ_EN | DONE_IRQ_EN);
+
+       /* Enable pull down transistors */
+       hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port));
+}
+
+/* -------------------------------------------------------------------------- */
+
+void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status)
+{
+       if ((int_status & MBX_OUT_FLG) == 0)
+               return;
+
+       dev->hpi.lcp.last_msg = hpi_recv_mbox(dev);
+       complete(&dev->hpi.lcp.msg_received);
+}
+
+/* -------------------------------------------------------------------------- */
+
+int c67x00_ll_reset(struct c67x00_device *dev)
+{
+       int rc;
+
+       mutex_lock(&dev->hpi.lcp.mutex);
+       hpi_send_mbox(dev, COMM_RESET);
+       rc = ll_recv_msg(dev);
+       mutex_unlock(&dev->hpi.lcp.mutex);
+
+       return rc;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * c67x00_ll_write_mem_le16 - write into c67x00 memory
+ * Only data is little endian, addr has cpu endianess.
+ */
+void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr,
+                             void *data, int len)
+{
+       u8 *buf = data;
+
+       /* Sanity check */
+       if (addr + len > 0xffff) {
+               dev_err(&dev->pdev->dev,
+                       "Trying to write beyond writable region!\n");
+               return;
+       }
+
+       if (addr & 0x01) {
+               /* unaligned access */
+               u16 tmp;
+               tmp = hpi_read_word(dev, addr - 1);
+               tmp = (tmp & 0x00ff) | (*buf++ << 8);
+               hpi_write_word(dev, addr - 1, tmp);
+               addr++;
+               len--;
+       }
+
+       hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2);
+       buf += len & ~0x01;
+       addr += len & ~0x01;
+       len &= 0x01;
+
+       if (len) {
+               u16 tmp;
+               tmp = hpi_read_word(dev, addr);
+               tmp = (tmp & 0xff00) | *buf;
+               hpi_write_word(dev, addr, tmp);
+       }
+}
+
+/**
+ * c67x00_ll_read_mem_le16 - read from c67x00 memory
+ * Only data is little endian, addr has cpu endianess.
+ */
+void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr,
+                            void *data, int len)
+{
+       u8 *buf = data;
+
+       if (addr & 0x01) {
+               /* unaligned access */
+               u16 tmp;
+               tmp = hpi_read_word(dev, addr - 1);
+               *buf++ = (tmp >> 8) & 0x00ff;
+               addr++;
+               len--;
+       }
+
+       hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2);
+       buf += len & ~0x01;
+       addr += len & ~0x01;
+       len &= 0x01;
+
+       if (len) {
+               u16 tmp;
+               tmp = hpi_read_word(dev, addr);
+               *buf = tmp & 0x00ff;
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+void c67x00_ll_init(struct c67x00_device *dev)
+{
+       mutex_init(&dev->hpi.lcp.mutex);
+       init_completion(&dev->hpi.lcp.msg_received);
+}
+
+void c67x00_ll_release(struct c67x00_device *dev)
+{
+}
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
new file mode 100644 (file)
index 0000000..85dfe29
--- /dev/null
@@ -0,0 +1,1170 @@
+/*
+ * c67x00-sched.c: Cypress C67X00 USB Host Controller Driver - TD scheduling
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#include <linux/kthread.h>
+
+#include "c67x00.h"
+#include "c67x00-hcd.h"
+
+/*
+ * These are the stages for a control urb, they are kept
+ * in both urb->interval and td->privdata.
+ */
+#define SETUP_STAGE            0
+#define DATA_STAGE             1
+#define STATUS_STAGE           2
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * struct c67x00_ep_data: Host endpoint data structure
+ */
+struct c67x00_ep_data {
+       struct list_head queue;
+       struct list_head node;
+       struct usb_host_endpoint *hep;
+       struct usb_device *dev;
+       u16 next_frame;         /* For int/isoc transactions */
+};
+
+/**
+ * struct c67x00_td
+ *
+ * Hardware parts are little endiannes, SW in CPU endianess.
+ */
+struct c67x00_td {
+       /* HW specific part */
+       __le16 ly_base_addr;    /* Bytes 0-1 */
+       __le16 port_length;     /* Bytes 2-3 */
+       u8 pid_ep;              /* Byte 4 */
+       u8 dev_addr;            /* Byte 5 */
+       u8 ctrl_reg;            /* Byte 6 */
+       u8 status;              /* Byte 7 */
+       u8 retry_cnt;           /* Byte 8 */
+#define TT_OFFSET              2
+#define TT_CONTROL             0
+#define TT_ISOCHRONOUS         1
+#define TT_BULK                        2
+#define TT_INTERRUPT           3
+       u8 residue;             /* Byte 9 */
+       __le16 next_td_addr;    /* Bytes 10-11 */
+       /* SW part */
+       struct list_head td_list;
+       u16 td_addr;
+       void *data;
+       struct urb *urb;
+       unsigned long privdata;
+
+       /* These are needed for handling the toggle bits:
+        * an urb can be dequeued while a td is in progress
+        * after checking the td, the toggle bit might need to
+        * be fixed */
+       struct c67x00_ep_data *ep_data;
+       unsigned int pipe;
+};
+
+struct c67x00_urb_priv {
+       struct list_head hep_node;
+       struct urb *urb;
+       int port;
+       int cnt;                /* packet number for isoc */
+       int status;
+       struct c67x00_ep_data *ep_data;
+};
+
+#define td_udev(td)    ((td)->ep_data->dev)
+
+#define CY_TD_SIZE             12
+
+#define TD_PIDEP_OFFSET                0x04
+#define TD_PIDEPMASK_PID       0xF0
+#define TD_PIDEPMASK_EP                0x0F
+#define TD_PORTLENMASK_DL      0x02FF
+#define TD_PORTLENMASK_PN      0xC000
+
+#define TD_STATUS_OFFSET       0x07
+#define TD_STATUSMASK_ACK      0x01
+#define TD_STATUSMASK_ERR      0x02
+#define TD_STATUSMASK_TMOUT    0x04
+#define TD_STATUSMASK_SEQ      0x08
+#define TD_STATUSMASK_SETUP    0x10
+#define TD_STATUSMASK_OVF      0x20
+#define TD_STATUSMASK_NAK      0x40
+#define TD_STATUSMASK_STALL    0x80
+
+#define TD_ERROR_MASK          (TD_STATUSMASK_ERR | TD_STATUSMASK_TMOUT | \
+                                TD_STATUSMASK_STALL)
+
+#define TD_RETRYCNT_OFFSET     0x08
+#define TD_RETRYCNTMASK_ACT_FLG        0x10
+#define TD_RETRYCNTMASK_TX_TYPE        0x0C
+#define TD_RETRYCNTMASK_RTY_CNT        0x03
+
+#define TD_RESIDUE_OVERFLOW    0x80
+
+#define TD_PID_IN              0x90
+
+/* Residue: signed 8bits, neg -> OVERFLOW, pos -> UNDERFLOW */
+#define td_residue(td)         ((__s8)(td->residue))
+#define td_ly_base_addr(td)    (__le16_to_cpu((td)->ly_base_addr))
+#define td_port_length(td)     (__le16_to_cpu((td)->port_length))
+#define td_next_td_addr(td)    (__le16_to_cpu((td)->next_td_addr))
+
+#define td_active(td)          ((td)->retry_cnt & TD_RETRYCNTMASK_ACT_FLG)
+#define td_length(td)          (td_port_length(td) & TD_PORTLENMASK_DL)
+
+#define td_sequence_ok(td)     (!td->status || \
+                                (!(td->status & TD_STATUSMASK_SEQ) ==  \
+                                 !(td->ctrl_reg & SEQ_SEL)))
+
+#define td_acked(td)           (!td->status || \
+                                (td->status & TD_STATUSMASK_ACK))
+#define td_actual_bytes(td)    (td_length(td) - td_residue(td))
+
+/* -------------------------------------------------------------------------- */
+
+#ifdef DEBUG
+
+/**
+ * dbg_td - Dump the contents of the TD
+ */
+static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg)
+{
+       struct device *dev = c67x00_hcd_dev(c67x00);
+
+       dev_dbg(dev, "### %s at 0x%04x\n", msg, td->td_addr);
+       dev_dbg(dev, "urb:      0x%p\n", td->urb);
+       dev_dbg(dev, "endpoint:   %4d\n", usb_pipeendpoint(td->pipe));
+       dev_dbg(dev, "pipeout:    %4d\n", usb_pipeout(td->pipe));
+       dev_dbg(dev, "ly_base_addr: 0x%04x\n", td_ly_base_addr(td));
+       dev_dbg(dev, "port_length:  0x%04x\n", td_port_length(td));
+       dev_dbg(dev, "pid_ep:         0x%02x\n", td->pid_ep);
+       dev_dbg(dev, "dev_addr:       0x%02x\n", td->dev_addr);
+       dev_dbg(dev, "ctrl_reg:       0x%02x\n", td->ctrl_reg);
+       dev_dbg(dev, "status:         0x%02x\n", td->status);
+       dev_dbg(dev, "retry_cnt:      0x%02x\n", td->retry_cnt);
+       dev_dbg(dev, "residue:        0x%02x\n", td->residue);
+       dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td));
+       dev_dbg(dev, "data:");
+       print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
+                      td->data, td_length(td), 1);
+}
+#else                          /* DEBUG */
+
+static inline void
+dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { }
+
+#endif                         /* DEBUG */
+
+/* -------------------------------------------------------------------------- */
+/* Helper functions */
+
+static inline u16 c67x00_get_current_frame_number(struct c67x00_hcd *c67x00)
+{
+       return c67x00_ll_husb_get_frame(c67x00->sie) & HOST_FRAME_MASK;
+}
+
+/**
+ * frame_add
+ * Software wraparound for framenumbers.
+ */
+static inline u16 frame_add(u16 a, u16 b)
+{
+       return (a + b) & HOST_FRAME_MASK;
+}
+
+/**
+ * frame_after - is frame a after frame b
+ */
+static inline int frame_after(u16 a, u16 b)
+{
+       return ((HOST_FRAME_MASK + a - b) & HOST_FRAME_MASK) <
+           (HOST_FRAME_MASK / 2);
+}
+
+/**
+ * frame_after_eq - is frame a after or equal to frame b
+ */
+static inline int frame_after_eq(u16 a, u16 b)
+{
+       return ((HOST_FRAME_MASK + 1 + a - b) & HOST_FRAME_MASK) <
+           (HOST_FRAME_MASK / 2);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * c67x00_release_urb - remove link from all tds to this urb
+ * Disconnects the urb from it's tds, so that it can be given back.
+ * pre: urb->hcpriv != NULL
+ */
+static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       struct c67x00_td *td;
+       struct c67x00_urb_priv *urbp;
+
+       BUG_ON(!urb);
+
+       c67x00->urb_count--;
+
+       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+               c67x00->urb_iso_count--;
+               if (c67x00->urb_iso_count == 0)
+                       c67x00->max_frame_bw = MAX_FRAME_BW_STD;
+       }
+
+       /* TODO this might be not so efficient when we've got many urbs!
+        * Alternatives:
+        *   * only clear when needed
+        *   * keep a list of tds with each urbp
+        */
+       list_for_each_entry(td, &c67x00->td_list, td_list)
+               if (urb == td->urb)
+                       td->urb = NULL;
+
+       urbp = urb->hcpriv;
+       urb->hcpriv = NULL;
+       list_del(&urbp->hep_node);
+       kfree(urbp);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static struct c67x00_ep_data *
+c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       struct usb_host_endpoint *hep = urb->ep;
+       struct c67x00_ep_data *ep_data;
+       int type;
+
+       c67x00->current_frame = c67x00_get_current_frame_number(c67x00);
+
+       /* Check if endpoint already has a c67x00_ep_data struct allocated */
+       if (hep->hcpriv) {
+               ep_data = hep->hcpriv;
+               if (frame_after(c67x00->current_frame, ep_data->next_frame))
+                       ep_data->next_frame =
+                           frame_add(c67x00->current_frame, 1);
+               return hep->hcpriv;
+       }
+
+       /* Allocate and initialize a new c67x00 endpoint data structure */
+       ep_data = kzalloc(sizeof(*ep_data), GFP_ATOMIC);
+       if (!ep_data)
+               return NULL;
+
+       INIT_LIST_HEAD(&ep_data->queue);
+       INIT_LIST_HEAD(&ep_data->node);
+       ep_data->hep = hep;
+
+       /* hold a reference to udev as long as this endpoint lives,
+        * this is needed to possibly fix the data toggle */
+       ep_data->dev = usb_get_dev(urb->dev);
+       hep->hcpriv = ep_data;
+
+       /* For ISOC and INT endpoints, start ASAP: */
+       ep_data->next_frame = frame_add(c67x00->current_frame, 1);
+
+       /* Add the endpoint data to one of the pipe lists; must be added
+          in order of endpoint address */
+       type = usb_pipetype(urb->pipe);
+       if (list_empty(&ep_data->node)) {
+               list_add(&ep_data->node, &c67x00->list[type]);
+       } else {
+               struct c67x00_ep_data *prev;
+
+               list_for_each_entry(prev, &c67x00->list[type], node) {
+                       if (prev->hep->desc.bEndpointAddress >
+                           hep->desc.bEndpointAddress) {
+                               list_add(&ep_data->node, prev->node.prev);
+                               break;
+                       }
+               }
+       }
+
+       return ep_data;
+}
+
+static int c67x00_ep_data_free(struct usb_host_endpoint *hep)
+{
+       struct c67x00_ep_data *ep_data = hep->hcpriv;
+
+       if (!ep_data)
+               return 0;
+
+       if (!list_empty(&ep_data->queue))
+               return -EBUSY;
+
+       usb_put_dev(ep_data->dev);
+       list_del(&ep_data->queue);
+       list_del(&ep_data->node);
+
+       kfree(ep_data);
+       hep->hcpriv = NULL;
+
+       return 0;
+}
+
+void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+{
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       unsigned long flags;
+
+       if (!list_empty(&ep->urb_list))
+               dev_warn(c67x00_hcd_dev(c67x00), "error: urb list not empty\n");
+
+       spin_lock_irqsave(&c67x00->lock, flags);
+
+       /* loop waiting for all transfers in the endpoint queue to complete */
+       while (c67x00_ep_data_free(ep)) {
+               /* Drop the lock so we can sleep waiting for the hardware */
+               spin_unlock_irqrestore(&c67x00->lock, flags);
+
+               /* it could happen that we reinitialize this completion, while
+                * somebody was waiting for that completion.  The timeout and
+                * while loop handle such cases, but this might be improved */
+               INIT_COMPLETION(c67x00->endpoint_disable);
+               c67x00_sched_kick(c67x00);
+               wait_for_completion_timeout(&c67x00->endpoint_disable, 1 * HZ);
+
+               spin_lock_irqsave(&c67x00->lock, flags);
+       }
+
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static inline int get_root_port(struct usb_device *dev)
+{
+       while (dev->parent->parent)
+               dev = dev->parent;
+       return dev->portnum;
+}
+
+int c67x00_urb_enqueue(struct usb_hcd *hcd,
+                      struct urb *urb, gfp_t mem_flags)
+{
+       int ret;
+       unsigned long flags;
+       struct c67x00_urb_priv *urbp;
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       int port = get_root_port(urb->dev)-1;
+
+       spin_lock_irqsave(&c67x00->lock, flags);
+
+       /* Make sure host controller is running */
+       if (!HC_IS_RUNNING(hcd->state)) {
+               ret = -ENODEV;
+               goto err_not_linked;
+       }
+
+       ret = usb_hcd_link_urb_to_ep(hcd, urb);
+       if (ret)
+               goto err_not_linked;
+
+       /* Allocate and initialize urb private data */
+       urbp = kzalloc(sizeof(*urbp), mem_flags);
+       if (!urbp) {
+               ret = -ENOMEM;
+               goto err_urbp;
+       }
+
+       INIT_LIST_HEAD(&urbp->hep_node);
+       urbp->urb = urb;
+       urbp->port = port;
+
+       urbp->ep_data = c67x00_ep_data_alloc(c67x00, urb);
+
+       if (!urbp->ep_data) {
+               ret = -ENOMEM;
+               goto err_epdata;
+       }
+
+       /* TODO claim bandwidth with usb_claim_bandwidth?
+        * also release it somewhere! */
+
+       urb->hcpriv = urbp;
+
+       urb->actual_length = 0; /* Nothing received/transmitted yet */
+
+       switch (usb_pipetype(urb->pipe)) {
+       case PIPE_CONTROL:
+               urb->interval = SETUP_STAGE;
+               break;
+       case PIPE_INTERRUPT:
+               break;
+       case PIPE_BULK:
+               break;
+       case PIPE_ISOCHRONOUS:
+               if (c67x00->urb_iso_count == 0)
+                       c67x00->max_frame_bw = MAX_FRAME_BW_ISO;
+               c67x00->urb_iso_count++;
+               /* Assume always URB_ISO_ASAP, FIXME */
+               if (list_empty(&urbp->ep_data->queue))
+                       urb->start_frame = urbp->ep_data->next_frame;
+               else {
+                       /* Go right after the last one */
+                       struct urb *last_urb;
+
+                       last_urb = list_entry(urbp->ep_data->queue.prev,
+                                             struct c67x00_urb_priv,
+                                             hep_node)->urb;
+                       urb->start_frame =
+                           frame_add(last_urb->start_frame,
+                                     last_urb->number_of_packets *
+                                     last_urb->interval);
+               }
+               urbp->cnt = 0;
+               break;
+       }
+
+       /* Add the URB to the endpoint queue */
+       list_add_tail(&urbp->hep_node, &urbp->ep_data->queue);
+
+       /* If this is the only URB, kick start the controller */
+       if (!c67x00->urb_count++)
+               c67x00_ll_hpi_enable_sofeop(c67x00->sie);
+
+       c67x00_sched_kick(c67x00);
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+
+       return 0;
+
+err_epdata:
+       kfree(urbp);
+err_urbp:
+       usb_hcd_unlink_urb_from_ep(hcd, urb);
+err_not_linked:
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+
+       return ret;
+}
+
+int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+       struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+       unsigned long flags;
+       int rc;
+
+       spin_lock_irqsave(&c67x00->lock, flags);
+       rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+       if (rc)
+               goto done;
+
+       c67x00_release_urb(c67x00, urb);
+       usb_hcd_unlink_urb_from_ep(hcd, urb);
+
+       spin_unlock(&c67x00->lock);
+       usb_hcd_giveback_urb(hcd, urb, status);
+       spin_lock(&c67x00->lock);
+
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+
+       return 0;
+
+ done:
+       spin_unlock_irqrestore(&c67x00->lock, flags);
+       return rc;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * pre: c67x00 locked, urb unlocked
+ */
+static void
+c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status)
+{
+       struct c67x00_urb_priv *urbp;
+
+       if (!urb)
+               return;
+
+       urbp = urb->hcpriv;
+       urbp->status = status;
+
+       list_del_init(&urbp->hep_node);
+
+       c67x00_release_urb(c67x00, urb);
+       usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00), urb);
+       spin_unlock(&c67x00->lock);
+       usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb, urbp->status);
+       spin_lock(&c67x00->lock);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int c67x00_claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
+                                int len, int periodic)
+{
+       struct c67x00_urb_priv *urbp = urb->hcpriv;
+       int bit_time;
+
+       /* According to the C67x00 BIOS user manual, page 3-18,19, the
+        * following calculations provide the full speed bit times for
+        * a transaction.
+        *
+        * FS(in)       = 112.5 +  9.36*BC + HOST_DELAY
+        * FS(in,iso)   =  90.5 +  9.36*BC + HOST_DELAY
+        * FS(out)      = 112.5 +  9.36*BC + HOST_DELAY
+        * FS(out,iso)  =  78.4 +  9.36*BC + HOST_DELAY
+        * LS(in)       = 802.4 + 75.78*BC + HOST_DELAY
+        * LS(out)      = 802.6 + 74.67*BC + HOST_DELAY
+        *
+        * HOST_DELAY == 106 for the c67200 and c67300.
+        */
+
+       /* make calculations in 1/100 bit times to maintain resolution */
+       if (urbp->ep_data->dev->speed == USB_SPEED_LOW) {
+               /* Low speed pipe */
+               if (usb_pipein(urb->pipe))
+                       bit_time = 80240 + 7578*len;
+               else
+                       bit_time = 80260 + 7467*len;
+       } else {
+               /* FS pipes */
+               if (usb_pipeisoc(urb->pipe))
+                       bit_time = usb_pipein(urb->pipe) ? 9050 : 7840;
+               else
+                       bit_time = 11250;
+               bit_time += 936*len;
+       }
+
+       /* Scale back down to integer bit times.  Use a host delay of 106.
+        * (this is the only place it is used) */
+       bit_time = ((bit_time+50) / 100) + 106;
+
+       if (unlikely(bit_time + c67x00->bandwidth_allocated >=
+                    c67x00->max_frame_bw))
+               return -EMSGSIZE;
+
+       if (unlikely(c67x00->next_td_addr + CY_TD_SIZE >=
+                    c67x00->td_base_addr + SIE_TD_SIZE))
+               return -EMSGSIZE;
+
+       if (unlikely(c67x00->next_buf_addr + len >=
+                    c67x00->buf_base_addr + SIE_TD_BUF_SIZE))
+               return -EMSGSIZE;
+
+       if (periodic) {
+               if (unlikely(bit_time + c67x00->periodic_bw_allocated >=
+                            MAX_PERIODIC_BW(c67x00->max_frame_bw)))
+                       return -EMSGSIZE;
+               c67x00->periodic_bw_allocated += bit_time;
+       }
+
+       c67x00->bandwidth_allocated += bit_time;
+       return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * td_addr and buf_addr must be word aligned
+ */
+static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
+                           void *data, int len, int pid, int toggle,
+                           unsigned long privdata)
+{
+       struct c67x00_td *td;
+       struct c67x00_urb_priv *urbp = urb->hcpriv;
+       const __u8 active_flag = 1, retry_cnt = 1;
+       __u8 cmd = 0;
+       int tt = 0;
+
+       if (c67x00_claim_frame_bw(c67x00, urb, len, usb_pipeisoc(urb->pipe)
+                                 || usb_pipeint(urb->pipe)))
+               return -EMSGSIZE;       /* Not really an error, but expected */
+
+       td = kzalloc(sizeof(*td), GFP_ATOMIC);
+       if (!td)
+               return -ENOMEM;
+
+       td->pipe = urb->pipe;
+       td->ep_data = urbp->ep_data;
+
+       if ((td_udev(td)->speed == USB_SPEED_LOW) &&
+           !(c67x00->low_speed_ports & (1 << urbp->port)))
+               cmd |= PREAMBLE_EN;
+
+       switch (usb_pipetype(td->pipe)) {
+       case PIPE_ISOCHRONOUS:
+               tt = TT_ISOCHRONOUS;
+               cmd |= ISO_EN;
+               break;
+       case PIPE_CONTROL:
+               tt = TT_CONTROL;
+               break;
+       case PIPE_BULK:
+               tt = TT_BULK;
+               break;
+       case PIPE_INTERRUPT:
+               tt = TT_INTERRUPT;
+               break;
+       }
+
+       if (toggle)
+               cmd |= SEQ_SEL;
+
+       cmd |= ARM_EN;
+
+       /* SW part */
+       td->td_addr = c67x00->next_td_addr;
+       c67x00->next_td_addr = c67x00->next_td_addr + CY_TD_SIZE;
+
+       /* HW part */
+       td->ly_base_addr = __cpu_to_le16(c67x00->next_buf_addr);
+       td->port_length = __cpu_to_le16((c67x00->sie->sie_num << 15) |
+                                       (urbp->port << 14) | (len & 0x3FF));
+       td->pid_ep = ((pid & 0xF) << TD_PIDEP_OFFSET) |
+           (usb_pipeendpoint(td->pipe) & 0xF);
+       td->dev_addr = usb_pipedevice(td->pipe) & 0x7F;
+       td->ctrl_reg = cmd;
+       td->status = 0;
+       td->retry_cnt = (tt << TT_OFFSET) | (active_flag << 4) | retry_cnt;
+       td->residue = 0;
+       td->next_td_addr = __cpu_to_le16(c67x00->next_td_addr);
+
+       /* SW part */
+       td->data = data;
+       td->urb = urb;
+       td->privdata = privdata;
+
+       c67x00->next_buf_addr += (len + 1) & ~0x01;     /* properly align */
+
+       list_add_tail(&td->td_list, &c67x00->td_list);
+       return 0;
+}
+
+static inline void c67x00_release_td(struct c67x00_td *td)
+{
+       list_del_init(&td->td_list);
+       kfree(td);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int c67x00_add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       int remaining;
+       int toggle;
+       int pid;
+       int ret = 0;
+       int maxps;
+       int need_empty;
+
+       toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                              usb_pipeout(urb->pipe));
+       remaining = urb->transfer_buffer_length - urb->actual_length;
+
+       maxps = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+
+       need_empty = (urb->transfer_flags & URB_ZERO_PACKET) &&
+           usb_pipeout(urb->pipe) && !(remaining % maxps);
+
+       while (remaining || need_empty) {
+               int len;
+               char *td_buf;
+
+               len = (remaining > maxps) ? maxps : remaining;
+               if (!len)
+                       need_empty = 0;
+
+               pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
+               td_buf = urb->transfer_buffer + urb->transfer_buffer_length -
+                   remaining;
+               ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, toggle,
+                                      DATA_STAGE);
+               if (ret)
+                       return ret;     /* td wasn't created */
+
+               toggle ^= 1;
+               remaining -= len;
+               if (usb_pipecontrol(urb->pipe))
+                       break;
+       }
+
+       return 0;
+}
+
+/**
+ * return 0 in case more bandwidth is available, else errorcode
+ */
+static int c67x00_add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       int ret;
+       int pid;
+
+       switch (urb->interval) {
+       default:
+       case SETUP_STAGE:
+               ret = c67x00_create_td(c67x00, urb, urb->setup_packet,
+                                      8, USB_PID_SETUP, 0, SETUP_STAGE);
+               if (ret)
+                       return ret;
+               urb->interval = SETUP_STAGE;
+               usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                             usb_pipeout(urb->pipe), 1);
+               break;
+       case DATA_STAGE:
+               if (urb->transfer_buffer_length) {
+                       ret = c67x00_add_data_urb(c67x00, urb);
+                       if (ret)
+                               return ret;
+                       break;
+               }               /* else fallthrough */
+       case STATUS_STAGE:
+               pid = !usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
+               ret = c67x00_create_td(c67x00, urb, NULL, 0, pid, 1,
+                                      STATUS_STAGE);
+               if (ret)
+                       return ret;
+               break;
+       }
+
+       return 0;
+}
+
+/*
+ * return 0 in case more bandwidth is available, else errorcode
+ */
+static int c67x00_add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       struct c67x00_urb_priv *urbp = urb->hcpriv;
+
+       if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) {
+               urbp->ep_data->next_frame =
+                   frame_add(urbp->ep_data->next_frame, urb->interval);
+               return c67x00_add_data_urb(c67x00, urb);
+       }
+       return 0;
+}
+
+static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+{
+       struct c67x00_urb_priv *urbp = urb->hcpriv;
+
+       if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) {
+               char *td_buf;
+               int len, pid, ret;
+
+               BUG_ON(urbp->cnt >= urb->number_of_packets);
+
+               td_buf = urb->transfer_buffer +
+                   urb->iso_frame_desc[urbp->cnt].offset;
+               len = urb->iso_frame_desc[urbp->cnt].length;
+               pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
+
+               ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0,
+                                      urbp->cnt);
+               if (ret) {
+                       printk(KERN_DEBUG "create failed: %d\n", ret);
+                       urb->iso_frame_desc[urbp->cnt].actual_length = 0;
+                       urb->iso_frame_desc[urbp->cnt].status = ret;
+                       if (urbp->cnt + 1 == urb->number_of_packets)
+                               c67x00_giveback_urb(c67x00, urb, 0);
+               }
+
+               urbp->ep_data->next_frame =
+                   frame_add(urbp->ep_data->next_frame, urb->interval);
+               urbp->cnt++;
+       }
+       return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void c67x00_fill_from_list(struct c67x00_hcd *c67x00, int type,
+                                 int (*add)(struct c67x00_hcd *, struct urb *))
+{
+       struct c67x00_ep_data *ep_data;
+       struct urb *urb;
+
+       /* traverse every endpoint on the list */
+       list_for_each_entry(ep_data, &c67x00->list[type], node) {
+               if (!list_empty(&ep_data->queue)) {
+                       /* and add the first urb */
+                       /* isochronous transfer rely on this */
+                       urb = list_entry(ep_data->queue.next,
+                                        struct c67x00_urb_priv,
+                                        hep_node)->urb;
+                       add(c67x00, urb);
+               }
+       }
+}
+
+static void c67x00_fill_frame(struct c67x00_hcd *c67x00)
+{
+       struct c67x00_td *td, *ttd;
+
+       /* Check if we can proceed */
+       if (!list_empty(&c67x00->td_list)) {
+               dev_warn(c67x00_hcd_dev(c67x00),
+                        "TD list not empty! This should not happen!\n");
+               list_for_each_entry_safe(td, ttd, &c67x00->td_list, td_list) {
+                       dbg_td(c67x00, td, "Unprocessed td");
+                       c67x00_release_td(td);
+               }
+       }
+
+       /* Reinitialize variables */
+       c67x00->bandwidth_allocated = 0;
+       c67x00->periodic_bw_allocated = 0;
+
+       c67x00->next_td_addr = c67x00->td_base_addr;
+       c67x00->next_buf_addr = c67x00->buf_base_addr;
+
+       /* Fill the list */
+       c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, c67x00_add_iso_urb);
+       c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, c67x00_add_int_urb);
+       c67x00_fill_from_list(c67x00, PIPE_CONTROL, c67x00_add_ctrl_urb);
+       c67x00_fill_from_list(c67x00, PIPE_BULK, c67x00_add_data_urb);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * Get TD from C67X00
+ */
+static inline void
+c67x00_parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
+{
+       c67x00_ll_read_mem_le16(c67x00->sie->dev,
+                               td->td_addr, td, CY_TD_SIZE);
+
+       if (usb_pipein(td->pipe) && td_actual_bytes(td))
+               c67x00_ll_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td),
+                                       td->data, td_actual_bytes(td));
+}
+
+static int c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td)
+{
+       if (td->status & TD_STATUSMASK_ERR) {
+               dbg_td(c67x00, td, "ERROR_FLAG");
+               return -EILSEQ;
+       }
+       if (td->status & TD_STATUSMASK_STALL) {
+               /* dbg_td(c67x00, td, "STALL"); */
+               return -EPIPE;
+       }
+       if (td->status & TD_STATUSMASK_TMOUT) {
+               dbg_td(c67x00, td, "TIMEOUT");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static inline int c67x00_end_of_data(struct c67x00_td *td)
+{
+       int maxps, need_empty, remaining;
+       struct urb *urb = td->urb;
+       int act_bytes;
+
+       act_bytes = td_actual_bytes(td);
+
+       if (unlikely(!act_bytes))
+               return 1;       /* This was an empty packet */
+
+       maxps = usb_maxpacket(td_udev(td), td->pipe, usb_pipeout(td->pipe));
+
+       if (unlikely(act_bytes < maxps))
+               return 1;       /* Smaller then full packet */
+
+       remaining = urb->transfer_buffer_length - urb->actual_length;
+       need_empty = (urb->transfer_flags & URB_ZERO_PACKET) &&
+           usb_pipeout(urb->pipe) && !(remaining % maxps);
+
+       if (unlikely(!remaining && !need_empty))
+               return 1;
+
+       return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* Remove all td's from the list which come
+ * after last_td and are meant for the same pipe.
+ * This is used when a short packet has occured */
+static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00,
+                                    struct c67x00_td *last_td)
+{
+       struct c67x00_td *td, *tmp;
+       td = last_td;
+       tmp = last_td;
+       while (td->td_list.next != &c67x00->td_list) {
+               td = list_entry(td->td_list.next, struct c67x00_td, td_list);
+               if (td->pipe == last_td->pipe) {
+                       c67x00_release_td(td);
+                       td = tmp;
+               }
+               tmp = td;
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00,
+                                       struct c67x00_td *td)
+{
+       struct urb *urb = td->urb;
+
+       if (!urb)
+               return;
+
+       urb->actual_length += td_actual_bytes(td);
+
+       switch (usb_pipetype(td->pipe)) {
+               /* isochronous tds are handled separately */
+       case PIPE_CONTROL:
+               switch (td->privdata) {
+               case SETUP_STAGE:
+                       urb->interval =
+                           urb->transfer_buffer_length ?
+                           DATA_STAGE : STATUS_STAGE;
+                       /* Don't count setup_packet with normal data: */
+                       urb->actual_length = 0;
+                       break;
+
+               case DATA_STAGE:
+                       if (c67x00_end_of_data(td)) {
+                               urb->interval = STATUS_STAGE;
+                               c67x00_clear_pipe(c67x00, td);
+                       }
+                       break;
+
+               case STATUS_STAGE:
+                       urb->interval = 0;
+                       c67x00_giveback_urb(c67x00, urb, 0);
+                       break;
+               }
+               break;
+
+       case PIPE_INTERRUPT:
+       case PIPE_BULK:
+               if (unlikely(c67x00_end_of_data(td))) {
+                       c67x00_clear_pipe(c67x00, td);
+                       c67x00_giveback_urb(c67x00, urb, 0);
+               }
+               break;
+       }
+}
+
+static void c67x00_handle_isoc(struct c67x00_hcd *c67x00, struct c67x00_td *td)
+{
+       struct urb *urb = td->urb;
+       struct c67x00_urb_priv *urbp;
+       int cnt;
+
+       if (!urb)
+               return;
+
+       urbp = urb->hcpriv;
+       cnt = td->privdata;
+
+       if (td->status & TD_ERROR_MASK)
+               urb->error_count++;
+
+       urb->iso_frame_desc[cnt].actual_length = td_actual_bytes(td);
+       urb->iso_frame_desc[cnt].status = c67x00_td_to_error(c67x00, td);
+       if (cnt + 1 == urb->number_of_packets)  /* Last packet */
+               c67x00_giveback_urb(c67x00, urb, 0);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * c67x00_check_td_list - handle tds which have been processed by the c67x00
+ * pre: current_td == 0
+ */
+static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00)
+{
+       struct c67x00_td *td, *tmp;
+       struct urb *urb;
+       int ack_ok;
+       int clear_endpoint;
+
+       list_for_each_entry_safe(td, tmp, &c67x00->td_list, td_list) {
+               /* get the TD */
+               c67x00_parse_td(c67x00, td);
+               urb = td->urb;  /* urb can be NULL! */
+               ack_ok = 0;
+               clear_endpoint = 1;
+
+               /* Handle isochronous transfers separately */
+               if (usb_pipeisoc(td->pipe)) {
+                       clear_endpoint = 0;
+                       c67x00_handle_isoc(c67x00, td);
+                       goto cont;
+               }
+
+               /* When an error occurs, all td's for that pipe go into an
+                * inactive state. This state matches successful transfers so
+                * we must make sure not to service them. */
+               if (td->status & TD_ERROR_MASK) {
+                       c67x00_giveback_urb(c67x00, urb,
+                                           c67x00_td_to_error(c67x00, td));
+                       goto cont;
+               }
+
+               if ((td->status & TD_STATUSMASK_NAK) || !td_sequence_ok(td) ||
+                   !td_acked(td))
+                       goto cont;
+
+               /* Sequence ok and acked, don't need to fix toggle */
+               ack_ok = 1;
+
+               if (unlikely(td->status & TD_STATUSMASK_OVF)) {
+                       if (td_residue(td) & TD_RESIDUE_OVERFLOW) {
+                               /* Overflow */
+                               c67x00_giveback_urb(c67x00, urb, -EOVERFLOW);
+                               goto cont;
+                       }
+               }
+
+               clear_endpoint = 0;
+               c67x00_handle_successful_td(c67x00, td);
+
+cont:
+               if (clear_endpoint)
+                       c67x00_clear_pipe(c67x00, td);
+               if (ack_ok)
+                       usb_settoggle(td_udev(td), usb_pipeendpoint(td->pipe),
+                                     usb_pipeout(td->pipe),
+                                     !(td->ctrl_reg & SEQ_SEL));
+               /* next in list could have been removed, due to clear_pipe! */
+               tmp = list_entry(td->td_list.next, typeof(*td), td_list);
+               c67x00_release_td(td);
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static inline int c67x00_all_tds_processed(struct c67x00_hcd *c67x00)
+{
+       /* If all tds are processed, we can check the previous frame (if
+        * there was any) and start our next frame.
+        */
+       return !c67x00_ll_husb_get_current_td(c67x00->sie);
+}
+
+/**
+ * Send td to C67X00
+ */
+static void c67x00_send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
+{
+       int len = td_length(td);
+
+       if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN))
+               c67x00_ll_write_mem_le16(c67x00->sie->dev, td_ly_base_addr(td),
+                                        td->data, len);
+
+       c67x00_ll_write_mem_le16(c67x00->sie->dev,
+                                td->td_addr, td, CY_TD_SIZE);
+}
+
+static void c67x00_send_frame(struct c67x00_hcd *c67x00)
+{
+       struct c67x00_td *td;
+
+       if (list_empty(&c67x00->td_list))
+               dev_warn(c67x00_hcd_dev(c67x00),
+                        "%s: td list should not be empty here!\n",
+                        __func__);
+
+       list_for_each_entry(td, &c67x00->td_list, td_list) {
+               if (td->td_list.next == &c67x00->td_list)
+                       td->next_td_addr = 0;   /* Last td in list */
+
+               c67x00_send_td(c67x00, td);
+       }
+
+       c67x00_ll_husb_set_current_td(c67x00->sie, c67x00->td_base_addr);
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * c67x00_do_work - Schedulers state machine
+ */
+static void c67x00_do_work(struct c67x00_hcd *c67x00)
+{
+       spin_lock(&c67x00->lock);
+       /* Make sure all tds are processed */
+       if (!c67x00_all_tds_processed(c67x00))
+               goto out;
+
+       c67x00_check_td_list(c67x00);
+
+       /* no td's are being processed (current == 0)
+        * and all have been "checked" */
+       complete(&c67x00->endpoint_disable);
+
+       if (!list_empty(&c67x00->td_list))
+               goto out;
+
+       c67x00->current_frame = c67x00_get_current_frame_number(c67x00);
+       if (c67x00->current_frame == c67x00->last_frame)
+               goto out;       /* Don't send tds in same frame */
+       c67x00->last_frame = c67x00->current_frame;
+
+       /* If no urbs are scheduled, our work is done */
+       if (!c67x00->urb_count) {
+               c67x00_ll_hpi_disable_sofeop(c67x00->sie);
+               goto out;
+       }
+
+       c67x00_fill_frame(c67x00);
+       if (!list_empty(&c67x00->td_list))
+               /* TD's have been added to the frame */
+               c67x00_send_frame(c67x00);
+
+ out:
+       spin_unlock(&c67x00->lock);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void c67x00_sched_tasklet(unsigned long __c67x00)
+{
+       struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00;
+       c67x00_do_work(c67x00);
+}
+
+void c67x00_sched_kick(struct c67x00_hcd *c67x00)
+{
+       tasklet_hi_schedule(&c67x00->tasklet);
+}
+
+int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00)
+{
+       tasklet_init(&c67x00->tasklet, c67x00_sched_tasklet,
+                    (unsigned long)c67x00);
+       return 0;
+}
+
+void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00)
+{
+       tasklet_kill(&c67x00->tasklet);
+}
diff --git a/drivers/usb/c67x00/c67x00.h b/drivers/usb/c67x00/c67x00.h
new file mode 100644 (file)
index 0000000..a26e9de
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * c67x00.h: Cypress C67X00 USB register and field definitions
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ *    based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#ifndef _USB_C67X00_H
+#define _USB_C67X00_H
+
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+
+/* ---------------------------------------------------------------------
+ * Cypress C67x00 register definitions
+ */
+
+/* Hardware Revision Register */
+#define HW_REV_REG             0xC004
+
+/* General USB registers */
+/* ===================== */
+
+/* USB Control Register */
+#define USB_CTL_REG(x)         ((x) ? 0xC0AA : 0xC08A)
+
+#define LOW_SPEED_PORT(x)      ((x) ? 0x0800 : 0x0400)
+#define HOST_MODE              0x0200
+#define PORT_RES_EN(x)         ((x) ? 0x0100 : 0x0080)
+#define SOF_EOP_EN(x)          ((x) ? 0x0002 : 0x0001)
+
+/* USB status register - Notice it has different content in hcd/udc mode */
+#define USB_STAT_REG(x)                ((x) ? 0xC0B0 : 0xC090)
+
+#define EP0_IRQ_FLG            0x0001
+#define EP1_IRQ_FLG            0x0002
+#define EP2_IRQ_FLG            0x0004
+#define EP3_IRQ_FLG            0x0008
+#define EP4_IRQ_FLG            0x0010
+#define EP5_IRQ_FLG            0x0020
+#define EP6_IRQ_FLG            0x0040
+#define EP7_IRQ_FLG            0x0080
+#define RESET_IRQ_FLG          0x0100
+#define SOF_EOP_IRQ_FLG                0x0200
+#define ID_IRQ_FLG             0x4000
+#define VBUS_IRQ_FLG           0x8000
+
+/* USB Host only registers */
+/* ======================= */
+
+/* Host n Control Register */
+#define HOST_CTL_REG(x)                ((x) ? 0xC0A0 : 0xC080)
+
+#define PREAMBLE_EN            0x0080  /* Preamble enable */
+#define SEQ_SEL                        0x0040  /* Data Toggle Sequence Bit Select */
+#define ISO_EN                 0x0010  /* Isochronous enable  */
+#define ARM_EN                 0x0001  /* Arm operation */
+
+/* Host n Interrupt Enable Register */
+#define HOST_IRQ_EN_REG(x)     ((x) ? 0xC0AC : 0xC08C)
+
+#define SOF_EOP_IRQ_EN         0x0200  /* SOF/EOP Interrupt Enable  */
+#define SOF_EOP_TMOUT_IRQ_EN   0x0800  /* SOF/EOP Timeout Interrupt Enable  */
+#define ID_IRQ_EN              0x4000  /* ID interrupt enable */
+#define VBUS_IRQ_EN            0x8000  /* VBUS interrupt enable */
+#define DONE_IRQ_EN            0x0001  /* Done Interrupt Enable  */
+
+/* USB status register */
+#define HOST_STAT_MASK         0x02FD
+#define PORT_CONNECT_CHANGE(x) ((x) ? 0x0020 : 0x0010)
+#define PORT_SE0_STATUS(x)     ((x) ? 0x0008 : 0x0004)
+
+/* Host Frame Register */
+#define HOST_FRAME_REG(x)      ((x) ? 0xC0B6 : 0xC096)
+
+#define HOST_FRAME_MASK                0x07FF
+
+/* USB Peripheral only registers */
+/* ============================= */
+
+/* Device n Port Sel reg */
+#define DEVICE_N_PORT_SEL(x)   ((x) ? 0xC0A4 : 0xC084)
+
+/* Device n Interrupt Enable Register */
+#define DEVICE_N_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C)
+
+#define DEVICE_N_ENDPOINT_N_CTL_REG(dev, ep)   ((dev)                  \
+                                                ? (0x0280 + (ep << 4)) \
+                                                : (0x0200 + (ep << 4)))
+#define DEVICE_N_ENDPOINT_N_STAT_REG(dev, ep)  ((dev)                  \
+                                                ? (0x0286 + (ep << 4)) \
+                                                : (0x0206 + (ep << 4)))
+
+#define DEVICE_N_ADDRESS(dev)  ((dev) ? (0xC0AE) : (0xC08E))
+
+/* HPI registers */
+/* ============= */
+
+/* HPI Status register */
+#define SOFEOP_FLG(x)          (1 << ((x) ? 12 : 10))
+#define SIEMSG_FLG(x)          (1 << (4 + (x)))
+#define RESET_FLG(x)           ((x) ? 0x0200 : 0x0002)
+#define DONE_FLG(x)            (1 << (2 + (x)))
+#define RESUME_FLG(x)          (1 << (6 + (x)))
+#define MBX_OUT_FLG            0x0001  /* Message out available */
+#define MBX_IN_FLG             0x0100
+#define ID_FLG                 0x4000
+#define VBUS_FLG               0x8000
+
+/* Interrupt routing register */
+#define HPI_IRQ_ROUTING_REG    0x0142
+
+#define HPI_SWAP_ENABLE(x)     ((x) ? 0x0100 : 0x0001)
+#define RESET_TO_HPI_ENABLE(x) ((x) ? 0x0200 : 0x0002)
+#define DONE_TO_HPI_ENABLE(x)  ((x) ? 0x0008 : 0x0004)
+#define RESUME_TO_HPI_ENABLE(x)        ((x) ? 0x0080 : 0x0040)
+#define SOFEOP_TO_HPI_EN(x)    ((x) ? 0x2000 : 0x0800)
+#define SOFEOP_TO_CPU_EN(x)    ((x) ? 0x1000 : 0x0400)
+#define ID_TO_HPI_ENABLE       0x4000
+#define VBUS_TO_HPI_ENABLE     0x8000
+
+/* SIE msg registers */
+#define SIEMSG_REG(x)          ((x) ? 0x0148 : 0x0144)
+
+#define HUSB_TDListDone                0x1000
+
+#define SUSB_EP0_MSG           0x0001
+#define SUSB_EP1_MSG           0x0002
+#define SUSB_EP2_MSG           0x0004
+#define SUSB_EP3_MSG           0x0008
+#define SUSB_EP4_MSG           0x0010
+#define SUSB_EP5_MSG           0x0020
+#define SUSB_EP6_MSG           0x0040
+#define SUSB_EP7_MSG           0x0080
+#define SUSB_RST_MSG           0x0100
+#define SUSB_SOF_MSG           0x0200
+#define SUSB_CFG_MSG           0x0400
+#define SUSB_SUS_MSG           0x0800
+#define SUSB_ID_MSG            0x4000
+#define SUSB_VBUS_MSG          0x8000
+
+/* BIOS interrupt routines */
+
+#define SUSBx_RECEIVE_INT(x)   ((x) ? 97 : 81)
+#define SUSBx_SEND_INT(x)      ((x) ? 96 : 80)
+
+#define SUSBx_DEV_DESC_VEC(x)  ((x) ? 0x00D4 : 0x00B4)
+#define SUSBx_CONF_DESC_VEC(x) ((x) ? 0x00D6 : 0x00B6)
+#define SUSBx_STRING_DESC_VEC(x) ((x) ? 0x00D8 : 0x00B8)
+
+#define CY_HCD_BUF_ADDR                0x500   /* Base address for host */
+#define SIE_TD_SIZE            0x200   /* size of the td list */
+#define SIE_TD_BUF_SIZE                0x400   /* size of the data buffer */
+
+#define SIE_TD_OFFSET(host)    ((host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0)
+#define SIE_BUF_OFFSET(host)   (SIE_TD_OFFSET(host) + SIE_TD_SIZE)
+
+/* Base address of HCD + 2 x TD_SIZE + 2 x TD_BUF_SIZE */
+#define CY_UDC_REQ_HEADER_BASE 0x1100
+/* 8- byte request headers for IN/OUT transfers */
+#define CY_UDC_REQ_HEADER_SIZE 8
+
+#define CY_UDC_REQ_HEADER_ADDR(ep_num) (CY_UDC_REQ_HEADER_BASE + \
+                                        ((ep_num) * CY_UDC_REQ_HEADER_SIZE))
+#define CY_UDC_DESC_BASE_ADDRESS       (CY_UDC_REQ_HEADER_ADDR(8))
+
+#define CY_UDC_BIOS_REPLACE_BASE       0x1800
+#define CY_UDC_REQ_BUFFER_BASE         0x2000
+#define CY_UDC_REQ_BUFFER_SIZE         0x0400
+#define CY_UDC_REQ_BUFFER_ADDR(ep_num) (CY_UDC_REQ_BUFFER_BASE + \
+                                        ((ep_num) * CY_UDC_REQ_BUFFER_SIZE))
+
+/* ---------------------------------------------------------------------
+ * Driver data structures
+ */
+
+struct c67x00_device;
+
+/**
+ * struct c67x00_sie - Common data associated with a SIE
+ * @lock: lock to protect this struct and the associated chip registers
+ * @private_data: subdriver dependent data
+ * @irq: subdriver dependent irq handler, set NULL when not used
+ * @dev: link to common driver structure
+ * @sie_num: SIE number on chip, starting from 0
+ * @mode: SIE mode (host/peripheral/otg/not used)
+ */
+struct c67x00_sie {
+       /* Entries to be used by the subdrivers */
+       spinlock_t lock;        /* protect this structure */
+       void *private_data;
+       void (*irq) (struct c67x00_sie *sie, u16 int_status, u16 msg);
+
+       /* Read only: */
+       struct c67x00_device *dev;
+       int sie_num;
+       int mode;
+};
+
+#define sie_dev(s)     (&(s)->dev->pdev->dev)
+
+/**
+ * struct c67x00_lcp
+ */
+struct c67x00_lcp {
+       /* Internal use only */
+       struct mutex mutex;
+       struct completion msg_received;
+       u16 last_msg;
+};
+
+/*
+ * struct c67x00_hpi
+ */
+struct c67x00_hpi {
+       void __iomem *base;
+       int regstep;
+       spinlock_t lock;
+       struct c67x00_lcp lcp;
+};
+
+#define C67X00_SIES    2
+#define C67X00_PORTS   2
+
+/**
+ * struct c67x00_device - Common data associated with a c67x00 instance
+ * @hpi: hpi addresses
+ * @sie: array of sie's on this chip
+ * @pdev: platform device of instance
+ * @pdata: configuration provided by the platform
+ */
+struct c67x00_device {
+       struct c67x00_hpi hpi;
+       struct c67x00_sie sie[C67X00_SIES];
+       struct platform_device *pdev;
+       struct c67x00_platform_data *pdata;
+};
+
+/* ---------------------------------------------------------------------
+ * Low level interface functions
+ */
+
+/* Host Port Interface (HPI) functions */
+u16 c67x00_ll_hpi_status(struct c67x00_device *dev);
+void c67x00_ll_hpi_reg_init(struct c67x00_device *dev);
+void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie);
+void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie);
+
+/* General functions */
+u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num);
+u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie);
+void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits);
+u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie);
+void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr,
+                             void *data, int len);
+void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr,
+                            void *data, int len);
+
+/* Host specific functions */
+void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value);
+void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port);
+void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr);
+u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie);
+u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie);
+void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie);
+void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port);
+
+/* Called by c67x00_irq to handle lcp interrupts */
+void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status);
+
+/* Setup and teardown */
+void c67x00_ll_init(struct c67x00_device *dev);
+void c67x00_ll_release(struct c67x00_device *dev);
+int c67x00_ll_reset(struct c67x00_device *dev);
+
+#endif                         /* _USB_C67X00_H */
index e819e5359d5765e1d2e1540432a6aa4981fa5d0a..3e69266e1f4db327c64f90d693aec503c887722b 100644 (file)
@@ -394,7 +394,9 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
        if (!io->urbs)
                goto nomem;
 
-       urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
+       urb_flags = URB_NO_INTERRUPT;
+       if (dma)
+               urb_flags |= URB_NO_TRANSFER_DMA_MAP;
        if (usb_pipein(pipe))
                urb_flags |= URB_SHORT_NOT_OK;
 
index f7b54651dd42eb77ccab5a29bae693c4570c6a7d..6e784d2db42324a91995732fc82f7c16f32201c7 100644 (file)
@@ -231,6 +231,26 @@ config SUPERH_BUILT_IN_M66592
           However, this problem is improved if change a value of
           NET_IP_ALIGN to 4.
 
+config USB_GADGET_PXA27X
+       boolean "PXA 27x"
+       depends on ARCH_PXA && PXA27x
+       help
+          Intel's PXA 27x series XScale ARM v5TE processors include
+          an integrated full speed USB 1.1 device controller.
+
+          It has up to 23 endpoints, as well as endpoint zero (for
+          control transfers).
+
+          Say "y" to link the driver statically, or "m" to build a
+          dynamically linked module called "pxa27x_udc" and force all
+          gadget drivers to also be dynamically linked.
+
+config USB_PXA27X
+       tristate
+       depends on USB_GADGET_PXA27X
+       default USB_GADGET
+       select USB_GADGET_SELECTED
+
 config USB_GADGET_GOKU
        boolean "Toshiba TC86C001 'Goku-S'"
        depends on PCI
index c3aab80b6c76e33095556539f15f2377a14d8adf..12357255d740a6a04e287839b31f47ee7bd8bf54 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_DUMMY_HCD)     += dummy_hcd.o
 obj-$(CONFIG_USB_NET2280)      += net2280.o
 obj-$(CONFIG_USB_AMD5536UDC)   += amd5536udc.o
 obj-$(CONFIG_USB_PXA2XX)       += pxa2xx_udc.o
+obj-$(CONFIG_USB_PXA27X)       += pxa27x_udc.o
 obj-$(CONFIG_USB_GOKU)         += goku_udc.o
 obj-$(CONFIG_USB_OMAP)         += omap_udc.o
 obj-$(CONFIG_USB_LH7A40X)      += lh7a40x_udc.o
index bb93bdd7659315da5707b2ae11e73aecac979996..8d61ea67a8174a801d1ee0f8e902b2239ff53b70 100644 (file)
@@ -235,10 +235,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
 #define        DEV_CONFIG_CDC
 #endif
 
-#ifdef CONFIG_USB_GADGET_PXA27X
-#define DEV_CONFIG_CDC
-#endif
-
 #ifdef CONFIG_USB_GADGET_S3C2410
 #define DEV_CONFIG_CDC
 #endif
@@ -270,6 +266,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
 #define        DEV_CONFIG_SUBSET
 #endif
 
+#ifdef CONFIG_USB_GADGET_PXA27X
+#define        DEV_CONFIG_SUBSET
+#endif
+
 #ifdef CONFIG_USB_GADGET_SUPERH
 #define        DEV_CONFIG_SUBSET
 #endif
index bf3f946fd45544e04cc1549ab68d71f2f2b8f0f2..47bb9f09a1aa1c698dea76218bbe4fc589917989 100644 (file)
@@ -2307,6 +2307,29 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
        return rc;
 }
 
+static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+       int     rc;
+
+       DBG(fsg, "bulk-in set wedge\n");
+       rc = usb_ep_set_wedge(fsg->bulk_in);
+       if (rc == -EAGAIN)
+               VDBG(fsg, "delayed bulk-in endpoint wedge\n");
+       while (rc != 0) {
+               if (rc != -EAGAIN) {
+                       WARN(fsg, "usb_ep_set_wedge -> %d\n", rc);
+                       rc = 0;
+                       break;
+               }
+
+               /* Wait for a short time and then try again */
+               if (msleep_interruptible(100) != 0)
+                       return -EINTR;
+               rc = usb_ep_set_wedge(fsg->bulk_in);
+       }
+       return rc;
+}
+
 static int pad_with_zeros(struct fsg_dev *fsg)
 {
        struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
@@ -2957,7 +2980,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                 * We aren't required to halt the OUT endpoint; instead
                 * we can simply accept and discard any data received
                 * until the next reset. */
-               halt_bulk_in_endpoint(fsg);
+               wedge_bulk_in_endpoint(fsg);
                set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
                return -EINVAL;
        }
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
new file mode 100644 (file)
index 0000000..75eba20
--- /dev/null
@@ -0,0 +1,2404 @@
+/*
+ * Handles the Intel 27x USB Device Controller (UDC)
+ *
+ * Inspired by original driver by Frank Becker, David Brownell, and others.
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+
+#include <asm/byteorder.h>
+#include <asm/hardware.h>
+
+#include <linux/usb.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include <asm/arch/udc.h>
+
+#include "pxa27x_udc.h"
+
+/*
+ * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x
+ * series processors.
+ *
+ * Such controller drivers work with a gadget driver.  The gadget driver
+ * returns descriptors, implements configuration and data protocols used
+ * by the host to interact with this device, and allocates endpoints to
+ * the different protocol interfaces.  The controller driver virtualizes
+ * usb hardware so that the gadget drivers will be more portable.
+ *
+ * This UDC hardware wants to implement a bit too much USB protocol. The
+ * biggest issues are:  that the endpoints have to be set up before the
+ * controller can be enabled (minor, and not uncommon); and each endpoint
+ * can only have one configuration, interface and alternative interface
+ * number (major, and very unusual). Once set up, these cannot be changed
+ * without a controller reset.
+ *
+ * The workaround is to setup all combinations necessary for the gadgets which
+ * will work with this driver. This is done in pxa_udc structure, statically.
+ * See pxa_udc, udc_usb_ep versus pxa_ep, and matching function find_pxa_ep.
+ * (You could modify this if needed.  Some drivers have a "fifo_mode" module
+ * parameter to facilitate such changes.)
+ *
+ * The combinations have been tested with these gadgets :
+ *  - zero gadget
+ *  - file storage gadget
+ *  - ether gadget
+ *
+ * The driver doesn't use DMA, only IO access and IRQ callbacks. No use is
+ * made of UDC's double buffering either. USB "On-The-Go" is not implemented.
+ *
+ * All the requests are handled the same way :
+ *  - the drivers tries to handle the request directly to the IO
+ *  - if the IO fifo is not big enough, the remaining is send/received in
+ *    interrupt handling.
+ */
+
+#define        DRIVER_VERSION  "2008-04-18"
+#define        DRIVER_DESC     "PXA 27x USB Device Controller driver"
+
+static const char driver_name[] = "pxa27x_udc";
+static struct pxa_udc *the_controller;
+
+static void handle_ep(struct pxa_ep *ep);
+
+/*
+ * Debug filesystem
+ */
+#ifdef CONFIG_USB_GADGET_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+
+static int state_dbg_show(struct seq_file *s, void *p)
+{
+       struct pxa_udc *udc = s->private;
+       int pos = 0, ret;
+       u32 tmp;
+
+       ret = -ENODEV;
+       if (!udc->driver)
+               goto out;
+
+       /* basic device status */
+       pos += seq_printf(s, DRIVER_DESC "\n"
+                        "%s version: %s\nGadget driver: %s\n",
+                        driver_name, DRIVER_VERSION,
+                        udc->driver ? udc->driver->driver.name : "(none)");
+
+       tmp = udc_readl(udc, UDCCR);
+       pos += seq_printf(s,
+                        "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), "
+                        "con=%d,inter=%d,altinter=%d\n", tmp,
+                        (tmp & UDCCR_OEN) ? " oen":"",
+                        (tmp & UDCCR_AALTHNP) ? " aalthnp":"",
+                        (tmp & UDCCR_AHNP) ? " rem" : "",
+                        (tmp & UDCCR_BHNP) ? " rstir" : "",
+                        (tmp & UDCCR_DWRE) ? " dwre" : "",
+                        (tmp & UDCCR_SMAC) ? " smac" : "",
+                        (tmp & UDCCR_EMCE) ? " emce" : "",
+                        (tmp & UDCCR_UDR) ? " udr" : "",
+                        (tmp & UDCCR_UDA) ? " uda" : "",
+                        (tmp & UDCCR_UDE) ? " ude" : "",
+                        (tmp & UDCCR_ACN) >> UDCCR_ACN_S,
+                        (tmp & UDCCR_AIN) >> UDCCR_AIN_S,
+                        (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S);
+       /* registers for device and ep0 */
+       pos += seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n",
+                       udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1));
+       pos += seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n",
+                       udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1));
+       pos += seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR));
+       pos += seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, "
+                       "reconfig=%lu\n",
+                       udc->stats.irqs_reset, udc->stats.irqs_suspend,
+                       udc->stats.irqs_resume, udc->stats.irqs_reconfig);
+
+       ret = 0;
+out:
+       return ret;
+}
+
+static int queues_dbg_show(struct seq_file *s, void *p)
+{
+       struct pxa_udc *udc = s->private;
+       struct pxa_ep *ep;
+       struct pxa27x_request *req;
+       int pos = 0, i, maxpkt, ret;
+
+       ret = -ENODEV;
+       if (!udc->driver)
+               goto out;
+
+       /* dump endpoint queues */
+       for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &udc->pxa_ep[i];
+               maxpkt = ep->fifo_size;
+               pos += seq_printf(s,  "%-12s max_pkt=%d %s\n",
+                               EPNAME(ep), maxpkt, "pio");
+
+               if (list_empty(&ep->queue)) {
+                       pos += seq_printf(s, "\t(nothing queued)\n");
+                       continue;
+               }
+
+               list_for_each_entry(req, &ep->queue, queue) {
+                       pos += seq_printf(s,  "\treq %p len %d/%d buf %p\n",
+                                       &req->req, req->req.actual,
+                                       req->req.length, req->req.buf);
+               }
+       }
+
+       ret = 0;
+out:
+       return ret;
+}
+
+static int eps_dbg_show(struct seq_file *s, void *p)
+{
+       struct pxa_udc *udc = s->private;
+       struct pxa_ep *ep;
+       int pos = 0, i, ret;
+       u32 tmp;
+
+       ret = -ENODEV;
+       if (!udc->driver)
+               goto out;
+
+       ep = &udc->pxa_ep[0];
+       tmp = udc_ep_readl(ep, UDCCSR);
+       pos += seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", tmp,
+                        (tmp & UDCCSR0_SA) ? " sa" : "",
+                        (tmp & UDCCSR0_RNE) ? " rne" : "",
+                        (tmp & UDCCSR0_FST) ? " fst" : "",
+                        (tmp & UDCCSR0_SST) ? " sst" : "",
+                        (tmp & UDCCSR0_DME) ? " dme" : "",
+                        (tmp & UDCCSR0_IPR) ? " ipr" : "",
+                        (tmp & UDCCSR0_OPC) ? " opc" : "");
+       for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &udc->pxa_ep[i];
+               tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR);
+               pos += seq_printf(s, "%-12s: "
+                               "IN %lu(%lu reqs), OUT %lu(%lu reqs), "
+                               "irqs=%lu, udccr=0x%08x, udccsr=0x%03x, "
+                               "udcbcr=%d\n",
+                               EPNAME(ep),
+                               ep->stats.in_bytes, ep->stats.in_ops,
+                               ep->stats.out_bytes, ep->stats.out_ops,
+                               ep->stats.irqs,
+                               tmp, udc_ep_readl(ep, UDCCSR),
+                               udc_ep_readl(ep, UDCBCR));
+       }
+
+       ret = 0;
+out:
+       return ret;
+}
+
+static int eps_dbg_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, eps_dbg_show, inode->i_private);
+}
+
+static int queues_dbg_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, queues_dbg_show, inode->i_private);
+}
+
+static int state_dbg_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, state_dbg_show, inode->i_private);
+}
+
+static const struct file_operations state_dbg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = state_dbg_open,
+       .llseek         = seq_lseek,
+       .read           = seq_read,
+       .release        = single_release,
+};
+
+static const struct file_operations queues_dbg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = queues_dbg_open,
+       .llseek         = seq_lseek,
+       .read           = seq_read,
+       .release        = single_release,
+};
+
+static const struct file_operations eps_dbg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = eps_dbg_open,
+       .llseek         = seq_lseek,
+       .read           = seq_read,
+       .release        = single_release,
+};
+
+static void pxa_init_debugfs(struct pxa_udc *udc)
+{
+       struct dentry *root, *state, *queues, *eps;
+
+       root = debugfs_create_dir(udc->gadget.name, NULL);
+       if (IS_ERR(root) || !root)
+               goto err_root;
+
+       state = debugfs_create_file("udcstate", 0400, root, udc,
+                       &state_dbg_fops);
+       if (!state)
+               goto err_state;
+       queues = debugfs_create_file("queues", 0400, root, udc,
+                       &queues_dbg_fops);
+       if (!queues)
+               goto err_queues;
+       eps = debugfs_create_file("epstate", 0400, root, udc,
+                       &eps_dbg_fops);
+       if (!queues)
+               goto err_eps;
+
+       udc->debugfs_root = root;
+       udc->debugfs_state = state;
+       udc->debugfs_queues = queues;
+       udc->debugfs_eps = eps;
+       return;
+err_eps:
+       debugfs_remove(eps);
+err_queues:
+       debugfs_remove(queues);
+err_state:
+       debugfs_remove(root);
+err_root:
+       dev_err(udc->dev, "debugfs is not available\n");
+}
+
+static void pxa_cleanup_debugfs(struct pxa_udc *udc)
+{
+       debugfs_remove(udc->debugfs_eps);
+       debugfs_remove(udc->debugfs_queues);
+       debugfs_remove(udc->debugfs_state);
+       debugfs_remove(udc->debugfs_root);
+       udc->debugfs_eps = NULL;
+       udc->debugfs_queues = NULL;
+       udc->debugfs_state = NULL;
+       udc->debugfs_root = NULL;
+}
+
+#else
+static inline void pxa_init_debugfs(struct pxa_udc *udc)
+{
+}
+
+static inline void pxa_cleanup_debugfs(struct pxa_udc *udc)
+{
+}
+#endif
+
+/**
+ * is_match_usb_pxa - check if usb_ep and pxa_ep match
+ * @udc_usb_ep: usb endpoint
+ * @ep: pxa endpoint
+ * @config: configuration required in pxa_ep
+ * @interface: interface required in pxa_ep
+ * @altsetting: altsetting required in pxa_ep
+ *
+ * Returns 1 if all criteria match between pxa and usb endpoint, 0 otherwise
+ */
+static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep,
+               int config, int interface, int altsetting)
+{
+       if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr)
+               return 0;
+       if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in)
+               return 0;
+       if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type)
+               return 0;
+       if ((ep->config != config) || (ep->interface != interface)
+                       || (ep->alternate != altsetting))
+               return 0;
+       return 1;
+}
+
+/**
+ * find_pxa_ep - find pxa_ep structure matching udc_usb_ep
+ * @udc: pxa udc
+ * @udc_usb_ep: udc_usb_ep structure
+ *
+ * Match udc_usb_ep and all pxa_ep available, to see if one matches.
+ * This is necessary because of the strong pxa hardware restriction requiring
+ * that once pxa endpoints are initialized, their configuration is freezed, and
+ * no change can be made to their address, direction, or in which configuration,
+ * interface or altsetting they are active ... which differs from more usual
+ * models which have endpoints be roughly just addressable fifos, and leave
+ * configuration events up to gadget drivers (like all control messages).
+ *
+ * Note that there is still a blurred point here :
+ *   - we rely on UDCCR register "active interface" and "active altsetting".
+ *     This is a nonsense in regard of USB spec, where multiple interfaces are
+ *     active at the same time.
+ *   - if we knew for sure that the pxa can handle multiple interface at the
+ *     same time, assuming Intel's Developer Guide is wrong, this function
+ *     should be reviewed, and a cache of couples (iface, altsetting) should
+ *     be kept in the pxa_udc structure. In this case this function would match
+ *     against the cache of couples instead of the "last altsetting" set up.
+ *
+ * Returns the matched pxa_ep structure or NULL if none found
+ */
+static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc,
+               struct udc_usb_ep *udc_usb_ep)
+{
+       int i;
+       struct pxa_ep *ep;
+       int cfg = udc->config;
+       int iface = udc->last_interface;
+       int alt = udc->last_alternate;
+
+       if (udc_usb_ep == &udc->udc_usb_ep[0])
+               return &udc->pxa_ep[0];
+
+       for (i = 1; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &udc->pxa_ep[i];
+               if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt))
+                       return ep;
+       }
+       return NULL;
+}
+
+/**
+ * update_pxa_ep_matches - update pxa_ep cached values in all udc_usb_ep
+ * @udc: pxa udc
+ *
+ * Context: in_interrupt()
+ *
+ * Updates all pxa_ep fields in udc_usb_ep structures, if this field was
+ * previously set up (and is not NULL). The update is necessary is a
+ * configuration change or altsetting change was issued by the USB host.
+ */
+static void update_pxa_ep_matches(struct pxa_udc *udc)
+{
+       int i;
+       struct udc_usb_ep *udc_usb_ep;
+
+       for (i = 1; i < NR_USB_ENDPOINTS; i++) {
+               udc_usb_ep = &udc->udc_usb_ep[i];
+               if (udc_usb_ep->pxa_ep)
+                       udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep);
+       }
+}
+
+/**
+ * pio_irq_enable - Enables irq generation for one endpoint
+ * @ep: udc endpoint
+ */
+static void pio_irq_enable(struct pxa_ep *ep)
+{
+       struct pxa_udc *udc = ep->dev;
+       int index = EPIDX(ep);
+       u32 udcicr0 = udc_readl(udc, UDCICR0);
+       u32 udcicr1 = udc_readl(udc, UDCICR1);
+
+       if (index < 16)
+               udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2)));
+       else
+               udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2)));
+}
+
+/**
+ * pio_irq_disable - Disables irq generation for one endpoint
+ * @ep: udc endpoint
+ * @index: endpoint number
+ */
+static void pio_irq_disable(struct pxa_ep *ep)
+{
+       struct pxa_udc *udc = ep->dev;
+       int index = EPIDX(ep);
+       u32 udcicr0 = udc_readl(udc, UDCICR0);
+       u32 udcicr1 = udc_readl(udc, UDCICR1);
+
+       if (index < 16)
+               udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2)));
+       else
+               udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2)));
+}
+
+/**
+ * udc_set_mask_UDCCR - set bits in UDCCR
+ * @udc: udc device
+ * @mask: bits to set in UDCCR
+ *
+ * Sets bits in UDCCR, leaving DME and FST bits as they were.
+ */
+static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask)
+{
+       u32 udccr = udc_readl(udc, UDCCR);
+       udc_writel(udc, UDCCR,
+                       (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS));
+}
+
+/**
+ * udc_clear_mask_UDCCR - clears bits in UDCCR
+ * @udc: udc device
+ * @mask: bit to clear in UDCCR
+ *
+ * Clears bits in UDCCR, leaving DME and FST bits as they were.
+ */
+static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask)
+{
+       u32 udccr = udc_readl(udc, UDCCR);
+       udc_writel(udc, UDCCR,
+                       (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS));
+}
+
+/**
+ * ep_count_bytes_remain - get how many bytes in udc endpoint
+ * @ep: udc endpoint
+ *
+ * Returns number of bytes in OUT fifos. Broken for IN fifos (-EOPNOTSUPP)
+ */
+static int ep_count_bytes_remain(struct pxa_ep *ep)
+{
+       if (ep->dir_in)
+               return -EOPNOTSUPP;
+       return udc_ep_readl(ep, UDCBCR) & 0x3ff;
+}
+
+/**
+ * ep_is_empty - checks if ep has byte ready for reading
+ * @ep: udc endpoint
+ *
+ * If endpoint is the control endpoint, checks if there are bytes in the
+ * control endpoint fifo. If endpoint is a data endpoint, checks if bytes
+ * are ready for reading on OUT endpoint.
+ *
+ * Returns 0 if ep not empty, 1 if ep empty, -EOPNOTSUPP if IN endpoint
+ */
+static int ep_is_empty(struct pxa_ep *ep)
+{
+       int ret;
+
+       if (!is_ep0(ep) && ep->dir_in)
+               return -EOPNOTSUPP;
+       if (is_ep0(ep))
+               ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE);
+       else
+               ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE);
+       return ret;
+}
+
+/**
+ * ep_is_full - checks if ep has place to write bytes
+ * @ep: udc endpoint
+ *
+ * If endpoint is not the control endpoint and is an IN endpoint, checks if
+ * there is place to write bytes into the endpoint.
+ *
+ * Returns 0 if ep not full, 1 if ep full, -EOPNOTSUPP if OUT endpoint
+ */
+static int ep_is_full(struct pxa_ep *ep)
+{
+       if (is_ep0(ep))
+               return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR);
+       if (!ep->dir_in)
+               return -EOPNOTSUPP;
+       return (!(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF));
+}
+
+/**
+ * epout_has_pkt - checks if OUT endpoint fifo has a packet available
+ * @ep: pxa endpoint
+ *
+ * Returns 1 if a complete packet is available, 0 if not, -EOPNOTSUPP for IN ep.
+ */
+static int epout_has_pkt(struct pxa_ep *ep)
+{
+       if (!is_ep0(ep) && ep->dir_in)
+               return -EOPNOTSUPP;
+       if (is_ep0(ep))
+               return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC);
+       return (udc_ep_readl(ep, UDCCSR) & UDCCSR_PC);
+}
+
+/**
+ * set_ep0state - Set ep0 automata state
+ * @dev: udc device
+ * @state: state
+ */
+static void set_ep0state(struct pxa_udc *udc, int state)
+{
+       struct pxa_ep *ep = &udc->pxa_ep[0];
+       char *old_stname = EP0_STNAME(udc);
+
+       udc->ep0state = state;
+       ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname,
+               EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR),
+               udc_ep_readl(ep, UDCBCR));
+}
+
+/**
+ * ep0_idle - Put control endpoint into idle state
+ * @dev: udc device
+ */
+static void ep0_idle(struct pxa_udc *dev)
+{
+       set_ep0state(dev, WAIT_FOR_SETUP);
+}
+
+/**
+ * inc_ep_stats_reqs - Update ep stats counts
+ * @ep: physical endpoint
+ * @req: usb request
+ * @is_in: ep direction (USB_DIR_IN or 0)
+ *
+ */
+static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in)
+{
+       if (is_in)
+               ep->stats.in_ops++;
+       else
+               ep->stats.out_ops++;
+}
+
+/**
+ * inc_ep_stats_bytes - Update ep stats counts
+ * @ep: physical endpoint
+ * @count: bytes transfered on endpoint
+ * @req: usb request
+ * @is_in: ep direction (USB_DIR_IN or 0)
+ */
+static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in)
+{
+       if (is_in)
+               ep->stats.in_bytes += count;
+       else
+               ep->stats.out_bytes += count;
+}
+
+/**
+ * pxa_ep_setup - Sets up an usb physical endpoint
+ * @ep: pxa27x physical endpoint
+ *
+ * Find the physical pxa27x ep, and setup its UDCCR
+ */
+static __init void pxa_ep_setup(struct pxa_ep *ep)
+{
+       u32 new_udccr;
+
+       new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN)
+               | ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN)
+               | ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN)
+               | ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN)
+               | ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET)
+               | ((ep->dir_in) ? UDCCONR_ED : 0)
+               | ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS)
+               | UDCCONR_EE;
+
+       udc_ep_writel(ep, UDCCR, new_udccr);
+}
+
+/**
+ * pxa_eps_setup - Sets up all usb physical endpoints
+ * @dev: udc device
+ *
+ * Setup all pxa physical endpoints, except ep0
+ */
+static __init void pxa_eps_setup(struct pxa_udc *dev)
+{
+       unsigned int i;
+
+       dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev);
+
+       for (i = 1; i < NR_PXA_ENDPOINTS; i++)
+               pxa_ep_setup(&dev->pxa_ep[i]);
+}
+
+/**
+ * pxa_ep_alloc_request - Allocate usb request
+ * @_ep: usb endpoint
+ * @gfp_flags:
+ *
+ * For the pxa27x, these can just wrap kmalloc/kfree.  gadget drivers
+ * must still pass correctly initialized endpoints, since other controller
+ * drivers may care about how it's currently set up (dma issues etc).
+  */
+static struct usb_request *
+pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+{
+       struct pxa27x_request *req;
+
+       req = kzalloc(sizeof *req, gfp_flags);
+       if (!req || !_ep)
+               return NULL;
+
+       INIT_LIST_HEAD(&req->queue);
+       req->in_use = 0;
+       req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+
+       return &req->req;
+}
+
+/**
+ * pxa_ep_free_request - Free usb request
+ * @_ep: usb endpoint
+ * @_req: usb request
+ *
+ * Wrapper around kfree to free _req
+ */
+static void pxa_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct pxa27x_request *req;
+
+       req = container_of(_req, struct pxa27x_request, req);
+       WARN_ON(!list_empty(&req->queue));
+       kfree(req);
+}
+
+/**
+ * ep_add_request - add a request to the endpoint's queue
+ * @ep: usb endpoint
+ * @req: usb request
+ *
+ * Context: ep->lock held
+ *
+ * Queues the request in the endpoint's queue, and enables the interrupts
+ * on the endpoint.
+ */
+static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       if (unlikely(!req))
+               return;
+       ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
+               req->req.length, udc_ep_readl(ep, UDCCSR));
+
+       req->in_use = 1;
+       list_add_tail(&req->queue, &ep->queue);
+       pio_irq_enable(ep);
+}
+
+/**
+ * ep_del_request - removes a request from the endpoint's queue
+ * @ep: usb endpoint
+ * @req: usb request
+ *
+ * Context: ep->lock held
+ *
+ * Unqueue the request from the endpoint's queue. If there are no more requests
+ * on the endpoint, and if it's not the control endpoint, interrupts are
+ * disabled on the endpoint.
+ */
+static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       if (unlikely(!req))
+               return;
+       ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
+               req->req.length, udc_ep_readl(ep, UDCCSR));
+
+       list_del_init(&req->queue);
+       req->in_use = 0;
+       if (!is_ep0(ep) && list_empty(&ep->queue))
+               pio_irq_disable(ep);
+}
+
+/**
+ * req_done - Complete an usb request
+ * @ep: pxa physical endpoint
+ * @req: pxa request
+ * @status: usb request status sent to gadget API
+ *
+ * Context: ep->lock held
+ *
+ * Retire a pxa27x usb request. Endpoint must be locked.
+ */
+static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
+{
+       ep_del_request(ep, req);
+       if (likely(req->req.status == -EINPROGRESS))
+               req->req.status = status;
+       else
+               status = req->req.status;
+
+       if (status && status != -ESHUTDOWN)
+               ep_dbg(ep, "complete req %p stat %d len %u/%u\n",
+                       &req->req, status,
+                       req->req.actual, req->req.length);
+
+       req->req.complete(&req->udc_usb_ep->usb_ep, &req->req);
+}
+
+/**
+ * ep_end_out_req - Ends control endpoint in request
+ * @ep: physical endpoint
+ * @req: pxa request
+ *
+ * Context: ep->lock held
+ *
+ * Ends endpoint in request (completes usb request).
+ */
+static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       inc_ep_stats_reqs(ep, !USB_DIR_IN);
+       req_done(ep, req, 0);
+}
+
+/**
+ * ep0_end_out_req - Ends control endpoint in request (ends data stage)
+ * @ep: physical endpoint
+ * @req: pxa request
+ *
+ * Context: ep->lock held
+ *
+ * Ends control endpoint in request (completes usb request), and puts
+ * control endpoint into idle state
+ */
+static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       set_ep0state(ep->dev, OUT_STATUS_STAGE);
+       ep_end_out_req(ep, req);
+       ep0_idle(ep->dev);
+}
+
+/**
+ * ep_end_in_req - Ends endpoint out request
+ * @ep: physical endpoint
+ * @req: pxa request
+ *
+ * Context: ep->lock held
+ *
+ * Ends endpoint out request (completes usb request).
+ */
+static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       inc_ep_stats_reqs(ep, USB_DIR_IN);
+       req_done(ep, req, 0);
+}
+
+/**
+ * ep0_end_in_req - Ends control endpoint out request (ends data stage)
+ * @ep: physical endpoint
+ * @req: pxa request
+ *
+ * Context: ep->lock held
+ *
+ * Ends control endpoint out request (completes usb request), and puts
+ * control endpoint into status state
+ */
+static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       struct pxa_udc *udc = ep->dev;
+
+       set_ep0state(udc, IN_STATUS_STAGE);
+       ep_end_in_req(ep, req);
+}
+
+/**
+ * nuke - Dequeue all requests
+ * @ep: pxa endpoint
+ * @status: usb request status
+ *
+ * Context: ep->lock held
+ *
+ * Dequeues all requests on an endpoint. As a side effect, interrupts will be
+ * disabled on that endpoint (because no more requests).
+ */
+static void nuke(struct pxa_ep *ep, int status)
+{
+       struct pxa27x_request *req;
+
+       while (!list_empty(&ep->queue)) {
+               req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+               req_done(ep, req, status);
+       }
+}
+
+/**
+ * read_packet - transfer 1 packet from an OUT endpoint into request
+ * @ep: pxa physical endpoint
+ * @req: usb request
+ *
+ * Takes bytes from OUT endpoint and transfers them info the usb request.
+ * If there is less space in request than bytes received in OUT endpoint,
+ * bytes are left in the OUT endpoint.
+ *
+ * Returns how many bytes were actually transfered
+ */
+static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       u32 *buf;
+       int bytes_ep, bufferspace, count, i;
+
+       bytes_ep = ep_count_bytes_remain(ep);
+       bufferspace = req->req.length - req->req.actual;
+
+       buf = (u32 *)(req->req.buf + req->req.actual);
+       prefetchw(buf);
+
+       if (likely(!ep_is_empty(ep)))
+               count = min(bytes_ep, bufferspace);
+       else /* zlp */
+               count = 0;
+
+       for (i = count; i > 0; i -= 4)
+               *buf++ = udc_ep_readl(ep, UDCDR);
+       req->req.actual += count;
+
+       udc_ep_writel(ep, UDCCSR, UDCCSR_PC);
+
+       return count;
+}
+
+/**
+ * write_packet - transfer 1 packet from request into an IN endpoint
+ * @ep: pxa physical endpoint
+ * @req: usb request
+ * @max: max bytes that fit into endpoint
+ *
+ * Takes bytes from usb request, and transfers them into the physical
+ * endpoint. If there are no bytes to transfer, doesn't write anything
+ * to physical endpoint.
+ *
+ * Returns how many bytes were actually transfered.
+ */
+static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req,
+                       unsigned int max)
+{
+       int length, count, remain, i;
+       u32 *buf;
+       u8 *buf_8;
+
+       buf = (u32 *)(req->req.buf + req->req.actual);
+       prefetch(buf);
+
+       length = min(req->req.length - req->req.actual, max);
+       req->req.actual += length;
+
+       remain = length & 0x3;
+       count = length & ~(0x3);
+       for (i = count; i > 0 ; i -= 4)
+               udc_ep_writel(ep, UDCDR, *buf++);
+
+       buf_8 = (u8 *)buf;
+       for (i = remain; i > 0; i--)
+               udc_ep_writeb(ep, UDCDR, *buf_8++);
+
+       ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain,
+               udc_ep_readl(ep, UDCCSR));
+
+       return length;
+}
+
+/**
+ * read_fifo - Transfer packets from OUT endpoint into usb request
+ * @ep: pxa physical endpoint
+ * @req: usb request
+ *
+ * Context: callable when in_interrupt()
+ *
+ * Unload as many packets as possible from the fifo we use for usb OUT
+ * transfers and put them into the request. Caller should have made sure
+ * there's at least one packet ready.
+ * Doesn't complete the request, that's the caller's job
+ *
+ * Returns 1 if the request completed, 0 otherwise
+ */
+static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       int count, is_short, completed = 0;
+
+       while (epout_has_pkt(ep)) {
+               count = read_packet(ep, req);
+               inc_ep_stats_bytes(ep, count, !USB_DIR_IN);
+
+               is_short = (count < ep->fifo_size);
+               ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
+                       udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
+                       &req->req, req->req.actual, req->req.length);
+
+               /* completion */
+               if (is_short || req->req.actual == req->req.length) {
+                       completed = 1;
+                       break;
+               }
+               /* finished that packet.  the next one may be waiting... */
+       }
+       return completed;
+}
+
+/**
+ * write_fifo - transfer packets from usb request into an IN endpoint
+ * @ep: pxa physical endpoint
+ * @req: pxa usb request
+ *
+ * Write to an IN endpoint fifo, as many packets as possible.
+ * irqs will use this to write the rest later.
+ * caller guarantees at least one packet buffer is ready (or a zlp).
+ * Doesn't complete the request, that's the caller's job
+ *
+ * Returns 1 if request fully transfered, 0 if partial transfer
+ */
+static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       unsigned max;
+       int count, is_short, is_last = 0, completed = 0, totcount = 0;
+       u32 udccsr;
+
+       max = ep->fifo_size;
+       do {
+               is_short = 0;
+
+               udccsr = udc_ep_readl(ep, UDCCSR);
+               if (udccsr & UDCCSR_PC) {
+                       ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n",
+                               udccsr);
+                       udc_ep_writel(ep, UDCCSR, UDCCSR_PC);
+               }
+               if (udccsr & UDCCSR_TRN) {
+                       ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n",
+                               udccsr);
+                       udc_ep_writel(ep, UDCCSR, UDCCSR_TRN);
+               }
+
+               count = write_packet(ep, req, max);
+               inc_ep_stats_bytes(ep, count, USB_DIR_IN);
+               totcount += count;
+
+               /* last packet is usually short (or a zlp) */
+               if (unlikely(count < max)) {
+                       is_last = 1;
+                       is_short = 1;
+               } else {
+                       if (likely(req->req.length > req->req.actual)
+                                       || req->req.zero)
+                               is_last = 0;
+                       else
+                               is_last = 1;
+                       /* interrupt/iso maxpacket may not fill the fifo */
+                       is_short = unlikely(max < ep->fifo_size);
+               }
+
+               if (is_short)
+                       udc_ep_writel(ep, UDCCSR, UDCCSR_SP);
+
+               /* requests complete when all IN data is in the FIFO */
+               if (is_last) {
+                       completed = 1;
+                       break;
+               }
+       } while (!ep_is_full(ep));
+
+       ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n",
+                       totcount, is_last ? "/L" : "", is_short ? "/S" : "",
+                       req->req.length - req->req.actual, &req->req);
+
+       return completed;
+}
+
+/**
+ * read_ep0_fifo - Transfer packets from control endpoint into usb request
+ * @ep: control endpoint
+ * @req: pxa usb request
+ *
+ * Special ep0 version of the above read_fifo. Reads as many bytes from control
+ * endpoint as can be read, and stores them into usb request (limited by request
+ * maximum length).
+ *
+ * Returns 0 if usb request only partially filled, 1 if fully filled
+ */
+static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       int count, is_short, completed = 0;
+
+       while (epout_has_pkt(ep)) {
+               count = read_packet(ep, req);
+               udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC);
+               inc_ep_stats_bytes(ep, count, !USB_DIR_IN);
+
+               is_short = (count < ep->fifo_size);
+               ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
+                       udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
+                       &req->req, req->req.actual, req->req.length);
+
+               if (is_short || req->req.actual >= req->req.length) {
+                       completed = 1;
+                       break;
+               }
+       }
+
+       return completed;
+}
+
+/**
+ * write_ep0_fifo - Send a request to control endpoint (ep0 in)
+ * @ep: control endpoint
+ * @req: request
+ *
+ * Context: callable when in_interrupt()
+ *
+ * Sends a request (or a part of the request) to the control endpoint (ep0 in).
+ * If the request doesn't fit, the remaining part will be sent from irq.
+ * The request is considered fully written only if either :
+ *   - last write transfered all remaining bytes, but fifo was not fully filled
+ *   - last write was a 0 length write
+ *
+ * Returns 1 if request fully written, 0 if request only partially sent
+ */
+static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+       unsigned        count;
+       int             is_last, is_short;
+
+       count = write_packet(ep, req, EP0_FIFO_SIZE);
+       inc_ep_stats_bytes(ep, count, USB_DIR_IN);
+
+       is_short = (count < EP0_FIFO_SIZE);
+       is_last = ((count == 0) || (count < EP0_FIFO_SIZE));
+
+       /* Sends either a short packet or a 0 length packet */
+       if (unlikely(is_short))
+               udc_ep_writel(ep, UDCCSR, UDCCSR0_IPR);
+
+       ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n",
+               count, is_short ? "/S" : "", is_last ? "/L" : "",
+               req->req.length - req->req.actual,
+               &req->req, udc_ep_readl(ep, UDCCSR));
+
+       return is_last;
+}
+
+/**
+ * pxa_ep_queue - Queue a request into an IN endpoint
+ * @_ep: usb endpoint
+ * @_req: usb request
+ * @gfp_flags: flags
+ *
+ * Context: normally called when !in_interrupt, but callable when in_interrupt()
+ * in the special case of ep0 setup :
+ *   (irq->handle_ep0_ctrl_req->gadget_setup->pxa_ep_queue)
+ *
+ * Returns 0 if succedeed, error otherwise
+ */
+static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+                       gfp_t gfp_flags)
+{
+       struct udc_usb_ep       *udc_usb_ep;
+       struct pxa_ep           *ep;
+       struct pxa27x_request   *req;
+       struct pxa_udc          *dev;
+       unsigned long           flags;
+       int                     rc = 0;
+       int                     is_first_req;
+       unsigned                length;
+
+       req = container_of(_req, struct pxa27x_request, req);
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+
+       if (unlikely(!_req || !_req->complete || !_req->buf))
+               return -EINVAL;
+
+       if (unlikely(!_ep))
+               return -EINVAL;
+
+       dev = udc_usb_ep->dev;
+       ep = udc_usb_ep->pxa_ep;
+       if (unlikely(!ep))
+               return -EINVAL;
+
+       dev = ep->dev;
+       if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+               ep_dbg(ep, "bogus device state\n");
+               return -ESHUTDOWN;
+       }
+
+       /* iso is always one packet per request, that's the only way
+        * we can report per-packet status.  that also helps with dma.
+        */
+       if (unlikely(EPXFERTYPE_is_ISO(ep)
+                       && req->req.length > ep->fifo_size))
+               return -EMSGSIZE;
+
+       spin_lock_irqsave(&ep->lock, flags);
+
+       is_first_req = list_empty(&ep->queue);
+       ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n",
+                       _req, is_first_req ? "yes" : "no",
+                       _req->length, _req->buf);
+
+       if (!ep->enabled) {
+               _req->status = -ESHUTDOWN;
+               rc = -ESHUTDOWN;
+               goto out;
+       }
+
+       if (req->in_use) {
+               ep_err(ep, "refusing to queue req %p (already queued)\n", req);
+               goto out;
+       }
+
+       length = _req->length;
+       _req->status = -EINPROGRESS;
+       _req->actual = 0;
+
+       ep_add_request(ep, req);
+
+       if (is_ep0(ep)) {
+               switch (dev->ep0state) {
+               case WAIT_ACK_SET_CONF_INTERF:
+                       if (length == 0) {
+                               ep_end_in_req(ep, req);
+                       } else {
+                               ep_err(ep, "got a request of %d bytes while"
+                                       "in state WATI_ACK_SET_CONF_INTERF\n",
+                                       length);
+                               ep_del_request(ep, req);
+                               rc = -EL2HLT;
+                       }
+                       ep0_idle(ep->dev);
+                       break;
+               case IN_DATA_STAGE:
+                       if (!ep_is_full(ep))
+                               if (write_ep0_fifo(ep, req))
+                                       ep0_end_in_req(ep, req);
+                       break;
+               case OUT_DATA_STAGE:
+                       if ((length == 0) || !epout_has_pkt(ep))
+                               if (read_ep0_fifo(ep, req))
+                                       ep0_end_out_req(ep, req);
+                       break;
+               default:
+                       ep_err(ep, "odd state %s to send me a request\n",
+                               EP0_STNAME(ep->dev));
+                       ep_del_request(ep, req);
+                       rc = -EL2HLT;
+                       break;
+               }
+       } else {
+               handle_ep(ep);
+       }
+
+out:
+       spin_unlock_irqrestore(&ep->lock, flags);
+       return rc;
+}
+
+/**
+ * pxa_ep_dequeue - Dequeue one request
+ * @_ep: usb endpoint
+ * @_req: usb request
+ *
+ * Return 0 if no error, -EINVAL or -ECONNRESET otherwise
+ */
+static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+       struct pxa27x_request   *req;
+       unsigned long           flags;
+       int                     rc;
+
+       if (!_ep)
+               return -EINVAL;
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       ep = udc_usb_ep->pxa_ep;
+       if (!ep || is_ep0(ep))
+               return -EINVAL;
+
+       spin_lock_irqsave(&ep->lock, flags);
+
+       /* make sure it's actually queued on this endpoint */
+       list_for_each_entry(req, &ep->queue, queue) {
+               if (&req->req == _req)
+                       break;
+       }
+
+       rc = -EINVAL;
+       if (&req->req != _req)
+               goto out;
+
+       rc = 0;
+       req_done(ep, req, -ECONNRESET);
+out:
+       spin_unlock_irqrestore(&ep->lock, flags);
+       return rc;
+}
+
+/**
+ * pxa_ep_set_halt - Halts operations on one endpoint
+ * @_ep: usb endpoint
+ * @value:
+ *
+ * Returns 0 if no error, -EINVAL, -EROFS, -EAGAIN otherwise
+ */
+static int pxa_ep_set_halt(struct usb_ep *_ep, int value)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+       unsigned long flags;
+       int rc;
+
+
+       if (!_ep)
+               return -EINVAL;
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       ep = udc_usb_ep->pxa_ep;
+       if (!ep || is_ep0(ep))
+               return -EINVAL;
+
+       if (value == 0) {
+               /*
+                * This path (reset toggle+halt) is needed to implement
+                * SET_INTERFACE on normal hardware.  but it can't be
+                * done from software on the PXA UDC, and the hardware
+                * forgets to do it as part of SET_INTERFACE automagic.
+                */
+               ep_dbg(ep, "only host can clear halt\n");
+               return -EROFS;
+       }
+
+       spin_lock_irqsave(&ep->lock, flags);
+
+       rc = -EAGAIN;
+       if (ep->dir_in  && (ep_is_full(ep) || !list_empty(&ep->queue)))
+               goto out;
+
+       /* FST, FEF bits are the same for control and non control endpoints */
+       rc = 0;
+       udc_ep_writel(ep, UDCCSR, UDCCSR_FST | UDCCSR_FEF);
+       if (is_ep0(ep))
+               set_ep0state(ep->dev, STALL);
+
+out:
+       spin_unlock_irqrestore(&ep->lock, flags);
+       return rc;
+}
+
+/**
+ * pxa_ep_fifo_status - Get how many bytes in physical endpoint
+ * @_ep: usb endpoint
+ *
+ * Returns number of bytes in OUT fifos. Broken for IN fifos.
+ */
+static int pxa_ep_fifo_status(struct usb_ep *_ep)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+
+       if (!_ep)
+               return -ENODEV;
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       ep = udc_usb_ep->pxa_ep;
+       if (!ep || is_ep0(ep))
+               return -ENODEV;
+
+       if (ep->dir_in)
+               return -EOPNOTSUPP;
+       if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep))
+               return 0;
+       else
+               return ep_count_bytes_remain(ep) + 1;
+}
+
+/**
+ * pxa_ep_fifo_flush - Flushes one endpoint
+ * @_ep: usb endpoint
+ *
+ * Discards all data in one endpoint(IN or OUT), except control endpoint.
+ */
+static void pxa_ep_fifo_flush(struct usb_ep *_ep)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+       unsigned long           flags;
+
+       if (!_ep)
+               return;
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       ep = udc_usb_ep->pxa_ep;
+       if (!ep || is_ep0(ep))
+               return;
+
+       spin_lock_irqsave(&ep->lock, flags);
+
+       if (unlikely(!list_empty(&ep->queue)))
+               ep_dbg(ep, "called while queue list not empty\n");
+       ep_dbg(ep, "called\n");
+
+       /* for OUT, just read and discard the FIFO contents. */
+       if (!ep->dir_in) {
+               while (!ep_is_empty(ep))
+                       udc_ep_readl(ep, UDCDR);
+       } else {
+               /* most IN status is the same, but ISO can't stall */
+               udc_ep_writel(ep, UDCCSR,
+                               UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN
+                               | (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST));
+       }
+
+       spin_unlock_irqrestore(&ep->lock, flags);
+
+       return;
+}
+
+/**
+ * pxa_ep_enable - Enables usb endpoint
+ * @_ep: usb endpoint
+ * @desc: usb endpoint descriptor
+ *
+ * Nothing much to do here, as ep configuration is done once and for all
+ * before udc is enabled. After udc enable, no physical endpoint configuration
+ * can be changed.
+ * Function makes sanity checks and flushes the endpoint.
+ */
+static int pxa_ep_enable(struct usb_ep *_ep,
+       const struct usb_endpoint_descriptor *desc)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+       struct pxa_udc          *udc;
+
+       if (!_ep || !desc)
+               return -EINVAL;
+
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       if (udc_usb_ep->pxa_ep) {
+               ep = udc_usb_ep->pxa_ep;
+               ep_warn(ep, "usb_ep %s already enabled, doing nothing\n",
+                       _ep->name);
+       } else {
+               ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep);
+       }
+
+       if (!ep || is_ep0(ep)) {
+               dev_err(udc_usb_ep->dev->dev,
+                       "unable to match pxa_ep for ep %s\n",
+                       _ep->name);
+               return -EINVAL;
+       }
+
+       if ((desc->bDescriptorType != USB_DT_ENDPOINT)
+                       || (ep->type != usb_endpoint_type(desc))) {
+               ep_err(ep, "type mismatch\n");
+               return -EINVAL;
+       }
+
+       if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) {
+               ep_err(ep, "bad maxpacket\n");
+               return -ERANGE;
+       }
+
+       udc_usb_ep->pxa_ep = ep;
+       udc = ep->dev;
+
+       if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+               ep_err(ep, "bogus device state\n");
+               return -ESHUTDOWN;
+       }
+
+       ep->enabled = 1;
+
+       /* flush fifo (mostly for OUT buffers) */
+       pxa_ep_fifo_flush(_ep);
+
+       ep_dbg(ep, "enabled\n");
+       return 0;
+}
+
+/**
+ * pxa_ep_disable - Disable usb endpoint
+ * @_ep: usb endpoint
+ *
+ * Same as for pxa_ep_enable, no physical endpoint configuration can be
+ * changed.
+ * Function flushes the endpoint and related requests.
+ */
+static int pxa_ep_disable(struct usb_ep *_ep)
+{
+       struct pxa_ep           *ep;
+       struct udc_usb_ep       *udc_usb_ep;
+       unsigned long           flags;
+
+       if (!_ep)
+               return -EINVAL;
+
+       udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+       ep = udc_usb_ep->pxa_ep;
+       if (!ep || is_ep0(ep) || !list_empty(&ep->queue))
+               return -EINVAL;
+
+       spin_lock_irqsave(&ep->lock, flags);
+       ep->enabled = 0;
+       nuke(ep, -ESHUTDOWN);
+       spin_unlock_irqrestore(&ep->lock, flags);
+
+       pxa_ep_fifo_flush(_ep);
+       udc_usb_ep->pxa_ep = NULL;
+
+       ep_dbg(ep, "disabled\n");
+       return 0;
+}
+
+static struct usb_ep_ops pxa_ep_ops = {
+       .enable         = pxa_ep_enable,
+       .disable        = pxa_ep_disable,
+
+       .alloc_request  = pxa_ep_alloc_request,
+       .free_request   = pxa_ep_free_request,
+
+       .queue          = pxa_ep_queue,
+       .dequeue        = pxa_ep_dequeue,
+
+       .set_halt       = pxa_ep_set_halt,
+       .fifo_status    = pxa_ep_fifo_status,
+       .fifo_flush     = pxa_ep_fifo_flush,
+};
+
+
+/**
+ * pxa_udc_get_frame - Returns usb frame number
+ * @_gadget: usb gadget
+ */
+static int pxa_udc_get_frame(struct usb_gadget *_gadget)
+{
+       struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+       return (udc_readl(udc, UDCFNR) & 0x7ff);
+}
+
+/**
+ * pxa_udc_wakeup - Force udc device out of suspend
+ * @_gadget: usb gadget
+ *
+ * Returns 0 if succesfull, error code otherwise
+ */
+static int pxa_udc_wakeup(struct usb_gadget *_gadget)
+{
+       struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+       /* host may not have enabled remote wakeup */
+       if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0)
+               return -EHOSTUNREACH;
+       udc_set_mask_UDCCR(udc, UDCCR_UDR);
+       return 0;
+}
+
+static const struct usb_gadget_ops pxa_udc_ops = {
+       .get_frame      = pxa_udc_get_frame,
+       .wakeup         = pxa_udc_wakeup,
+       /* current versions must always be self-powered */
+};
+
+/**
+ * udc_disable - disable udc device controller
+ * @udc: udc device
+ *
+ * Disables the udc device : disables clocks, udc interrupts, control endpoint
+ * interrupts.
+ */
+static void udc_disable(struct pxa_udc *udc)
+{
+       udc_writel(udc, UDCICR0, 0);
+       udc_writel(udc, UDCICR1, 0);
+
+       udc_clear_mask_UDCCR(udc, UDCCR_UDE);
+       clk_disable(udc->clk);
+
+       ep0_idle(udc);
+       udc->gadget.speed = USB_SPEED_UNKNOWN;
+       udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+}
+
+/**
+ * udc_init_data - Initialize udc device data structures
+ * @dev: udc device
+ *
+ * Initializes gadget endpoint list, endpoints locks. No action is taken
+ * on the hardware.
+ */
+static __init void udc_init_data(struct pxa_udc *dev)
+{
+       int i;
+       struct pxa_ep *ep;
+
+       /* device/ep0 records init */
+       INIT_LIST_HEAD(&dev->gadget.ep_list);
+       INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
+       dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
+       ep0_idle(dev);
+       strcpy(dev->dev->bus_id, "");
+
+       /* PXA endpoints init */
+       for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &dev->pxa_ep[i];
+
+               ep->enabled = is_ep0(ep);
+               INIT_LIST_HEAD(&ep->queue);
+               spin_lock_init(&ep->lock);
+       }
+
+       /* USB endpoints init */
+       for (i = 0; i < NR_USB_ENDPOINTS; i++)
+               if (i != 0)
+                       list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
+                                       &dev->gadget.ep_list);
+}
+
+/**
+ * udc_enable - Enables the udc device
+ * @dev: udc device
+ *
+ * Enables the udc device : enables clocks, udc interrupts, control endpoint
+ * interrupts, sets usb as UDC client and setups endpoints.
+ */
+static void udc_enable(struct pxa_udc *udc)
+{
+       udc_writel(udc, UDCICR0, 0);
+       udc_writel(udc, UDCICR1, 0);
+       udc_writel(udc, UP2OCR, UP2OCR_HXOE);
+       udc_clear_mask_UDCCR(udc, UDCCR_UDE);
+
+       clk_enable(udc->clk);
+
+       ep0_idle(udc);
+       udc->gadget.speed = USB_SPEED_FULL;
+       memset(&udc->stats, 0, sizeof(udc->stats));
+
+       udc_set_mask_UDCCR(udc, UDCCR_UDE);
+       udelay(2);
+       if (udc_readl(udc, UDCCR) & UDCCR_EMCE)
+               dev_err(udc->dev, "Configuration errors, udc disabled\n");
+
+       /*
+        * Caller must be able to sleep in order to cope with startup transients
+        */
+       msleep(100);
+
+       /* enable suspend/resume and reset irqs */
+       udc_writel(udc, UDCICR1,
+                       UDCICR1_IECC | UDCICR1_IERU
+                       | UDCICR1_IESU | UDCICR1_IERS);
+
+       /* enable ep0 irqs */
+       pio_irq_enable(&udc->pxa_ep[0]);
+
+       dev_info(udc->dev, "UDC connecting\n");
+       if (udc->mach->udc_command)
+               udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+}
+
+/**
+ * usb_gadget_register_driver - Register gadget driver
+ * @driver: gadget driver
+ *
+ * When a driver is successfully registered, it will receive control requests
+ * including set_configuration(), which enables non-control requests.  Then
+ * usb traffic follows until a disconnect is reported.  Then a host may connect
+ * again, or the driver might get unbound.
+ *
+ * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
+ */
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       struct pxa_udc *udc = the_controller;
+       int retval;
+
+       if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind
+                       || !driver->disconnect || !driver->setup)
+               return -EINVAL;
+       if (!udc)
+               return -ENODEV;
+       if (udc->driver)
+               return -EBUSY;
+
+       /* first hook up the driver ... */
+       udc->driver = driver;
+       udc->gadget.dev.driver = &driver->driver;
+
+       retval = device_add(&udc->gadget.dev);
+       if (retval) {
+               dev_err(udc->dev, "device_add error %d\n", retval);
+               goto add_fail;
+       }
+       retval = driver->bind(&udc->gadget);
+       if (retval) {
+               dev_err(udc->dev, "bind to driver %s --> error %d\n",
+                       driver->driver.name, retval);
+               goto bind_fail;
+       }
+       dev_dbg(udc->dev, "registered gadget driver '%s'\n",
+               driver->driver.name);
+
+       udc_enable(udc);
+       return 0;
+
+bind_fail:
+       device_del(&udc->gadget.dev);
+add_fail:
+       udc->driver = NULL;
+       udc->gadget.dev.driver = NULL;
+       return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+
+/**
+ * stop_activity - Stops udc endpoints
+ * @udc: udc device
+ * @driver: gadget driver
+ *
+ * Disables all udc endpoints (even control endpoint), report disconnect to
+ * the gadget user.
+ */
+static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver)
+{
+       int i;
+
+       /* don't disconnect drivers more than once */
+       if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+               driver = NULL;
+       udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+       for (i = 0; i < NR_USB_ENDPOINTS; i++)
+               pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep);
+
+       if (driver)
+               driver->disconnect(&udc->gadget);
+}
+
+/**
+ * usb_gadget_unregister_driver - Unregister the gadget driver
+ * @driver: gadget driver
+ *
+ * Returns 0 if no error, -ENODEV, -EINVAL otherwise
+ */
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       struct pxa_udc *udc = the_controller;
+
+       if (!udc)
+               return -ENODEV;
+       if (!driver || driver != udc->driver || !driver->unbind)
+               return -EINVAL;
+
+       stop_activity(udc, driver);
+       udc_disable(udc);
+
+       driver->unbind(&udc->gadget);
+       udc->driver = NULL;
+
+       device_del(&udc->gadget.dev);
+
+       dev_info(udc->dev, "unregistered gadget driver '%s'\n",
+                driver->driver.name);
+       return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/**
+ * handle_ep0_ctrl_req - handle control endpoint control request
+ * @udc: udc device
+ * @req: control request
+ */
+static void handle_ep0_ctrl_req(struct pxa_udc *udc,
+                               struct pxa27x_request *req)
+{
+       struct pxa_ep *ep = &udc->pxa_ep[0];
+       union {
+               struct usb_ctrlrequest  r;
+               u32                     word[2];
+       } u;
+       int i;
+       int have_extrabytes = 0;
+
+       nuke(ep, -EPROTO);
+
+       /* read SETUP packet */
+       for (i = 0; i < 2; i++) {
+               if (unlikely(ep_is_empty(ep)))
+                       goto stall;
+               u.word[i] = udc_ep_readl(ep, UDCDR);
+       }
+
+       have_extrabytes = !ep_is_empty(ep);
+       while (!ep_is_empty(ep)) {
+               i = udc_ep_readl(ep, UDCDR);
+               ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
+       }
+
+       le16_to_cpus(&u.r.wValue);
+       le16_to_cpus(&u.r.wIndex);
+       le16_to_cpus(&u.r.wLength);
+
+       ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+               u.r.bRequestType, u.r.bRequest,
+               u.r.wValue, u.r.wIndex, u.r.wLength);
+       if (unlikely(have_extrabytes))
+               goto stall;
+
+       if (u.r.bRequestType & USB_DIR_IN)
+               set_ep0state(udc, IN_DATA_STAGE);
+       else
+               set_ep0state(udc, OUT_DATA_STAGE);
+
+       /* Tell UDC to enter Data Stage */
+       udc_ep_writel(ep, UDCCSR, UDCCSR0_SA | UDCCSR0_OPC);
+
+       i = udc->driver->setup(&udc->gadget, &u.r);
+       if (i < 0)
+               goto stall;
+out:
+       return;
+stall:
+       ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n",
+               udc_ep_readl(ep, UDCCSR), i);
+       udc_ep_writel(ep, UDCCSR, UDCCSR0_FST | UDCCSR0_FTF);
+       set_ep0state(udc, STALL);
+       goto out;
+}
+
+/**
+ * handle_ep0 - Handle control endpoint data transfers
+ * @udc: udc device
+ * @fifo_irq: 1 if triggered by fifo service type irq
+ * @opc_irq: 1 if triggered by output packet complete type irq
+ *
+ * Context : when in_interrupt() or with ep->lock held
+ *
+ * Tries to transfer all pending request data into the endpoint and/or
+ * transfer all pending data in the endpoint into usb requests.
+ * Handles states of ep0 automata.
+ *
+ * PXA27x hardware handles several standard usb control requests without
+ * driver notification.  The requests fully handled by hardware are :
+ *  SET_ADDRESS, SET_FEATURE, CLEAR_FEATURE, GET_CONFIGURATION, GET_INTERFACE,
+ *  GET_STATUS
+ * The requests handled by hardware, but with irq notification are :
+ *  SYNCH_FRAME, SET_CONFIGURATION, SET_INTERFACE
+ * The remaining standard requests really handled by handle_ep0 are :
+ *  GET_DESCRIPTOR, SET_DESCRIPTOR, specific requests.
+ * Requests standardized outside of USB 2.0 chapter 9 are handled more
+ * uniformly, by gadget drivers.
+ *
+ * The control endpoint state machine is _not_ USB spec compliant, it's even
+ * hardly compliant with Intel PXA270 developers guide.
+ * The key points which inferred this state machine are :
+ *   - on every setup token, bit UDCCSR0_SA is raised and held until cleared by
+ *     software.
+ *   - on every OUT packet received, UDCCSR0_OPC is raised and held until
+ *     cleared by software.
+ *   - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it
+ *     before reading ep0.
+ *   - irq can be called on a "packet complete" event (opc_irq=1), while
+ *     UDCCSR0_OPC is not yet raised (delta can be as big as 100ms
+ *     from experimentation).
+ *   - as UDCCSR0_SA can be activated while in irq handling, and clearing
+ *     UDCCSR0_OPC would flush the setup data, we almost never clear UDCCSR0_OPC
+ *     => we never actually read the "status stage" packet of an IN data stage
+ *     => this is not documented in Intel documentation
+ *   - hardware as no idea of STATUS STAGE, it only handle SETUP STAGE and DATA
+ *     STAGE. The driver add STATUS STAGE to send last zero length packet in
+ *     OUT_STATUS_STAGE.
+ *   - special attention was needed for IN_STATUS_STAGE. If a packet complete
+ *     event is detected, we terminate the status stage without ackowledging the
+ *     packet (not to risk to loose a potential SETUP packet)
+ */
+static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
+{
+       u32                     udccsr0;
+       struct pxa_ep           *ep = &udc->pxa_ep[0];
+       struct pxa27x_request   *req = NULL;
+       int                     completed = 0;
+
+       udccsr0 = udc_ep_readl(ep, UDCCSR);
+       ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
+               EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
+               (fifo_irq << 1 | opc_irq));
+
+       if (!list_empty(&ep->queue))
+               req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+
+       if (udccsr0 & UDCCSR0_SST) {
+               ep_dbg(ep, "clearing stall status\n");
+               nuke(ep, -EPIPE);
+               udc_ep_writel(ep, UDCCSR, UDCCSR0_SST);
+               ep0_idle(udc);
+       }
+
+       if (udccsr0 & UDCCSR0_SA) {
+               nuke(ep, 0);
+               set_ep0state(udc, SETUP_STAGE);
+       }
+
+       switch (udc->ep0state) {
+       case WAIT_FOR_SETUP:
+               /*
+                * Hardware bug : beware, we cannot clear OPC, since we would
+                * miss a potential OPC irq for a setup packet.
+                * So, we only do ... nothing, and hope for a next irq with
+                * UDCCSR0_SA set.
+                */
+               break;
+       case SETUP_STAGE:
+               udccsr0 &= UDCCSR0_CTRL_REQ_MASK;
+               if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK))
+                       handle_ep0_ctrl_req(udc, req);
+               break;
+       case IN_DATA_STAGE:                     /* GET_DESCRIPTOR */
+               if (epout_has_pkt(ep))
+                       udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC);
+               if (req && !ep_is_full(ep))
+                       completed = write_ep0_fifo(ep, req);
+               if (completed)
+                       ep0_end_in_req(ep, req);
+               break;
+       case OUT_DATA_STAGE:                    /* SET_DESCRIPTOR */
+               if (epout_has_pkt(ep) && req)
+                       completed = read_ep0_fifo(ep, req);
+               if (completed)
+                       ep0_end_out_req(ep, req);
+               break;
+       case STALL:
+               udc_ep_writel(ep, UDCCSR, UDCCSR0_FST);
+               break;
+       case IN_STATUS_STAGE:
+               /*
+                * Hardware bug : beware, we cannot clear OPC, since we would
+                * miss a potential PC irq for a setup packet.
+                * So, we only put the ep0 into WAIT_FOR_SETUP state.
+                */
+               if (opc_irq)
+                       ep0_idle(udc);
+               break;
+       case OUT_STATUS_STAGE:
+       case WAIT_ACK_SET_CONF_INTERF:
+               ep_warn(ep, "should never get in %s state here!!!\n",
+                               EP0_STNAME(ep->dev));
+               ep0_idle(udc);
+               break;
+       }
+}
+
+/**
+ * handle_ep - Handle endpoint data tranfers
+ * @ep: pxa physical endpoint
+ *
+ * Tries to transfer all pending request data into the endpoint and/or
+ * transfer all pending data in the endpoint into usb requests.
+ *
+ * Is always called when in_interrupt() or with ep->lock held.
+ */
+static void handle_ep(struct pxa_ep *ep)
+{
+       struct pxa27x_request   *req;
+       int completed;
+       u32 udccsr;
+       int is_in = ep->dir_in;
+       int loop = 0;
+
+       do {
+               completed = 0;
+               udccsr = udc_ep_readl(ep, UDCCSR);
+               if (likely(!list_empty(&ep->queue)))
+                       req = list_entry(ep->queue.next,
+                                       struct pxa27x_request, queue);
+               else
+                       req = NULL;
+
+               ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n",
+                               req, udccsr, loop++);
+
+               if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN)))
+                       udc_ep_writel(ep, UDCCSR,
+                                       udccsr & (UDCCSR_SST | UDCCSR_TRN));
+               if (!req)
+                       break;
+
+               if (unlikely(is_in)) {
+                       if (likely(!ep_is_full(ep)))
+                               completed = write_fifo(ep, req);
+                       if (completed)
+                               ep_end_in_req(ep, req);
+               } else {
+                       if (likely(epout_has_pkt(ep)))
+                               completed = read_fifo(ep, req);
+                       if (completed)
+                               ep_end_out_req(ep, req);
+               }
+       } while (completed);
+}
+
+/**
+ * pxa27x_change_configuration - Handle SET_CONF usb request notification
+ * @udc: udc device
+ * @config: usb configuration
+ *
+ * Post the request to upper level.
+ * Don't use any pxa specific harware configuration capabilities
+ */
+static void pxa27x_change_configuration(struct pxa_udc *udc, int config)
+{
+       struct usb_ctrlrequest req ;
+
+       dev_dbg(udc->dev, "config=%d\n", config);
+
+       udc->config = config;
+       udc->last_interface = 0;
+       udc->last_alternate = 0;
+
+       req.bRequestType = 0;
+       req.bRequest = USB_REQ_SET_CONFIGURATION;
+       req.wValue = config;
+       req.wIndex = 0;
+       req.wLength = 0;
+
+       set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
+       udc->driver->setup(&udc->gadget, &req);
+}
+
+/**
+ * pxa27x_change_interface - Handle SET_INTERF usb request notification
+ * @udc: udc device
+ * @iface: interface number
+ * @alt: alternate setting number
+ *
+ * Post the request to upper level.
+ * Don't use any pxa specific harware configuration capabilities
+ */
+static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt)
+{
+       struct usb_ctrlrequest  req;
+
+       dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt);
+
+       udc->last_interface = iface;
+       udc->last_alternate = alt;
+
+       req.bRequestType = USB_RECIP_INTERFACE;
+       req.bRequest = USB_REQ_SET_INTERFACE;
+       req.wValue = alt;
+       req.wIndex = iface;
+       req.wLength = 0;
+
+       set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
+       udc->driver->setup(&udc->gadget, &req);
+}
+
+/*
+ * irq_handle_data - Handle data transfer
+ * @irq: irq IRQ number
+ * @udc: dev pxa_udc device structure
+ *
+ * Called from irq handler, transferts data to or from endpoint to queue
+ */
+static void irq_handle_data(int irq, struct pxa_udc *udc)
+{
+       int i;
+       struct pxa_ep *ep;
+       u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK;
+       u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK;
+
+       if (udcisr0 & UDCISR_INT_MASK) {
+               udc->pxa_ep[0].stats.irqs++;
+               udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK));
+               handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR),
+                               !!(udcisr0 & UDCICR_PKTCOMPL));
+       }
+
+       udcisr0 >>= 2;
+       for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) {
+               if (!(udcisr0 & UDCISR_INT_MASK))
+                       continue;
+
+               udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK));
+               ep = &udc->pxa_ep[i];
+               ep->stats.irqs++;
+               handle_ep(ep);
+       }
+
+       for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) {
+               udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK));
+               if (!(udcisr1 & UDCISR_INT_MASK))
+                       continue;
+
+               ep = &udc->pxa_ep[i];
+               ep->stats.irqs++;
+               handle_ep(ep);
+       }
+
+}
+
+/**
+ * irq_udc_suspend - Handle IRQ "UDC Suspend"
+ * @udc: udc device
+ */
+static void irq_udc_suspend(struct pxa_udc *udc)
+{
+       udc_writel(udc, UDCISR1, UDCISR1_IRSU);
+       udc->stats.irqs_suspend++;
+
+       if (udc->gadget.speed != USB_SPEED_UNKNOWN
+                       && udc->driver && udc->driver->suspend)
+               udc->driver->suspend(&udc->gadget);
+       ep0_idle(udc);
+}
+
+/**
+  * irq_udc_resume - Handle IRQ "UDC Resume"
+  * @udc: udc device
+  */
+static void irq_udc_resume(struct pxa_udc *udc)
+{
+       udc_writel(udc, UDCISR1, UDCISR1_IRRU);
+       udc->stats.irqs_resume++;
+
+       if (udc->gadget.speed != USB_SPEED_UNKNOWN
+                       && udc->driver && udc->driver->resume)
+               udc->driver->resume(&udc->gadget);
+}
+
+/**
+ * irq_udc_reconfig - Handle IRQ "UDC Change Configuration"
+ * @udc: udc device
+ */
+static void irq_udc_reconfig(struct pxa_udc *udc)
+{
+       unsigned config, interface, alternate, config_change;
+       u32 udccr = udc_readl(udc, UDCCR);
+
+       udc_writel(udc, UDCISR1, UDCISR1_IRCC);
+       udc->stats.irqs_reconfig++;
+
+       config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S;
+       config_change = (config != udc->config);
+       pxa27x_change_configuration(udc, config);
+
+       interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S;
+       alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S;
+       pxa27x_change_interface(udc, interface, alternate);
+
+       if (config_change)
+               update_pxa_ep_matches(udc);
+       udc_set_mask_UDCCR(udc, UDCCR_SMAC);
+}
+
+/**
+ * irq_udc_reset - Handle IRQ "UDC Reset"
+ * @udc: udc device
+ */
+static void irq_udc_reset(struct pxa_udc *udc)
+{
+       u32 udccr = udc_readl(udc, UDCCR);
+       struct pxa_ep *ep = &udc->pxa_ep[0];
+
+       dev_info(udc->dev, "USB reset\n");
+       udc_writel(udc, UDCISR1, UDCISR1_IRRS);
+       udc->stats.irqs_reset++;
+
+       if ((udccr & UDCCR_UDA) == 0) {
+               dev_dbg(udc->dev, "USB reset start\n");
+               stop_activity(udc, udc->driver);
+       }
+       udc->gadget.speed = USB_SPEED_FULL;
+       memset(&udc->stats, 0, sizeof udc->stats);
+
+       nuke(ep, -EPROTO);
+       udc_ep_writel(ep, UDCCSR, UDCCSR0_FTF | UDCCSR0_OPC);
+       ep0_idle(udc);
+}
+
+/**
+ * pxa_udc_irq - Main irq handler
+ * @irq: irq number
+ * @_dev: udc device
+ *
+ * Handles all udc interrupts
+ */
+static irqreturn_t pxa_udc_irq(int irq, void *_dev)
+{
+       struct pxa_udc *udc = _dev;
+       u32 udcisr0 = udc_readl(udc, UDCISR0);
+       u32 udcisr1 = udc_readl(udc, UDCISR1);
+       u32 udccr = udc_readl(udc, UDCCR);
+       u32 udcisr1_spec;
+
+       dev_vdbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, "
+                "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr);
+
+       udcisr1_spec = udcisr1 & 0xf8000000;
+       if (unlikely(udcisr1_spec & UDCISR1_IRSU))
+               irq_udc_suspend(udc);
+       if (unlikely(udcisr1_spec & UDCISR1_IRRU))
+               irq_udc_resume(udc);
+       if (unlikely(udcisr1_spec & UDCISR1_IRCC))
+               irq_udc_reconfig(udc);
+       if (unlikely(udcisr1_spec & UDCISR1_IRRS))
+               irq_udc_reset(udc);
+
+       if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK))
+               irq_handle_data(irq, udc);
+
+       return IRQ_HANDLED;
+}
+
+static struct pxa_udc memory = {
+       .gadget = {
+               .ops            = &pxa_udc_ops,
+               .ep0            = &memory.udc_usb_ep[0].usb_ep,
+               .name           = driver_name,
+               .dev = {
+                       .bus_id         = "gadget",
+               },
+       },
+
+       .udc_usb_ep = {
+               USB_EP_CTRL,
+               USB_EP_OUT_BULK(1),
+               USB_EP_IN_BULK(2),
+               USB_EP_IN_ISO(3),
+               USB_EP_OUT_ISO(4),
+               USB_EP_IN_INT(5),
+       },
+
+       .pxa_ep = {
+               PXA_EP_CTRL,
+               /* Endpoints for gadget zero */
+               PXA_EP_OUT_BULK(1, 1, 3, 0, 0),
+               PXA_EP_IN_BULK(2,  2, 3, 0, 0),
+               /* Endpoints for ether gadget, file storage gadget */
+               PXA_EP_OUT_BULK(3, 1, 1, 0, 0),
+               PXA_EP_IN_BULK(4,  2, 1, 0, 0),
+               PXA_EP_IN_ISO(5,   3, 1, 0, 0),
+               PXA_EP_OUT_ISO(6,  4, 1, 0, 0),
+               PXA_EP_IN_INT(7,   5, 1, 0, 0),
+               /* Endpoints for RNDIS, serial */
+               PXA_EP_OUT_BULK(8, 1, 2, 0, 0),
+               PXA_EP_IN_BULK(9,  2, 2, 0, 0),
+               PXA_EP_IN_INT(10,  5, 2, 0, 0),
+               /*
+                * All the following endpoints are only for completion.  They
+                * won't never work, as multiple interfaces are really broken on
+                * the pxa.
+               */
+               PXA_EP_OUT_BULK(11, 1, 2, 1, 0),
+               PXA_EP_IN_BULK(12,  2, 2, 1, 0),
+               /* Endpoint for CDC Ether */
+               PXA_EP_OUT_BULK(13, 1, 1, 1, 1),
+               PXA_EP_IN_BULK(14,  2, 1, 1, 1),
+       }
+};
+
+/**
+ * pxa_udc_probe - probes the udc device
+ * @_dev: platform device
+ *
+ * Perform basic init : allocates udc clock, creates sysfs files, requests
+ * irq.
+ */
+static int __init pxa_udc_probe(struct platform_device *pdev)
+{
+       struct resource *regs;
+       struct pxa_udc *udc = &memory;
+       int retval;
+
+       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!regs)
+               return -ENXIO;
+       udc->irq = platform_get_irq(pdev, 0);
+       if (udc->irq < 0)
+               return udc->irq;
+
+       udc->dev = &pdev->dev;
+       udc->mach = pdev->dev.platform_data;
+
+       udc->clk = clk_get(&pdev->dev, "UDCCLK");
+       if (IS_ERR(udc->clk)) {
+               retval = PTR_ERR(udc->clk);
+               goto err_clk;
+       }
+
+       retval = -ENOMEM;
+       udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
+       if (!udc->regs) {
+               dev_err(&pdev->dev, "Unable to map UDC I/O memory\n");
+               goto err_map;
+       }
+
+       device_initialize(&udc->gadget.dev);
+       udc->gadget.dev.parent = &pdev->dev;
+       udc->gadget.dev.dma_mask = NULL;
+
+       the_controller = udc;
+       platform_set_drvdata(pdev, udc);
+       udc_init_data(udc);
+       pxa_eps_setup(udc);
+
+       /* irq setup after old hardware state is cleaned up */
+       retval = request_irq(udc->irq, pxa_udc_irq,
+                       IRQF_SHARED, driver_name, udc);
+       if (retval != 0) {
+               dev_err(udc->dev, "%s: can't get irq %i, err %d\n",
+                       driver_name, IRQ_USB, retval);
+               goto err_irq;
+       }
+
+       pxa_init_debugfs(udc);
+       return 0;
+err_irq:
+       iounmap(udc->regs);
+err_map:
+       clk_put(udc->clk);
+       udc->clk = NULL;
+err_clk:
+       return retval;
+}
+
+/**
+ * pxa_udc_remove - removes the udc device driver
+ * @_dev: platform device
+ */
+static int __exit pxa_udc_remove(struct platform_device *_dev)
+{
+       struct pxa_udc *udc = platform_get_drvdata(_dev);
+
+       usb_gadget_unregister_driver(udc->driver);
+       free_irq(udc->irq, udc);
+       pxa_cleanup_debugfs(udc);
+
+       platform_set_drvdata(_dev, NULL);
+       the_controller = NULL;
+       clk_put(udc->clk);
+
+       return 0;
+}
+
+static void pxa_udc_shutdown(struct platform_device *_dev)
+{
+       struct pxa_udc *udc = platform_get_drvdata(_dev);
+
+       udc_disable(udc);
+}
+
+#ifdef CONFIG_PM
+/**
+ * pxa_udc_suspend - Suspend udc device
+ * @_dev: platform device
+ * @state: suspend state
+ *
+ * Suspends udc : saves configuration registers (UDCCR*), then disables the udc
+ * device.
+ */
+static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
+{
+       int i;
+       struct pxa_udc *udc = platform_get_drvdata(_dev);
+       struct pxa_ep *ep;
+
+       ep = &udc->pxa_ep[0];
+       udc->udccsr0 = udc_ep_readl(ep, UDCCSR);
+       for (i = 1; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &udc->pxa_ep[i];
+               ep->udccsr_value = udc_ep_readl(ep, UDCCSR);
+               ep->udccr_value  = udc_ep_readl(ep, UDCCR);
+               ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n",
+                               ep->udccsr_value, ep->udccr_value);
+       }
+
+       udc_disable(udc);
+
+       return 0;
+}
+
+/**
+ * pxa_udc_resume - Resume udc device
+ * @_dev: platform device
+ *
+ * Resumes udc : restores configuration registers (UDCCR*), then enables the udc
+ * device.
+ */
+static int pxa_udc_resume(struct platform_device *_dev)
+{
+       int i;
+       struct pxa_udc *udc = platform_get_drvdata(_dev);
+       struct pxa_ep *ep;
+
+       ep = &udc->pxa_ep[0];
+       udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME));
+       for (i = 1; i < NR_PXA_ENDPOINTS; i++) {
+               ep = &udc->pxa_ep[i];
+               udc_ep_writel(ep, UDCCSR, ep->udccsr_value);
+               udc_ep_writel(ep, UDCCR,  ep->udccr_value);
+               ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n",
+                               ep->udccsr_value, ep->udccr_value);
+       }
+
+       udc_enable(udc);
+       /*
+        * We do not handle OTG yet.
+        *
+        * OTGPH bit is set when sleep mode is entered.
+        * it indicates that OTG pad is retaining its state.
+        * Upon exit from sleep mode and before clearing OTGPH,
+        * Software must configure the USB OTG pad, UDC, and UHC
+        * to the state they were in before entering sleep mode.
+        *
+        * Should be : PSSR |= PSSR_OTGPH;
+        */
+
+       return 0;
+}
+#endif
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:pxa2xx-udc");
+
+static struct platform_driver udc_driver = {
+       .driver         = {
+               .name   = "pxa2xx-udc",
+               .owner  = THIS_MODULE,
+       },
+       .remove         = __exit_p(pxa_udc_remove),
+       .shutdown       = pxa_udc_shutdown,
+#ifdef CONFIG_PM
+       .suspend        = pxa_udc_suspend,
+       .resume         = pxa_udc_resume
+#endif
+};
+
+static int __init udc_init(void)
+{
+       printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
+       return platform_driver_probe(&udc_driver, pxa_udc_probe);
+}
+module_init(udc_init);
+
+
+static void __exit udc_exit(void)
+{
+       platform_driver_unregister(&udc_driver);
+}
+module_exit(udc_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Robert Jarzmik");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
new file mode 100644 (file)
index 0000000..1d1b793
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+ * linux/drivers/usb/gadget/pxa27x_udc.h
+ * Intel PXA27x on-chip full speed USB device controller
+ *
+ * Inspired by original driver by Frank Becker, David Brownell, and others.
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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 __LINUX_USB_GADGET_PXA27X_H
+#define __LINUX_USB_GADGET_PXA27X_H
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+/*
+ * Register definitions
+ */
+/* Offsets */
+#define UDCCR          0x0000          /* UDC Control Register */
+#define UDCICR0                0x0004          /* UDC Interrupt Control Register0 */
+#define UDCICR1                0x0008          /* UDC Interrupt Control Register1 */
+#define UDCISR0                0x000C          /* UDC Interrupt Status Register 0 */
+#define UDCISR1                0x0010          /* UDC Interrupt Status Register 1 */
+#define UDCFNR         0x0014          /* UDC Frame Number Register */
+#define UDCOTGICR      0x0018          /* UDC On-The-Go interrupt control */
+#define UP2OCR         0x0020          /* USB Port 2 Output Control register */
+#define UP3OCR         0x0024          /* USB Port 3 Output Control register */
+#define UDCCSRn(x)     (0x0100 + ((x)<<2)) /* UDC Control/Status register */
+#define UDCBCRn(x)     (0x0200 + ((x)<<2)) /* UDC Byte Count Register */
+#define UDCDRn(x)      (0x0300 + ((x)<<2)) /* UDC Data Register  */
+#define UDCCRn(x)      (0x0400 + ((x)<<2)) /* UDC Control Register */
+
+#define UDCCR_OEN      (1 << 31)       /* On-the-Go Enable */
+#define UDCCR_AALTHNP  (1 << 30)       /* A-device Alternate Host Negotiation
+                                          Protocol Port Support */
+#define UDCCR_AHNP     (1 << 29)       /* A-device Host Negotiation Protocol
+                                          Support */
+#define UDCCR_BHNP     (1 << 28)       /* B-device Host Negotiation Protocol
+                                          Enable */
+#define UDCCR_DWRE     (1 << 16)       /* Device Remote Wake-up Enable */
+#define UDCCR_ACN      (0x03 << 11)    /* Active UDC configuration Number */
+#define UDCCR_ACN_S    11
+#define UDCCR_AIN      (0x07 << 8)     /* Active UDC interface Number */
+#define UDCCR_AIN_S    8
+#define UDCCR_AAISN    (0x07 << 5)     /* Active UDC Alternate Interface
+                                          Setting Number */
+#define UDCCR_AAISN_S  5
+#define UDCCR_SMAC     (1 << 4)        /* Switch Endpoint Memory to Active
+                                          Configuration */
+#define UDCCR_EMCE     (1 << 3)        /* Endpoint Memory Configuration
+                                          Error */
+#define UDCCR_UDR      (1 << 2)        /* UDC Resume */
+#define UDCCR_UDA      (1 << 1)        /* UDC Active */
+#define UDCCR_UDE      (1 << 0)        /* UDC Enable */
+
+#define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCICR1_IECC   (1 << 31)       /* IntEn - Configuration Change */
+#define UDCICR1_IESOF  (1 << 30)       /* IntEn - Start of Frame */
+#define UDCICR1_IERU   (1 << 29)       /* IntEn - Resume */
+#define UDCICR1_IESU   (1 << 28)       /* IntEn - Suspend */
+#define UDCICR1_IERS   (1 << 27)       /* IntEn - Reset */
+#define UDCICR_FIFOERR (1 << 1)        /* FIFO Error interrupt for EP */
+#define UDCICR_PKTCOMPL        (1 << 0)        /* Packet Complete interrupt for EP */
+#define UDCICR_INT_MASK        (UDCICR_FIFOERR | UDCICR_PKTCOMPL)
+
+#define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCISR1_IRCC   (1 << 31)       /* IntReq - Configuration Change */
+#define UDCISR1_IRSOF  (1 << 30)       /* IntReq - Start of Frame */
+#define UDCISR1_IRRU   (1 << 29)       /* IntReq - Resume */
+#define UDCISR1_IRSU   (1 << 28)       /* IntReq - Suspend */
+#define UDCISR1_IRRS   (1 << 27)       /* IntReq - Reset */
+#define UDCISR_INT_MASK        (UDCICR_FIFOERR | UDCICR_PKTCOMPL)
+
+#define UDCOTGICR_IESF (1 << 24)       /* OTG SET_FEATURE command recvd */
+#define UDCOTGICR_IEXR (1 << 17)       /* Extra Transciever Interrupt
+                                          Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16)       /* Extra Transciever Interrupt
+                                          Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40R (1 << 9)     /* OTG Vbus Valid 4.0V Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV40F (1 << 8)     /* OTG Vbus Valid 4.0V Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV44R (1 << 7)     /* OTG Vbus Valid 4.4V Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEVV44F (1 << 6)     /* OTG Vbus Valid 4.4V Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESVR        (1 << 5)        /* OTG Session Valid Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESVF        (1 << 4)        /* OTG Session Valid Falling Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IESDR        (1 << 3)        /* OTG A-Device SRP Detect Rising
+                                          Edge Interrupt Enable */
+#define UDCOTGICR_IESDF        (1 << 2)        /* OTG A-Device SRP Detect Falling
+                                          Edge Interrupt Enable */
+#define UDCOTGICR_IEIDR        (1 << 1)        /* OTG ID Change Rising Edge
+                                          Interrupt Enable */
+#define UDCOTGICR_IEIDF        (1 << 0)        /* OTG ID Change Falling Edge
+                                          Interrupt Enable */
+
+/* Host Port 2 field bits */
+#define UP2OCR_CPVEN   (1 << 0)        /* Charge Pump Vbus Enable */
+#define UP2OCR_CPVPE   (1 << 1)        /* Charge Pump Vbus Pulse Enable */
+                                       /* Transceiver enablers */
+#define UP2OCR_DPPDE   (1 << 2)        /*   D+ Pull Down Enable */
+#define UP2OCR_DMPDE   (1 << 3)        /*   D- Pull Down Enable */
+#define UP2OCR_DPPUE   (1 << 4)        /*   D+ Pull Up Enable */
+#define UP2OCR_DMPUE   (1 << 5)        /*   D- Pull Up Enable */
+#define UP2OCR_DPPUBE  (1 << 6)        /*   D+ Pull Up Bypass Enable */
+#define UP2OCR_DMPUBE  (1 << 7)        /*   D- Pull Up Bypass Enable */
+#define UP2OCR_EXSP    (1 << 8)        /* External Transceiver Speed Control */
+#define UP2OCR_EXSUS   (1 << 9)        /* External Transceiver Speed Enable */
+#define UP2OCR_IDON    (1 << 10)       /* OTG ID Read Enable */
+#define UP2OCR_HXS     (1 << 16)       /* Transceiver Output Select */
+#define UP2OCR_HXOE    (1 << 17)       /* Transceiver Output Enable */
+#define UP2OCR_SEOS    (1 << 24)       /* Single-Ended Output Select */
+
+#define UDCCSR0_SA     (1 << 7)        /* Setup Active */
+#define UDCCSR0_RNE    (1 << 6)        /* Receive FIFO Not Empty */
+#define UDCCSR0_FST    (1 << 5)        /* Force Stall */
+#define UDCCSR0_SST    (1 << 4)        /* Sent Stall */
+#define UDCCSR0_DME    (1 << 3)        /* DMA Enable */
+#define UDCCSR0_FTF    (1 << 2)        /* Flush Transmit FIFO */
+#define UDCCSR0_IPR    (1 << 1)        /* IN Packet Ready */
+#define UDCCSR0_OPC    (1 << 0)        /* OUT Packet Complete */
+
+#define UDCCSR_DPE     (1 << 9)        /* Data Packet Error */
+#define UDCCSR_FEF     (1 << 8)        /* Flush Endpoint FIFO */
+#define UDCCSR_SP      (1 << 7)        /* Short Packet Control/Status */
+#define UDCCSR_BNE     (1 << 6)        /* Buffer Not Empty (IN endpoints) */
+#define UDCCSR_BNF     (1 << 6)        /* Buffer Not Full (OUT endpoints) */
+#define UDCCSR_FST     (1 << 5)        /* Force STALL */
+#define UDCCSR_SST     (1 << 4)        /* Sent STALL */
+#define UDCCSR_DME     (1 << 3)        /* DMA Enable */
+#define UDCCSR_TRN     (1 << 2)        /* Tx/Rx NAK */
+#define UDCCSR_PC      (1 << 1)        /* Packet Complete */
+#define UDCCSR_FS      (1 << 0)        /* FIFO needs service */
+
+#define UDCCONR_CN     (0x03 << 25)    /* Configuration Number */
+#define UDCCONR_CN_S   25
+#define UDCCONR_IN     (0x07 << 22)    /* Interface Number */
+#define UDCCONR_IN_S   22
+#define UDCCONR_AISN   (0x07 << 19)    /* Alternate Interface Number */
+#define UDCCONR_AISN_S 19
+#define UDCCONR_EN     (0x0f << 15)    /* Endpoint Number */
+#define UDCCONR_EN_S   15
+#define UDCCONR_ET     (0x03 << 13)    /* Endpoint Type: */
+#define UDCCONR_ET_S   13
+#define UDCCONR_ET_INT (0x03 << 13)    /*   Interrupt */
+#define UDCCONR_ET_BULK        (0x02 << 13)    /*   Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13)    /*   Isochronous */
+#define UDCCONR_ET_NU  (0x00 << 13)    /*   Not used */
+#define UDCCONR_ED     (1 << 12)       /* Endpoint Direction */
+#define UDCCONR_MPS    (0x3ff << 2)    /* Maximum Packet Size */
+#define UDCCONR_MPS_S  2
+#define UDCCONR_DE     (1 << 1)        /* Double Buffering Enable */
+#define UDCCONR_EE     (1 << 0)        /* Endpoint Enable */
+
+#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_SMAC | UDCCR_UDR | UDCCR_UDE)
+#define UDCCSR_WR_MASK (UDCCSR_DME | UDCCSR_FST)
+#define UDC_FNR_MASK   (0x7ff)
+#define UDC_BCR_MASK   (0x3ff)
+
+/*
+ * UDCCR = UDC Endpoint Configuration Registers
+ * UDCCSR = UDC Control/Status Register for this EP
+ * UDCBCR = UDC Byte Count Remaining (contents of OUT fifo)
+ * UDCDR = UDC Endpoint Data Register (the fifo)
+ */
+#define ofs_UDCCR(ep)  (UDCCRn(ep->idx))
+#define ofs_UDCCSR(ep) (UDCCSRn(ep->idx))
+#define ofs_UDCBCR(ep) (UDCBCRn(ep->idx))
+#define ofs_UDCDR(ep)  (UDCDRn(ep->idx))
+
+/* Register access macros */
+#define udc_ep_readl(ep, reg)  \
+       __raw_readl((ep)->dev->regs + ofs_##reg(ep))
+#define udc_ep_writel(ep, reg, value)  \
+       __raw_writel((value), ep->dev->regs + ofs_##reg(ep))
+#define udc_ep_readb(ep, reg)  \
+       __raw_readb((ep)->dev->regs + ofs_##reg(ep))
+#define udc_ep_writeb(ep, reg, value)  \
+       __raw_writeb((value), ep->dev->regs + ofs_##reg(ep))
+#define udc_readl(dev, reg)    \
+       __raw_readl((dev)->regs + (reg))
+#define udc_writel(udc, reg, value)    \
+       __raw_writel((value), (udc)->regs + (reg))
+
+#define UDCCSR_MASK            (UDCCSR_FST | UDCCSR_DME)
+#define UDCCISR0_EP_MASK       ~0
+#define UDCCISR1_EP_MASK       0xffff
+#define UDCCSR0_CTRL_REQ_MASK  (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE)
+
+#define EPIDX(ep)      (ep->idx)
+#define EPADDR(ep)     (ep->addr)
+#define EPXFERTYPE(ep) (ep->type)
+#define EPNAME(ep)     (ep->name)
+#define is_ep0(ep)     (!ep->idx)
+#define EPXFERTYPE_is_ISO(ep) (EPXFERTYPE(ep) == USB_ENDPOINT_XFER_ISOC)
+
+/*
+ * Endpoint definitions
+ *
+ * Once enabled, pxa endpoint configuration is freezed, and cannot change
+ * unless a reset happens or the udc is disabled.
+ * Therefore, we must define all pxa potential endpoint definitions needed for
+ * all gadget and set them up before the udc is enabled.
+ *
+ * As the architecture chosen is fully static, meaning the pxa endpoint
+ * configurations are set up once and for all, we must provide a way to match
+ * one usb endpoint (usb_ep) to several pxa endpoints. The reason is that gadget
+ * layer autoconf doesn't choose the usb_ep endpoint on (config, interface, alt)
+ * criteria, while the pxa architecture requires that.
+ *
+ * The solution is to define several pxa endpoints matching one usb_ep. Ex:
+ *   - "ep1-in" matches pxa endpoint EPA (which is an IN ep at addr 1, when
+ *     the udc talks on (config=3, interface=0, alt=0)
+ *   - "ep1-in" matches pxa endpoint EPB (which is an IN ep at addr 1, when
+ *     the udc talks on (config=3, interface=0, alt=1)
+ *   - "ep1-in" matches pxa endpoint EPC (which is an IN ep at addr 1, when
+ *     the udc talks on (config=2, interface=0, alt=0)
+ *
+ * We'll define the pxa endpoint by its index (EPA => idx=1, EPB => idx=2, ...)
+ */
+
+/*
+ * Endpoint definition helpers
+ */
+#define USB_EP_DEF(addr, bname, dir, type, maxpkt) \
+{ .usb_ep = { .name = bname, .ops = &pxa_ep_ops, .maxpacket = maxpkt, }, \
+  .desc = {    .bEndpointAddress = addr | (dir ? USB_DIR_IN : 0), \
+               .bmAttributes = type, \
+               .wMaxPacketSize = maxpkt, }, \
+  .dev = &memory \
+}
+#define USB_EP_BULK(addr, bname, dir) \
+  USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE)
+#define USB_EP_ISO(addr, bname, dir) \
+  USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE)
+#define USB_EP_INT(addr, bname, dir) \
+  USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE)
+#define USB_EP_IN_BULK(n)      USB_EP_BULK(n, "ep" #n "in-bulk", 1)
+#define USB_EP_OUT_BULK(n)     USB_EP_BULK(n, "ep" #n "out-bulk", 0)
+#define USB_EP_IN_ISO(n)       USB_EP_ISO(n,  "ep" #n "in-iso", 1)
+#define USB_EP_OUT_ISO(n)      USB_EP_ISO(n,  "ep" #n "out-iso", 0)
+#define USB_EP_IN_INT(n)       USB_EP_INT(n,  "ep" #n "in-int", 1)
+#define USB_EP_CTRL            USB_EP_DEF(0,  "ep0", 0, 0, EP0_FIFO_SIZE)
+
+#define PXA_EP_DEF(_idx, _addr, dir, _type, maxpkt, _config, iface, altset) \
+{ \
+       .dev = &memory, \
+       .name = "ep" #_idx, \
+       .idx = _idx, .enabled = 0, \
+       .dir_in = dir, .addr = _addr, \
+       .config = _config, .interface = iface, .alternate = altset, \
+       .type = _type, .fifo_size = maxpkt, \
+}
+#define PXA_EP_BULK(_idx, addr, dir, config, iface, alt) \
+  PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE, \
+               config, iface, alt)
+#define PXA_EP_ISO(_idx, addr, dir, config, iface, alt) \
+  PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE, \
+               config, iface, alt)
+#define PXA_EP_INT(_idx, addr, dir, config, iface, alt) \
+  PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE, \
+               config, iface, alt)
+#define PXA_EP_IN_BULK(i, adr, c, f, a)                PXA_EP_BULK(i, adr, 1, c, f, a)
+#define PXA_EP_OUT_BULK(i, adr, c, f, a)       PXA_EP_BULK(i, adr, 0, c, f, a)
+#define PXA_EP_IN_ISO(i, adr, c, f, a)         PXA_EP_ISO(i, adr, 1, c, f, a)
+#define PXA_EP_OUT_ISO(i, adr, c, f, a)                PXA_EP_ISO(i, adr, 0, c, f, a)
+#define PXA_EP_IN_INT(i, adr, c, f, a)         PXA_EP_INT(i, adr, 1, c, f, a)
+#define PXA_EP_CTRL    PXA_EP_DEF(0, 0, 0, 0, EP0_FIFO_SIZE, 0, 0, 0)
+
+struct pxa27x_udc;
+
+struct stats {
+       unsigned long in_ops;
+       unsigned long out_ops;
+       unsigned long in_bytes;
+       unsigned long out_bytes;
+       unsigned long irqs;
+};
+
+/**
+ * struct udc_usb_ep - container of each usb_ep structure
+ * @usb_ep: usb endpoint
+ * @desc: usb descriptor, especially type and address
+ * @dev: udc managing this endpoint
+ * @pxa_ep: matching pxa_ep (cache of find_pxa_ep() call)
+ */
+struct udc_usb_ep {
+       struct usb_ep usb_ep;
+       struct usb_endpoint_descriptor desc;
+       struct pxa_udc *dev;
+       struct pxa_ep *pxa_ep;
+};
+
+/**
+ * struct pxa_ep - pxa endpoint
+ * @dev: udc device
+ * @queue: requests queue
+ * @lock: lock to pxa_ep data (queues and stats)
+ * @enabled: true when endpoint enabled (not stopped by gadget layer)
+ * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX)
+ * @name: endpoint name (for trace/debug purpose)
+ * @dir_in: 1 if IN endpoint, 0 if OUT endpoint
+ * @addr: usb endpoint number
+ * @config: configuration in which this endpoint is active
+ * @interface: interface in which this endpoint is active
+ * @alternate: altsetting in which this endpoitn is active
+ * @fifo_size: max packet size in the endpoint fifo
+ * @type: endpoint type (bulk, iso, int, ...)
+ * @udccsr_value: save register of UDCCSR0 for suspend/resume
+ * @udccr_value: save register of UDCCR for suspend/resume
+ * @stats: endpoint statistics
+ *
+ * The *PROBLEM* is that pxa's endpoint configuration scheme is both misdesigned
+ * (cares about config/interface/altsetting, thus placing needless limits on
+ * device capability) and full of implementation bugs forcing it to be set up
+ * for use more or less like a pxa255.
+ *
+ * As we define the pxa_ep statically, we must guess all needed pxa_ep for all
+ * gadget which may work with this udc driver.
+ */
+struct pxa_ep {
+       struct pxa_udc          *dev;
+
+       struct list_head        queue;
+       spinlock_t              lock;           /* Protects this structure */
+                                               /* (queues, stats) */
+       unsigned                enabled:1;
+
+       unsigned                idx:5;
+       char                    *name;
+
+       /*
+        * Specific pxa endpoint data, needed for hardware initialization
+        */
+       unsigned                dir_in:1;
+       unsigned                addr:3;
+       unsigned                config:2;
+       unsigned                interface:3;
+       unsigned                alternate:3;
+       unsigned                fifo_size;
+       unsigned                type;
+
+#ifdef CONFIG_PM
+       u32                     udccsr_value;
+       u32                     udccr_value;
+#endif
+       struct stats            stats;
+};
+
+/**
+ * struct pxa27x_request - container of each usb_request structure
+ * @req: usb request
+ * @udc_usb_ep: usb endpoint the request was submitted on
+ * @in_use: sanity check if request already queued on an pxa_ep
+ * @queue: linked list of requests, linked on pxa_ep->queue
+ */
+struct pxa27x_request {
+       struct usb_request                      req;
+       struct udc_usb_ep                       *udc_usb_ep;
+       unsigned                                in_use:1;
+       struct list_head                        queue;
+};
+
+enum ep0_state {
+       WAIT_FOR_SETUP,
+       SETUP_STAGE,
+       IN_DATA_STAGE,
+       OUT_DATA_STAGE,
+       IN_STATUS_STAGE,
+       OUT_STATUS_STAGE,
+       STALL,
+       WAIT_ACK_SET_CONF_INTERF
+};
+
+static char *ep0_state_name[] = {
+       "WAIT_FOR_SETUP", "SETUP_STAGE", "IN_DATA_STAGE", "OUT_DATA_STAGE",
+       "IN_STATUS_STAGE", "OUT_STATUS_STAGE", "STALL",
+       "WAIT_ACK_SET_CONF_INTERF"
+};
+#define EP0_STNAME(udc) ep0_state_name[(udc)->ep0state]
+
+#define EP0_FIFO_SIZE  16U
+#define BULK_FIFO_SIZE 64U
+#define ISO_FIFO_SIZE  256U
+#define INT_FIFO_SIZE  16U
+
+struct udc_stats {
+       unsigned long   irqs_reset;
+       unsigned long   irqs_suspend;
+       unsigned long   irqs_resume;
+       unsigned long   irqs_reconfig;
+};
+
+#define NR_USB_ENDPOINTS (1 + 5)       /* ep0 + ep1in-bulk + .. + ep3in-iso */
+#define NR_PXA_ENDPOINTS (1 + 14)      /* ep0 + epA + epB + .. + epX */
+
+/**
+ * struct pxa_udc - udc structure
+ * @regs: mapped IO space
+ * @irq: udc irq
+ * @clk: udc clock
+ * @usb_gadget: udc gadget structure
+ * @driver: bound gadget (zero, g_ether, g_file_storage, ...)
+ * @dev: device
+ * @mach: machine info, used to activate specific GPIO
+ * @ep0state: control endpoint state machine state
+ * @stats: statistics on udc usage
+ * @udc_usb_ep: array of usb endpoints offered by the gadget
+ * @pxa_ep: array of pxa available endpoints
+ * @config: UDC active configuration
+ * @last_interface: UDC interface of the last SET_INTERFACE host request
+ * @last_alternate: UDC altsetting of the last SET_INTERFACE host request
+ * @udccsr0: save of udccsr0 in case of suspend
+ * @debugfs_root: root entry of debug filesystem
+ * @debugfs_state: debugfs entry for "udcstate"
+ * @debugfs_queues: debugfs entry for "queues"
+ * @debugfs_eps: debugfs entry for "epstate"
+ */
+struct pxa_udc {
+       void __iomem                            *regs;
+       int                                     irq;
+       struct clk                              *clk;
+
+       struct usb_gadget                       gadget;
+       struct usb_gadget_driver                *driver;
+       struct device                           *dev;
+       struct pxa2xx_udc_mach_info             *mach;
+
+       enum ep0_state                          ep0state;
+       struct udc_stats                        stats;
+
+       struct udc_usb_ep                       udc_usb_ep[NR_USB_ENDPOINTS];
+       struct pxa_ep                           pxa_ep[NR_PXA_ENDPOINTS];
+
+       unsigned                                config:2;
+       unsigned                                last_interface:3;
+       unsigned                                last_alternate:3;
+
+#ifdef CONFIG_PM
+       unsigned                                udccsr0;
+#endif
+#ifdef CONFIG_USB_GADGET_DEBUG_FS
+       struct dentry                           *debugfs_root;
+       struct dentry                           *debugfs_state;
+       struct dentry                           *debugfs_queues;
+       struct dentry                           *debugfs_eps;
+#endif
+};
+
+static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget)
+{
+       return container_of(gadget, struct pxa_udc, gadget);
+}
+
+/*
+ * Debugging/message support
+ */
+#define ep_dbg(ep, fmt, arg...) \
+       dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_vdbg(ep, fmt, arg...) \
+       dev_vdbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_err(ep, fmt, arg...) \
+       dev_err(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_info(ep, fmt, arg...) \
+       dev_info(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_warn(ep, fmt, arg...) \
+       dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg)
+
+#endif /* __LINUX_USB_GADGET_PXA27X_H */
index 8d158e5640e37782ea0dbed21c08277092a2614e..54cdd6f940346732fe38379ad75cd542a66e5709 100644 (file)
@@ -135,7 +135,10 @@ struct gs_port {
        int                     port_in_use;    /* open/close in progress */
        wait_queue_head_t       port_write_wait;/* waiting to write */
        struct gs_buf           *port_write_buf;
-       struct usb_cdc_line_coding      port_line_coding;
+       struct usb_cdc_line_coding port_line_coding;    /* 8-N-1 etc */
+       u16                     port_handshake_bits;
+#define RS232_RTS      (1 << 1)
+#define RS232_DTE      (1 << 0)
 };
 
 /* the device structure holds info for the USB device */
@@ -199,6 +202,8 @@ static int gs_setup_standard(struct usb_gadget *gadget,
 static int gs_setup_class(struct usb_gadget *gadget,
        const struct usb_ctrlrequest *ctrl);
 static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req);
+static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
+       struct usb_request *req);
 static void gs_disconnect(struct usb_gadget *gadget);
 static int gs_set_config(struct gs_dev *dev, unsigned config);
 static void gs_reset_config(struct gs_dev *dev);
@@ -406,7 +411,7 @@ static struct usb_cdc_acm_descriptor gs_acm_descriptor = {
        .bLength =              sizeof(gs_acm_descriptor),
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_ACM_TYPE,
-       .bmCapabilities =       0,
+       .bmCapabilities =       (1 << 1),
 };
 
 static const struct usb_cdc_union_desc gs_union_desc = {
@@ -1502,6 +1507,8 @@ static int gs_setup(struct usb_gadget *gadget,
        u16 wValue = le16_to_cpu(ctrl->wValue);
        u16 wLength = le16_to_cpu(ctrl->wLength);
 
+       req->complete = gs_setup_complete;
+
        switch (ctrl->bRequestType & USB_TYPE_MASK) {
        case USB_TYPE_STANDARD:
                ret = gs_setup_standard(gadget,ctrl);
@@ -1679,18 +1686,14 @@ static int gs_setup_class(struct usb_gadget *gadget,
 
        switch (ctrl->bRequest) {
        case USB_CDC_REQ_SET_LINE_CODING:
-               /* FIXME Submit req to read the data; have its completion
-                * handler copy that data to port->port_line_coding (iff
-                * it's valid) and maybe pass it on.  Until then, fail.
-                */
-               pr_warning("gs_setup: set_line_coding "
-                               "unuspported\n");
+               if (wLength != sizeof(struct usb_cdc_line_coding))
+                       break;
+               ret = wLength;
+               req->complete = gs_setup_complete_set_line_coding;
                break;
 
        case USB_CDC_REQ_GET_LINE_CODING:
-               port = dev->dev_port[0];        /* ACM only has one port */
-               ret = min(wLength,
-                       (u16)sizeof(struct usb_cdc_line_coding));
+               ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding));
                if (port) {
                        spin_lock(&port->port_lock);
                        memcpy(req->buf, &port->port_line_coding, ret);
@@ -1699,15 +1702,27 @@ static int gs_setup_class(struct usb_gadget *gadget,
                break;
 
        case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
-               /* FIXME Submit req to read the data; have its completion
-                * handler use that to set the state (iff it's valid) and
-                * maybe pass it on.  Until then, fail.
-                */
-               pr_warning("gs_setup: set_control_line_state "
-                               "unuspported\n");
+               if (wLength != 0)
+                       break;
+               ret = 0;
+               if (port) {
+                       /* REVISIT:  we currently just remember this data.
+                        * If we change that, update whatever hardware needs
+                        * updating.
+                        */
+                       spin_lock(&port->port_lock);
+                       port->port_handshake_bits = wValue;
+                       spin_unlock(&port->port_lock);
+               }
                break;
 
        default:
+               /* NOTE:  strictly speaking, we should accept AT-commands
+                * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE.
+                * But our call management descriptor says we don't handle
+                * call management, so we should be able to get by without
+                * handling those "required" commands (except by stalling).
+                */
                pr_err("gs_setup: unknown class request, "
                                "type=%02x, request=%02x, value=%04x, "
                                "index=%04x, length=%d\n",
@@ -1719,6 +1734,42 @@ static int gs_setup_class(struct usb_gadget *gadget,
        return ret;
 }
 
+static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
+               struct usb_request *req)
+{
+       struct gs_dev *dev = ep->driver_data;
+       struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
+
+       switch (req->status) {
+       case 0:
+               /* normal completion */
+               if (req->actual != sizeof(port->port_line_coding))
+                       usb_ep_set_halt(ep);
+               else if (port) {
+                       struct usb_cdc_line_coding      *value = req->buf;
+
+                       /* REVISIT:  we currently just remember this data.
+                        * If we change that, (a) validate it first, then
+                        * (b) update whatever hardware needs updating.
+                        */
+                       spin_lock(&port->port_lock);
+                       port->port_line_coding = *value;
+                       spin_unlock(&port->port_lock);
+               }
+               break;
+
+       case -ESHUTDOWN:
+               /* disconnect */
+               gs_free_req(ep, req);
+               break;
+
+       default:
+               /* unexpected */
+               break;
+       }
+       return;
+}
+
 /*
  * gs_setup_complete
  */
@@ -1906,6 +1957,11 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
                }
        }
 
+       /* REVISIT the ACM mode should be able to actually *issue* some
+        * notifications, for at least serial state change events if
+        * not also for network connection; say so in bmCapabilities.
+        */
+
        pr_info("gs_set_config: %s configured, %s speed %s config\n",
                GS_LONG_NAME,
                gadget->speed == USB_SPEED_HIGH ? "high" : "full",
index d3d4f4048e6c39f7f958e263cf1761d194c25d34..fce4924dbbe88b6c49dbea3fe33221e224aece05 100644 (file)
@@ -23,9 +23,7 @@
 /*
  * Gadget Zero only needs two bulk endpoints, and is an example of how you
  * can write a hardware-agnostic gadget driver running inside a USB device.
- *
- * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't
- * affect most of the driver.
+ * Some hardware details are visible, but don't affect most of the driver.
  *
  * Use it with the Linux host/master side "usbtest" driver to get a basic
  * functional test of your device-side usb stack, or with "usb-skeleton".
@@ -37,6 +35,7 @@
  *   buflen=N          default N=4096, buffer size used
  *   qlen=N            default N=32, how many buffers in the loopback queue
  *   loopdefault       default false, list loopback config first
+ *   autoresume=N      default N=0, seconds before triggering remote wakeup
  *
  * Many drivers will only have one configuration, letting them be much
  * simpler if they also don't support high speed operation (like this
 
 /*-------------------------------------------------------------------------*/
 
-#define DRIVER_VERSION         "Lughnasadh, 2007"
+#define DRIVER_VERSION         "Earth Day 2008"
 
-static const char shortname [] = "zero";
-static const char longname [] = "Gadget Zero";
+static const char shortname[] = "zero";
+static const char longname[] = "Gadget Zero";
 
-static const char source_sink [] = "source and sink data";
-static const char loopback [] = "loop input to output";
+static const char source_sink[] = "source and sink data";
+static const char loopback[] = "loop input to output";
 
 /*-------------------------------------------------------------------------*/
 
@@ -120,16 +119,16 @@ static unsigned buflen = 4096;
 static unsigned qlen = 32;
 static unsigned pattern = 0;
 
-module_param (buflen, uint, S_IRUGO);
-module_param (qlen, uint, S_IRUGO);
-module_param (pattern, uint, S_IRUGO|S_IWUSR);
+module_param(buflen, uint, S_IRUGO);
+module_param(qlen, uint, S_IRUGO);
+module_param(pattern, uint, S_IRUGO|S_IWUSR);
 
 /*
  * if it's nonzero, autoresume says how many seconds to wait
  * before trying to wake up the host after suspend.
  */
 static unsigned autoresume = 0;
-module_param (autoresume, uint, 0);
+module_param(autoresume, uint, 0);
 
 /*
  * Normally the "loopback" configuration is second (index 1) so
@@ -138,8 +137,7 @@ module_param (autoresume, uint, 0);
  * Or controllers (like superh) that only support one config.
  */
 static int loopdefault = 0;
-
-module_param (loopdefault, bool, S_IRUGO|S_IWUSR);
+module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
 
 /*-------------------------------------------------------------------------*/
 
@@ -176,24 +174,22 @@ module_param (loopdefault, bool, S_IRUGO|S_IWUSR);
 #define        CONFIG_SOURCE_SINK      3
 #define        CONFIG_LOOPBACK         2
 
-static struct usb_device_descriptor
-device_desc = {
+static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
-       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
+       .bcdUSB =               __constant_cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_VENDOR_SPEC,
 
-       .idVendor =             __constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
+       .idVendor =             __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
+       .idProduct =            __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
        .iManufacturer =        STRING_MANUFACTURER,
        .iProduct =             STRING_PRODUCT,
        .iSerialNumber =        STRING_SERIAL,
        .bNumConfigurations =   2,
 };
 
-static struct usb_config_descriptor
-source_sink_config = {
+static struct usb_config_descriptor source_sink_config = {
        .bLength =              sizeof source_sink_config,
        .bDescriptorType =      USB_DT_CONFIG,
 
@@ -205,8 +201,7 @@ source_sink_config = {
        .bMaxPower =            1,      /* self-powered */
 };
 
-static struct usb_config_descriptor
-loopback_config = {
+static struct usb_config_descriptor loopback_config = {
        .bLength =              sizeof loopback_config,
        .bDescriptorType =      USB_DT_CONFIG,
 
@@ -218,8 +213,7 @@ loopback_config = {
        .bMaxPower =            1,      /* self-powered */
 };
 
-static struct usb_otg_descriptor
-otg_descriptor = {
+static struct usb_otg_descriptor otg_descriptor = {
        .bLength =              sizeof otg_descriptor,
        .bDescriptorType =      USB_DT_OTG,
 
@@ -228,8 +222,7 @@ otg_descriptor = {
 
 /* one interface in each configuration */
 
-static const struct usb_interface_descriptor
-source_sink_intf = {
+static const struct usb_interface_descriptor source_sink_intf = {
        .bLength =              sizeof source_sink_intf,
        .bDescriptorType =      USB_DT_INTERFACE,
 
@@ -238,8 +231,7 @@ source_sink_intf = {
        .iInterface =           STRING_SOURCE_SINK,
 };
 
-static const struct usb_interface_descriptor
-loopback_intf = {
+static const struct usb_interface_descriptor loopback_intf = {
        .bLength =              sizeof loopback_intf,
        .bDescriptorType =      USB_DT_INTERFACE,
 
@@ -250,8 +242,7 @@ loopback_intf = {
 
 /* two full speed bulk endpoints; their use is config-dependent */
 
-static struct usb_endpoint_descriptor
-fs_source_desc = {
+static struct usb_endpoint_descriptor fs_source_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -259,8 +250,7 @@ fs_source_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static struct usb_endpoint_descriptor
-fs_sink_desc = {
+static struct usb_endpoint_descriptor fs_sink_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
@@ -268,7 +258,7 @@ fs_sink_desc = {
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
 };
 
-static const struct usb_descriptor_header *fs_source_sink_function [] = {
+static const struct usb_descriptor_header *fs_source_sink_function[] = {
        (struct usb_descriptor_header *) &otg_descriptor,
        (struct usb_descriptor_header *) &source_sink_intf,
        (struct usb_descriptor_header *) &fs_sink_desc,
@@ -276,7 +266,7 @@ static const struct usb_descriptor_header *fs_source_sink_function [] = {
        NULL,
 };
 
-static const struct usb_descriptor_header *fs_loopback_function [] = {
+static const struct usb_descriptor_header *fs_loopback_function[] = {
        (struct usb_descriptor_header *) &otg_descriptor,
        (struct usb_descriptor_header *) &loopback_intf,
        (struct usb_descriptor_header *) &fs_sink_desc,
@@ -293,36 +283,33 @@ static const struct usb_descriptor_header *fs_loopback_function [] = {
  * for the config descriptor.
  */
 
-static struct usb_endpoint_descriptor
-hs_source_desc = {
+static struct usb_endpoint_descriptor hs_source_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (512),
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_endpoint_descriptor
-hs_sink_desc = {
+static struct usb_endpoint_descriptor hs_sink_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (512),
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static struct usb_qualifier_descriptor
-dev_qualifier = {
+static struct usb_qualifier_descriptor dev_qualifier = {
        .bLength =              sizeof dev_qualifier,
        .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
 
-       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
+       .bcdUSB =               __constant_cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_VENDOR_SPEC,
 
        .bNumConfigurations =   2,
 };
 
-static const struct usb_descriptor_header *hs_source_sink_function [] = {
+static const struct usb_descriptor_header *hs_source_sink_function[] = {
        (struct usb_descriptor_header *) &otg_descriptor,
        (struct usb_descriptor_header *) &source_sink_intf,
        (struct usb_descriptor_header *) &hs_source_desc,
@@ -330,7 +317,7 @@ static const struct usb_descriptor_header *hs_source_sink_function [] = {
        NULL,
 };
 
-static const struct usb_descriptor_header *hs_loopback_function [] = {
+static const struct usb_descriptor_header *hs_loopback_function[] = {
        (struct usb_descriptor_header *) &otg_descriptor,
        (struct usb_descriptor_header *) &loopback_intf,
        (struct usb_descriptor_header *) &hs_source_desc,
@@ -355,7 +342,7 @@ static char serial[] = "0123456789.0123456789.0123456789";
 
 
 /* static strings, in UTF-8 */
-static struct usb_string               strings [] = {
+static struct usb_string strings[] = {
        { STRING_MANUFACTURER, manufacturer, },
        { STRING_PRODUCT, longname, },
        { STRING_SERIAL, serial, },
@@ -364,7 +351,7 @@ static struct usb_string            strings [] = {
        {  }                    /* end of list */
 };
 
-static struct usb_gadget_strings       stringtab = {
+static struct usb_gadget_strings stringtab = {
        .language       = 0x0409,       /* en-us */
        .strings        = strings,
 };
@@ -387,8 +374,7 @@ static struct usb_gadget_strings    stringtab = {
  * high bandwidth modes at high speed.  (Maybe work like Intel's test
  * device?)
  */
-static int
-config_buf (struct usb_gadget *gadget,
+static int config_buf(struct usb_gadget *gadget,
                u8 *buf, u8 type, unsigned index)
 {
        int                             is_source_sink;
@@ -419,7 +405,7 @@ config_buf (struct usb_gadget *gadget,
        if (!gadget_is_otg(gadget))
                function++;
 
-       len = usb_gadget_config_buf (is_source_sink
+       len = usb_gadget_config_buf(is_source_sink
                                        ? &source_sink_config
                                        : &loopback_config,
                        buf, USB_BUFSIZ, function);
@@ -431,27 +417,26 @@ config_buf (struct usb_gadget *gadget,
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_request *
-alloc_ep_req (struct usb_ep *ep, unsigned length)
+static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
 {
        struct usb_request      *req;
 
-       req = usb_ep_alloc_request (ep, GFP_ATOMIC);
+       req = usb_ep_alloc_request(ep, GFP_ATOMIC);
        if (req) {
                req->length = length;
                req->buf = kmalloc(length, GFP_ATOMIC);
                if (!req->buf) {
-                       usb_ep_free_request (ep, req);
+                       usb_ep_free_request(ep, req);
                        req = NULL;
                }
        }
        return req;
 }
 
-static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
+static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
 {
        kfree(req->buf);
-       usb_ep_free_request (ep, req);
+       usb_ep_free_request(ep, req);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -472,7 +457,7 @@ static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
 /* optionally require specific source/sink data patterns  */
 
 static int
-check_read_data (
+check_read_data(
        struct zero_dev         *dev,
        struct usb_ep           *ep,
        struct usb_request      *req
@@ -498,8 +483,8 @@ check_read_data (
                                continue;
                        break;
                }
-               ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);
-               usb_ep_set_halt (ep);
+               ERROR(dev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
+               usb_ep_set_halt(ep);
                return -EINVAL;
        }
        return 0;
@@ -512,7 +497,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
 
        switch (pattern) {
        case 0:
-               memset (req->buf, 0, req->length);
+               memset(req->buf, 0, req->length);
                break;
        case 1:
                for  (i = 0; i < req->length; i++)
@@ -525,7 +510,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
  * irq delay between end of one request and start of the next.
  * that prevents using hardware dma queues.
  */
-static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
+static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
 {
        struct zero_dev *dev = ep->driver_data;
        int             status = req->status;
@@ -534,8 +519,8 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
 
        case 0:                         /* normal completion? */
                if (ep == dev->out_ep) {
-                       check_read_data (dev, ep, req);
-                       memset (req->buf, 0x55, req->length);
+                       check_read_data(dev, ep, req);
+                       memset(req->buf, 0x55, req->length);
                } else
                        reinit_write_data(ep, req);
                break;
@@ -544,11 +529,11 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
        case -ECONNABORTED:             /* hardware forced ep reset */
        case -ECONNRESET:               /* request dequeued */
        case -ESHUTDOWN:                /* disconnect from host */
-               VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
+               VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
                                req->actual, req->length);
                if (ep == dev->out_ep)
-                       check_read_data (dev, ep, req);
-               free_ep_req (ep, req);
+                       check_read_data(dev, ep, req);
+               free_ep_req(ep, req);
                return;
 
        case -EOVERFLOW:                /* buffer overrun on read means that
@@ -557,18 +542,18 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
                                         */
        default:
 #if 1
-               DBG (dev, "%s complete --> %d, %d/%d\n", ep->name,
+               DBG(dev, "%s complete --> %d, %d/%d\n", ep->name,
                                status, req->actual, req->length);
 #endif
        case -EREMOTEIO:                /* short read */
                break;
        }
 
-       status = usb_ep_queue (ep, req, GFP_ATOMIC);
+       status = usb_ep_queue(ep, req, GFP_ATOMIC);
        if (status) {
-               ERROR (dev, "kill %s:  resubmit %d bytes --> %d\n",
+               ERROR(dev, "kill %s:  resubmit %d bytes --> %d\n",
                                ep->name, req->length, status);
-               usb_ep_set_halt (ep);
+               usb_ep_set_halt(ep);
                /* FIXME recover later ... somehow */
        }
 }
@@ -578,24 +563,24 @@ static struct usb_request *source_sink_start_ep(struct usb_ep *ep)
        struct usb_request      *req;
        int                     status;
 
-       req = alloc_ep_req (ep, buflen);
+       req = alloc_ep_req(ep, buflen);
        if (!req)
                return NULL;
 
-       memset (req->buf, 0, req->length);
+       memset(req->buf, 0, req->length);
        req->complete = source_sink_complete;
 
-       if (strcmp (ep->name, EP_IN_NAME) == 0)
+       if (strcmp(ep->name, EP_IN_NAME) == 0)
                reinit_write_data(ep, req);
        else
-               memset (req->buf, 0x55, req->length);
+               memset(req->buf, 0x55, req->length);
 
        status = usb_ep_queue(ep, req, GFP_ATOMIC);
        if (status) {
                struct zero_dev *dev = ep->driver_data;
 
-               ERROR (dev, "start %s --> %d\n", ep->name, status);
-               free_ep_req (ep, req);
+               ERROR(dev, "start %s --> %d\n", ep->name, status);
+               free_ep_req(ep, req);
                req = NULL;
        }
 
@@ -608,34 +593,34 @@ static int set_source_sink_config(struct zero_dev *dev)
        struct usb_ep           *ep;
        struct usb_gadget       *gadget = dev->gadget;
 
-       gadget_for_each_ep (ep, gadget) {
+       gadget_for_each_ep(ep, gadget) {
                const struct usb_endpoint_descriptor    *d;
 
                /* one endpoint writes (sources) zeroes in (to the host) */
-               if (strcmp (ep->name, EP_IN_NAME) == 0) {
-                       d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
-                       result = usb_ep_enable (ep, d);
+               if (strcmp(ep->name, EP_IN_NAME) == 0) {
+                       d = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
+                       result = usb_ep_enable(ep, d);
                        if (result == 0) {
                                ep->driver_data = dev;
                                if (source_sink_start_ep(ep) != NULL) {
                                        dev->in_ep = ep;
                                        continue;
                                }
-                               usb_ep_disable (ep);
+                               usb_ep_disable(ep);
                                result = -EIO;
                        }
 
                /* one endpoint reads (sinks) anything out (from the host) */
-               } else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
-                       d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
-                       result = usb_ep_enable (ep, d);
+               } else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
+                       d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
+                       result = usb_ep_enable(ep, d);
                        if (result == 0) {
                                ep->driver_data = dev;
                                if (source_sink_start_ep(ep) != NULL) {
                                        dev->out_ep = ep;
                                        continue;
                                }
-                               usb_ep_disable (ep);
+                               usb_ep_disable(ep);
                                result = -EIO;
                        }
 
@@ -644,11 +629,11 @@ static int set_source_sink_config(struct zero_dev *dev)
                        continue;
 
                /* stop on error */
-               ERROR (dev, "can't start %s, result %d\n", ep->name, result);
+               ERROR(dev, "can't start %s, result %d\n", ep->name, result);
                break;
        }
        if (result == 0)
-               DBG (dev, "buflen %d\n", buflen);
+               DBG(dev, "buflen %d\n", buflen);
 
        /* caller is responsible for cleanup on error */
        return result;
@@ -656,7 +641,7 @@ static int set_source_sink_config(struct zero_dev *dev)
 
 /*-------------------------------------------------------------------------*/
 
-static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
+static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
 {
        struct zero_dev *dev = ep->driver_data;
        int             status = req->status;
@@ -668,19 +653,19 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
                        /* loop this OUT packet back IN to the host */
                        req->zero = (req->actual < req->length);
                        req->length = req->actual;
-                       status = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC);
+                       status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
                        if (status == 0)
                                return;
 
                        /* "should never get here" */
-                       ERROR (dev, "can't loop %s to %s: %d\n",
+                       ERROR(dev, "can't loop %s to %s: %d\n",
                                ep->name, dev->in_ep->name,
                                status);
                }
 
                /* queue the buffer for some later OUT packet */
                req->length = buflen;
-               status = usb_ep_queue (dev->out_ep, req, GFP_ATOMIC);
+               status = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
                if (status == 0)
                        return;
 
@@ -688,7 +673,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
                /* FALLTHROUGH */
 
        default:
-               ERROR (dev, "%s loop complete --> %d, %d/%d\n", ep->name,
+               ERROR(dev, "%s loop complete --> %d, %d/%d\n", ep->name,
                                status, req->actual, req->length);
                /* FALLTHROUGH */
 
@@ -700,7 +685,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
        case -ECONNABORTED:             /* hardware forced ep reset */
        case -ECONNRESET:               /* request dequeued */
        case -ESHUTDOWN:                /* disconnect from host */
-               free_ep_req (ep, req);
+               free_ep_req(ep, req);
                return;
        }
 }
@@ -711,13 +696,13 @@ static int set_loopback_config(struct zero_dev *dev)
        struct usb_ep           *ep;
        struct usb_gadget       *gadget = dev->gadget;
 
-       gadget_for_each_ep (ep, gadget) {
+       gadget_for_each_ep(ep, gadget) {
                const struct usb_endpoint_descriptor    *d;
 
                /* one endpoint writes data back IN to the host */
-               if (strcmp (ep->name, EP_IN_NAME) == 0) {
-                       d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
-                       result = usb_ep_enable (ep, d);
+               if (strcmp(ep->name, EP_IN_NAME) == 0) {
+                       d = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
+                       result = usb_ep_enable(ep, d);
                        if (result == 0) {
                                ep->driver_data = dev;
                                dev->in_ep = ep;
@@ -725,9 +710,9 @@ static int set_loopback_config(struct zero_dev *dev)
                        }
 
                /* one endpoint just reads OUT packets */
-               } else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
-                       d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
-                       result = usb_ep_enable (ep, d);
+               } else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
+                       d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
+                       result = usb_ep_enable(ep, d);
                        if (result == 0) {
                                ep->driver_data = dev;
                                dev->out_ep = ep;
@@ -739,7 +724,7 @@ static int set_loopback_config(struct zero_dev *dev)
                        continue;
 
                /* stop on error */
-               ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
+               ERROR(dev, "can't enable %s, result %d\n", ep->name, result);
                break;
        }
 
@@ -753,19 +738,19 @@ static int set_loopback_config(struct zero_dev *dev)
 
                ep = dev->out_ep;
                for (i = 0; i < qlen && result == 0; i++) {
-                       req = alloc_ep_req (ep, buflen);
+                       req = alloc_ep_req(ep, buflen);
                        if (req) {
                                req->complete = loopback_complete;
-                               result = usb_ep_queue (ep, req, GFP_ATOMIC);
+                               result = usb_ep_queue(ep, req, GFP_ATOMIC);
                                if (result)
-                                       DBG (dev, "%s queue req --> %d\n",
+                                       DBG(dev, "%s queue req --> %d\n",
                                                        ep->name, result);
                        } else
                                result = -ENOMEM;
                }
        }
        if (result == 0)
-               DBG (dev, "qlen %d, buflen %d\n", qlen, buflen);
+               DBG(dev, "qlen %d, buflen %d\n", qlen, buflen);
 
        /* caller is responsible for cleanup on error */
        return result;
@@ -773,26 +758,26 @@ static int set_loopback_config(struct zero_dev *dev)
 
 /*-------------------------------------------------------------------------*/
 
-static void zero_reset_config (struct zero_dev *dev)
+static void zero_reset_config(struct zero_dev *dev)
 {
        if (dev->config == 0)
                return;
 
-       DBG (dev, "reset config\n");
+       DBG(dev, "reset config\n");
 
        /* just disable endpoints, forcing completion of pending i/o.
         * all our completion handlers free their requests in this case.
         */
        if (dev->in_ep) {
-               usb_ep_disable (dev->in_ep);
+               usb_ep_disable(dev->in_ep);
                dev->in_ep = NULL;
        }
        if (dev->out_ep) {
-               usb_ep_disable (dev->out_ep);
+               usb_ep_disable(dev->out_ep);
                dev->out_ep = NULL;
        }
        dev->config = 0;
-       del_timer (&dev->resume);
+       del_timer(&dev->resume);
 }
 
 /* change our operational config.  this code must agree with the code
@@ -813,12 +798,12 @@ static int zero_set_config(struct zero_dev *dev, unsigned number)
        if (number == dev->config)
                return 0;
 
-       if (gadget_is_sa1100 (gadget) && dev->config) {
+       if (gadget_is_sa1100(gadget) && dev->config) {
                /* tx fifo is full, but we can't clear it...*/
                ERROR(dev, "can't change configurations\n");
                return -ESPIPE;
        }
-       zero_reset_config (dev);
+       zero_reset_config(dev);
 
        switch (number) {
        case CONFIG_SOURCE_SINK:
@@ -837,7 +822,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number)
        if (!result && (!dev->in_ep || !dev->out_ep))
                result = -ENODEV;
        if (result)
-               zero_reset_config (dev);
+               zero_reset_config(dev);
        else {
                char *speed;
 
@@ -849,7 +834,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number)
                }
 
                dev->config = number;
-               INFO (dev, "%s speed config #%d: %s\n", speed, number,
+               INFO(dev, "%s speed config #%d: %s\n", speed, number,
                                (number == CONFIG_SOURCE_SINK)
                                        ? source_sink : loopback);
        }
@@ -858,10 +843,10 @@ static int zero_set_config(struct zero_dev *dev, unsigned number)
 
 /*-------------------------------------------------------------------------*/
 
-static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req)
+static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req)
 {
        if (req->status || req->actual != req->length)
-               DBG ((struct zero_dev *) ep->driver_data,
+               DBG((struct zero_dev *) ep->driver_data,
                                "setup complete --> %d, %d/%d\n",
                                req->status, req->actual, req->length);
 }
@@ -874,9 +859,9 @@ static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req)
  * the work is in config-specific setup.
  */
 static int
-zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 {
-       struct zero_dev         *dev = get_gadget_data (gadget);
+       struct zero_dev         *dev = get_gadget_data(gadget);
        struct usb_request      *req = dev->req;
        int                     value = -EOPNOTSUPP;
        u16                     w_index = le16_to_cpu(ctrl->wIndex);
@@ -895,14 +880,14 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                switch (w_value >> 8) {
 
                case USB_DT_DEVICE:
-                       value = min (w_length, (u16) sizeof device_desc);
-                       memcpy (req->buf, &device_desc, value);
+                       value = min(w_length, (u16) sizeof device_desc);
+                       memcpy(req->buf, &device_desc, value);
                        break;
                case USB_DT_DEVICE_QUALIFIER:
                        if (!gadget_is_dualspeed(gadget))
                                break;
-                       value = min (w_length, (u16) sizeof dev_qualifier);
-                       memcpy (req->buf, &dev_qualifier, value);
+                       value = min(w_length, (u16) sizeof dev_qualifier);
+                       memcpy(req->buf, &dev_qualifier, value);
                        break;
 
                case USB_DT_OTHER_SPEED_CONFIG:
@@ -910,11 +895,11 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                                break;
                        // FALLTHROUGH
                case USB_DT_CONFIG:
-                       value = config_buf (gadget, req->buf,
+                       value = config_buf(gadget, req->buf,
                                        w_value >> 8,
                                        w_value & 0xff);
                        if (value >= 0)
-                               value = min (w_length, (u16) value);
+                               value = min(w_length, (u16) value);
                        break;
 
                case USB_DT_STRING:
@@ -923,10 +908,10 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                         * add string tables for other languages, using
                         * any UTF-8 characters
                         */
-                       value = usb_gadget_get_string (&stringtab,
+                       value = usb_gadget_get_string(&stringtab,
                                        w_value & 0xff, req->buf);
                        if (value >= 0)
-                               value = min (w_length, (u16) value);
+                               value = min(w_length, (u16) value);
                        break;
                }
                break;
@@ -936,20 +921,20 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                if (ctrl->bRequestType != 0)
                        goto unknown;
                if (gadget->a_hnp_support)
-                       DBG (dev, "HNP available\n");
+                       DBG(dev, "HNP available\n");
                else if (gadget->a_alt_hnp_support)
-                       DBG (dev, "HNP needs a different root port\n");
+                       DBG(dev, "HNP needs a different root port\n");
                else
-                       VDBG (dev, "HNP inactive\n");
-               spin_lock (&dev->lock);
+                       VDBG(dev, "HNP inactive\n");
+               spin_lock(&dev->lock);
                value = zero_set_config(dev, w_value);
-               spin_unlock (&dev->lock);
+               spin_unlock(&dev->lock);
                break;
        case USB_REQ_GET_CONFIGURATION:
                if (ctrl->bRequestType != USB_DIR_IN)
                        goto unknown;
                *(u8 *)req->buf = dev->config;
-               value = min (w_length, (u16) 1);
+               value = min(w_length, (u16) 1);
                break;
 
        /* until we add altsetting support, or other interfaces,
@@ -959,7 +944,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
        case USB_REQ_SET_INTERFACE:
                if (ctrl->bRequestType != USB_RECIP_INTERFACE)
                        goto unknown;
-               spin_lock (&dev->lock);
+               spin_lock(&dev->lock);
                if (dev->config && w_index == 0 && w_value == 0) {
                        u8              config = dev->config;
 
@@ -970,11 +955,11 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                         * if we had more than one interface we couldn't
                         * use this "reset the config" shortcut.
                         */
-                       zero_reset_config (dev);
+                       zero_reset_config(dev);
                        zero_set_config(dev, config);
                        value = 0;
                }
-               spin_unlock (&dev->lock);
+               spin_unlock(&dev->lock);
                break;
        case USB_REQ_GET_INTERFACE:
                if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
@@ -986,7 +971,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                        break;
                }
                *(u8 *)req->buf = 0;
-               value = min (w_length, (u16) 1);
+               value = min(w_length, (u16) 1);
                break;
 
        /*
@@ -1018,7 +1003,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 
        default:
 unknown:
-               VDBG (dev,
+               VDBG(dev,
                        "unknown control req%02x.%02x v%04x i%04x l%d\n",
                        ctrl->bRequestType, ctrl->bRequest,
                        w_value, w_index, w_length);
@@ -1028,11 +1013,11 @@ unknown:
        if (value >= 0) {
                req->length = value;
                req->zero = value < w_length;
-               value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
+               value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
                if (value < 0) {
-                       DBG (dev, "ep_queue --> %d\n", value);
+                       DBG(dev, "ep_queue --> %d\n", value);
                        req->status = 0;
-                       zero_setup_complete (gadget->ep0, req);
+                       zero_setup_complete(gadget->ep0, req);
                }
        }
 
@@ -1040,28 +1025,26 @@ unknown:
        return value;
 }
 
-static void
-zero_disconnect (struct usb_gadget *gadget)
+static void zero_disconnect(struct usb_gadget *gadget)
 {
-       struct zero_dev         *dev = get_gadget_data (gadget);
+       struct zero_dev         *dev = get_gadget_data(gadget);
        unsigned long           flags;
 
-       spin_lock_irqsave (&dev->lock, flags);
-       zero_reset_config (dev);
+       spin_lock_irqsave(&dev->lock, flags);
+       zero_reset_config(dev);
 
        /* a more significant application might have some non-usb
         * activities to quiesce here, saving resources like power
         * or pushing the notification up a network stack.
         */
-       spin_unlock_irqrestore (&dev->lock, flags);
+       spin_unlock_irqrestore(&dev->lock, flags);
 
        /* next we may get setup() calls to enumerate new connections;
         * or an unbind() during shutdown (including removing module).
         */
 }
 
-static void
-zero_autoresume (unsigned long _dev)
+static void zero_autoresume(unsigned long _dev)
 {
        struct zero_dev *dev = (struct zero_dev *) _dev;
        int             status;
@@ -1070,32 +1053,30 @@ zero_autoresume (unsigned long _dev)
         * more significant than just a timer firing...
         */
        if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
-               status = usb_gadget_wakeup (dev->gadget);
-               DBG (dev, "wakeup --> %d\n", status);
+               status = usb_gadget_wakeup(dev->gadget);
+               DBG(dev, "wakeup --> %d\n", status);
        }
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void /* __init_or_exit */
-zero_unbind (struct usb_gadget *gadget)
+static void zero_unbind(struct usb_gadget *gadget)
 {
-       struct zero_dev         *dev = get_gadget_data (gadget);
+       struct zero_dev         *dev = get_gadget_data(gadget);
 
-       DBG (dev, "unbind\n");
+       DBG(dev, "unbind\n");
 
        /* we've already been disconnected ... no i/o is active */
        if (dev->req) {
                dev->req->length = USB_BUFSIZ;
-               free_ep_req (gadget->ep0, dev->req);
+               free_ep_req(gadget->ep0, dev->req);
        }
-       del_timer_sync (&dev->resume);
-       kfree (dev);
-       set_gadget_data (gadget, NULL);
+       del_timer_sync(&dev->resume);
+       kfree(dev);
+       set_gadget_data(gadget, NULL);
 }
 
-static int __init
-zero_bind (struct usb_gadget *gadget)
+static int __init zero_bind(struct usb_gadget *gadget)
 {
        struct zero_dev         *dev;
        struct usb_ep           *ep;
@@ -1111,8 +1092,8 @@ zero_bind (struct usb_gadget *gadget)
         * autoconfigure on any sane usb controller driver,
         * but there may also be important quirks to address.
         */
-       usb_ep_autoconfig_reset (gadget);
-       ep = usb_ep_autoconfig (gadget, &fs_source_desc);
+       usb_ep_autoconfig_reset(gadget);
+       ep = usb_ep_autoconfig(gadget, &fs_source_desc);
        if (!ep) {
 autoconf_fail:
                pr_err("%s: can't autoconfigure on %s\n",
@@ -1122,15 +1103,15 @@ autoconf_fail:
        EP_IN_NAME = ep->name;
        ep->driver_data = ep;   /* claim */
 
-       ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
+       ep = usb_ep_autoconfig(gadget, &fs_sink_desc);
        if (!ep)
                goto autoconf_fail;
        EP_OUT_NAME = ep->name;
        ep->driver_data = ep;   /* claim */
 
-       gcnum = usb_gadget_controller_number (gadget);
+       gcnum = usb_gadget_controller_number(gadget);
        if (gcnum >= 0)
-               device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+               device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
        else {
                /* gadget zero is so simple (for now, no altsettings) that
                 * it SHOULD NOT have problems with bulk-capable hardware.
@@ -1141,7 +1122,7 @@ autoconf_fail:
                 */
                pr_warning("%s: controller '%s' not recognized\n",
                        shortname, gadget->name);
-               device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999);
+               device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
        }
 
 
@@ -1149,12 +1130,16 @@ autoconf_fail:
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev)
                return -ENOMEM;
-       spin_lock_init (&dev->lock);
+       spin_lock_init(&dev->lock);
        dev->gadget = gadget;
-       set_gadget_data (gadget, dev);
+       set_gadget_data(gadget, dev);
+
+       init_timer(&dev->resume);
+       dev->resume.function = zero_autoresume;
+       dev->resume.data = (unsigned long) dev;
 
        /* preallocate control response and buffer */
-       dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
+       dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
        if (!dev->req)
                goto enomem;
        dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
@@ -1182,11 +1167,8 @@ autoconf_fail:
                loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       usb_gadget_set_selfpowered (gadget);
+       usb_gadget_set_selfpowered(gadget);
 
-       init_timer (&dev->resume);
-       dev->resume.function = zero_autoresume;
-       dev->resume.data = (unsigned long) dev;
        if (autoresume) {
                source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
                loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
@@ -1194,45 +1176,43 @@ autoconf_fail:
 
        gadget->ep0->driver_data = dev;
 
-       INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname);
-       INFO (dev, "using %s, OUT %s IN %s\n", gadget->name,
+       INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
+       INFO(dev, "using %s, OUT %s IN %s\n", gadget->name,
                EP_OUT_NAME, EP_IN_NAME);
 
-       snprintf (manufacturer, sizeof manufacturer, "%s %s with %s",
+       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
                init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        return 0;
 
 enomem:
-       zero_unbind (gadget);
+       zero_unbind(gadget);
        return -ENOMEM;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void
-zero_suspend (struct usb_gadget *gadget)
+static void zero_suspend(struct usb_gadget *gadget)
 {
-       struct zero_dev         *dev = get_gadget_data (gadget);
+       struct zero_dev         *dev = get_gadget_data(gadget);
 
        if (gadget->speed == USB_SPEED_UNKNOWN)
                return;
 
        if (autoresume) {
-               mod_timer (&dev->resume, jiffies + (HZ * autoresume));
-               DBG (dev, "suspend, wakeup in %d seconds\n", autoresume);
+               mod_timer(&dev->resume, jiffies + (HZ * autoresume));
+               DBG(dev, "suspend, wakeup in %d seconds\n", autoresume);
        } else
-               DBG (dev, "suspend\n");
+               DBG(dev, "suspend\n");
 }
 
-static void
-zero_resume (struct usb_gadget *gadget)
+static void zero_resume(struct usb_gadget *gadget)
 {
-       struct zero_dev         *dev = get_gadget_data (gadget);
+       struct zero_dev         *dev = get_gadget_data(gadget);
 
-       DBG (dev, "resume\n");
-       del_timer (&dev->resume);
+       DBG(dev, "resume\n");
+       del_timer(&dev->resume);
 }
 
 
@@ -1264,15 +1244,15 @@ MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
 
 
-static int __init init (void)
+static int __init init(void)
 {
-       return usb_gadget_register_driver (&zero_driver);
+       return usb_gadget_register_driver(&zero_driver);
 }
-module_init (init);
+module_init(init);
 
-static void __exit cleanup (void)
+static void __exit cleanup(void)
 {
-       usb_gadget_unregister_driver (&zero_driver);
+       usb_gadget_unregister_driver(&zero_driver);
 }
-module_exit (cleanup);
+module_exit(cleanup);
 
index 0b87480dd713af0671575ce9cd055b00350ad384..1ef6df395e0c83954351fa2dcec9d260a6c97a52 100644 (file)
@@ -4,6 +4,19 @@
 comment "USB Host Controller Drivers"
        depends on USB
 
+config USB_C67X00_HCD
+       tristate "Cypress C67x00 HCD support"
+       depends on USB
+       help
+         The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role
+         host/peripheral/OTG USB controllers.
+
+         Enable this option to support this chip in host controller mode.
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called c67x00.
+
 config USB_EHCI_HCD
        tristate "EHCI HCD (USB 2.0) support"
        depends on USB && USB_ARCH_HAS_EHCI
@@ -95,6 +108,32 @@ config USB_ISP116X_HCD
          To compile this driver as a module, choose M here: the
          module will be called isp116x-hcd.
 
+config USB_ISP1760_HCD
+       tristate "ISP 1760 HCD support"
+       depends on USB && EXPERIMENTAL
+       ---help---
+         The ISP1760 chip is a USB 2.0 host controller.
+
+         This driver does not support isochronous transfers or OTG.
+
+         To compile this driver as a module, choose M here: the
+         module will be called isp1760-hcd.
+
+config USB_ISP1760_PCI
+       bool "Support for the PCI bus"
+       depends on USB_ISP1760_HCD && PCI
+       ---help---
+         Enables support for the device present on the PCI bus.
+         This should only be required if you happen to have the eval kit from
+         NXP and you are going to test it.
+
+config USB_ISP1760_OF
+       bool "Support for the OF platform bus"
+       depends on USB_ISP1760_HCD && PPC_OF
+       ---help---
+         Enables support for the device present on the PowerPC
+         OpenFirmware platform bus.
+
 config USB_OHCI_HCD
        tristate "OHCI HCD support"
        depends on USB && USB_ARCH_HAS_OHCI
index bb8e9d44f371243c91097cae75ac3c5b931a757d..f1edda2dcfdecdaf49f91f775ad8d11a981d110a 100644 (file)
@@ -6,6 +6,8 @@ ifeq ($(CONFIG_USB_DEBUG),y)
        EXTRA_CFLAGS            += -DDEBUG
 endif
 
+isp1760-objs := isp1760-hcd.o isp1760-if.o
+
 obj-$(CONFIG_PCI)              += pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
@@ -16,4 +18,4 @@ obj-$(CONFIG_USB_SL811_HCD)   += sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)     += sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)     += u132-hcd.o
 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
-
+obj-$(CONFIG_USB_ISP1760_HCD)  += isp1760.o
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
new file mode 100644 (file)
index 0000000..4ba96c1
--- /dev/null
@@ -0,0 +1,2231 @@
+/*
+ * Driver for the NXP ISP1760 chip
+ *
+ * However, the code might contain some bugs. What doesn't work for sure is:
+ * - ISO
+ * - OTG
+ e The interrupt line is configured as active low, level.
+ *
+ * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <asm/unaligned.h>
+
+#include "../core/hcd.h"
+#include "isp1760-hcd.h"
+
+static struct kmem_cache *qtd_cachep;
+static struct kmem_cache *qh_cachep;
+
+struct isp1760_hcd {
+       u32 hcs_params;
+       spinlock_t              lock;
+       struct inter_packet_info atl_ints[32];
+       struct inter_packet_info int_ints[32];
+       struct memory_chunk memory_pool[BLOCKS];
+
+       /* periodic schedule support */
+#define        DEFAULT_I_TDPS          1024
+       unsigned                periodic_size;
+       unsigned                i_thresh;
+       unsigned long           reset_done;
+       unsigned long           next_statechange;
+};
+
+static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
+{
+       return (struct isp1760_hcd *) (hcd->hcd_priv);
+}
+static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv)
+{
+       return container_of((void *) priv, struct usb_hcd, hcd_priv);
+}
+
+/* Section 2.2 Host Controller Capability Registers */
+#define HC_LENGTH(p)           (((p)>>00)&0x00ff)      /* bits 7:0 */
+#define HC_VERSION(p)          (((p)>>16)&0xffff)      /* bits 31:16 */
+#define HCS_INDICATOR(p)       ((p)&(1 << 16)) /* true: has port indicators */
+#define HCS_PPC(p)             ((p)&(1 << 4))  /* true: port power control */
+#define HCS_N_PORTS(p)         (((p)>>0)&0xf)  /* bits 3:0, ports on HC */
+#define HCC_ISOC_CACHE(p)       ((p)&(1 << 7))  /* true: can cache isoc frame */
+#define HCC_ISOC_THRES(p)       (((p)>>4)&0x7)  /* bits 6:4, uframes cached */
+
+/* Section 2.3 Host Controller Operational Registers */
+#define CMD_LRESET     (1<<7)          /* partial reset (no ports, etc) */
+#define CMD_RESET      (1<<1)          /* reset HC not bus */
+#define CMD_RUN                (1<<0)          /* start/stop HC */
+#define STS_PCD                (1<<2)          /* port change detect */
+#define FLAG_CF                (1<<0)          /* true: we'll support "high speed" */
+
+#define PORT_OWNER     (1<<13)         /* true: companion hc owns this port */
+#define PORT_POWER     (1<<12)         /* true: has power (see PPC) */
+#define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */
+#define PORT_RESET     (1<<8)          /* reset port */
+#define PORT_SUSPEND   (1<<7)          /* suspend port */
+#define PORT_RESUME    (1<<6)          /* resume it */
+#define PORT_PE                (1<<2)          /* port enable */
+#define PORT_CSC       (1<<1)          /* connect status change */
+#define PORT_CONNECT   (1<<0)          /* device connected */
+#define PORT_RWC_BITS   (PORT_CSC)
+
+struct isp1760_qtd {
+       struct isp1760_qtd *hw_next;
+       u8 packet_type;
+       u8 toggle;
+
+       void *data_buffer;
+       /* the rest is HCD-private */
+       struct list_head qtd_list;
+       struct urb *urb;
+       size_t length;
+
+       /* isp special*/
+       u32 status;
+#define URB_COMPLETE_NOTIFY    (1 << 0)
+#define URB_ENQUEUED           (1 << 1)
+#define URB_TYPE_ATL           (1 << 2)
+#define URB_TYPE_INT           (1 << 3)
+};
+
+struct isp1760_qh {
+       /* first part defined by EHCI spec */
+       struct list_head qtd_list;
+       struct isp1760_hcd *priv;
+
+       /* periodic schedule info */
+       unsigned short period;          /* polling interval */
+       struct usb_device *dev;
+
+       u32 toggle;
+       u32 ping;
+};
+
+#define ehci_port_speed(priv, portsc) (1 << USB_PORT_FEAT_HIGHSPEED)
+
+static unsigned int isp1760_readl(__u32 __iomem *regs)
+{
+       return readl(regs);
+}
+
+static void isp1760_writel(const unsigned int val, __u32 __iomem *regs)
+{
+       writel(val, regs);
+}
+
+/*
+ * The next two copy via MMIO data to/from the device. memcpy_{to|from}io()
+ * doesn't quite work because some people have to enforce 32-bit access
+ */
+static void priv_read_copy(struct isp1760_hcd *priv, u32 *src,
+               __u32 __iomem *dst, u32 offset, u32 len)
+{
+       struct usb_hcd *hcd = priv_to_hcd(priv);
+       u32 val;
+       u8 *buff8;
+
+       if (!src) {
+               printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len);
+               return;
+       }
+       isp1760_writel(offset,  hcd->regs + HC_MEMORY_REG);
+       /* XXX
+        * 90nsec delay, the spec says something how this could be avoided.
+        */
+       mdelay(1);
+
+       while (len >= 4) {
+               *src = __raw_readl(dst);
+               len -= 4;
+               src++;
+               dst++;
+       }
+
+       if (!len)
+               return;
+
+       /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully
+        * allocated.
+        */
+       val = isp1760_readl(dst);
+
+       buff8 = (u8 *)src;
+       while (len) {
+
+               *buff8 = val;
+               val >>= 8;
+               len--;
+               buff8++;
+       }
+}
+
+static void priv_write_copy(const struct isp1760_hcd *priv, const u32 *src,
+               __u32 __iomem *dst, u32 len)
+{
+       while (len >= 4) {
+               __raw_writel(*src, dst);
+               len -= 4;
+               src++;
+               dst++;
+       }
+
+       if (!len)
+               return;
+       /* in case we have 3, 2 or 1 by left. The buffer is allocated and the
+        * extra bytes should not be read by the HW
+        */
+
+       __raw_writel(*src, dst);
+}
+
+/* memory management of the 60kb on the chip from 0x1000 to 0xffff */
+static void init_memory(struct isp1760_hcd *priv)
+{
+       int i;
+       u32 payload;
+
+       payload = 0x1000;
+       for (i = 0; i < BLOCK_1_NUM; i++) {
+               priv->memory_pool[i].start = payload;
+               priv->memory_pool[i].size = BLOCK_1_SIZE;
+               priv->memory_pool[i].free = 1;
+               payload += priv->memory_pool[i].size;
+       }
+
+
+       for (i = BLOCK_1_NUM; i < BLOCK_1_NUM + BLOCK_2_NUM; i++) {
+               priv->memory_pool[i].start = payload;
+               priv->memory_pool[i].size = BLOCK_2_SIZE;
+               priv->memory_pool[i].free = 1;
+               payload += priv->memory_pool[i].size;
+       }
+
+
+       for (i = BLOCK_1_NUM + BLOCK_2_NUM; i < BLOCKS; i++) {
+               priv->memory_pool[i].start = payload;
+               priv->memory_pool[i].size = BLOCK_3_SIZE;
+               priv->memory_pool[i].free = 1;
+               payload += priv->memory_pool[i].size;
+       }
+
+       BUG_ON(payload - priv->memory_pool[i - 1].size > PAYLOAD_SIZE);
+}
+
+static u32 alloc_mem(struct isp1760_hcd *priv, u32 size)
+{
+       int i;
+
+       if (!size)
+               return ISP1760_NULL_POINTER;
+
+       for (i = 0; i < BLOCKS; i++) {
+               if (priv->memory_pool[i].size >= size &&
+                               priv->memory_pool[i].free) {
+
+                       priv->memory_pool[i].free = 0;
+                       return priv->memory_pool[i].start;
+               }
+       }
+
+       printk(KERN_ERR "ISP1760 MEM: can not allocate %d bytes of memory\n",
+                       size);
+       printk(KERN_ERR "Current memory map:\n");
+       for (i = 0; i < BLOCKS; i++) {
+               printk(KERN_ERR "Pool %2d size %4d status: %d\n",
+                               i, priv->memory_pool[i].size,
+                               priv->memory_pool[i].free);
+       }
+       /* XXX maybe -ENOMEM could be possible */
+       BUG();
+       return 0;
+}
+
+static void free_mem(struct isp1760_hcd *priv, u32 mem)
+{
+       int i;
+
+       if (mem == ISP1760_NULL_POINTER)
+               return;
+
+       for (i = 0; i < BLOCKS; i++) {
+               if (priv->memory_pool[i].start == mem) {
+
+                       BUG_ON(priv->memory_pool[i].free);
+
+                       priv->memory_pool[i].free = 1;
+                       return ;
+               }
+       }
+
+       printk(KERN_ERR "Trying to free not-here-allocated memory :%08x\n",
+                       mem);
+       BUG();
+}
+
+static void isp1760_init_regs(struct usb_hcd *hcd)
+{
+       isp1760_writel(0, hcd->regs + HC_BUFFER_STATUS_REG);
+       isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_ATL_PTD_SKIPMAP_REG);
+       isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_INT_PTD_SKIPMAP_REG);
+       isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_ISO_PTD_SKIPMAP_REG);
+
+       isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_ATL_PTD_DONEMAP_REG);
+       isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_INT_PTD_DONEMAP_REG);
+       isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs +
+                       HC_ISO_PTD_DONEMAP_REG);
+}
+
+static int handshake(struct isp1760_hcd *priv, void __iomem *ptr,
+                     u32 mask, u32 done, int usec)
+{
+       u32 result;
+
+       do {
+               result = isp1760_readl(ptr);
+               if (result == ~0)
+                       return -ENODEV;
+               result &= mask;
+               if (result == done)
+                       return 0;
+               udelay(1);
+               usec--;
+       } while (usec > 0);
+       return -ETIMEDOUT;
+}
+
+/* reset a non-running (STS_HALT == 1) controller */
+static int ehci_reset(struct isp1760_hcd *priv)
+{
+       int retval;
+       struct usb_hcd *hcd = priv_to_hcd(priv);
+       u32 command = isp1760_readl(hcd->regs + HC_USBCMD);
+
+       command |= CMD_RESET;
+       isp1760_writel(command, hcd->regs + HC_USBCMD);
+       hcd->state = HC_STATE_HALT;
+       priv->next_statechange = jiffies;
+       retval = handshake(priv, hcd->regs + HC_USBCMD,
+                           CMD_RESET, 0, 250 * 1000);
+       return retval;
+}
+
+static void qh_destroy(struct isp1760_qh *qh)
+{
+       BUG_ON(!list_empty(&qh->qtd_list));
+       kmem_cache_free(qh_cachep, qh);
+}
+
+static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv,
+               gfp_t flags)
+{
+       struct isp1760_qh *qh;
+
+       qh = kmem_cache_zalloc(qh_cachep, flags);
+       if (!qh)
+               return qh;
+
+       INIT_LIST_HEAD(&qh->qtd_list);
+       qh->priv = priv;
+       return qh;
+}
+
+/* magic numbers that can affect system performance */
+#define        EHCI_TUNE_CERR          3       /* 0-3 qtd retries; 0 == don't stop */
+#define        EHCI_TUNE_RL_HS         4       /* nak throttle; see 4.9 */
+#define        EHCI_TUNE_RL_TT         0
+#define        EHCI_TUNE_MULT_HS       1       /* 1-3 transactions/uframe; 4.10.3 */
+#define        EHCI_TUNE_MULT_TT       1
+#define        EHCI_TUNE_FLS           2       /* (small) 256 frame schedule */
+
+/* one-time init, only for memory state */
+static int priv_init(struct usb_hcd *hcd)
+{
+       struct isp1760_hcd              *priv = hcd_to_priv(hcd);
+       u32                     hcc_params;
+
+       spin_lock_init(&priv->lock);
+
+       /*
+        * hw default: 1K periodic list heads, one per frame.
+        * periodic_size can shrink by USBCMD update if hcc_params allows.
+        */
+       priv->periodic_size = DEFAULT_I_TDPS;
+
+       /* controllers may cache some of the periodic schedule ... */
+       hcc_params = isp1760_readl(hcd->regs + HC_HCCPARAMS);
+       /* full frame cache */
+       if (HCC_ISOC_CACHE(hcc_params))
+               priv->i_thresh = 8;
+       else /* N microframes cached */
+               priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
+
+       return 0;
+}
+
+static int isp1760_hc_setup(struct usb_hcd *hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       int result;
+       u32 scratch;
+
+       isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG);
+       scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG);
+       if (scratch != 0xdeadbabe) {
+               printk(KERN_ERR "ISP1760: Scratch test failed.\n");
+               return -ENODEV;
+       }
+
+       /* pre reset */
+       isp1760_init_regs(hcd);
+
+       /* reset */
+       isp1760_writel(SW_RESET_RESET_ALL, hcd->regs + HC_RESET_REG);
+       mdelay(100);
+
+       isp1760_writel(SW_RESET_RESET_HC, hcd->regs + HC_RESET_REG);
+       mdelay(100);
+
+       result = ehci_reset(priv);
+       if (result)
+               return result;
+
+       /* Step 11 passed */
+
+       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG);
+       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE);
+
+       /* ATL reset */
+       scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL);
+       mdelay(10);
+       isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL);
+
+       isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL);
+       mdelay(10);
+
+       priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS);
+
+       return priv_init(hcd);
+}
+
+static void isp1760_init_maps(struct usb_hcd *hcd)
+{
+       /*set last maps, for iso its only 1, else 32 tds bitmap*/
+       isp1760_writel(0x80000000, hcd->regs + HC_ATL_PTD_LASTPTD_REG);
+       isp1760_writel(0x80000000, hcd->regs + HC_INT_PTD_LASTPTD_REG);
+       isp1760_writel(0x00000001, hcd->regs + HC_ISO_PTD_LASTPTD_REG);
+}
+
+static void isp1760_enable_interrupts(struct usb_hcd *hcd)
+{
+       isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_AND_REG);
+       isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_OR_REG);
+       isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_AND_REG);
+       isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_OR_REG);
+       isp1760_writel(0, hcd->regs + HC_ISO_IRQ_MASK_AND_REG);
+       isp1760_writel(0xffffffff, hcd->regs + HC_ISO_IRQ_MASK_OR_REG);
+       /* step 23 passed */
+}
+
+static int isp1760_run(struct usb_hcd *hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       int retval;
+       u32 temp;
+       u32 command;
+       u32 chipid;
+
+       hcd->uses_new_polling = 1;
+       hcd->poll_rh = 0;
+
+       hcd->state = HC_STATE_RUNNING;
+       isp1760_enable_interrupts(hcd);
+       temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
+       temp |= FINAL_HW_CONFIG;
+       isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL);
+
+       command = isp1760_readl(hcd->regs + HC_USBCMD);
+       command &= ~(CMD_LRESET|CMD_RESET);
+       command |= CMD_RUN;
+       isp1760_writel(command, hcd->regs + HC_USBCMD);
+
+       retval = handshake(priv, hcd->regs + HC_USBCMD, CMD_RUN, CMD_RUN,
+                       250 * 1000);
+       if (retval)
+               return retval;
+
+       /*
+        * XXX
+        * Spec says to write FLAG_CF as last config action, priv code grabs
+        * the semaphore while doing so.
+        */
+       down_write(&ehci_cf_port_reset_rwsem);
+       isp1760_writel(FLAG_CF, hcd->regs + HC_CONFIGFLAG);
+
+       retval = handshake(priv, hcd->regs + HC_CONFIGFLAG, FLAG_CF, FLAG_CF,
+                       250 * 1000);
+       up_write(&ehci_cf_port_reset_rwsem);
+       if (retval)
+               return retval;
+
+       chipid = isp1760_readl(hcd->regs + HC_CHIP_ID_REG);
+       isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff,
+                       chipid >> 16);
+
+       /* PTD Register Init Part 2, Step 28 */
+       /* enable INTs */
+       isp1760_init_maps(hcd);
+
+       /* GRR this is run-once init(), being done every time the HC starts.
+        * So long as they're part of class devices, we can't do it init()
+        * since the class device isn't created that early.
+        */
+       return 0;
+}
+
+static u32 base_to_chip(u32 base)
+{
+       return ((base - 0x400) >> 3);
+}
+
+static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh,
+                       struct isp1760_qtd *qtd, struct urb *urb,
+                       u32 payload, struct ptd *ptd)
+{
+       u32 dw0;
+       u32 dw1;
+       u32 dw2;
+       u32 dw3;
+       u32 maxpacket;
+       u32 multi;
+       u32 pid_code;
+       u32 rl = RL_COUNTER;
+       u32 nak = NAK_COUNTER;
+
+       /* according to 3.6.2, max packet len can not be > 0x400 */
+       maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+       multi =  1 + ((maxpacket >> 11) & 0x3);
+       maxpacket &= 0x7ff;
+
+       /* DW0 */
+       dw0 = PTD_VALID;
+       dw0 |= PTD_LENGTH(qtd->length);
+       dw0 |= PTD_MAXPACKET(maxpacket);
+       dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe));
+       dw1 = usb_pipeendpoint(urb->pipe) >> 1;
+
+       /* DW1 */
+       dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe));
+
+       pid_code = qtd->packet_type;
+       dw1 |= PTD_PID_TOKEN(pid_code);
+
+       if (usb_pipebulk(urb->pipe))
+               dw1 |= PTD_TRANS_BULK;
+       else if  (usb_pipeint(urb->pipe))
+               dw1 |= PTD_TRANS_INT;
+
+       if (urb->dev->speed != USB_SPEED_HIGH) {
+               /* split transaction */
+
+               dw1 |= PTD_TRANS_SPLIT;
+               if (urb->dev->speed == USB_SPEED_LOW)
+                       dw1 |= PTD_SE_USB_LOSPEED;
+
+               dw1 |= PTD_PORT_NUM(urb->dev->ttport);
+               dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum);
+
+               /* SE bit for Split INT transfers */
+               if (usb_pipeint(urb->pipe) &&
+                               (urb->dev->speed == USB_SPEED_LOW))
+                       dw1 |= 2 << 16;
+
+               dw3 = 0;
+               rl = 0;
+               nak = 0;
+       } else {
+               dw0 |= PTD_MULTI(multi);
+               if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe))
+                       dw3 = qh->ping;
+               else
+                       dw3 = 0;
+       }
+       /* DW2 */
+       dw2 = 0;
+       dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload));
+       dw2 |= PTD_RL_CNT(rl);
+       dw3 |= PTD_NAC_CNT(nak);
+
+       /* DW3 */
+       if (usb_pipecontrol(urb->pipe))
+               dw3 |= PTD_DATA_TOGGLE(qtd->toggle);
+       else
+               dw3 |= qh->toggle;
+
+
+       dw3 |= PTD_ACTIVE;
+       /* Cerr */
+       dw3 |= PTD_CERR(ERR_COUNTER);
+
+       memset(ptd, 0, sizeof(*ptd));
+
+       ptd->dw0 = cpu_to_le32(dw0);
+       ptd->dw1 = cpu_to_le32(dw1);
+       ptd->dw2 = cpu_to_le32(dw2);
+       ptd->dw3 = cpu_to_le32(dw3);
+}
+
+static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh,
+                       struct isp1760_qtd *qtd, struct urb *urb,
+                       u32 payload, struct ptd *ptd)
+{
+       u32 maxpacket;
+       u32 multi;
+       u32 numberofusofs;
+       u32 i;
+       u32 usofmask, usof;
+       u32 period;
+
+       maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+       multi =  1 + ((maxpacket >> 11) & 0x3);
+       maxpacket &= 0x7ff;
+       /* length of the data per uframe */
+       maxpacket = multi * maxpacket;
+
+       numberofusofs = urb->transfer_buffer_length / maxpacket;
+       if (urb->transfer_buffer_length % maxpacket)
+               numberofusofs += 1;
+
+       usofmask = 1;
+       usof = 0;
+       for (i = 0; i < numberofusofs; i++) {
+               usof |= usofmask;
+               usofmask <<= 1;
+       }
+
+       if (urb->dev->speed != USB_SPEED_HIGH) {
+               /* split */
+               ptd->dw5 = __constant_cpu_to_le32(0x1c);
+
+               if (qh->period >= 32)
+                       period = qh->period / 2;
+               else
+                       period = qh->period;
+
+       } else {
+
+               if (qh->period >= 8)
+                       period = qh->period/8;
+               else
+                       period = qh->period;
+
+               if (period >= 32)
+                       period  = 16;
+
+               if (qh->period >= 8) {
+                       /* millisecond period */
+                       period = (period << 3);
+               } else {
+                       /* usof based tranmsfers */
+                       /* minimum 4 usofs */
+                       usof = 0x11;
+               }
+       }
+
+       ptd->dw2 |= cpu_to_le32(period);
+       ptd->dw4 = cpu_to_le32(usof);
+}
+
+static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh,
+                       struct isp1760_qtd *qtd, struct urb *urb,
+                       u32 payload, struct ptd *ptd)
+{
+       transform_into_atl(priv, qh, qtd, urb, payload, ptd);
+       transform_add_int(priv, qh, qtd, urb,  payload, ptd);
+}
+
+static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len,
+               u32 token)
+{
+       int count;
+
+       qtd->data_buffer = databuffer;
+       qtd->packet_type = GET_QTD_TOKEN_TYPE(token);
+       qtd->toggle = GET_DATA_TOGGLE(token);
+
+       if (len > HC_ATL_PL_SIZE)
+               count = HC_ATL_PL_SIZE;
+       else
+               count = len;
+
+       qtd->length = count;
+       return count;
+}
+
+static int check_error(struct ptd *ptd)
+{
+       int error = 0;
+       u32 dw3;
+
+       dw3 = le32_to_cpu(ptd->dw3);
+       if (dw3 & DW3_HALT_BIT)
+               error = -EPIPE;
+
+       if (dw3 & DW3_ERROR_BIT) {
+               printk(KERN_ERR "error bit is set in DW3\n");
+               error = -EPIPE;
+       }
+
+       if (dw3 & DW3_QTD_ACTIVE) {
+               printk(KERN_ERR "transfer active bit is set DW3\n");
+               printk(KERN_ERR "nak counter: %d, rl: %d\n", (dw3 >> 19) & 0xf,
+                               (le32_to_cpu(ptd->dw2) >> 25) & 0xf);
+       }
+
+       return error;
+}
+
+static void check_int_err_status(u32 dw4)
+{
+       u32 i;
+
+       dw4 >>= 8;
+
+       for (i = 0; i < 8; i++) {
+               switch (dw4 & 0x7) {
+               case INT_UNDERRUN:
+                       printk(KERN_ERR "ERROR: under run , %d\n", i);
+                       break;
+
+               case INT_EXACT:
+                       printk(KERN_ERR "ERROR: transaction error, %d\n", i);
+                       break;
+
+               case INT_BABBLE:
+                       printk(KERN_ERR "ERROR: babble error, %d\n", i);
+                       break;
+               }
+               dw4 >>= 3;
+       }
+}
+
+static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv,
+               u32 payload)
+{
+       u32 token;
+       struct usb_hcd *hcd = priv_to_hcd(priv);
+
+       token = qtd->packet_type;
+
+       if (qtd->length && (qtd->length <= HC_ATL_PL_SIZE)) {
+               switch (token) {
+               case IN_PID:
+                       break;
+               case OUT_PID:
+               case SETUP_PID:
+                       priv_write_copy(priv, qtd->data_buffer,
+                                       hcd->regs + payload,
+                                       qtd->length);
+               }
+       }
+}
+
+static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload,
+               struct isp1760_hcd *priv, struct isp1760_qh *qh,
+               struct urb *urb, u32 slot, struct isp1760_qtd *qtd)
+{
+       struct ptd ptd;
+       struct usb_hcd *hcd = priv_to_hcd(priv);
+
+       transform_into_atl(priv, qh, qtd, urb, payload, &ptd);
+       priv_write_copy(priv, (u32 *)&ptd, hcd->regs + atl_regs, sizeof(ptd));
+       enqueue_one_qtd(qtd, priv, payload);
+
+       priv->atl_ints[slot].urb = urb;
+       priv->atl_ints[slot].qh = qh;
+       priv->atl_ints[slot].qtd = qtd;
+       priv->atl_ints[slot].data_buffer = qtd->data_buffer;
+       priv->atl_ints[slot].payload = payload;
+       qtd->status |= URB_ENQUEUED | URB_TYPE_ATL;
+       qtd->status |= slot << 16;
+}
+
+static void enqueue_one_int_qtd(u32 int_regs, u32 payload,
+               struct isp1760_hcd *priv, struct isp1760_qh *qh,
+               struct urb *urb, u32 slot,  struct isp1760_qtd *qtd)
+{
+       struct ptd ptd;
+       struct usb_hcd *hcd = priv_to_hcd(priv);
+
+       transform_into_int(priv, qh, qtd, urb, payload, &ptd);
+       priv_write_copy(priv, (u32 *)&ptd, hcd->regs + int_regs, sizeof(ptd));
+       enqueue_one_qtd(qtd, priv, payload);
+
+       priv->int_ints[slot].urb = urb;
+       priv->int_ints[slot].qh = qh;
+       priv->int_ints[slot].qtd = qtd;
+       priv->int_ints[slot].data_buffer = qtd->data_buffer;
+       priv->int_ints[slot].payload = payload;
+       qtd->status |= URB_ENQUEUED | URB_TYPE_INT;
+       qtd->status |= slot << 16;
+}
+
+void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
+               struct isp1760_qtd *qtd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       u32 skip_map, or_map;
+       u32 queue_entry;
+       u32 slot;
+       u32 atl_regs, payload;
+       u32 buffstatus;
+
+       skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
+
+       BUG_ON(!skip_map);
+       slot = __ffs(skip_map);
+       queue_entry = 1 << slot;
+
+       atl_regs = ATL_REGS_OFFSET + slot * sizeof(struct ptd);
+
+       payload = alloc_mem(priv, qtd->length);
+
+       enqueue_one_atl_qtd(atl_regs, payload, priv, qh, qtd->urb, slot, qtd);
+
+       or_map = isp1760_readl(hcd->regs + HC_ATL_IRQ_MASK_OR_REG);
+       or_map |= queue_entry;
+       isp1760_writel(or_map, hcd->regs + HC_ATL_IRQ_MASK_OR_REG);
+
+       skip_map &= ~queue_entry;
+       isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
+
+       buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG);
+       buffstatus |= ATL_BUFFER;
+       isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG);
+}
+
+void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
+               struct isp1760_qtd *qtd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       u32 skip_map, or_map;
+       u32 queue_entry;
+       u32 slot;
+       u32 int_regs, payload;
+       u32 buffstatus;
+
+       skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
+
+       BUG_ON(!skip_map);
+       slot = __ffs(skip_map);
+       queue_entry = 1 << slot;
+
+       int_regs = INT_REGS_OFFSET + slot * sizeof(struct ptd);
+
+       payload = alloc_mem(priv, qtd->length);
+
+       enqueue_one_int_qtd(int_regs, payload, priv, qh, qtd->urb, slot, qtd);
+
+       or_map = isp1760_readl(hcd->regs + HC_INT_IRQ_MASK_OR_REG);
+       or_map |= queue_entry;
+       isp1760_writel(or_map, hcd->regs + HC_INT_IRQ_MASK_OR_REG);
+
+       skip_map &= ~queue_entry;
+       isp1760_writel(skip_map, hcd->regs + HC_INT_PTD_SKIPMAP_REG);
+
+       buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG);
+       buffstatus |= INT_BUFFER;
+       isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG);
+}
+
+static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, int status)
+__releases(priv->lock)
+__acquires(priv->lock)
+{
+       if (!urb->unlinked) {
+               if (status == -EINPROGRESS)
+                       status = 0;
+       }
+
+       /* complete() can reenter this HCD */
+       usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
+       spin_unlock(&priv->lock);
+       usb_hcd_giveback_urb(priv_to_hcd(priv), urb, status);
+       spin_lock(&priv->lock);
+}
+
+static void isp1760_qtd_free(struct isp1760_qtd *qtd)
+{
+       kmem_cache_free(qtd_cachep, qtd);
+}
+
+static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd)
+{
+       struct isp1760_qtd *tmp_qtd;
+
+       tmp_qtd = qtd->hw_next;
+       list_del(&qtd->qtd_list);
+       isp1760_qtd_free(qtd);
+       return tmp_qtd;
+}
+
+/*
+ * Remove this QTD from the QH list and free its memory. If this QTD
+ * isn't the last one than remove also his successor(s).
+ * Returns the QTD which is part of an new URB and should be enqueued.
+ */
+static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd)
+{
+       struct isp1760_qtd *tmp_qtd;
+       int last_one;
+
+       do {
+               tmp_qtd = qtd->hw_next;
+               last_one = qtd->status & URB_COMPLETE_NOTIFY;
+               list_del(&qtd->qtd_list);
+               isp1760_qtd_free(qtd);
+               qtd = tmp_qtd;
+       } while (!last_one && qtd);
+
+       return qtd;
+}
+
+static void do_atl_int(struct usb_hcd *usb_hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(usb_hcd);
+       u32 done_map, skip_map;
+       struct ptd ptd;
+       struct urb *urb = NULL;
+       u32 atl_regs_base;
+       u32 atl_regs;
+       u32 queue_entry;
+       u32 payload;
+       u32 length;
+       u32 or_map;
+       u32 status = -EINVAL;
+       int error;
+       struct isp1760_qtd *qtd;
+       struct isp1760_qh *qh;
+       u32 rl;
+       u32 nakcount;
+
+       done_map = isp1760_readl(usb_hcd->regs +
+                       HC_ATL_PTD_DONEMAP_REG);
+       skip_map = isp1760_readl(usb_hcd->regs +
+                       HC_ATL_PTD_SKIPMAP_REG);
+
+       or_map = isp1760_readl(usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG);
+       or_map &= ~done_map;
+       isp1760_writel(or_map, usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG);
+
+       atl_regs_base = ATL_REGS_OFFSET;
+       while (done_map) {
+               u32 dw1;
+               u32 dw2;
+               u32 dw3;
+
+               status = 0;
+
+               queue_entry = __ffs(done_map);
+               done_map &= ~(1 << queue_entry);
+               skip_map |= 1 << queue_entry;
+
+               atl_regs = atl_regs_base + queue_entry * sizeof(struct ptd);
+
+               urb = priv->atl_ints[queue_entry].urb;
+               qtd = priv->atl_ints[queue_entry].qtd;
+               qh = priv->atl_ints[queue_entry].qh;
+               payload = priv->atl_ints[queue_entry].payload;
+
+               if (!qh) {
+                       printk(KERN_ERR "qh is 0\n");
+                       continue;
+               }
+               priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs,
+                               atl_regs, sizeof(ptd));
+
+               dw1 = le32_to_cpu(ptd.dw1);
+               dw2 = le32_to_cpu(ptd.dw2);
+               dw3 = le32_to_cpu(ptd.dw3);
+               rl = (dw2 >> 25) & 0x0f;
+               nakcount = (dw3 >> 19) & 0xf;
+
+               /* Transfer Error, *but* active and no HALT -> reload */
+               if ((dw3 & DW3_ERROR_BIT) && (dw3 & DW3_QTD_ACTIVE) &&
+                               !(dw3 & DW3_HALT_BIT)) {
+
+                       /* according to ppriv code, we have to
+                        * reload this one if trasfered bytes != requested bytes
+                        * else act like everything went smooth..
+                        * XXX This just doesn't feel right and hasn't
+                        * triggered so far.
+                        */
+
+                       length = PTD_XFERRED_LENGTH(dw3);
+                       printk(KERN_ERR "Should reload now.... transfered %d "
+                                       "of %zu\n", length, qtd->length);
+                       BUG();
+               }
+
+               if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) {
+                       u32 buffstatus;
+
+                       /* XXX
+                        * NAKs are handled in HW by the chip. Usually if the
+                        * device is not able to send data fast enough.
+                        * This did not trigger for a long time now.
+                        */
+                       printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
+                                       "%d of %d done: %08x cur: %08x\n", qtd,
+                                       urb, qh, PTD_XFERRED_LENGTH(dw3),
+                                       qtd->length, done_map,
+                                       (1 << queue_entry));
+
+                       /* RL counter = ERR counter */
+                       dw3 &= ~(0xf << 19);
+                       dw3 |= rl << 19;
+                       dw3 &= ~(3 << (55 - 32));
+                       dw3 |= ERR_COUNTER << (55 - 32);
+
+                       /*
+                        * It is not needed to write skip map back because it
+                        * is unchanged. Just make sure that this entry is
+                        * unskipped once it gets written to the HW.
+                        */
+                       skip_map &= ~(1 << queue_entry);
+                       or_map = isp1760_readl(usb_hcd->regs +
+                                       HC_ATL_IRQ_MASK_OR_REG);
+                       or_map |= 1 << queue_entry;
+                       isp1760_writel(or_map, usb_hcd->regs +
+                                       HC_ATL_IRQ_MASK_OR_REG);
+
+                       ptd.dw3 = cpu_to_le32(dw3);
+                       priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
+                                       atl_regs, sizeof(ptd));
+
+                       ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID);
+                       priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
+                                       atl_regs, sizeof(ptd));
+
+                       buffstatus = isp1760_readl(usb_hcd->regs +
+                                       HC_BUFFER_STATUS_REG);
+                       buffstatus |= ATL_BUFFER;
+                       isp1760_writel(buffstatus, usb_hcd->regs +
+                                       HC_BUFFER_STATUS_REG);
+                       continue;
+               }
+
+               error = check_error(&ptd);
+               if (error) {
+                       status = error;
+                       priv->atl_ints[queue_entry].qh->toggle = 0;
+                       priv->atl_ints[queue_entry].qh->ping = 0;
+                       urb->status = -EPIPE;
+
+#if 0
+                       printk(KERN_ERR "Error in %s().\n", __func__);
+                       printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x "
+                                       "dw3: %08x dw4: %08x dw5: %08x dw6: "
+                                       "%08x dw7: %08x\n",
+                                       ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3,
+                                       ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7);
+#endif
+               } else {
+                       if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+                               priv->atl_ints[queue_entry].qh->toggle = dw3 &
+                                       (1 << 25);
+                               priv->atl_ints[queue_entry].qh->ping = dw3 &
+                                       (1 << 26);
+                       }
+               }
+
+               length = PTD_XFERRED_LENGTH(dw3);
+               if (length) {
+                       switch (DW1_GET_PID(dw1)) {
+                       case IN_PID:
+                               priv_read_copy(priv,
+                                       priv->atl_ints[queue_entry].data_buffer,
+                                       usb_hcd->regs + payload, payload,
+                                       length);
+
+                       case OUT_PID:
+
+                               urb->actual_length += length;
+
+                       case SETUP_PID:
+                               break;
+                       }
+               }
+
+               priv->atl_ints[queue_entry].data_buffer = NULL;
+               priv->atl_ints[queue_entry].urb = NULL;
+               priv->atl_ints[queue_entry].qtd = NULL;
+               priv->atl_ints[queue_entry].qh = NULL;
+
+               free_mem(priv, payload);
+
+               isp1760_writel(skip_map, usb_hcd->regs +
+                               HC_ATL_PTD_SKIPMAP_REG);
+
+               if (urb->status == -EPIPE) {
+                       /* HALT was received */
+
+                       qtd = clean_up_qtdlist(qtd);
+                       isp1760_urb_done(priv, urb, urb->status);
+
+               } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
+                       /* short BULK received */
+
+                       printk(KERN_ERR "short bulk, %d instead %d\n", length,
+                                       qtd->length);
+                       if (urb->transfer_flags & URB_SHORT_NOT_OK) {
+                               urb->status = -EREMOTEIO;
+                               printk(KERN_ERR "not okey\n");
+                       }
+
+                       if (urb->status == -EINPROGRESS)
+                               urb->status = 0;
+
+                       qtd = clean_up_qtdlist(qtd);
+
+                       isp1760_urb_done(priv, urb, urb->status);
+
+               } else if (qtd->status & URB_COMPLETE_NOTIFY) {
+                       /* that was the last qtd of that URB */
+
+                       if (urb->status == -EINPROGRESS)
+                               urb->status = 0;
+
+                       qtd = clean_this_qtd(qtd);
+                       isp1760_urb_done(priv, urb, urb->status);
+
+               } else {
+                       /* next QTD of this URB */
+
+                       qtd = clean_this_qtd(qtd);
+                       BUG_ON(!qtd);
+               }
+
+               if (qtd)
+                       enqueue_an_ATL_packet(usb_hcd, qh, qtd);
+
+               skip_map = isp1760_readl(usb_hcd->regs +
+                               HC_ATL_PTD_SKIPMAP_REG);
+       }
+}
+
+static void do_intl_int(struct usb_hcd *usb_hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(usb_hcd);
+       u32 done_map, skip_map;
+       struct ptd ptd;
+       struct urb *urb = NULL;
+       u32 int_regs;
+       u32 int_regs_base;
+       u32 payload;
+       u32 length;
+       u32 or_map;
+       int error;
+       u32 queue_entry;
+       struct isp1760_qtd *qtd;
+       struct isp1760_qh *qh;
+
+       done_map = isp1760_readl(usb_hcd->regs +
+                       HC_INT_PTD_DONEMAP_REG);
+       skip_map = isp1760_readl(usb_hcd->regs +
+                       HC_INT_PTD_SKIPMAP_REG);
+
+       or_map = isp1760_readl(usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG);
+       or_map &= ~done_map;
+       isp1760_writel(or_map, usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG);
+
+       int_regs_base = INT_REGS_OFFSET;
+
+       while (done_map) {
+               u32 dw1;
+               u32 dw3;
+
+               queue_entry = __ffs(done_map);
+               done_map &= ~(1 << queue_entry);
+               skip_map |= 1 << queue_entry;
+
+               int_regs = int_regs_base + queue_entry * sizeof(struct ptd);
+               urb = priv->int_ints[queue_entry].urb;
+               qtd = priv->int_ints[queue_entry].qtd;
+               qh = priv->int_ints[queue_entry].qh;
+               payload = priv->int_ints[queue_entry].payload;
+
+               if (!qh) {
+                       printk(KERN_ERR "(INT) qh is 0\n");
+                       continue;
+               }
+
+               priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs,
+                               int_regs, sizeof(ptd));
+               dw1 = le32_to_cpu(ptd.dw1);
+               dw3 = le32_to_cpu(ptd.dw3);
+               check_int_err_status(le32_to_cpu(ptd.dw4));
+
+               error = check_error(&ptd);
+               if (error) {
+#if 0
+                       printk(KERN_ERR "Error in %s().\n", __func__);
+                       printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x "
+                                       "dw3: %08x dw4: %08x dw5: %08x dw6: "
+                                       "%08x dw7: %08x\n",
+                                       ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3,
+                                       ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7);
+#endif
+                       urb->status = -EPIPE;
+                       priv->int_ints[queue_entry].qh->toggle = 0;
+                       priv->int_ints[queue_entry].qh->ping = 0;
+
+               } else {
+                       priv->int_ints[queue_entry].qh->toggle =
+                               dw3 & (1 << 25);
+                       priv->int_ints[queue_entry].qh->ping = dw3 & (1 << 26);
+               }
+
+               if (urb->dev->speed != USB_SPEED_HIGH)
+                       length = PTD_XFERRED_LENGTH_LO(dw3);
+               else
+                       length = PTD_XFERRED_LENGTH(dw3);
+
+               if (length) {
+                       switch (DW1_GET_PID(dw1)) {
+                       case IN_PID:
+                               priv_read_copy(priv,
+                                       priv->int_ints[queue_entry].data_buffer,
+                                       usb_hcd->regs + payload , payload,
+                                       length);
+                       case OUT_PID:
+
+                               urb->actual_length += length;
+
+                       case SETUP_PID:
+                               break;
+                       }
+               }
+
+               priv->int_ints[queue_entry].data_buffer = NULL;
+               priv->int_ints[queue_entry].urb = NULL;
+               priv->int_ints[queue_entry].qtd = NULL;
+               priv->int_ints[queue_entry].qh = NULL;
+
+               isp1760_writel(skip_map, usb_hcd->regs +
+                               HC_INT_PTD_SKIPMAP_REG);
+               free_mem(priv, payload);
+
+               if (urb->status == -EPIPE) {
+                       /* HALT received */
+
+                        qtd = clean_up_qtdlist(qtd);
+                        isp1760_urb_done(priv, urb, urb->status);
+
+               } else if (qtd->status & URB_COMPLETE_NOTIFY) {
+
+                       if (urb->status == -EINPROGRESS)
+                               urb->status = 0;
+
+                       qtd = clean_this_qtd(qtd);
+                       isp1760_urb_done(priv, urb, urb->status);
+
+               } else {
+                       /* next QTD of this URB */
+
+                       qtd = clean_this_qtd(qtd);
+                       BUG_ON(!qtd);
+               }
+
+               if (qtd)
+                       enqueue_an_INT_packet(usb_hcd, qh, qtd);
+
+               skip_map = isp1760_readl(usb_hcd->regs +
+                               HC_INT_PTD_SKIPMAP_REG);
+       }
+}
+
+#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
+static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb,
+               gfp_t flags)
+{
+       struct isp1760_qh *qh;
+       int is_input, type;
+
+       qh = isp1760_qh_alloc(priv, flags);
+       if (!qh)
+               return qh;
+
+       /*
+        * init endpoint/device data for this QH
+        */
+       is_input = usb_pipein(urb->pipe);
+       type = usb_pipetype(urb->pipe);
+
+       if (type == PIPE_INTERRUPT) {
+
+               if (urb->dev->speed == USB_SPEED_HIGH) {
+
+                       qh->period = urb->interval >> 3;
+                       if (qh->period == 0 && urb->interval != 1) {
+                               /* NOTE interval 2 or 4 uframes could work.
+                                * But interval 1 scheduling is simpler, and
+                                * includes high bandwidth.
+                                */
+                               printk(KERN_ERR "intr period %d uframes, NYET!",
+                                               urb->interval);
+                               qh_destroy(qh);
+                               return NULL;
+                       }
+               } else {
+                       qh->period = urb->interval;
+               }
+       }
+
+       /* support for tt scheduling, and access to toggles */
+       qh->dev = urb->dev;
+
+       if (!usb_pipecontrol(urb->pipe))
+               usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input,
+                               1);
+       return qh;
+}
+
+/*
+ * For control/bulk/interrupt, return QH with these TDs appended.
+ * Allocates and initializes the QH if necessary.
+ * Returns null if it can't allocate a QH it needs to.
+ * If the QH has TDs (urbs) already, that's great.
+ */
+static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv,
+               struct urb *urb, struct list_head *qtd_list, int epnum,
+               void **ptr)
+{
+       struct isp1760_qh *qh;
+       struct isp1760_qtd *qtd;
+       struct isp1760_qtd *prev_qtd;
+
+       qh = (struct isp1760_qh *)*ptr;
+       if (!qh) {
+               /* can't sleep here, we have priv->lock... */
+               qh = qh_make(priv, urb, GFP_ATOMIC);
+               if (!qh)
+                       return qh;
+               *ptr = qh;
+       }
+
+       qtd = list_entry(qtd_list->next, struct isp1760_qtd,
+                       qtd_list);
+       if (!list_empty(&qh->qtd_list))
+               prev_qtd = list_entry(qh->qtd_list.prev,
+                               struct isp1760_qtd, qtd_list);
+       else
+               prev_qtd = NULL;
+
+       list_splice(qtd_list, qh->qtd_list.prev);
+       if (prev_qtd) {
+               BUG_ON(prev_qtd->hw_next);
+               prev_qtd->hw_next = qtd;
+       }
+
+       urb->hcpriv = qh;
+       return qh;
+}
+
+static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb,
+               struct list_head *qtd_list)
+{
+       struct list_head *entry, *temp;
+
+       list_for_each_safe(entry, temp, qtd_list) {
+               struct isp1760_qtd      *qtd;
+
+               qtd = list_entry(entry, struct isp1760_qtd, qtd_list);
+               list_del(&qtd->qtd_list);
+               isp1760_qtd_free(qtd);
+       }
+}
+
+static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb,
+               struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p)
+{
+       struct isp1760_qtd         *qtd;
+       int                     epnum;
+       unsigned long           flags;
+       struct isp1760_qh          *qh = NULL;
+       int                     rc;
+       int qh_busy;
+
+       qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list);
+       epnum = urb->ep->desc.bEndpointAddress;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &priv_to_hcd(priv)->flags)) {
+               rc = -ESHUTDOWN;
+               goto done;
+       }
+       rc = usb_hcd_link_urb_to_ep(priv_to_hcd(priv), urb);
+       if (rc)
+               goto done;
+
+       qh = urb->ep->hcpriv;
+       if (qh)
+               qh_busy = !list_empty(&qh->qtd_list);
+       else
+               qh_busy = 0;
+
+       qh = qh_append_tds(priv, urb, qtd_list, epnum, &urb->ep->hcpriv);
+       if (!qh) {
+               usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb);
+               rc = -ENOMEM;
+               goto done;
+       }
+
+       if (!qh_busy)
+               p(priv_to_hcd(priv), qh, qtd);
+
+done:
+       spin_unlock_irqrestore(&priv->lock, flags);
+       if (!qh)
+               qtd_list_free(priv, urb, qtd_list);
+       return rc;
+}
+
+static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv,
+               gfp_t flags)
+{
+       struct isp1760_qtd *qtd;
+
+       qtd = kmem_cache_zalloc(qtd_cachep, flags);
+       if (qtd)
+               INIT_LIST_HEAD(&qtd->qtd_list);
+
+       return qtd;
+}
+
+/*
+ * create a list of filled qtds for this URB; won't link into qh.
+ */
+static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv,
+               struct urb *urb, struct list_head *head, gfp_t flags)
+{
+       struct isp1760_qtd *qtd, *qtd_prev;
+       void *buf;
+       int len, maxpacket;
+       int is_input;
+       u32 token;
+
+       /*
+        * URBs map to sequences of QTDs:  one logical transaction
+        */
+       qtd = isp1760_qtd_alloc(priv, flags);
+       if (!qtd)
+               return NULL;
+
+       list_add_tail(&qtd->qtd_list, head);
+       qtd->urb = urb;
+       urb->status = -EINPROGRESS;
+
+       token = 0;
+       /* for split transactions, SplitXState initialized to zero */
+
+       len = urb->transfer_buffer_length;
+       is_input = usb_pipein(urb->pipe);
+       if (usb_pipecontrol(urb->pipe)) {
+               /* SETUP pid */
+               qtd_fill(qtd, urb->setup_packet,
+                               sizeof(struct usb_ctrlrequest),
+                               token | SETUP_PID);
+
+               /* ... and always at least one more pid */
+               token ^= DATA_TOGGLE;
+               qtd_prev = qtd;
+               qtd = isp1760_qtd_alloc(priv, flags);
+               if (!qtd)
+                       goto cleanup;
+               qtd->urb = urb;
+               qtd_prev->hw_next = qtd;
+               list_add_tail(&qtd->qtd_list, head);
+
+               /* for zero length DATA stages, STATUS is always IN */
+               if (len == 0)
+                       token |= IN_PID;
+       }
+
+       /*
+        * data transfer stage:  buffer setup
+        */
+       buf = urb->transfer_buffer;
+
+       if (is_input)
+               token |= IN_PID;
+       else
+               token |= OUT_PID;
+
+       maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
+
+       /*
+        * buffer gets wrapped in one or more qtds;
+        * last one may be "short" (including zero len)
+        * and may serve as a control status ack
+        */
+       for (;;) {
+               int this_qtd_len;
+
+               if (!buf && len) {
+                       /* XXX This looks like usb storage / SCSI bug */
+                       printk(KERN_ERR "buf is null, dma is %08lx len is %d\n",
+                                       (long unsigned)urb->transfer_dma, len);
+                       WARN_ON(1);
+               }
+
+               this_qtd_len = qtd_fill(qtd, buf, len, token);
+               len -= this_qtd_len;
+               buf += this_qtd_len;
+
+               /* qh makes control packets use qtd toggle; maybe switch it */
+               if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
+                       token ^= DATA_TOGGLE;
+
+               if (len <= 0)
+                       break;
+
+               qtd_prev = qtd;
+               qtd = isp1760_qtd_alloc(priv, flags);
+               if (!qtd)
+                       goto cleanup;
+               qtd->urb = urb;
+               qtd_prev->hw_next = qtd;
+               list_add_tail(&qtd->qtd_list, head);
+       }
+
+       /*
+        * control requests may need a terminating data "status" ack;
+        * bulk ones may need a terminating short packet (zero length).
+        */
+       if (urb->transfer_buffer_length != 0) {
+               int one_more = 0;
+
+               if (usb_pipecontrol(urb->pipe)) {
+                       one_more = 1;
+                       /* "in" <--> "out"  */
+                       token ^= IN_PID;
+                       /* force DATA1 */
+                       token |= DATA_TOGGLE;
+               } else if (usb_pipebulk(urb->pipe)
+                               && (urb->transfer_flags & URB_ZERO_PACKET)
+                               && !(urb->transfer_buffer_length % maxpacket)) {
+                       one_more = 1;
+               }
+               if (one_more) {
+                       qtd_prev = qtd;
+                       qtd = isp1760_qtd_alloc(priv, flags);
+                       if (!qtd)
+                               goto cleanup;
+                       qtd->urb = urb;
+                       qtd_prev->hw_next = qtd;
+                       list_add_tail(&qtd->qtd_list, head);
+
+                       /* never any data in such packets */
+                       qtd_fill(qtd, NULL, 0, token);
+               }
+       }
+
+       qtd->status = URB_COMPLETE_NOTIFY;
+       return head;
+
+cleanup:
+       qtd_list_free(priv, urb, head);
+       return NULL;
+}
+
+static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+               gfp_t mem_flags)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       struct list_head qtd_list;
+       packet_enqueue *pe;
+
+       INIT_LIST_HEAD(&qtd_list);
+
+       switch (usb_pipetype(urb->pipe)) {
+       case PIPE_CONTROL:
+       case PIPE_BULK:
+
+               if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags))
+                       return -ENOMEM;
+               pe =  enqueue_an_ATL_packet;
+               break;
+
+       case PIPE_INTERRUPT:
+               if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags))
+                       return -ENOMEM;
+               pe = enqueue_an_INT_packet;
+               break;
+
+       case PIPE_ISOCHRONOUS:
+               printk(KERN_ERR "PIPE_ISOCHRONOUS ain't supported\n");
+       default:
+               return -EPIPE;
+       }
+
+       isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe);
+       return 0;
+}
+
+static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
+               int status)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       struct inter_packet_info *ints;
+       u32 i;
+       u32 reg_base, or_reg, skip_reg;
+       int flags;
+       struct ptd ptd;
+
+       switch (usb_pipetype(urb->pipe)) {
+       case PIPE_ISOCHRONOUS:
+               return -EPIPE;
+               break;
+
+       case PIPE_INTERRUPT:
+               ints = priv->int_ints;
+               reg_base = INT_REGS_OFFSET;
+               or_reg = HC_INT_IRQ_MASK_OR_REG;
+               skip_reg = HC_INT_PTD_SKIPMAP_REG;
+               break;
+
+       default:
+               ints = priv->atl_ints;
+               reg_base = ATL_REGS_OFFSET;
+               or_reg = HC_ATL_IRQ_MASK_OR_REG;
+               skip_reg = HC_ATL_PTD_SKIPMAP_REG;
+               break;
+       }
+
+       memset(&ptd, 0, sizeof(ptd));
+       spin_lock_irqsave(&priv->lock, flags);
+
+       for (i = 0; i < 32; i++) {
+               if (ints->urb == urb) {
+                       u32 skip_map;
+                       u32 or_map;
+                       struct isp1760_qtd *qtd;
+
+                       skip_map = isp1760_readl(hcd->regs + skip_reg);
+                       skip_map |= 1 << i;
+                       isp1760_writel(skip_map, hcd->regs + skip_reg);
+
+                       or_map = isp1760_readl(hcd->regs + or_reg);
+                       or_map &= ~(1 << i);
+                       isp1760_writel(or_map, hcd->regs + or_reg);
+
+                       priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base
+                                       + i * sizeof(ptd), sizeof(ptd));
+                       qtd = ints->qtd;
+
+                       clean_up_qtdlist(qtd);
+
+                       free_mem(priv, ints->payload);
+
+                       ints->urb = NULL;
+                       ints->qh = NULL;
+                       ints->qtd = NULL;
+                       ints->data_buffer = NULL;
+                       ints->payload = 0;
+
+                       isp1760_urb_done(priv, urb, status);
+                       break;
+               }
+               ints++;
+       }
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return 0;
+}
+
+static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(usb_hcd);
+       u32 imask;
+       irqreturn_t irqret = IRQ_NONE;
+
+       spin_lock(&priv->lock);
+
+       if (!(usb_hcd->state & HC_STATE_RUNNING))
+               goto leave;
+
+       imask = isp1760_readl(usb_hcd->regs + HC_INTERRUPT_REG);
+       if (unlikely(!imask))
+               goto leave;
+
+       isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG);
+       if (imask & HC_ATL_INT)
+               do_atl_int(usb_hcd);
+
+       if (imask & HC_INTL_INT)
+               do_intl_int(usb_hcd);
+
+       irqret = IRQ_HANDLED;
+leave:
+       spin_unlock(&priv->lock);
+       return irqret;
+}
+
+static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       u32 temp, status = 0;
+       u32 mask;
+       int retval = 1;
+       unsigned long flags;
+
+       /* if !USB_SUSPEND, root hub timers won't get shut down ... */
+       if (!HC_IS_RUNNING(hcd->state))
+               return 0;
+
+       /* init status to no-changes */
+       buf[0] = 0;
+       mask = PORT_CSC;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       temp = isp1760_readl(hcd->regs + HC_PORTSC1);
+
+       if (temp & PORT_OWNER) {
+               if (temp & PORT_CSC) {
+                       temp &= ~PORT_CSC;
+                       isp1760_writel(temp, hcd->regs + HC_PORTSC1);
+                       goto done;
+               }
+       }
+
+       /*
+        * Return status information even for ports with OWNER set.
+        * Otherwise khubd wouldn't see the disconnect event when a
+        * high-speed device is switched over to the companion
+        * controller by the user.
+        */
+
+       if ((temp & mask) != 0
+                       || ((temp & PORT_RESUME) != 0
+                               && time_after_eq(jiffies,
+                                       priv->reset_done))) {
+               buf [0] |= 1 << (0 + 1);
+               status = STS_PCD;
+       }
+       /* FIXME autosuspend idle root hubs */
+done:
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return status ? retval : 0;
+}
+
+static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
+               struct usb_hub_descriptor *desc)
+{
+       int ports = HCS_N_PORTS(priv->hcs_params);
+       u16 temp;
+
+       desc->bDescriptorType = 0x29;
+       /* priv 1.0, 2.3.9 says 20ms max */
+       desc->bPwrOn2PwrGood = 10;
+       desc->bHubContrCurrent = 0;
+
+       desc->bNbrPorts = ports;
+       temp = 1 + (ports / 8);
+       desc->bDescLength = 7 + 2 * temp;
+
+       /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
+       memset(&desc->bitmap[0], 0, temp);
+       memset(&desc->bitmap[temp], 0xff, temp);
+
+       /* per-port overcurrent reporting */
+       temp = 0x0008;
+       if (HCS_PPC(priv->hcs_params))
+               /* per-port power control */
+               temp |= 0x0001;
+       else
+               /* no power switching */
+               temp |= 0x0002;
+       desc->wHubCharacteristics = cpu_to_le16(temp);
+}
+
+#define        PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
+
+static int check_reset_complete(struct isp1760_hcd *priv, int index,
+               u32 __iomem *status_reg, int port_status)
+{
+       if (!(port_status & PORT_CONNECT))
+               return port_status;
+
+       /* if reset finished and it's still not enabled -- handoff */
+       if (!(port_status & PORT_PE)) {
+
+               printk(KERN_ERR "port %d full speed --> companion\n",
+                       index + 1);
+
+               port_status |= PORT_OWNER;
+               port_status &= ~PORT_RWC_BITS;
+               isp1760_writel(port_status, status_reg);
+
+       } else
+               printk(KERN_ERR "port %d high speed\n", index + 1);
+
+       return port_status;
+}
+
+static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
+               u16 wValue, u16 wIndex, char *buf, u16 wLength)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       int ports = HCS_N_PORTS(priv->hcs_params);
+       u32 __iomem *status_reg = hcd->regs + HC_PORTSC1;
+       u32 temp, status;
+       unsigned long flags;
+       int retval = 0;
+       unsigned selector;
+
+       /*
+        * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
+        * HCS_INDICATOR may say we can change LEDs to off/amber/green.
+        * (track current state ourselves) ... blink for diagnostics,
+        * power, "this is the one", etc.  EHCI spec supports this.
+        */
+
+       spin_lock_irqsave(&priv->lock, flags);
+       switch (typeReq) {
+       case ClearHubFeature:
+               switch (wValue) {
+               case C_HUB_LOCAL_POWER:
+               case C_HUB_OVER_CURRENT:
+                       /* no hub-wide feature/status flags */
+                       break;
+               default:
+                       goto error;
+               }
+               break;
+       case ClearPortFeature:
+               if (!wIndex || wIndex > ports)
+                       goto error;
+               wIndex--;
+               temp = isp1760_readl(status_reg);
+
+               /*
+                * Even if OWNER is set, so the port is owned by the
+                * companion controller, khubd needs to be able to clear
+                * the port-change status bits (especially
+                * USB_PORT_FEAT_C_CONNECTION).
+                */
+
+               switch (wValue) {
+               case USB_PORT_FEAT_ENABLE:
+                       isp1760_writel(temp & ~PORT_PE, status_reg);
+                       break;
+               case USB_PORT_FEAT_C_ENABLE:
+                       /* XXX error? */
+                       break;
+               case USB_PORT_FEAT_SUSPEND:
+                       if (temp & PORT_RESET)
+                               goto error;
+
+                       if (temp & PORT_SUSPEND) {
+                               if ((temp & PORT_PE) == 0)
+                                       goto error;
+                               /* resume signaling for 20 msec */
+                               temp &= ~(PORT_RWC_BITS);
+                               isp1760_writel(temp | PORT_RESUME,
+                                               status_reg);
+                               priv->reset_done = jiffies +
+                                       msecs_to_jiffies(20);
+                       }
+                       break;
+               case USB_PORT_FEAT_C_SUSPEND:
+                       /* we auto-clear this feature */
+                       break;
+               case USB_PORT_FEAT_POWER:
+                       if (HCS_PPC(priv->hcs_params))
+                               isp1760_writel(temp & ~PORT_POWER, status_reg);
+                       break;
+               case USB_PORT_FEAT_C_CONNECTION:
+                       isp1760_writel(temp | PORT_CSC,
+                                       status_reg);
+                       break;
+               case USB_PORT_FEAT_C_OVER_CURRENT:
+                       /* XXX error ?*/
+                       break;
+               case USB_PORT_FEAT_C_RESET:
+                       /* GetPortStatus clears reset */
+                       break;
+               default:
+                       goto error;
+               }
+               isp1760_readl(hcd->regs + HC_USBCMD);
+               break;
+       case GetHubDescriptor:
+               isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *)
+                       buf);
+               break;
+       case GetHubStatus:
+               /* no hub-wide feature/status flags */
+               memset(buf, 0, 4);
+               break;
+       case GetPortStatus:
+               if (!wIndex || wIndex > ports)
+                       goto error;
+               wIndex--;
+               status = 0;
+               temp = isp1760_readl(status_reg);
+
+               /* wPortChange bits */
+               if (temp & PORT_CSC)
+                       status |= 1 << USB_PORT_FEAT_C_CONNECTION;
+
+
+               /* whoever resumes must GetPortStatus to complete it!! */
+               if (temp & PORT_RESUME) {
+                       printk(KERN_ERR "Port resume should be skipped.\n");
+
+                       /* Remote Wakeup received? */
+                       if (!priv->reset_done) {
+                               /* resume signaling for 20 msec */
+                               priv->reset_done = jiffies
+                                               + msecs_to_jiffies(20);
+                               /* check the port again */
+                               mod_timer(&priv_to_hcd(priv)->rh_timer,
+                                               priv->reset_done);
+                       }
+
+                       /* resume completed? */
+                       else if (time_after_eq(jiffies,
+                                       priv->reset_done)) {
+                               status |= 1 << USB_PORT_FEAT_C_SUSPEND;
+                               priv->reset_done = 0;
+
+                               /* stop resume signaling */
+                               temp = isp1760_readl(status_reg);
+                               isp1760_writel(
+                                       temp & ~(PORT_RWC_BITS | PORT_RESUME),
+                                       status_reg);
+                               retval = handshake(priv, status_reg,
+                                          PORT_RESUME, 0, 2000 /* 2msec */);
+                               if (retval != 0) {
+                                       isp1760_err(priv,
+                                               "port %d resume error %d\n",
+                                               wIndex + 1, retval);
+                                       goto error;
+                               }
+                               temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
+                       }
+               }
+
+               /* whoever resets must GetPortStatus to complete it!! */
+               if ((temp & PORT_RESET)
+                               && time_after_eq(jiffies,
+                                       priv->reset_done)) {
+                       status |= 1 << USB_PORT_FEAT_C_RESET;
+                       priv->reset_done = 0;
+
+                       /* force reset to complete */
+                       isp1760_writel(temp & ~PORT_RESET,
+                                       status_reg);
+                       /* REVISIT:  some hardware needs 550+ usec to clear
+                        * this bit; seems too long to spin routinely...
+                        */
+                       retval = handshake(priv, status_reg,
+                                       PORT_RESET, 0, 750);
+                       if (retval != 0) {
+                               isp1760_err(priv, "port %d reset error %d\n",
+                                               wIndex + 1, retval);
+                               goto error;
+                       }
+
+                       /* see what we found out */
+                       temp = check_reset_complete(priv, wIndex, status_reg,
+                                       isp1760_readl(status_reg));
+               }
+               /*
+                * Even if OWNER is set, there's no harm letting khubd
+                * see the wPortStatus values (they should all be 0 except
+                * for PORT_POWER anyway).
+                */
+
+               if (temp & PORT_OWNER)
+                       printk(KERN_ERR "Warning: PORT_OWNER is set\n");
+
+               if (temp & PORT_CONNECT) {
+                       status |= 1 << USB_PORT_FEAT_CONNECTION;
+                       /* status may be from integrated TT */
+                       status |= ehci_port_speed(priv, temp);
+               }
+               if (temp & PORT_PE)
+                       status |= 1 << USB_PORT_FEAT_ENABLE;
+               if (temp & (PORT_SUSPEND|PORT_RESUME))
+                       status |= 1 << USB_PORT_FEAT_SUSPEND;
+               if (temp & PORT_RESET)
+                       status |= 1 << USB_PORT_FEAT_RESET;
+               if (temp & PORT_POWER)
+                       status |= 1 << USB_PORT_FEAT_POWER;
+
+               put_unaligned(cpu_to_le32(status), (__le32 *) buf);
+               break;
+       case SetHubFeature:
+               switch (wValue) {
+               case C_HUB_LOCAL_POWER:
+               case C_HUB_OVER_CURRENT:
+                       /* no hub-wide feature/status flags */
+                       break;
+               default:
+                       goto error;
+               }
+               break;
+       case SetPortFeature:
+               selector = wIndex >> 8;
+               wIndex &= 0xff;
+               if (!wIndex || wIndex > ports)
+                       goto error;
+               wIndex--;
+               temp = isp1760_readl(status_reg);
+               if (temp & PORT_OWNER)
+                       break;
+
+/*             temp &= ~PORT_RWC_BITS; */
+               switch (wValue) {
+               case USB_PORT_FEAT_ENABLE:
+                       isp1760_writel(temp | PORT_PE, status_reg);
+                       break;
+
+               case USB_PORT_FEAT_SUSPEND:
+                       if ((temp & PORT_PE) == 0
+                                       || (temp & PORT_RESET) != 0)
+                               goto error;
+
+                       isp1760_writel(temp | PORT_SUSPEND, status_reg);
+                       break;
+               case USB_PORT_FEAT_POWER:
+                       if (HCS_PPC(priv->hcs_params))
+                               isp1760_writel(temp | PORT_POWER,
+                                               status_reg);
+                       break;
+               case USB_PORT_FEAT_RESET:
+                       if (temp & PORT_RESUME)
+                               goto error;
+                       /* line status bits may report this as low speed,
+                        * which can be fine if this root hub has a
+                        * transaction translator built in.
+                        */
+                       if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
+                                       && PORT_USB11(temp)) {
+                               temp |= PORT_OWNER;
+                       } else {
+                               temp |= PORT_RESET;
+                               temp &= ~PORT_PE;
+
+                               /*
+                                * caller must wait, then call GetPortStatus
+                                * usb 2.0 spec says 50 ms resets on root
+                                */
+                               priv->reset_done = jiffies +
+                                       msecs_to_jiffies(50);
+                       }
+                       isp1760_writel(temp, status_reg);
+                       break;
+               default:
+                       goto error;
+               }
+               isp1760_readl(hcd->regs + HC_USBCMD);
+               break;
+
+       default:
+error:
+               /* "stall" on error */
+               retval = -EPIPE;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return retval;
+}
+
+static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd,
+               struct usb_host_endpoint *ep)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(usb_hcd);
+       struct isp1760_qh *qh;
+       struct isp1760_qtd *qtd;
+       u32 flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       qh = ep->hcpriv;
+       if (!qh)
+               goto out;
+
+       ep->hcpriv = NULL;
+       do {
+               /* more than entry might get removed */
+               if (list_empty(&qh->qtd_list))
+                       break;
+
+               qtd = list_first_entry(&qh->qtd_list, struct isp1760_qtd,
+                               qtd_list);
+
+               if (qtd->status & URB_ENQUEUED) {
+
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       isp1760_urb_dequeue(usb_hcd, qtd->urb, -ECONNRESET);
+                       spin_lock_irqsave(&priv->lock, flags);
+               } else {
+                       struct urb *urb;
+
+                       urb = qtd->urb;
+                       clean_up_qtdlist(qtd);
+                       isp1760_urb_done(priv, urb, -ECONNRESET);
+               }
+       } while (1);
+
+       qh_destroy(qh);
+       /* remove requests and leak them.
+        * ATL are pretty fast done, INT could take a while...
+        * The latter shoule be removed
+        */
+out:
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int isp1760_get_frame(struct usb_hcd *hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       u32 fr;
+
+       fr = isp1760_readl(hcd->regs + HC_FRINDEX);
+       return (fr >> 3) % priv->periodic_size;
+}
+
+static void isp1760_stop(struct usb_hcd *hcd)
+{
+       struct isp1760_hcd *priv = hcd_to_priv(hcd);
+
+       isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,
+                       NULL, 0);
+       mdelay(20);
+
+       spin_lock_irq(&priv->lock);
+       ehci_reset(priv);
+       /* Disable IRQ */
+       isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL);
+       spin_unlock_irq(&priv->lock);
+
+       isp1760_writel(0, hcd->regs + HC_CONFIGFLAG);
+}
+
+static void isp1760_shutdown(struct usb_hcd *hcd)
+{
+       u32 command;
+
+       isp1760_stop(hcd);
+       isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL);
+
+       command = isp1760_readl(hcd->regs + HC_USBCMD);
+       command &= ~CMD_RUN;
+       isp1760_writel(command, hcd->regs + HC_USBCMD);
+}
+
+static const struct hc_driver isp1760_hc_driver = {
+       .description            = "isp1760-hcd",
+       .product_desc           = "NXP ISP1760 USB Host Controller",
+       .hcd_priv_size          = sizeof(struct isp1760_hcd),
+       .irq                    = isp1760_irq,
+       .flags                  = HCD_MEMORY | HCD_USB2,
+       .reset                  = isp1760_hc_setup,
+       .start                  = isp1760_run,
+       .stop                   = isp1760_stop,
+       .shutdown               = isp1760_shutdown,
+       .urb_enqueue            = isp1760_urb_enqueue,
+       .urb_dequeue            = isp1760_urb_dequeue,
+       .endpoint_disable       = isp1760_endpoint_disable,
+       .get_frame_number       = isp1760_get_frame,
+       .hub_status_data        = isp1760_hub_status_data,
+       .hub_control            = isp1760_hub_control,
+};
+
+int __init init_kmem_once(void)
+{
+       qtd_cachep = kmem_cache_create("isp1760_qtd",
+                       sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY |
+                       SLAB_MEM_SPREAD, NULL);
+
+       if (!qtd_cachep)
+               return -ENOMEM;
+
+       qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh),
+                       0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL);
+
+       if (!qh_cachep) {
+               kmem_cache_destroy(qtd_cachep);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void deinit_kmem_cache(void)
+{
+       kmem_cache_destroy(qtd_cachep);
+       kmem_cache_destroy(qh_cachep);
+}
+
+struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
+               u64 irqflags, struct device *dev, const char *busname)
+{
+       struct usb_hcd *hcd;
+       struct isp1760_hcd *priv;
+       int ret;
+
+       if (usb_disabled())
+               return ERR_PTR(-ENODEV);
+
+       /* prevent usb-core allocating DMA pages */
+       dev->dma_mask = NULL;
+
+       hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id);
+       if (!hcd)
+               return ERR_PTR(-ENOMEM);
+
+       priv = hcd_to_priv(hcd);
+       init_memory(priv);
+       hcd->regs = ioremap(res_start, res_len);
+       if (!hcd->regs) {
+               ret = -EIO;
+               goto err_put;
+       }
+
+       ret = usb_add_hcd(hcd, irq, irqflags);
+       if (ret)
+               goto err_unmap;
+
+       hcd->irq = irq;
+       hcd->rsrc_start = res_start;
+       hcd->rsrc_len = res_len;
+
+       return hcd;
+
+err_unmap:
+        iounmap(hcd->regs);
+
+err_put:
+        usb_put_hcd(hcd);
+
+        return ERR_PTR(ret);
+}
+
+MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP");
+MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
new file mode 100644 (file)
index 0000000..3d86d0f
--- /dev/null
@@ -0,0 +1,206 @@
+#ifndef _ISP1760_HCD_H_
+#define _ISP1760_HCD_H_
+
+/* exports for if */
+struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
+               u64 irqflags, struct device *dev, const char *busname);
+int init_kmem_once(void);
+void deinit_kmem_cache(void);
+
+/* EHCI capability registers */
+#define HC_CAPLENGTH           0x00
+#define HC_HCSPARAMS           0x04
+#define HC_HCCPARAMS           0x08
+
+/* EHCI operational registers */
+#define HC_USBCMD              0x20
+#define HC_USBSTS              0x24
+#define HC_FRINDEX             0x2c
+#define HC_CONFIGFLAG          0x60
+#define HC_PORTSC1             0x64
+#define HC_ISO_PTD_DONEMAP_REG 0x130
+#define HC_ISO_PTD_SKIPMAP_REG 0x134
+#define HC_ISO_PTD_LASTPTD_REG 0x138
+#define HC_INT_PTD_DONEMAP_REG 0x140
+#define HC_INT_PTD_SKIPMAP_REG 0x144
+#define HC_INT_PTD_LASTPTD_REG 0x148
+#define HC_ATL_PTD_DONEMAP_REG 0x150
+#define HC_ATL_PTD_SKIPMAP_REG 0x154
+#define HC_ATL_PTD_LASTPTD_REG 0x158
+
+/* Configuration Register */
+#define HC_HW_MODE_CTRL                0x300
+#define ALL_ATX_RESET          (1 << 31)
+#define HW_DATA_BUS_32BIT      (1 << 8)
+#define HW_DACK_POL_HIGH       (1 << 6)
+#define HW_DREQ_POL_HIGH       (1 << 5)
+#define HW_INTR_HIGH_ACT       (1 << 2)
+#define HW_INTR_EDGE_TRIG      (1 << 1)
+#define HW_GLOBAL_INTR_EN      (1 << 0)
+
+#define HC_CHIP_ID_REG         0x304
+#define HC_SCRATCH_REG         0x308
+
+#define HC_RESET_REG           0x30c
+#define SW_RESET_RESET_HC      (1 << 1)
+#define SW_RESET_RESET_ALL     (1 << 0)
+
+#define HC_BUFFER_STATUS_REG   0x334
+#define ATL_BUFFER             0x1
+#define INT_BUFFER             0x2
+#define ISO_BUFFER             0x4
+#define BUFFER_MAP             0x7
+
+#define HC_MEMORY_REG          0x33c
+#define HC_PORT1_CTRL          0x374
+#define PORT1_POWER            (3 << 3)
+#define PORT1_INIT1            (1 << 7)
+#define PORT1_INIT2            (1 << 23)
+
+/* Interrupt Register */
+#define HC_INTERRUPT_REG       0x310
+
+#define HC_INTERRUPT_ENABLE    0x314
+#define INTERRUPT_ENABLE_MASK  (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT)
+#define FINAL_HW_CONFIG        (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT)
+
+#define HC_ISO_INT             (1 << 9)
+#define HC_ATL_INT             (1 << 8)
+#define HC_INTL_INT            (1 << 7)
+#define HC_EOT_INT             (1 << 3)
+#define HC_SOT_INT             (1 << 1)
+
+#define HC_ISO_IRQ_MASK_OR_REG 0x318
+#define HC_INT_IRQ_MASK_OR_REG 0x31C
+#define HC_ATL_IRQ_MASK_OR_REG 0x320
+#define HC_ISO_IRQ_MASK_AND_REG        0x324
+#define HC_INT_IRQ_MASK_AND_REG        0x328
+#define HC_ATL_IRQ_MASK_AND_REG        0x32C
+
+/* Register sets */
+#define HC_BEGIN_OF_ATL                0x0c00
+#define HC_BEGIN_OF_INT                0x0800
+#define HC_BEGIN_OF_ISO                0x0400
+#define HC_BEGIN_OF_PAYLOAD    0x1000
+
+/* urb state*/
+#define DELETE_URB             (0x0008)
+#define NO_TRANSFER_ACTIVE     (0xffffffff)
+
+#define ATL_REGS_OFFSET                (0xc00)
+#define INT_REGS_OFFSET                (0x800)
+
+/* Philips Transfer Descriptor (PTD) */
+struct ptd {
+       __le32 dw0;
+       __le32 dw1;
+       __le32 dw2;
+       __le32 dw3;
+       __le32 dw4;
+       __le32 dw5;
+       __le32 dw6;
+       __le32 dw7;
+};
+
+struct inter_packet_info {
+       void *data_buffer;
+       u32 payload;
+#define PTD_FIRE_NEXT          (1 << 0)
+#define PTD_URB_FINISHED       (1 << 1)
+       struct urb *urb;
+       struct isp1760_qh *qh;
+       struct isp1760_qtd *qtd;
+};
+
+
+typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
+               struct isp1760_qtd *qtd);
+
+#define isp1760_info(priv, fmt, args...) \
+       dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args)
+
+#define isp1760_err(priv, fmt, args...) \
+       dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args)
+
+/* chip memory management */
+struct memory_chunk {
+       unsigned int start;
+       unsigned int size;
+       unsigned int free;
+};
+
+/*
+ * 60kb divided in:
+ * - 32 blocks @ 256  bytes
+ * - 20 blocks @ 1024 bytes
+ * -  4 blocks @ 8192 bytes
+ */
+
+#define BLOCK_1_NUM 32
+#define BLOCK_2_NUM 20
+#define BLOCK_3_NUM 4
+
+#define BLOCK_1_SIZE 256
+#define BLOCK_2_SIZE 1024
+#define BLOCK_3_SIZE 8192
+#define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM)
+#define PAYLOAD_SIZE 0xf000
+
+/* I saw if some reloads if the pointer was negative */
+#define ISP1760_NULL_POINTER   (0x400)
+
+/* ATL */
+/* DW0 */
+#define PTD_VALID                      1
+#define PTD_LENGTH(x)                  (((u32) x) << 3)
+#define PTD_MAXPACKET(x)               (((u32) x) << 18)
+#define PTD_MULTI(x)                   (((u32) x) << 29)
+#define PTD_ENDPOINT(x)                        (((u32) x) << 31)
+/* DW1 */
+#define PTD_DEVICE_ADDR(x)             (((u32) x) << 3)
+#define PTD_PID_TOKEN(x)               (((u32) x) << 10)
+#define PTD_TRANS_BULK                 ((u32) 2 << 12)
+#define PTD_TRANS_INT                  ((u32) 3 << 12)
+#define PTD_TRANS_SPLIT                        ((u32) 1 << 14)
+#define PTD_SE_USB_LOSPEED             ((u32) 2 << 16)
+#define PTD_PORT_NUM(x)                        (((u32) x) << 18)
+#define PTD_HUB_NUM(x)                 (((u32) x) << 25)
+#define PTD_PING(x)                    (((u32) x) << 26)
+/* DW2 */
+#define PTD_RL_CNT(x)                  (((u32) x) << 25)
+#define PTD_DATA_START_ADDR(x)         (((u32) x) << 8)
+#define BASE_ADDR                      0x1000
+/* DW3 */
+#define PTD_CERR(x)                    (((u32) x) << 23)
+#define PTD_NAC_CNT(x)                 (((u32) x) << 19)
+#define PTD_ACTIVE                     ((u32) 1 << 31)
+#define PTD_DATA_TOGGLE(x)             (((u32) x) << 25)
+
+#define DW3_HALT_BIT                   (1 << 30)
+#define DW3_ERROR_BIT                  (1 << 28)
+#define DW3_QTD_ACTIVE                 (1 << 31)
+
+#define INT_UNDERRUN                   (1 << 2)
+#define INT_BABBLE                     (1 << 1)
+#define INT_EXACT                      (1 << 0)
+
+#define DW1_GET_PID(x)                 (((x) >> 10) & 0x3)
+#define PTD_XFERRED_LENGTH(x)          ((x) & 0x7fff)
+#define PTD_XFERRED_LENGTH_LO(x)       ((x) & 0x7ff)
+
+#define SETUP_PID      (2)
+#define IN_PID         (1)
+#define OUT_PID                (0)
+#define GET_QTD_TOKEN_TYPE(x)  ((x) & 0x3)
+
+#define DATA_TOGGLE            (1 << 31)
+#define GET_DATA_TOGGLE(x)     ((x) >> 31)
+
+/* Errata 1 */
+#define RL_COUNTER     (0)
+#define NAK_COUNTER    (0)
+#define ERR_COUNTER    (2)
+
+#define HC_ATL_PL_SIZE (8192)
+
+#endif
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
new file mode 100644 (file)
index 0000000..73fb2a3
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Glue code for the ISP1760 driver and bus
+ * Currently there is support for
+ * - OpenFirmware
+ * - PCI
+ *
+ * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/io.h>
+
+#include "../core/hcd.h"
+#include "isp1760-hcd.h"
+
+#ifdef CONFIG_USB_ISP1760_OF
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#endif
+
+#ifdef CONFIG_USB_ISP1760_PCI
+#include <linux/pci.h>
+#endif
+
+#ifdef CONFIG_USB_ISP1760_OF
+static int of_isp1760_probe(struct of_device *dev,
+               const struct of_device_id *match)
+{
+       struct usb_hcd *hcd;
+       struct device_node *dp = dev->node;
+       struct resource *res;
+       struct resource memory;
+       struct of_irq oirq;
+       int virq;
+       u64 res_len;
+       int ret;
+
+       ret = of_address_to_resource(dp, 0, &memory);
+       if (ret)
+               return -ENXIO;
+
+       res = request_mem_region(memory.start, memory.end - memory.start + 1,
+                       dev->dev.bus_id);
+       if (!res)
+               return -EBUSY;
+
+       res_len = memory.end - memory.start + 1;
+
+       if (of_irq_map_one(dp, 0, &oirq)) {
+               ret = -ENODEV;
+               goto release_reg;
+       }
+
+       virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+                       oirq.size);
+
+       hcd = isp1760_register(memory.start, res_len, virq,
+               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id);
+       if (IS_ERR(hcd)) {
+               ret = PTR_ERR(hcd);
+               goto release_reg;
+       }
+
+       dev_set_drvdata(&dev->dev, hcd);
+       return ret;
+
+release_reg:
+       release_mem_region(memory.start, memory.end - memory.start + 1);
+       return ret;
+}
+
+static int of_isp1760_remove(struct of_device *dev)
+{
+       struct usb_hcd *hcd = dev_get_drvdata(&dev->dev);
+
+       dev_set_drvdata(&dev->dev, NULL);
+
+       usb_remove_hcd(hcd);
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+       return 0;
+}
+
+static struct of_device_id of_isp1760_match[] = {
+       {
+               .compatible = "nxp,usb-isp1760",
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, of_isp1760_match);
+
+static struct of_platform_driver isp1760_of_driver = {
+       .name           = "nxp-isp1760",
+       .match_table    = of_isp1760_match,
+       .probe          = of_isp1760_probe,
+       .remove         = of_isp1760_remove,
+};
+#endif
+
+#ifdef CONFIG_USB_ISP1760_PCI
+static u32 nxp_pci_io_base;
+static u32 iolength;
+static u32 pci_mem_phy0;
+static u32 length;
+static u8 *chip_addr;
+static u8 *iobase;
+
+static int __devinit isp1761_pci_probe(struct pci_dev *dev,
+               const struct pci_device_id *id)
+{
+       u8 latency, limit;
+       __u32 reg_data;
+       int retry_count;
+       int length;
+       int status = 1;
+       struct usb_hcd *hcd;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       if (pci_enable_device(dev) < 0)
+               return -ENODEV;
+
+       if (!dev->irq)
+               return -ENODEV;
+
+       /* Grab the PLX PCI mem maped port start address we need  */
+       nxp_pci_io_base = pci_resource_start(dev, 0);
+       iolength = pci_resource_len(dev, 0);
+
+       if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
+               printk(KERN_ERR "request region #1\n");
+               return -EBUSY;
+       }
+
+       iobase = ioremap_nocache(nxp_pci_io_base, iolength);
+       if (!iobase) {
+               printk(KERN_ERR "ioremap #1\n");
+               release_mem_region(nxp_pci_io_base, iolength);
+               return -ENOMEM;
+       }
+       /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
+       pci_mem_phy0 = pci_resource_start(dev, 3);
+       length = pci_resource_len(dev, 3);
+
+       if (length < 0xffff) {
+               printk(KERN_ERR "memory length for this resource is less than "
+                               "required\n");
+               release_mem_region(nxp_pci_io_base, iolength);
+               iounmap(iobase);
+               return  -ENOMEM;
+       }
+
+       if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) {
+               printk(KERN_ERR "host controller already in use\n");
+               release_mem_region(nxp_pci_io_base, iolength);
+               iounmap(iobase);
+               return -EBUSY;
+       }
+
+       /* bad pci latencies can contribute to overruns */
+       pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
+       if (latency) {
+               pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
+               if (limit && limit < latency)
+                       pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
+       }
+
+       /* Try to check whether we can access Scratch Register of
+        * Host Controller or not. The initial PCI access is retried until
+        * local init for the PCI bridge is completed
+        */
+       retry_count = 20;
+       reg_data = 0;
+       while ((reg_data != 0xFACE) && retry_count) {
+               /*by default host is in 16bit mode, so
+                * io operations at this stage must be 16 bit
+                * */
+               writel(0xface, chip_addr + HC_SCRATCH_REG);
+               udelay(100);
+               reg_data = readl(chip_addr + HC_SCRATCH_REG);
+               retry_count--;
+       }
+
+       /* Host Controller presence is detected by writing to scratch register
+        * and reading back and checking the contents are same or not
+        */
+       if (reg_data != 0xFACE) {
+               err("scratch register mismatch %x", reg_data);
+               goto clean;
+       }
+
+       pci_set_master(dev);
+
+       status = readl(iobase + 0x68);
+       status |= 0x900;
+       writel(status, iobase + 0x68);
+
+       dev->dev.dma_mask = NULL;
+       hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
+               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id);
+       pci_set_drvdata(dev, hcd);
+       if (!hcd)
+               return 0;
+clean:
+       status = -ENODEV;
+       iounmap(iobase);
+       release_mem_region(pci_mem_phy0, length);
+       release_mem_region(nxp_pci_io_base, iolength);
+       return status;
+}
+static void isp1761_pci_remove(struct pci_dev *dev)
+{
+       struct usb_hcd *hcd;
+
+       hcd = pci_get_drvdata(dev);
+
+       usb_remove_hcd(hcd);
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       pci_disable_device(dev);
+
+       iounmap(iobase);
+       iounmap(chip_addr);
+
+       release_mem_region(nxp_pci_io_base, iolength);
+       release_mem_region(pci_mem_phy0, length);
+}
+
+static void isp1761_pci_shutdown(struct pci_dev *dev)
+{
+       printk(KERN_ERR "ips1761_pci_shutdown\n");
+}
+
+static const struct pci_device_id isp1760_plx [] = { {
+       /* handle any USB 2.0 EHCI controller */
+       PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0),
+               .driver_data = 0,
+},
+{ /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, isp1760_plx);
+
+static struct pci_driver isp1761_pci_driver = {
+       .name =         "isp1760",
+       .id_table =     isp1760_plx,
+       .probe =        isp1761_pci_probe,
+       .remove =       isp1761_pci_remove,
+       .shutdown =     isp1761_pci_shutdown,
+};
+#endif
+
+static int __init isp1760_init(void)
+{
+       int ret;
+
+       init_kmem_once();
+
+#ifdef CONFIG_USB_ISP1760_OF
+       ret = of_register_platform_driver(&isp1760_of_driver);
+       if (ret) {
+               deinit_kmem_cache();
+               return ret;
+       }
+#endif
+#ifdef CONFIG_USB_ISP1760_PCI
+       ret = pci_register_driver(&isp1761_pci_driver);
+       if (ret)
+               goto unreg_of;
+#endif
+       return ret;
+
+#ifdef CONFIG_USB_ISP1760_PCI
+unreg_of:
+#endif
+#ifdef CONFIG_USB_ISP1760_OF
+       of_unregister_platform_driver(&isp1760_of_driver);
+#endif
+       deinit_kmem_cache();
+       return ret;
+}
+module_init(isp1760_init);
+
+static void __exit isp1760_exit(void)
+{
+#ifdef CONFIG_USB_ISP1760_OF
+       of_unregister_platform_driver(&isp1760_of_driver);
+#endif
+#ifdef CONFIG_USB_ISP1760_PCI
+       pci_unregister_driver(&isp1761_pci_driver);
+#endif
+       deinit_kmem_cache();
+}
+module_exit(isp1760_exit);
index 17dc2eccda83e7d6dca6bfd725fbd87fdce8b649..79a78029f896869892fa2696bd8f1764cc79f9e7 100644 (file)
@@ -613,7 +613,7 @@ static void start_hnp(struct ohci_hcd *ohci);
 static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
 {
        __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
-       u32     temp;
+       u32     temp = 0;
        u16     now = ohci_readl(ohci, &ohci->regs->fmnumber);
        u16     reset_done = now + PORT_RESET_MSEC;
        int     limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC);
index d3e0d8aa398078f7c5c15313f19f656202dcafaa..3a7bfe7a8874c321990bb802910ea4a902671c9a 100644 (file)
@@ -234,7 +234,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
        return 0;
 }
 
-static int remote_wakeup_is_broken(struct uhci_hcd *uhci)
+static int global_suspend_mode_is_broken(struct uhci_hcd *uhci)
 {
        int port;
        const char *sys_info;
@@ -261,27 +261,60 @@ __releases(uhci->lock)
 __acquires(uhci->lock)
 {
        int auto_stop;
-       int int_enable, egsm_enable;
+       int int_enable, egsm_enable, wakeup_enable;
        struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub;
 
        auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
        dev_dbg(&rhdev->dev, "%s%s\n", __func__,
                        (auto_stop ? " (auto-stop)" : ""));
 
-       /* Enable resume-detect interrupts if they work.
-        * Then enter Global Suspend mode if _it_ works, still configured.
+       /* Start off by assuming Resume-Detect interrupts and EGSM work
+        * and that remote wakeups should be enabled.
         */
        egsm_enable = USBCMD_EGSM;
-       uhci->working_RD = 1;
+       uhci->RD_enable = 1;
        int_enable = USBINTR_RESUME;
-       if (remote_wakeup_is_broken(uhci))
-               egsm_enable = 0;
-       if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable ||
+       wakeup_enable = 1;
+
+       /* In auto-stop mode wakeups must always be detected, but
+        * Resume-Detect interrupts may be prohibited.  (In the absence
+        * of CONFIG_PM, they are always disallowed.)
+        */
+       if (auto_stop) {
+               if (!device_may_wakeup(&rhdev->dev))
+                       int_enable = 0;
+
+       /* In bus-suspend mode wakeups may be disabled, but if they are
+        * allowed then so are Resume-Detect interrupts.
+        */
+       } else {
 #ifdef CONFIG_PM
-                       (!auto_stop && !rhdev->do_remote_wakeup) ||
+               if (!rhdev->do_remote_wakeup)
+                       wakeup_enable = 0;
 #endif
-                       (auto_stop && !device_may_wakeup(&rhdev->dev)))
-               uhci->working_RD = int_enable = 0;
+       }
+
+       /* EGSM causes the root hub to echo a 'K' signal (resume) out any
+        * port which requests a remote wakeup.  According to the USB spec,
+        * every hub is supposed to do this.  But if we are ignoring
+        * remote-wakeup requests anyway then there's no point to it.
+        * We also shouldn't enable EGSM if it's broken.
+        */
+       if (!wakeup_enable || global_suspend_mode_is_broken(uhci))
+               egsm_enable = 0;
+
+       /* If we're ignoring wakeup events then there's no reason to
+        * enable Resume-Detect interrupts.  We also shouldn't enable
+        * them if they are broken or disallowed.
+        *
+        * This logic may lead us to enabling RD but not EGSM.  The UHCI
+        * spec foolishly says that RD works only when EGSM is on, but
+        * there's no harm in enabling it anyway -- perhaps some chips
+        * will implement it!
+        */
+       if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) ||
+                       !int_enable)
+               uhci->RD_enable = int_enable = 0;
 
        outw(int_enable, uhci->io_addr + USBINTR);
        outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD);
@@ -308,7 +341,11 @@ __acquires(uhci->lock)
 
        uhci->rh_state = new_state;
        uhci->is_stopped = UHCI_IS_STOPPED;
-       uhci_to_hcd(uhci)->poll_rh = !int_enable;
+
+       /* If interrupts don't work and remote wakeup is enabled then
+        * the suspended root hub needs to be polled.
+        */
+       uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable);
 
        uhci_scan_schedule(uhci);
        uhci_fsbr_off(uhci);
@@ -344,9 +381,12 @@ __acquires(uhci->lock)
         * for 20 ms.
         */
        if (uhci->rh_state == UHCI_RH_SUSPENDED) {
+               unsigned egsm;
+
+               /* Keep EGSM on if it was set before */
+               egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM;
                uhci->rh_state = UHCI_RH_RESUMING;
-               outw(USBCMD_FGR | USBCMD_EGSM | USBCMD_CF,
-                               uhci->io_addr + USBCMD);
+               outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD);
                spin_unlock_irq(&uhci->lock);
                msleep(20);
                spin_lock_irq(&uhci->lock);
@@ -801,8 +841,10 @@ static int uhci_pci_resume(struct usb_hcd *hcd)
 
        spin_unlock_irq(&uhci->lock);
 
-       if (!uhci->working_RD) {
-               /* Suspended root hub needs to be polled */
+       /* If interrupts don't work and remote wakeup is enabled then
+        * the suspended root hub needs to be polled.
+        */
+       if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) {
                hcd->poll_rh = 1;
                usb_hcd_poll_rh_status(hcd);
        }
index 340d6ed3e6e92006c858e80ee8bdcd5f0ef0b179..7d01c5677f92ced1517c73dc562e853c2e6990fa 100644 (file)
@@ -400,8 +400,9 @@ struct uhci_hcd {
        unsigned int scan_in_progress:1;        /* Schedule scan is running */
        unsigned int need_rescan:1;             /* Redo the schedule scan */
        unsigned int dead:1;                    /* Controller has died */
-       unsigned int working_RD:1;              /* Suspended root hub doesn't
-                                                  need to be polled */
+       unsigned int RD_enable:1;               /* Suspended root hub with
+                                                  Resume-Detect interrupts
+                                                  enabled */
        unsigned int is_initialized:1;          /* Data structure is usable */
        unsigned int fsbr_is_on:1;              /* FSBR is turned on */
        unsigned int fsbr_is_wanted:1;          /* Does any URB want FSBR? */
index 11580e81e2c633b0163214680342334105b64dc8..7aafd53fbcab8452c08b1c510e2f6537a7f8f987 100644 (file)
@@ -148,7 +148,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in
 
 /* Structure to hold all of our device specific stuff */
 struct ld_usb {
-       struct semaphore        sem;            /* locks this structure */
+       struct mutex            mutex;          /* locks this structure */
        struct usb_interface*   intf;           /* save off the usb interface pointer */
 
        int                     open_count;     /* number of times this port has been opened */
@@ -319,7 +319,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
                return -ENODEV;
 
        /* lock this device */
-       if (down_interruptible(&dev->sem))
+       if (mutex_lock_interruptible(&dev->mutex))
                return -ERESTARTSYS;
 
        /* allow opening only once */
@@ -358,7 +358,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
        file->private_data = dev;
 
 unlock_exit:
-       up(&dev->sem);
+       mutex_unlock(&dev->mutex);
 
        return retval;
 }
@@ -378,7 +378,7 @@ static int ld_usb_release(struct inode *inode, struct file *file)
                goto exit;
        }
 
-       if (down_interruptible(&dev->sem)) {
+       if (mutex_lock_interruptible(&dev->mutex)) {
                retval = -ERESTARTSYS;
                goto exit;
        }
@@ -389,7 +389,7 @@ static int ld_usb_release(struct inode *inode, struct file *file)
        }
        if (dev->intf == NULL) {
                /* the device was unplugged before the file was released */
-               up(&dev->sem);
+               mutex_unlock(&dev->mutex);
                /* unlock here as ld_usb_delete frees dev */
                ld_usb_delete(dev);
                goto exit;
@@ -402,7 +402,7 @@ static int ld_usb_release(struct inode *inode, struct file *file)
        dev->open_count = 0;
 
 unlock_exit:
-       up(&dev->sem);
+       mutex_unlock(&dev->mutex);
 
 exit:
        return retval;
@@ -448,7 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
                goto exit;
 
        /* lock this object */
-       if (down_interruptible(&dev->sem)) {
+       if (mutex_lock_interruptible(&dev->mutex)) {
                retval = -ERESTARTSYS;
                goto exit;
        }
@@ -505,7 +505,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
 
 unlock_exit:
        /* unlock the device */
-       up(&dev->sem);
+       mutex_unlock(&dev->mutex);
 
 exit:
        return retval;
@@ -528,7 +528,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
                goto exit;
 
        /* lock this object */
-       if (down_interruptible(&dev->sem)) {
+       if (mutex_lock_interruptible(&dev->mutex)) {
                retval = -ERESTARTSYS;
                goto exit;
        }
@@ -602,7 +602,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
 
 unlock_exit:
        /* unlock the device */
-       up(&dev->sem);
+       mutex_unlock(&dev->mutex);
 
 exit:
        return retval;
@@ -651,7 +651,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
                dev_err(&intf->dev, "Out of memory\n");
                goto exit;
        }
-       init_MUTEX(&dev->sem);
+       mutex_init(&dev->mutex);
        spin_lock_init(&dev->rbsl);
        dev->intf = intf;
        init_waitqueue_head(&dev->read_wait);
@@ -765,15 +765,15 @@ static void ld_usb_disconnect(struct usb_interface *intf)
        /* give back our minor */
        usb_deregister_dev(intf, &ld_usb_class);
 
-       down(&dev->sem);
+       mutex_lock(&dev->mutex);
 
        /* if the device is not opened, then we clean up right now */
        if (!dev->open_count) {
-               up(&dev->sem);
+               mutex_unlock(&dev->mutex);
                ld_usb_delete(dev);
        } else {
                dev->intf = NULL;
-               up(&dev->sem);
+               mutex_unlock(&dev->mutex);
        }
 
        dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
index a51983854ca0625da79cbf97daa98b75090b4199..742be3c3594788b23464050e1a09afafed91fbde 100644 (file)
@@ -79,30 +79,10 @@ static struct usb_device *testdev_to_usbdev (struct usbtest_dev *test)
 /* set up all urbs so they can be used with either bulk or interrupt */
 #define        INTERRUPT_RATE          1       /* msec/transfer */
 
-#define xprintk(tdev,level,fmt,args...) \
-       dev_printk(level ,  &(tdev)->intf->dev ,  fmt ,  ## args)
-
-#ifdef DEBUG
-#define DBG(dev,fmt,args...) \
-       xprintk(dev , KERN_DEBUG , fmt , ## args)
-#else
-#define DBG(dev,fmt,args...) \
-       do { } while (0)
-#endif /* DEBUG */
-
-#ifdef VERBOSE
-#define VDBG DBG
-#else
-#define VDBG(dev,fmt,args...) \
-       do { } while (0)
-#endif /* VERBOSE */
-
-#define ERROR(dev,fmt,args...) \
-       xprintk(dev , KERN_ERR , fmt , ## args)
-#define WARN(dev,fmt,args...) \
-       xprintk(dev , KERN_WARNING , fmt , ## args)
-#define INFO(dev,fmt,args...) \
-       xprintk(dev , KERN_INFO , fmt , ## args)
+#define ERROR(tdev, fmt, args...) \
+       dev_err(&(tdev)->intf->dev , fmt , ## args)
+#define WARN(tdev, fmt, args...) \
+       dev_warn(&(tdev)->intf->dev , fmt , ## args)
 
 /*-------------------------------------------------------------------------*/
 
@@ -236,7 +216,7 @@ static struct urb *simple_alloc_urb (
 
 static unsigned pattern = 0;
 module_param (pattern, uint, S_IRUGO);
-// MODULE_PARM_DESC (pattern, "i/o pattern (0 == zeroes)");
+MODULE_PARM_DESC(pattern, "i/o pattern (0 == zeroes)");
 
 static inline void simple_fill_buf (struct urb *urb)
 {
@@ -257,7 +237,7 @@ static inline void simple_fill_buf (struct urb *urb)
        }
 }
 
-static inline int simple_check_buf (struct urb *urb)
+static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
 {
        unsigned        i;
        u8              expected;
@@ -285,7 +265,7 @@ static inline int simple_check_buf (struct urb *urb)
                }
                if (*buf == expected)
                        continue;
-               dbg ("buf[%d] = %d (not %d)", i, *buf, expected);
+               ERROR(tdev, "buf[%d] = %d (not %d)\n", i, *buf, expected);
                return -EINVAL;
        }
        return 0;
@@ -299,6 +279,7 @@ static void simple_free_urb (struct urb *urb)
 }
 
 static int simple_io (
+       struct usbtest_dev      *tdev,
        struct urb              *urb,
        int                     iterations,
        int                     vary,
@@ -324,7 +305,7 @@ static int simple_io (
                retval = urb->status;
                urb->dev = udev;
                if (retval == 0 && usb_pipein (urb->pipe))
-                       retval = simple_check_buf (urb);
+                       retval = simple_check_buf(tdev, urb);
 
                if (vary) {
                        int     len = urb->transfer_buffer_length;
@@ -341,7 +322,7 @@ static int simple_io (
        urb->transfer_buffer_length = max;
 
        if (expected != retval)
-               dev_dbg (&udev->dev,
+               dev_err(&udev->dev,
                        "%s failed, iterations left %d, status %d (not %d)\n",
                                label, iterations, retval, expected);
        return retval;
@@ -357,7 +338,7 @@ static int simple_io (
 static void free_sglist (struct scatterlist *sg, int nents)
 {
        unsigned                i;
-       
+
        if (!sg)
                return;
        for (i = 0; i < nents; i++) {
@@ -415,7 +396,7 @@ alloc_sglist (int nents, int max, int vary)
 }
 
 static int perform_sglist (
-       struct usb_device       *udev,
+       struct usbtest_dev      *tdev,
        unsigned                iterations,
        int                     pipe,
        struct usb_sg_request   *req,
@@ -423,6 +404,7 @@ static int perform_sglist (
        int                     nents
 )
 {
+       struct usb_device       *udev = testdev_to_usbdev(tdev);
        int                     retval = 0;
 
        while (retval == 0 && iterations-- > 0) {
@@ -431,7 +413,7 @@ static int perform_sglist (
                                        ? (INTERRUPT_RATE << 3)
                                        : INTERRUPT_RATE,
                                sg, nents, 0, GFP_KERNEL);
-               
+
                if (retval)
                        break;
                usb_sg_wait (req);
@@ -446,7 +428,8 @@ static int perform_sglist (
        // failure if retval is as we expected ...
 
        if (retval)
-               dbg ("perform_sglist failed, iterations left %d, status %d",
+               ERROR(tdev, "perform_sglist failed, "
+                               "iterations left %d, status %d\n",
                                iterations, retval);
        return retval;
 }
@@ -505,28 +488,28 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate)
                        alternate);
 }
 
-static int is_good_config (char *buf, int len)
+static int is_good_config(struct usbtest_dev *tdev, int len)
 {
        struct usb_config_descriptor    *config;
-       
+
        if (len < sizeof *config)
                return 0;
-       config = (struct usb_config_descriptor *) buf;
+       config = (struct usb_config_descriptor *) tdev->buf;
 
        switch (config->bDescriptorType) {
        case USB_DT_CONFIG:
        case USB_DT_OTHER_SPEED_CONFIG:
                if (config->bLength != 9) {
-                       dbg ("bogus config descriptor length");
+                       ERROR(tdev, "bogus config descriptor length\n");
                        return 0;
                }
                /* this bit 'must be 1' but often isn't */
                if (!realworld && !(config->bmAttributes & 0x80)) {
-                       dbg ("high bit of config attributes not set");
+                       ERROR(tdev, "high bit of config attributes not set\n");
                        return 0;
                }
                if (config->bmAttributes & 0x1f) {      /* reserved == 0 */
-                       dbg ("reserved config bits set");
+                       ERROR(tdev, "reserved config bits set\n");
                        return 0;
                }
                break;
@@ -538,7 +521,7 @@ static int is_good_config (char *buf, int len)
                return 1;
        if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE)             /* max partial read */
                return 1;
-       dbg ("bogus config descriptor read size");
+       ERROR(tdev, "bogus config descriptor read size\n");
        return 0;
 }
 
@@ -571,7 +554,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                /* 9.2.3 constrains the range here */
                alt = iface->altsetting [i].desc.bAlternateSetting;
                if (alt < 0 || alt >= iface->num_altsetting) {
-                       dev_dbg (&iface->dev,
+                       dev_err(&iface->dev,
                                        "invalid alt [%d].bAltSetting = %d\n",
                                        i, alt);
                }
@@ -583,7 +566,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                /* [9.4.10] set_interface */
                retval = set_altsetting (dev, alt);
                if (retval) {
-                       dev_dbg (&iface->dev, "can't set_interface = %d, %d\n",
+                       dev_err(&iface->dev, "can't set_interface = %d, %d\n",
                                        alt, retval);
                        return retval;
                }
@@ -591,7 +574,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                /* [9.4.4] get_interface always works */
                retval = get_altsetting (dev);
                if (retval != alt) {
-                       dev_dbg (&iface->dev, "get alt should be %d, was %d\n",
+                       dev_err(&iface->dev, "get alt should be %d, was %d\n",
                                        alt, retval);
                        return (retval < 0) ? retval : -EDOM;
                }
@@ -611,7 +594,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                                USB_DIR_IN | USB_RECIP_DEVICE,
                                0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT);
                if (retval != 1 || dev->buf [0] != expected) {
-                       dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n",
+                       dev_err(&iface->dev, "get config --> %d %d (1 %d)\n",
                                retval, dev->buf[0], expected);
                        return (retval < 0) ? retval : -EDOM;
                }
@@ -621,7 +604,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
        retval = usb_get_descriptor (udev, USB_DT_DEVICE, 0,
                        dev->buf, sizeof udev->descriptor);
        if (retval != sizeof udev->descriptor) {
-               dev_dbg (&iface->dev, "dev descriptor --> %d\n", retval);
+               dev_err(&iface->dev, "dev descriptor --> %d\n", retval);
                return (retval < 0) ? retval : -EDOM;
        }
 
@@ -629,8 +612,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
        for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
                retval = usb_get_descriptor (udev, USB_DT_CONFIG, i,
                                dev->buf, TBUF_SIZE);
-               if (!is_good_config (dev->buf, retval)) {
-                       dev_dbg (&iface->dev,
+               if (!is_good_config(dev, retval)) {
+                       dev_err(&iface->dev,
                                        "config [%d] descriptor --> %d\n",
                                        i, retval);
                        return (retval < 0) ? retval : -EDOM;
@@ -650,14 +633,14 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                                sizeof (struct usb_qualifier_descriptor));
                if (retval == -EPIPE) {
                        if (udev->speed == USB_SPEED_HIGH) {
-                               dev_dbg (&iface->dev,
+                               dev_err(&iface->dev,
                                                "hs dev qualifier --> %d\n",
                                                retval);
                                return (retval < 0) ? retval : -EDOM;
                        }
                        /* usb2.0 but not high-speed capable; fine */
                } else if (retval != sizeof (struct usb_qualifier_descriptor)) {
-                       dev_dbg (&iface->dev, "dev qualifier --> %d\n", retval);
+                       dev_err(&iface->dev, "dev qualifier --> %d\n", retval);
                        return (retval < 0) ? retval : -EDOM;
                } else
                        d = (struct usb_qualifier_descriptor *) dev->buf;
@@ -669,8 +652,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
                                retval = usb_get_descriptor (udev,
                                        USB_DT_OTHER_SPEED_CONFIG, i,
                                        dev->buf, TBUF_SIZE);
-                               if (!is_good_config (dev->buf, retval)) {
-                                       dev_dbg (&iface->dev,
+                               if (!is_good_config(dev, retval)) {
+                                       dev_err(&iface->dev,
                                                "other speed config --> %d\n",
                                                retval);
                                        return (retval < 0) ? retval : -EDOM;
@@ -683,7 +666,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
        /* [9.4.5] get_status always works */
        retval = usb_get_status (udev, USB_RECIP_DEVICE, 0, dev->buf);
        if (retval != 2) {
-               dev_dbg (&iface->dev, "get dev status --> %d\n", retval);
+               dev_err(&iface->dev, "get dev status --> %d\n", retval);
                return (retval < 0) ? retval : -EDOM;
        }
 
@@ -693,11 +676,11 @@ static int ch9_postconfig (struct usbtest_dev *dev)
        retval = usb_get_status (udev, USB_RECIP_INTERFACE,
                        iface->altsetting [0].desc.bInterfaceNumber, dev->buf);
        if (retval != 2) {
-               dev_dbg (&iface->dev, "get interface status --> %d\n", retval);
+               dev_err(&iface->dev, "get interface status --> %d\n", retval);
                return (retval < 0) ? retval : -EDOM;
        }
        // FIXME get status for each endpoint in the interface
-       
+
        return 0;
 }
 
@@ -752,8 +735,9 @@ static void ctrl_complete (struct urb *urb)
         */
        if (subcase->number > 0) {
                if ((subcase->number - ctx->last) != 1) {
-                       dbg ("subcase %d completed out of order, last %d",
-                                       subcase->number, ctx->last);
+                       ERROR(ctx->dev,
+                               "subcase %d completed out of order, last %d\n",
+                               subcase->number, ctx->last);
                        status = -EDOM;
                        ctx->last = subcase->number;
                        goto error;
@@ -777,7 +761,7 @@ static void ctrl_complete (struct urb *urb)
                else if (subcase->number == 12 && status == -EPIPE)
                        status = 0;
                else
-                       dbg ("subtest %d error, status %d",
+                       ERROR(ctx->dev, "subtest %d error, status %d\n",
                                        subcase->number, status);
        }
 
@@ -788,9 +772,12 @@ error:
                        int             i;
 
                        ctx->status = status;
-                       info ("control queue %02x.%02x, err %d, %d left",
+                       ERROR(ctx->dev, "control queue %02x.%02x, err %d, "
+                                       "%d left, subcase %d, len %d/%d\n",
                                        reqp->bRequestType, reqp->bRequest,
-                                       status, ctx->count);
+                                       status, ctx->count, subcase->number,
+                                       urb->actual_length,
+                                       urb->transfer_buffer_length);
 
                        /* FIXME this "unlink everything" exit route should
                         * be a separate test case.
@@ -799,7 +786,8 @@ error:
                        /* unlink whatever's still pending */
                        for (i = 1; i < ctx->param->sglen; i++) {
                                struct urb      *u = ctx->urb [
-       (i + subcase->number) % ctx->param->sglen];
+                                               (i + subcase->number)
+                                               % ctx->param->sglen];
 
                                if (u == urb || !u->dev)
                                        continue;
@@ -812,7 +800,8 @@ error:
                                case -EIDRM:
                                        continue;
                                default:
-                                       dbg ("urb unlink --> %d", status);
+                                       ERROR(ctx->dev, "urb unlink --> %d\n",
+                                                       status);
                                }
                        }
                        status = ctx->status;
@@ -822,14 +811,15 @@ error:
        /* resubmit if we need to, else mark this as done */
        if ((status == 0) && (ctx->pending < ctx->count)) {
                if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) {
-                       dbg ("can't resubmit ctrl %02x.%02x, err %d",
+                       ERROR(ctx->dev,
+                               "can't resubmit ctrl %02x.%02x, err %d\n",
                                reqp->bRequestType, reqp->bRequest, status);
                        urb->dev = NULL;
                } else
                        ctx->pending++;
        } else
                urb->dev = NULL;
-       
+
        /* signal completion when nothing's queued */
        if (ctx->pending == 0)
                complete (&ctx->complete);
@@ -918,11 +908,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
                        req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8);
                        // interface == 0
                        len = sizeof (struct usb_interface_descriptor);
-                       expected = EPIPE;
+                       expected = -EPIPE;
                        break;
                // NOTE: two consecutive stalls in the queue here.
                // that tests fault recovery a bit more aggressively.
-               case 8:         // clear endpoint halt (USUALLY STALLS)
+               case 8:         // clear endpoint halt (MAY STALL)
                        req.bRequest = USB_REQ_CLEAR_FEATURE;
                        req.bRequestType = USB_RECIP_ENDPOINT;
                        // wValue 0 == ep halt
@@ -965,7 +955,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
                        break;
                case 14:        // short read; try to fill the last packet
                        req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0);
-                       // device descriptor size == 18 bytes 
+                       /* device descriptor size == 18 bytes */
                        len = udev->descriptor.bMaxPacketSize0;
                        switch (len) {
                        case 8:         len = 24; break;
@@ -974,7 +964,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
                        expected = -EREMOTEIO;
                        break;
                default:
-                       err ("bogus number of ctrl queue testcases!");
+                       ERROR(dev, "bogus number of ctrl queue testcases!\n");
                        context.status = -EINVAL;
                        goto cleanup;
                }
@@ -1003,7 +993,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
        for (i = 0; i < param->sglen; i++) {
                context.status = usb_submit_urb (urb [i], GFP_ATOMIC);
                if (context.status != 0) {
-                       dbg ("can't submit urb[%d], status %d",
+                       ERROR(dev, "can't submit urb[%d], status %d\n",
                                        i, context.status);
                        context.count = context.pending;
                        break;
@@ -1070,7 +1060,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
         * due to errors, or is just NAKing requests.
         */
        if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) {
-               dev_dbg (&dev->intf->dev, "submit fail %d\n", retval);
+               dev_err(&dev->intf->dev, "submit fail %d\n", retval);
                return retval;
        }
 
@@ -1087,13 +1077,13 @@ retry:
                         * "normal" drivers would prevent resubmission, but
                         * since we're testing unlink paths, we can't.
                         */
-                       dev_dbg (&dev->intf->dev, "unlink retry\n");
+                       ERROR(dev,  "unlink retry\n");
                        goto retry;
                }
        } else
                usb_kill_urb (urb);
        if (!(retval == 0 || retval == -EINPROGRESS)) {
-               dev_dbg (&dev->intf->dev, "unlink fail %d\n", retval);
+               dev_err(&dev->intf->dev, "unlink fail %d\n", retval);
                return retval;
        }
 
@@ -1121,7 +1111,7 @@ static int unlink_simple (struct usbtest_dev *dev, int pipe, int len)
 
 /*-------------------------------------------------------------------------*/
 
-static int verify_not_halted (int ep, struct urb *urb)
+static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
 {
        int     retval;
        u16     status;
@@ -1129,20 +1119,21 @@ static int verify_not_halted (int ep, struct urb *urb)
        /* shouldn't look or act halted */
        retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status);
        if (retval < 0) {
-               dbg ("ep %02x couldn't get no-halt status, %d", ep, retval);
+               ERROR(tdev, "ep %02x couldn't get no-halt status, %d\n",
+                               ep, retval);
                return retval;
        }
        if (status != 0) {
-               dbg ("ep %02x bogus status: %04x != 0", ep, status);
+               ERROR(tdev, "ep %02x bogus status: %04x != 0\n", ep, status);
                return -EINVAL;
        }
-       retval = simple_io (urb, 1, 0, 0, __func__);
+       retval = simple_io(tdev, urb, 1, 0, 0, __func__);
        if (retval != 0)
                return -EINVAL;
        return 0;
 }
 
-static int verify_halted (int ep, struct urb *urb)
+static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
 {
        int     retval;
        u16     status;
@@ -1150,29 +1141,30 @@ static int verify_halted (int ep, struct urb *urb)
        /* should look and act halted */
        retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status);
        if (retval < 0) {
-               dbg ("ep %02x couldn't get halt status, %d", ep, retval);
+               ERROR(tdev, "ep %02x couldn't get halt status, %d\n",
+                               ep, retval);
                return retval;
        }
        le16_to_cpus(&status);
        if (status != 1) {
-               dbg ("ep %02x bogus status: %04x != 1", ep, status);
+               ERROR(tdev, "ep %02x bogus status: %04x != 1\n", ep, status);
                return -EINVAL;
        }
-       retval = simple_io (urb, 1, 0, -EPIPE, __func__);
+       retval = simple_io(tdev, urb, 1, 0, -EPIPE, __func__);
        if (retval != -EPIPE)
                return -EINVAL;
-       retval = simple_io (urb, 1, 0, -EPIPE, "verify_still_halted");
+       retval = simple_io(tdev, urb, 1, 0, -EPIPE, "verify_still_halted");
        if (retval != -EPIPE)
                return -EINVAL;
        return 0;
 }
 
-static int test_halt (int ep, struct urb *urb)
+static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb)
 {
        int     retval;
 
        /* shouldn't look or act halted now */
-       retval = verify_not_halted (ep, urb);
+       retval = verify_not_halted(tdev, ep, urb);
        if (retval < 0)
                return retval;
 
@@ -1182,20 +1174,20 @@ static int test_halt (int ep, struct urb *urb)
                        USB_ENDPOINT_HALT, ep,
                        NULL, 0, USB_CTRL_SET_TIMEOUT);
        if (retval < 0) {
-               dbg ("ep %02x couldn't set halt, %d", ep, retval);
+               ERROR(tdev, "ep %02x couldn't set halt, %d\n", ep, retval);
                return retval;
        }
-       retval = verify_halted (ep, urb);
+       retval = verify_halted(tdev, ep, urb);
        if (retval < 0)
                return retval;
 
        /* clear halt (tests API + protocol), verify it worked */
        retval = usb_clear_halt (urb->dev, urb->pipe);
        if (retval < 0) {
-               dbg ("ep %02x couldn't clear halt, %d", ep, retval);
+               ERROR(tdev, "ep %02x couldn't clear halt, %d\n", ep, retval);
                return retval;
        }
-       retval = verify_not_halted (ep, urb);
+       retval = verify_not_halted(tdev, ep, urb);
        if (retval < 0)
                return retval;
 
@@ -1217,7 +1209,7 @@ static int halt_simple (struct usbtest_dev *dev)
        if (dev->in_pipe) {
                ep = usb_pipeendpoint (dev->in_pipe) | USB_DIR_IN;
                urb->pipe = dev->in_pipe;
-               retval = test_halt (ep, urb);
+               retval = test_halt(dev, ep, urb);
                if (retval < 0)
                        goto done;
        }
@@ -1225,7 +1217,7 @@ static int halt_simple (struct usbtest_dev *dev)
        if (dev->out_pipe) {
                ep = usb_pipeendpoint (dev->out_pipe);
                urb->pipe = dev->out_pipe;
-               retval = test_halt (ep, urb);
+               retval = test_halt(dev, ep, urb);
        }
 done:
        simple_free_urb (urb);
@@ -1275,7 +1267,7 @@ static int ctrl_out (struct usbtest_dev *dev,
                if (retval != len) {
                        what = "write";
                        if (retval >= 0) {
-                               INFO(dev, "ctrl_out, wlen %d (expected %d)\n",
+                               ERROR(dev, "ctrl_out, wlen %d (expected %d)\n",
                                                retval, len);
                                retval = -EBADMSG;
                        }
@@ -1289,7 +1281,7 @@ static int ctrl_out (struct usbtest_dev *dev,
                if (retval != len) {
                        what = "read";
                        if (retval >= 0) {
-                               INFO(dev, "ctrl_out, rlen %d (expected %d)\n",
+                               ERROR(dev, "ctrl_out, rlen %d (expected %d)\n",
                                                retval, len);
                                retval = -EBADMSG;
                        }
@@ -1299,7 +1291,7 @@ static int ctrl_out (struct usbtest_dev *dev,
                /* fail if we can't verify */
                for (j = 0; j < len; j++) {
                        if (buf [j] != (u8) (i + j)) {
-                               INFO (dev, "ctrl_out, byte %d is %d not %d\n",
+                               ERROR(dev, "ctrl_out, byte %d is %d not %d\n",
                                        j, buf [j], (u8) i + j);
                                retval = -EBADMSG;
                                break;
@@ -1321,7 +1313,7 @@ static int ctrl_out (struct usbtest_dev *dev,
        }
 
        if (retval < 0)
-               INFO (dev, "ctrl_out %s failed, code %d, count %d\n",
+               ERROR (dev, "ctrl_out %s failed, code %d, count %d\n",
                        what, retval, i);
 
        kfree (buf);
@@ -1366,7 +1358,7 @@ static void iso_callback (struct urb *urb)
                case 0:
                        goto done;
                default:
-                       dev_dbg (&ctx->dev->intf->dev,
+                       dev_err(&ctx->dev->intf->dev,
                                        "iso resubmit err %d\n",
                                        status);
                        /* FALLTHROUGH */
@@ -1381,7 +1373,7 @@ static void iso_callback (struct urb *urb)
        ctx->pending--;
        if (ctx->pending == 0) {
                if (ctx->errors)
-                       dev_dbg (&ctx->dev->intf->dev,
+                       dev_err(&ctx->dev->intf->dev,
                                "iso test, %lu errors out of %lu\n",
                                ctx->errors, ctx->packet_count);
                complete (&ctx->done);
@@ -1458,7 +1450,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
 
        memset (urbs, 0, sizeof urbs);
        udev = testdev_to_usbdev (dev);
-       dev_dbg (&dev->intf->dev,
+       dev_info(&dev->intf->dev,
                "... iso period %d %sframes, wMaxPacket %04x\n",
                1 << (desc->bInterval - 1),
                (udev->speed == USB_SPEED_HIGH) ? "micro" : "",
@@ -1475,7 +1467,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
                urbs [i]->context = &context;
        }
        packets *= param->iterations;
-       dev_dbg (&dev->intf->dev,
+       dev_info(&dev->intf->dev,
                "... total %lu msec (%lu packets)\n",
                (packets * (1 << (desc->bInterval - 1)))
                        / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1),
@@ -1537,6 +1529,13 @@ fail:
  * except indirectly by consuming USB bandwidth and CPU resources for test
  * threads and request completion.  But the only way to know that for sure
  * is to test when HC queues are in use by many devices.
+ *
+ * WARNING:  Because usbfs grabs udev->dev.sem before calling this ioctl(),
+ * it locks out usbcore in certain code paths.  Notably, if you disconnect
+ * the device-under-test, khubd will wait block forever waiting for the
+ * ioctl to complete ... so that usb_disconnect() can abort the pending
+ * urbs and then call usbtest_disconnect().  To abort a test, you're best
+ * off just killing the userspace task and waiting for it to exit.
  */
 
 static int
@@ -1575,7 +1574,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
         * altsettings; force a default so most tests don't need to check.
         */
        if (dev->info->alt >= 0) {
-               int     res;
+               int     res;
 
                if (intf->altsetting->desc.bInterfaceNumber) {
                        mutex_unlock(&dev->lock);
@@ -1604,7 +1603,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        switch (param->test_num) {
 
        case 0:
-               dev_dbg (&intf->dev, "TEST 0:  NOP\n");
+               dev_info(&intf->dev, "TEST 0:  NOP\n");
                retval = 0;
                break;
 
@@ -1612,7 +1611,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        case 1:
                if (dev->out_pipe == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                                "TEST 1:  write %d bytes %u times\n",
                                param->length, param->iterations);
                urb = simple_alloc_urb (udev, dev->out_pipe, param->length);
@@ -1621,13 +1620,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk sink (maybe accepts short writes)
-               retval = simple_io (urb, param->iterations, 0, 0, "test1");
+               retval = simple_io(dev, urb, param->iterations, 0, 0, "test1");
                simple_free_urb (urb);
                break;
        case 2:
                if (dev->in_pipe == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                                "TEST 2:  read %d bytes %u times\n",
                                param->length, param->iterations);
                urb = simple_alloc_urb (udev, dev->in_pipe, param->length);
@@ -1636,13 +1635,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk source (maybe generates short writes)
-               retval = simple_io (urb, param->iterations, 0, 0, "test2");
+               retval = simple_io(dev, urb, param->iterations, 0, 0, "test2");
                simple_free_urb (urb);
                break;
        case 3:
                if (dev->out_pipe == 0 || param->vary == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                                "TEST 3:  write/%d 0..%d bytes %u times\n",
                                param->vary, param->length, param->iterations);
                urb = simple_alloc_urb (udev, dev->out_pipe, param->length);
@@ -1651,14 +1650,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk sink (maybe accepts short writes)
-               retval = simple_io (urb, param->iterations, param->vary,
+               retval = simple_io(dev, urb, param->iterations, param->vary,
                                        0, "test3");
                simple_free_urb (urb);
                break;
        case 4:
                if (dev->in_pipe == 0 || param->vary == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                                "TEST 4:  read/%d 0..%d bytes %u times\n",
                                param->vary, param->length, param->iterations);
                urb = simple_alloc_urb (udev, dev->in_pipe, param->length);
@@ -1667,7 +1666,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk source (maybe generates short writes)
-               retval = simple_io (urb, param->iterations, param->vary,
+               retval = simple_io(dev, urb, param->iterations, param->vary,
                                        0, "test4");
                simple_free_urb (urb);
                break;
@@ -1676,7 +1675,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        case 5:
                if (dev->out_pipe == 0 || param->sglen == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 5:  write %d sglists %d entries of %d bytes\n",
                                param->iterations,
                                param->sglen, param->length);
@@ -1686,7 +1685,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk sink (maybe accepts short writes)
-               retval = perform_sglist (udev, param->iterations, dev->out_pipe,
+               retval = perform_sglist(dev, param->iterations, dev->out_pipe,
                                &req, sg, param->sglen);
                free_sglist (sg, param->sglen);
                break;
@@ -1694,7 +1693,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        case 6:
                if (dev->in_pipe == 0 || param->sglen == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 6:  read %d sglists %d entries of %d bytes\n",
                                param->iterations,
                                param->sglen, param->length);
@@ -1704,14 +1703,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk source (maybe generates short writes)
-               retval = perform_sglist (udev, param->iterations, dev->in_pipe,
+               retval = perform_sglist(dev, param->iterations, dev->in_pipe,
                                &req, sg, param->sglen);
                free_sglist (sg, param->sglen);
                break;
        case 7:
                if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 7:  write/%d %d sglists %d entries 0..%d bytes\n",
                                param->vary, param->iterations,
                                param->sglen, param->length);
@@ -1721,14 +1720,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk sink (maybe accepts short writes)
-               retval = perform_sglist (udev, param->iterations, dev->out_pipe,
+               retval = perform_sglist(dev, param->iterations, dev->out_pipe,
                                &req, sg, param->sglen);
                free_sglist (sg, param->sglen);
                break;
        case 8:
                if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 8:  read/%d %d sglists %d entries 0..%d bytes\n",
                                param->vary, param->iterations,
                                param->sglen, param->length);
@@ -1738,7 +1737,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                        break;
                }
                // FIRMWARE:  bulk source (maybe generates short writes)
-               retval = perform_sglist (udev, param->iterations, dev->in_pipe,
+               retval = perform_sglist(dev, param->iterations, dev->in_pipe,
                                &req, sg, param->sglen);
                free_sglist (sg, param->sglen);
                break;
@@ -1746,13 +1745,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        /* non-queued sanity tests for control (chapter 9 subset) */
        case 9:
                retval = 0;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 9:  ch9 (subset) control tests, %d times\n",
                                param->iterations);
                for (i = param->iterations; retval == 0 && i--; /* NOP */)
                        retval = ch9_postconfig (dev);
                if (retval)
-                       dbg ("ch9 subset failed, iterations left %d", i);
+                       dev_err(&intf->dev, "ch9 subset failed, "
+                                       "iterations left %d\n", i);
                break;
 
        /* queued control messaging */
@@ -1760,7 +1760,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                if (param->sglen == 0)
                        break;
                retval = 0;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                                "TEST 10:  queue %d control calls, %d times\n",
                                param->sglen,
                                param->iterations);
@@ -1772,26 +1772,26 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                if (dev->in_pipe == 0 || !param->length)
                        break;
                retval = 0;
-               dev_dbg (&intf->dev, "TEST 11:  unlink %d reads of %d\n",
+               dev_info(&intf->dev, "TEST 11:  unlink %d reads of %d\n",
                                param->iterations, param->length);
                for (i = param->iterations; retval == 0 && i--; /* NOP */)
                        retval = unlink_simple (dev, dev->in_pipe,
                                                param->length);
                if (retval)
-                       dev_dbg (&intf->dev, "unlink reads failed %d, "
+                       dev_err(&intf->dev, "unlink reads failed %d, "
                                "iterations left %d\n", retval, i);
                break;
        case 12:
                if (dev->out_pipe == 0 || !param->length)
                        break;
                retval = 0;
-               dev_dbg (&intf->dev, "TEST 12:  unlink %d writes of %d\n",
+               dev_info(&intf->dev, "TEST 12:  unlink %d writes of %d\n",
                                param->iterations, param->length);
                for (i = param->iterations; retval == 0 && i--; /* NOP */)
                        retval = unlink_simple (dev, dev->out_pipe,
                                                param->length);
                if (retval)
-                       dev_dbg (&intf->dev, "unlink writes failed %d, "
+                       dev_err(&intf->dev, "unlink writes failed %d, "
                                "iterations left %d\n", retval, i);
                break;
 
@@ -1800,24 +1800,24 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
                if (dev->out_pipe == 0 && dev->in_pipe == 0)
                        break;
                retval = 0;
-               dev_dbg (&intf->dev, "TEST 13:  set/clear %d halts\n",
+               dev_info(&intf->dev, "TEST 13:  set/clear %d halts\n",
                                param->iterations);
                for (i = param->iterations; retval == 0 && i--; /* NOP */)
                        retval = halt_simple (dev);
-               
+
                if (retval)
-                       DBG (dev, "halts failed, iterations left %d\n", i);
+                       ERROR(dev, "halts failed, iterations left %d\n", i);
                break;
 
        /* control write tests */
        case 14:
                if (!dev->info->ctrl_out)
                        break;
-               dev_dbg (&intf->dev, "TEST 14:  %d ep0out, %d..%d vary %d\n",
+               dev_info(&intf->dev, "TEST 14:  %d ep0out, %d..%d vary %d\n",
                                param->iterations,
                                realworld ? 1 : 0, param->length,
                                param->vary);
-               retval = ctrl_out (dev, param->iterations, 
+               retval = ctrl_out(dev, param->iterations,
                                param->length, param->vary);
                break;
 
@@ -1825,7 +1825,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        case 15:
                if (dev->out_iso_pipe == 0 || param->sglen == 0)
                        break;
-               dev_dbg (&intf->dev, 
+               dev_info(&intf->dev,
                        "TEST 15:  write %d iso, %d entries of %d bytes\n",
                                param->iterations,
                                param->sglen, param->length);
@@ -1838,7 +1838,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
        case 16:
                if (dev->in_iso_pipe == 0 || param->sglen == 0)
                        break;
-               dev_dbg (&intf->dev,
+               dev_info(&intf->dev,
                        "TEST 16:  read %d iso, %d entries of %d bytes\n",
                                param->iterations,
                                param->sglen, param->length);
@@ -1898,7 +1898,8 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
                        return -ENODEV;
                if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product)
                        return -ENODEV;
-               dbg ("matched module params, vend=0x%04x prod=0x%04x",
+               dev_info(&intf->dev, "matched module params, "
+                                       "vend=0x%04x prod=0x%04x\n",
                                le16_to_cpu(udev->descriptor.idVendor),
                                le16_to_cpu(udev->descriptor.idProduct));
        }
@@ -1940,7 +1941,8 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
 
                        status = get_endpoints (dev, intf);
                        if (status < 0) {
-                               dbg ("couldn't get endpoints, %d\n", status);
+                               WARN(dev, "couldn't get endpoints, %d\n",
+                                               status);
                                return status;
                        }
                        /* may find bulk or ISO pipes */
@@ -2082,21 +2084,9 @@ static struct usbtest_info generic_info = {
 };
 #endif
 
-// FIXME remove this 
-static struct usbtest_info hact_info = {
-       .name           = "FX2/hact",
-       //.ep_in                = 6,
-       .ep_out         = 2,
-       .alt            = -1,
-};
-
 
 static struct usb_device_id id_table [] = {
 
-       { USB_DEVICE (0x0547, 0x1002),
-               .driver_info = (unsigned long) &hact_info,
-               },
-
        /*-------------------------------------------------------------*/
 
        /* EZ-USB devices which download firmware to replace (or in our
@@ -2185,7 +2175,7 @@ static int __init usbtest_init (void)
 {
 #ifdef GENERIC
        if (vendor)
-               dbg ("params: vend=0x%04x prod=0x%04x", vendor, product);
+               pr_debug("params: vend=0x%04x prod=0x%04x\n", vendor, product);
 #endif
        return usb_register (&usbtest_driver);
 }
index 9b1bb347dc2d7e0b1865c4f36191118b207e5dde..db6f97a93c02c3b813e8feafd17ba6cb2acb1efc 100644 (file)
@@ -147,7 +147,7 @@ static void serial_buf_free(struct circ_buf *cb)
  */
 static int serial_buf_data_avail(struct circ_buf *cb)
 {
-       return CIRC_CNT(cb->head,cb->tail,AIRCABLE_BUF_SIZE);
+       return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE);
 }
 
 /*
@@ -171,7 +171,7 @@ static int serial_buf_put(struct circ_buf *cb, const char *buf, int count)
                cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1);
                buf += c;
                count -= c;
-               ret= c;
+               ret = c;
        }
        return ret;
 }
@@ -197,7 +197,7 @@ static int serial_buf_get(struct circ_buf *cb, char *buf, int count)
                cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1);
                buf += c;
                count -= c;
-               ret= c;
+               ret = c;
        }
        return ret;
 }
@@ -208,7 +208,7 @@ static void aircable_send(struct usb_serial_port *port)
 {
        int count, result;
        struct aircable_private *priv = usb_get_serial_port_data(port);
-       unsigned charbuf;
+       unsigned char *buf;
        __le16 *dbuf;
        dbg("%s - port %d", __func__, port->number);
        if (port->write_urb_busy)
@@ -229,7 +229,8 @@ static void aircable_send(struct usb_serial_port *port)
        buf[1] = TX_HEADER_1;
        dbuf = (__le16 *)&buf[2];
        *dbuf = cpu_to_le16((u16)count);
-       serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE);
+       serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH,
+                                                       MAX_HCI_FRAMESIZE);
 
        memcpy(port->write_urb->transfer_buffer, buf,
               count + HCI_HEADER_LENGTH);
@@ -261,7 +262,7 @@ static void aircable_read(struct work_struct *work)
        struct tty_struct *tty;
        unsigned char *data;
        int count;
-       if (priv->rx_flags & THROTTLED){
+       if (priv->rx_flags & THROTTLED) {
                if (priv->rx_flags & ACTUALLY_THROTTLED)
                        schedule_work(&priv->rx_work);
                return;
@@ -282,10 +283,10 @@ static void aircable_read(struct work_struct *work)
        count = min(64, serial_buf_data_avail(priv->rx_buf));
 
        if (count <= 0)
-               return; //We have finished sending everything.
+               return; /* We have finished sending everything. */
 
        tty_prepare_flip_string(tty, &data, count);
-       if (!data){
+       if (!data) {
                err("%s- kzalloc(%d) failed.", __func__, count);
                return;
        }
@@ -304,9 +305,10 @@ static void aircable_read(struct work_struct *work)
 static int aircable_probe(struct usb_serial *serial,
                          const struct usb_device_id *id)
 {
-       struct usb_host_interface *iface_desc = serial->interface->cur_altsetting;
+       struct usb_host_interface *iface_desc = serial->interface->
+                                                               cur_altsetting;
        struct usb_endpoint_descriptor *endpoint;
-       int num_bulk_out=0;
+       int num_bulk_out = 0;
        int i;
 
        for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
@@ -325,13 +327,13 @@ static int aircable_probe(struct usb_serial *serial,
        return 0;
 }
 
-static int aircable_attach (struct usb_serial *serial)
+static int aircable_attach(struct usb_serial *serial)
 {
        struct usb_serial_port *port = serial->port[0];
        struct aircable_private *priv;
 
        priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL);
-       if (!priv){
+       if (!priv) {
                err("%s- kmalloc(%Zd) failed.", __func__,
                        sizeof(struct aircable_private));
                return -ENOMEM;
@@ -392,7 +394,7 @@ static int aircable_write(struct usb_serial_port *port,
 
        usb_serial_debug_data(debug, &port->dev, __func__, count, source);
 
-       if (!count){
+       if (!count) {
                dbg("%s - write request of 0 bytes", __func__);
                return count;
        }
@@ -418,31 +420,31 @@ static void aircable_write_bulk_callback(struct urb *urb)
 
        /* This has been taken from cypress_m8.c cypress_write_int_callback */
        switch (status) {
-               case 0:
-                       /* success */
-                       break;
-               case -ECONNRESET:
-               case -ENOENT:
-               case -ESHUTDOWN:
-                       /* this urb is terminated, clean up */
-                       dbg("%s - urb shutting down with status: %d",
-                           __func__, status);
-                       port->write_urb_busy = 0;
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d",
+                   __func__, status);
+               port->write_urb_busy = 0;
+               return;
+       default:
+               /* error in the urb, so we have to resubmit it */
+               dbg("%s - Overflow in write", __func__);
+               dbg("%s - nonzero write bulk status received: %d",
+                   __func__, status);
+               port->write_urb->transfer_buffer_length = 1;
+               port->write_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+               if (result)
+                       dev_err(&urb->dev->dev,
+                           "%s - failed resubmitting write urb, error %d\n",
+                                                       __func__, result);
+               else
                        return;
-               default:
-                       /* error in the urb, so we have to resubmit it */
-                       dbg("%s - Overflow in write", __func__);
-                       dbg("%s - nonzero write bulk status received: %d",
-                           __func__, status);
-                       port->write_urb->transfer_buffer_length = 1;
-                       port->write_urb->dev = port->serial->dev;
-                       result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-                       if (result)
-                               dev_err(&urb->dev->dev,
-                                       "%s - failed resubmitting write urb, error %d\n",
-                                       __func__, result);
-                       else
-                               return;
        }
 
        port->write_urb_busy = 0;
@@ -472,11 +474,11 @@ static void aircable_read_bulk_callback(struct urb *urb)
                        dbg("%s - caught -EPROTO, resubmitting the urb",
                            __func__);
                        usb_fill_bulk_urb(port->read_urb, port->serial->dev,
-                                         usb_rcvbulkpipe(port->serial->dev,
-                                                         port->bulk_in_endpointAddress),
-                                         port->read_urb->transfer_buffer,
-                                         port->read_urb->transfer_buffer_length,
-                                         aircable_read_bulk_callback, port);
+                               usb_rcvbulkpipe(port->serial->dev,
+                                       port->bulk_in_endpointAddress),
+                               port->read_urb->transfer_buffer,
+                               port->read_urb->transfer_buffer_length,
+                               aircable_read_bulk_callback, port);
 
                        result = usb_submit_urb(urb, GFP_ATOMIC);
                        if (result)
@@ -490,7 +492,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
        }
 
        usb_serial_debug_data(debug, &port->dev, __func__,
-                               urb->actual_length,urb->transfer_buffer);
+                               urb->actual_length, urb->transfer_buffer);
 
        tty = port->tty;
        if (tty && urb->actual_length) {
@@ -507,9 +509,9 @@ static void aircable_read_bulk_callback(struct urb *urb)
                        no_packages = urb->actual_length / (HCI_COMPLETE_FRAME);
 
                        if (urb->actual_length % HCI_COMPLETE_FRAME != 0)
-                               no_packages+=1;
+                               no_packages++;
 
-                       for (i = 0; i < no_packages ;i++) {
+                       for (i = 0; i < no_packagesi++) {
                                if (remaining > (HCI_COMPLETE_FRAME))
                                        package_length = HCI_COMPLETE_FRAME;
                                else
@@ -529,7 +531,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
        if (port->open_count) {
                usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                                  usb_rcvbulkpipe(port->serial->dev,
-                                                 port->bulk_in_endpointAddress),
+                                         port->bulk_in_endpointAddress),
                                  port->read_urb->transfer_buffer,
                                  port->read_urb->transfer_buffer_length,
                                  aircable_read_bulk_callback, port);
@@ -602,7 +604,7 @@ static struct usb_serial_driver aircable_device = {
        .unthrottle =           aircable_unthrottle,
 };
 
-static int __init aircable_init (void)
+static int __init aircable_init(void)
 {
        int retval;
        retval = usb_serial_register(&aircable_device);
@@ -619,7 +621,7 @@ failed_usb_register:
        return retval;
 }
 
-static void __exit aircable_exit (void)
+static void __exit aircable_exit(void)
 {
        usb_deregister(&aircable_driver);
        usb_serial_deregister(&aircable_device);
index 725b6b94c2740c2f0c58743caeca428c11cccc28..0798c14ce787767718e216b000cc8e6aef10c5ed 100644 (file)
@@ -68,8 +68,9 @@ static int airprime_send_setup(struct usb_serial_port *port)
                        val |= 0x02;
 
                return usb_control_msg(serial->dev,
-                               usb_rcvctrlpipe(serial->dev, 0),
-                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+                                       usb_rcvctrlpipe(serial->dev, 0),
+                                       0x22, 0x21, val, 0, NULL, 0,
+                                       USB_CTRL_SET_TIMEOUT);
        }
 
        return 0;
@@ -90,17 +91,19 @@ static void airprime_read_bulk_callback(struct urb *urb)
                    __func__, status);
                return;
        }
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               tty_insert_flip_string (tty, data, urb->actual_length);
-               tty_flip_buffer_push (tty);
+               tty_insert_flip_string(tty, data, urb->actual_length);
+               tty_flip_buffer_push(tty);
        }
 
-       result = usb_submit_urb (urb, GFP_ATOMIC);
+       result = usb_submit_urb(urb, GFP_ATOMIC);
        if (result)
-               dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
+               dev_err(&port->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
                        __func__, result);
        return;
 }
@@ -115,7 +118,7 @@ static void airprime_write_bulk_callback(struct urb *urb)
        dbg("%s - port %d", __func__, port->number);
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree (urb->transfer_buffer);
+       kfree(urb->transfer_buffer);
 
        if (status)
                dbg("%s - nonzero write bulk status received: %d",
@@ -171,7 +174,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                }
                usb_fill_bulk_urb(urb, serial->dev,
                                  usb_rcvbulkpipe(serial->dev,
-                                                 port->bulk_out_endpointAddress),
+                                         port->bulk_out_endpointAddress),
                                  buffer, buffer_size,
                                  airprime_read_bulk_callback, port);
                result = usb_submit_urb(urb, GFP_KERNEL);
@@ -183,7 +186,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                                __func__, i, port->number, result);
                        goto errout;
                }
-               /* remember this urb so we can kill it when the port is closed */
+               /* remember this urb so we can kill it when the
+                  port is closed */
                priv->read_urbp[i] = urb;
        }
 
@@ -192,22 +196,22 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
        goto out;
 
  errout:
-       /* some error happened, cancel any submitted urbs and clean up anything that
-          got allocated successfully */
+       /* some error happened, cancel any submitted urbs and clean up
+          anything that got allocated successfully */
 
        while (i-- != 0) {
                urb = priv->read_urbp[i];
                buffer = urb->transfer_buffer;
-               usb_kill_urb (urb);
-               usb_free_urb (urb);
-               kfree (buffer);
+               usb_kill_urb(urb);
+               usb_free_urb(urb);
+               kfree(buffer);
        }
 
  out:
        return result;
 }
 
-static void airprime_close(struct usb_serial_port *port, struct file * filp)
+static void airprime_close(struct usb_serial_port *port, struct file *filp)
 {
        struct airprime_private *priv = usb_get_serial_port_data(port);
        int i;
@@ -220,16 +224,16 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
        mutex_lock(&port->serial->disc_mutex);
        if (!port->serial->disconnected)
                airprime_send_setup(port);
-       mutex_lock(&port->serial->disc_mutex);
+       mutex_unlock(&port->serial->disc_mutex);
 
        for (i = 0; i < NUM_READ_URBS; ++i) {
-               usb_kill_urb (priv->read_urbp[i]);
-               kfree (priv->read_urbp[i]->transfer_buffer);
-               usb_free_urb (priv->read_urbp[i]);
+               usb_kill_urb(priv->read_urbp[i]);
+               kfree(priv->read_urbp[i]->transfer_buffer);
+               usb_free_urb(priv->read_urbp[i]);
        }
 
        /* free up private structure */
-       kfree (priv);
+       kfree(priv);
        usb_set_serial_port_data(port, NULL);
 }
 
@@ -259,10 +263,10 @@ static int airprime_write(struct usb_serial_port *port,
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
                dev_err(&port->dev, "no more free urbs\n");
-               kfree (buffer);
+               kfree(buffer);
                return -ENOMEM;
        }
-       memcpy (buffer, buf, count);
+       memcpy(buffer, buf, count);
 
        usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
 
@@ -279,7 +283,7 @@ static int airprime_write(struct usb_serial_port *port,
                        "%s - usb_submit_urb(write bulk) failed with status = %d\n",
                        __func__, status);
                count = status;
-               kfree (buffer);
+               kfree(buffer);
        } else {
                spin_lock_irqsave(&priv->lock, flags);
                ++priv->outstanding_urbs;
@@ -287,7 +291,7 @@ static int airprime_write(struct usb_serial_port *port,
        }
        /* we are done with this urb, so let the host driver
         * really free it when it is finished with it */
-       usb_free_urb (urb);
+       usb_free_urb(urb);
        return count;
 }
 
@@ -315,8 +319,10 @@ static int __init airprime_init(void)
 {
        int retval;
 
-       airprime_device.num_ports =
-               (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS;
+       airprime_device.num_ports = endpoints;
+       if (endpoints < 0 || endpoints >= MAX_BULK_EPS)
+               airprime_device.num_ports = NUM_BULK_EPS;
+
        retval = usb_serial_register(&airprime_device);
        if (retval)
                return retval;
@@ -341,6 +347,7 @@ MODULE_LICENSE("GPL");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled");
 module_param(buffer_size, int, 0);
-MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)");
+MODULE_PARM_DESC(buffer_size,
+               "Size of the transfer buffers in bytes (default 4096)");
 module_param(endpoints, int, 0);
 MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");
index 599ab2e548a7c3e483abc255471ee5b92838c90e..77895c8f8f3189fb774acb59cad0f3f3a324cbad 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 
 static int debug;
@@ -246,29 +246,29 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        baud = tty_get_baud_rate(port->tty);
 
        switch (baud) {
-               case 75:
-               case 150:
-               case 300:
-               case 600:
-               case 1200:
-               case 1800:
-               case 2400:
-               case 4800:
-               case 9600:
-               case 19200:
-               case 38400:
-               case 57600:
-               case 115200:
-               case 230400:
-               case 460800:
-                       /* Report the resulting rate back to the caller */
-                       tty_encode_baud_rate(port->tty, baud, baud);
-                       break;
-               /* set 9600 as default (if given baudrate is invalid for example) */
-               default:
-                       tty_encode_baud_rate(port->tty, 9600, 9600);
-               case 0:
-                       baud = 9600;
+       case 75:
+       case 150:
+       case 300:
+       case 600:
+       case 1200:
+       case 1800:
+       case 2400:
+       case 4800:
+       case 9600:
+       case 19200:
+       case 38400:
+       case 57600:
+       case 115200:
+       case 230400:
+       case 460800:
+               /* Report the resulting rate back to the caller */
+               tty_encode_baud_rate(port->tty, baud, baud);
+               break;
+       /* set 9600 as default (if given baudrate is invalid for example) */
+       default:
+               tty_encode_baud_rate(port->tty, 9600, 9600);
+       case 0:
+               baud = 9600;
        }
 
        /*
@@ -380,19 +380,19 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
        switch (cmd) {
        case TIOCGSERIAL:
                /* XXX: Some of these values are probably wrong. */
-               memset(&serstruct, 0, sizeof (serstruct));
+               memset(&serstruct, 0, sizeof(serstruct));
                serstruct.type = PORT_16654;
                serstruct.line = port->serial->minor;
                serstruct.port = port->number;
                serstruct.custom_divisor = 0;
                serstruct.baud_base = 460800;
 
-               if (copy_to_user(user_arg, &serstruct, sizeof (serstruct)))
+               if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
                        return -EFAULT;
 
                return 0;
        case TIOCSSERIAL:
-               if (copy_from_user(&serstruct, user_arg, sizeof (serstruct)))
+               if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
                        return -EFAULT;
                return 0;
        default:
index d947d955bceb9504d9beae2d9877ddb41c105e28..ba28fdc9ccd2f589a2ec5038616dc91795fd9757 100644 (file)
@@ -130,7 +130,7 @@ static int ch341_get_status(struct usb_device *dev)
                return -ENOMEM;
 
        r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size);
-       if ( r < 0)
+       if (r < 0)
                goto out;
 
        /* Not having the datasheet for the CH341, we ignore the bytes returned
index dc0ea08ed2315773b0f85fbcaf25848d83d69be9..f5b57b196c5a0821845209b9ff74052f9eb2bb5a 100644 (file)
@@ -73,6 +73,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+       { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
        { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
        { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
        { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
index c7329f43d9c9dc885fd65cb21ed80b29b4938162..5b349ece724744ac8358063ee53733e7d824a0be 100644 (file)
@@ -133,6 +133,14 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
 static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
index 6da539ede0ee992185ccb4b789b28f485bc39024..504edf8c3a3f1a32efdabdcffef0dfea76ddd018 100644 (file)
 /* AlphaMicro Components AMC-232USB01 device */
 #define FTDI_AMC232_PID 0xFF00 /* Product Id */
 
+/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */
+/* the VID is the standard ftdi vid (FTDI_VID) */
+#define FTDI_SCS_DEVICE_0_PID 0xD010    /* SCS PTC-IIusb */
+#define FTDI_SCS_DEVICE_1_PID 0xD011    /* SCS Tracker / DSP TNC */
+#define FTDI_SCS_DEVICE_2_PID 0xD012
+#define FTDI_SCS_DEVICE_3_PID 0xD013
+#define FTDI_SCS_DEVICE_4_PID 0xD014
+#define FTDI_SCS_DEVICE_5_PID 0xD015
+#define FTDI_SCS_DEVICE_6_PID 0xD016
+#define FTDI_SCS_DEVICE_7_PID 0xD017
+
 /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */
 #define FTDI_ACTZWAVE_PID      0xF2D0
 
index 8a217648b250311abf685cd0f89cc558de41f7ca..a01e987c7d32e274d8d060ef15276fae913a1ca0 100644 (file)
@@ -643,7 +643,7 @@ static void read_buf_callback(struct urb *urb)
 static int iuu_bulk_write(struct usb_serial_port *port)
 {
        struct iuu_private *priv = usb_get_serial_port_data(port);
-       unsigned int flags;
+       unsigned long flags;
        int result;
        int i;
        char *buf_ptr = port->write_urb->transfer_buffer;
@@ -694,7 +694,7 @@ static void iuu_uart_read_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct iuu_private *priv = usb_get_serial_port_data(port);
-       unsigned int flags;
+       unsigned long flags;
        int status;
        int error = 0;
        int len = 0;
@@ -759,7 +759,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf,
                          int count)
 {
        struct iuu_private *priv = usb_get_serial_port_data(port);
-       unsigned int flags;
+       unsigned long flags;
        dbg("%s - enter", __func__);
 
        if (count > 256)
index 6bcb82d3911a7baf386c0eda874cf3ea68ab1ba5..78f2f6db494d790fb4d00d75c0ef9c1229ef89ef 100644 (file)
@@ -1713,7 +1713,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
 {
        struct moschip_port *mos7840_port;
        unsigned int mcr;
-       unsigned int status;
+       int status;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -1740,11 +1740,10 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
 
        mos7840_port->shadowMCR = mcr;
 
-       status = 0;
        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
        if (status < 0) {
                dbg("setting MODEM_CONTROL_REGISTER Failed\n");
-               return -1;
+               return status;
        }
 
        return 0;
index 0f6d234d699b1327b2691ebca03f2a2707fe43a1..3d9249632ae12e7051174817241ef37ea6f2cd4c 100644 (file)
@@ -123,7 +123,8 @@ config USB_STORAGE_ALAUDA
 
 config USB_STORAGE_ONETOUCH
        bool "Support OneTouch Button on Maxtor Hard Drives"
-       depends on USB_STORAGE && INPUT_EVDEV
+       depends on USB_STORAGE
+       depends on INPUT=y || INPUT=USB_STORAGE
        help
          Say Y here to include additional code to support the Maxtor OneTouch
          USB hard drive's onetouch button.
index d88824b3511c0de74a320a0be30554052d374f7f..898e67d30e563bfc4b8a11cf1715cee5a1edec56 100644 (file)
@@ -46,7 +46,7 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
        }
 
        memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd));
-       memset(srb->cmnd, 0, sizeof(srb->cmnd));
+       memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
 
        /* check if we support the command */
        if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */
index 971d13dd5e65a55e9256c932d63bc6b0a0caa1e4..3addcd8f827bd3d17463dbc67395c072cfae4d81 100644 (file)
@@ -292,6 +292,7 @@ struct isd200_info {
 
        /* maximum number of LUNs supported */
        unsigned char MaxLUNs;
+       unsigned char cmnd[BLK_MAX_CDB];
        struct scsi_cmnd srb;
        struct scatterlist sg;
 };
@@ -450,6 +451,7 @@ static int isd200_action( struct us_data *us, int action,
 
        memset(&ata, 0, sizeof(ata));
        memset(&srb_dev, 0, sizeof(srb_dev));
+       srb->cmnd = info->cmnd;
        srb->device = &srb_dev;
        ++srb->serial_number;
 
index a28d49122e7a046301799edfade54e95f50d1cdd..d617e8ae6b006b6d0b014774d86eb78bd1c9c6e3 100644 (file)
@@ -135,7 +135,7 @@ static int usu_probe(struct usb_interface *intf,
        stat[type].fls |= USU_MOD_FL_THREAD;
        spin_unlock_irqrestore(&usu_lock, flags);
 
-       task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type);
+       task = kthread_run(usu_probe_thread, (void*)type, "libusual_%ld", type);
        if (IS_ERR(task)) {
                rc = PTR_ERR(task);
                printk(KERN_WARNING "libusual: "
index dfd42fe9e5f0567d27e009f5514ab5a70d742b97..98b89ea9e3123bd94fac382fd4da32803b0280a9 100644 (file)
@@ -38,7 +38,7 @@
 #include "onetouch.h"
 #include "debug.h"
 
-void onetouch_release_input(void *onetouch_);
+static void onetouch_release_input(void *onetouch_);
 
 struct usb_onetouch {
        char name[128];
@@ -223,7 +223,7 @@ int onetouch_connect_input(struct us_data *ss)
        return error;
 }
 
-void onetouch_release_input(void *onetouch_)
+static void onetouch_release_input(void *onetouch_)
 {
        struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_;
 
index 732bf52a775e743d0039601b54dd20a127d00040..a0ed889230aa324124575307151d34a6ceb9d09e 100644 (file)
@@ -44,7 +44,8 @@
  *       running with this patch.
  * Send your submission to either Phil Dibowitz <phil@ipom.com> or
  * Alan Stern <stern@rowland.harvard.edu>, and don't forget to CC: the
- * USB development list <linux-usb-devel@lists.sourceforge.net>.
+ * USB development list <linux-usb@vger.kernel.org> and the USB storage list
+ * <usb-storage@lists.one-eyed-alien.net>
  */
 
 /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
@@ -557,6 +558,13 @@ UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
                US_FL_SINGLE_LUN),
 #endif
 
+/* Reported by Dmitry Khlystov <adminimus@gmail.com> */
+UNUSUAL_DEV(  0x04e8, 0x507c, 0x0220, 0x0220,
+               "Samsung",
+               "YP-U3",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64),
+
 /* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */
 UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
                "Belkin",
@@ -1200,6 +1208,17 @@ UNUSUAL_DEV(  0x084d, 0x0011, 0x0110, 0x0110,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_BULK32),
 
+/* Andrew Lunn <andrew@lunn.ch>
+ * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL
+ * on LUN 4.
+ * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera"
+*/
+UNUSUAL_DEV(  0x0851, 0x1543, 0x0200, 0x0200,
+               "PanDigital",
+               "Photo Frame",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_NOT_LOCKABLE),
+
 /* Submitted by Jan De Luyck <lkml@kcore.org> */
 UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
                "CITIZEN",
@@ -1342,6 +1361,13 @@ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY),
 
+/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
+UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
+               "INTOVA",
+               "Pixtreme",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /*
  * Entry for Jenoptik JD 5200z3
  *
index a856effad3bde74c9707bce6e9ff2dfe96681009..e268aacb773a57e5041aac509389543b853614a0 100644 (file)
@@ -539,7 +539,8 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
                                " has %s in unusual_devs.h (kernel"
                                " %s)\n"
                                "   Please send a copy of this message to "
-                               "<linux-usb-devel@lists.sourceforge.net>\n",
+                               "<linux-usb@vger.kernel.org> and "
+                               "<usb-storage@lists.one-eyed-alien.net>\n",
                                le16_to_cpu(ddesc->idVendor),
                                le16_to_cpu(ddesc->idProduct),
                                le16_to_cpu(ddesc->bcdDevice),
index bb1dadaa4a23a1054cca3fbd56791d3cf50fcb1d..2cdaf1ff8315984e02c0df55b8c2b49255228c98 100644 (file)
@@ -171,7 +171,6 @@ config FB_SYS_FOPS
 config FB_DEFERRED_IO
        bool
        depends on FB
-       default y
 
 config FB_METRONOME
        tristate
index 8ffdf35787688084deced4c51cd8704bb92f4c19..b004036d40873aec5a5c8905a626722ab8b29533 100644 (file)
@@ -441,14 +441,15 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
 
        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) {
+       if (value < 2) {
                dev_notice(info->device, "Bypassing pixel clock divider\n");
                lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
        } else {
-               lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
+               value = (value / 2) - 1;
+               dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n",
+                               value);
+               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));
index 275d9dab0c6108e2f56b73c6bb5d2da1d3fdedc2..e721644bad743c27313b4d78db17b3f87a10de94 100644 (file)
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -299,7 +297,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *
        par->physbase = op->resource[0].start;
        par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&info->var, dp->node, 1);
+       sbusfb_fill_var(&info->var, dp, 1);
        linebytes = of_getintprop_default(dp, "linebytes",
                                          info->var.xres);
 
@@ -329,7 +327,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *
        if (!info->screen_base)
                goto out_unmap_regs;
 
-       bw2_blank(0, info);
+       bw2_blank(FB_BLANK_UNBLANK, info);
 
        bw2_init_fix(info, linebytes);
 
index 0db0fecba93b6718af12b5af3b053333c6783496..b17e746717795615dc71a710abb801e9920eef7b 100644 (file)
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -482,7 +481,7 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id
 
        spin_lock_init(&par->lock);
 
-       sbusfb_fill_var(&info->var, dp->node, 8);
+       sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
        info->var.green.length = 8;
        info->var.blue.length = 8;
index 010ea53978f822cdc7cafd9dce2f85c7ec9054b5..3aa7b6cb0268591283b72f77425344be184d1420 100644 (file)
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -373,7 +371,7 @@ static int __devinit cg3_probe(struct of_device *op,
        par->physbase = op->resource[0].start;
        par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&info->var, dp->node, 8);
+       sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
        info->var.green.length = 8;
        info->var.blue.length = 8;
@@ -398,7 +396,7 @@ static int __devinit cg3_probe(struct of_device *op,
        if (!info->screen_base)
                goto out_unmap_regs;
 
-       cg3_blank(0, info);
+       cg3_blank(FB_BLANK_UNBLANK, info);
 
        if (!of_find_property(dp, "width", NULL)) {
                err = cg3_do_default_mode(par);
index fc90db6da65a94267e8e2e8f22865b5843abdabb..2f64bb3bd2540e7f5c77c03e7d5894578ddad572 100644 (file)
@@ -17,9 +17,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -728,7 +728,7 @@ static int __devinit cg6_probe(struct of_device *op,
        par->physbase = op->resource[0].start;
        par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&info->var, dp->node, 8);
+       sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
        info->var.green.length = 8;
        info->var.blue.length = 8;
@@ -767,7 +767,7 @@ static int __devinit cg6_probe(struct of_device *op,
 
        cg6_bt_init(par);
        cg6_chip_init(info);
-       cg6_blank(0, info);
+       cg6_blank(FB_BLANK_UNBLANK, info);
 
        if (fb_alloc_cmap(&info->cmap, 256, 0))
                goto out_unmap_regs;
index ad31983b43eb6a169a100b2846e96f1554e32b1b..5fa8b76673cb5c07de0066c6f6577434e13b86fc 100644 (file)
@@ -1853,6 +1853,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct display *p = &fb_display[vc->vc_num];
        int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
+       unsigned short saved_ec;
+       int ret;
 
        if (fbcon_is_inactive(vc, info))
                return -EINVAL;
@@ -1865,6 +1867,11 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
         *           whole screen (prevents flicker).
         */
 
+       saved_ec = vc->vc_video_erase_char;
+       vc->vc_video_erase_char = vc->vc_scrl_erase_char;
+
+       ret = 0;
+
        switch (dir) {
        case SM_UP:
                if (count > vc->vc_rows)        /* Maximum realistic size */
@@ -1883,7 +1890,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                                        (b - count)),
                                    vc->vc_scrl_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       ret = 1;
                        break;
 
                case SCROLL_WRAP_MOVE:
@@ -1955,7 +1962,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                                        (b - count)),
                                    vc->vc_scrl_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       ret = 1;
+                       break;
                }
                break;
 
@@ -1974,7 +1982,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                                        t),
                                    vc->vc_scrl_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       ret = 1;
                        break;
 
                case SCROLL_WRAP_MOVE:
@@ -2044,10 +2052,13 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
                                                        t),
                                    vc->vc_scrl_erase_char,
                                    vc->vc_size_row * count);
-                       return 1;
+                       ret = 1;
+                       break;
                }
+               break;
        }
-       return 0;
+       vc->vc_video_erase_char = saved_ec;
+       return ret;
 }
 
 
@@ -2507,6 +2518,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
                        c = vc->vc_video_erase_char;
                        vc->vc_video_erase_char =
                            ((c & 0xfe00) >> 1) | (c & 0xff);
+                       c = vc->vc_def_color;
+                       vc->vc_scrl_erase_char =
+                           ((c & 0xFE00) >> 1) | (c & 0xFF);
                        vc->vc_attr >>= 1;
                }
        } else if (!vc->vc_hi_font_mask && cnt == 512) {
@@ -2537,9 +2551,14 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
                        if (vc->vc_can_do_color) {
                                vc->vc_video_erase_char =
                                    ((c & 0xff00) << 1) | (c & 0xff);
+                               c = vc->vc_def_color;
+                               vc->vc_scrl_erase_char =
+                                   ((c & 0xFF00) << 1) | (c & 0xFF);
                                vc->vc_attr <<= 1;
-                       } else
+                       } else {
                                vc->vc_video_erase_char = c & ~0x100;
+                               vc->vc_scrl_erase_char = c & ~0x100;
+                       }
                }
 
        }
index 93dca3e2aa502d7537aca3fbae7069af80b4f6eb..7992b13ee68fcac9a60840b0e17a9a3581e6713c 100644 (file)
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/upa.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -941,7 +940,7 @@ static int __devinit ffb_probe(struct of_device *op,
        info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
        info->pseudo_palette = par->pseudo_palette;
 
-       sbusfb_fill_var(&info->var, dp->node, 32);
+       sbusfb_fill_var(&info->var, dp, 32);
        par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
        ffb_fixup_var_rgb(&info->var);
 
@@ -987,7 +986,7 @@ static int __devinit ffb_probe(struct of_device *op,
         * chosen console, it will have video outputs off in
         * the DAC.
         */
-       ffb_blank(0, info);
+       ffb_blank(FB_BLANK_UNBLANK, info);
 
        if (fb_alloc_cmap(&info->cmap, 256, 0))
                goto out_unmap_dac;
index f3160fc29795354a680e13d5a576876f70b42af7..8bc46e9303402da0b78211d433f38949d4d687e1 100644 (file)
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -562,7 +561,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id *
        par->physbase = op->resource[0].start;
        par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&info->var, dp->node, 32);
+       sbusfb_fill_var(&info->var, dp, 32);
        leo_fixup_var_rgb(&info->var);
 
        linebytes = of_getintprop_default(dp, "linebytes",
@@ -601,7 +600,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id *
        leo_init_wids(info);
        leo_init_hw(info);
 
-       leo_blank(0, info);
+       leo_blank(FB_BLANK_UNBLANK, info);
 
        if (fb_alloc_cmap(&info->cmap, 256, 0))
                goto out_unmap_regs;
index c95874fe9076579de587a7c1f87c9ded194ff7b5..9e903454ffc138b053c4ad32f7b12dd3636e8f94 100644 (file)
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -275,7 +274,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
        par->physbase = op->resource[2].start;
        par->which_io = op->resource[2].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&info->var, dp->node, 8);
+       sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
        info->var.green.length = 8;
        info->var.blue.length = 8;
@@ -295,7 +294,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
        if (!info->screen_base)
                goto out_unmap_regs;
 
-       p9100_blank(0, info);
+       p9100_blank(FB_BLANK_UNBLANK, info);
 
        if (fb_alloc_cmap(&info->cmap, 256, 0))
                goto out_unmap_screen;
index 685761a0732c2d4196b727875af516627e9ae2a8..4db6b48a87155b1f7316ad6f5145d37922edec8f 100644 (file)
@@ -100,7 +100,6 @@ static int rgbfb_remove(struct platform_device *pdev)
                fb_dealloc_cmap(&info->cmap);
                framebuffer_release(info);
                platform_set_drvdata(pdev, NULL);
-               kfree(info);
        }
 
        pnx4008_free_dum_channel(channel_owned, pdev->id);
@@ -168,23 +167,21 @@ static int __devinit rgbfb_probe(struct platform_device *pdev)
 
        ret = fb_alloc_cmap(&info->cmap, 256, 0);
        if (ret < 0)
-               goto err2;
+               goto err1;
 
        ret = register_framebuffer(info);
        if (ret < 0)
-               goto err3;
+               goto err2;
        platform_set_drvdata(pdev, info);
 
        return 0;
 
-err3:
-       fb_dealloc_cmap(&info->cmap);
 err2:
-       framebuffer_release(info);
+       fb_dealloc_cmap(&info->cmap);
 err1:
        pnx4008_free_dum_channel(channel_owned, pdev->id);
 err0:
-       kfree(info);
+       framebuffer_release(info);
 err:
        return ret;
 }
index 3ab6e3d973a1670bef82cc28fa89cf1ba8e46d8f..48aea39c35a5e007f1f359f7c723e9d224c01cd2 100644 (file)
@@ -1301,8 +1301,8 @@ static void pxafb_decode_mode_info(struct pxafb_info *fbi,
        }
 }
 
-static int pxafb_decode_mach_info(struct pxafb_info *fbi,
-                                 struct pxafb_mach_info *inf)
+static void pxafb_decode_mach_info(struct pxafb_info *fbi,
+                                  struct pxafb_mach_info *inf)
 {
        unsigned int lcd_conn = inf->lcd_conn;
 
@@ -1333,7 +1333,7 @@ static int pxafb_decode_mach_info(struct pxafb_info *fbi,
                fbi->lccr0 = inf->lccr0;
                fbi->lccr3 = inf->lccr3;
                fbi->lccr4 = inf->lccr4;
-               return -EINVAL;
+               goto decode_mode;
        }
 
        if (lcd_conn == LCD_MONO_STN_8BPP)
@@ -1343,8 +1343,8 @@ static int pxafb_decode_mach_info(struct pxafb_info *fbi,
        fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
        fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL)  ? LCCR3_PCP : 0;
 
+decode_mode:
        pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
-       return 0;
 }
 
 static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
index 4deaac05b9380b6dc74a0ce4baf24db9ef4c1ef0..37d764ad56b052a8249dc8d9062c7af07a09d167 100644 (file)
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/of_device.h>
 
-#include <asm/oplib.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
 
-void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp)
+void sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp,
+                    int bpp)
 {
        memset(var, 0, sizeof(*var));
 
-       var->xres = prom_getintdefault(prom_node, "width", 1152);
-       var->yres = prom_getintdefault(prom_node, "height", 900);
+       var->xres = of_getintprop_default(dp, "width", 1152);
+       var->yres = of_getintprop_default(dp, "height", 900);
        var->xres_virtual = var->xres;
        var->yres_virtual = var->yres;
        var->bits_per_pixel = bpp;
index 492828c3fe8fcf4c8a3d9992bea57ef51a44a89f..7ba3250236bd7a453f32c8942c447922b03345a3 100644 (file)
@@ -11,7 +11,8 @@ struct sbus_mmap_map {
 #define SBUS_MMAP_FBSIZE(n) (-n)
 #define SBUS_MMAP_EMPTY        0x80000000
 
-extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp);
+extern void sbusfb_fill_var(struct fb_var_screeninfo *var,
+                           struct device_node *dp, int bpp);
 struct vm_area_struct;
 extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
                              unsigned long physbase, unsigned long fbsize,
@@ -21,6 +22,6 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                        struct fb_info *info,
                        int type, int fb_depth, unsigned long fb_size);
 int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
-               unsigned long arg);
+                       unsigned long arg);
 
 #endif /* _SBUSLIB_H */
index c3869a96ab5877162ea6e72960f7d0fdf73e9cd1..b1dde09e70156d31c8cfcd7a5345b241155875d7 100644 (file)
@@ -9,10 +9,9 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 
 struct s3d_info {
        struct fb_info          *info;
index 71bf3f1f00bcf1b9f2aa018281494a9a2a6b0e72..c2ba51b7ea18af54dd9be3d0a6b25b90cf93edae 100644 (file)
@@ -9,10 +9,9 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 
 /* XXX This device has a 'dev-comm' property which aparently is
  * XXX a pointer into the openfirmware's address space which is
index a71774305772bb8d60270f216b53bd6a996906e5..2a03f78bbb0d53f60db6eaba3be24d09e31d4cdd 100644 (file)
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -84,7 +83,7 @@ struct tcx_tec {
 
 struct tcx_thc {
        u32 thc_rev;
-        u32 thc_pad0[511];
+       u32 thc_pad0[511];
        u32 thc_hs;             /* hsync timing */
        u32 thc_hsdvs;
        u32 thc_hd;
@@ -126,10 +125,10 @@ struct tcx_par {
 };
 
 /* Reset control plane so that WID is 8-bit plane. */
-static void __tcx_set_control_plane (struct tcx_par *par)
+static void __tcx_set_control_plane(struct tcx_par *par)
 {
        u32 __iomem *p, *pend;
-        
+
        if (par->lowdepth)
                return;
 
@@ -143,8 +142,8 @@ static void __tcx_set_control_plane (struct tcx_par *par)
                sbus_writel(tmp, p);
        }
 }
-                                                
-static void tcx_reset (struct fb_info *info)
+
+static void tcx_reset(struct fb_info *info)
 {
        struct tcx_par *par = (struct tcx_par *) info->par;
        unsigned long flags;
@@ -365,7 +364,8 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
                           info->screen_base, par->fbsize);
 }
 
-static int __devinit tcx_init_one(struct of_device *op)
+static int __devinit tcx_probe(struct of_device *op,
+                              const struct of_device_id *match)
 {
        struct device_node *dp = op->node;
        struct fb_info *info;
@@ -384,7 +384,7 @@ static int __devinit tcx_init_one(struct of_device *op)
        par->lowdepth =
                (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
 
-       sbusfb_fill_var(&info->var, dp->node, 8);
+       sbusfb_fill_var(&info->var, dp, 8);
        info->var.red.length = 8;
        info->var.green.length = 8;
        info->var.blue.length = 8;
@@ -488,13 +488,6 @@ out_err:
        return err;
 }
 
-static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct of_device *op = to_of_device(&dev->dev);
-
-       return tcx_init_one(op);
-}
-
 static int __devexit tcx_remove(struct of_device *op)
 {
        struct fb_info *info = dev_get_drvdata(&op->dev);
index bd54cd0de39af13fc4170665878ed63ac1af4acb..beefab2992c042834fff60ad45a6ee92680ffcb0 100644 (file)
@@ -27,7 +27,6 @@
 #define VERSION                "0.7.8-NEWAPI"
 
 struct tridentfb_par {
-       int vclk;               /* in MHz */
        void __iomem *io_virt;  /* iospace virtual memory address */
 };
 
@@ -669,27 +668,26 @@ static void set_screen_start(int base)
                 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
 }
 
-/* Use 20.12 fixed-point for NTSC value and frequency calculation */
-#define calc_freq(n, m, k)  ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
-
 /* Set dotclock frequency */
-static void set_vclk(int freq)
+static void set_vclk(unsigned long freq)
 {
        int m, n, k;
-       int f, fi, d, di;
+       unsigned long f, fi, d, di;
        unsigned char lo = 0, hi = 0;
 
-       d = 20;
+       d = 20000;
        for (k = 2; k >= 0; k--)
                for (m = 0; m < 63; m++)
                        for (n = 0; n < 128; n++) {
-                               fi = calc_freq(n, m, k);
+                               fi = ((14318l * (n + 8)) / (m + 2)) >> k;
                                if ((di = abs(fi - freq)) < d) {
                                        d = di;
                                        f = fi;
                                        lo = n;
                                        hi = (k << 6) | m;
                                }
+                               if (fi > freq)
+                                       break;
                        }
        if (chip3D) {
                write3C4(ClockHigh, hi);
@@ -888,6 +886,8 @@ static int tridentfb_set_par(struct fb_info *info)
        struct fb_var_screeninfo *var = &info->var;
        int bpp = var->bits_per_pixel;
        unsigned char tmp;
+       unsigned long vclk;
+
        debug("enter\n");
        hdispend = var->xres / 8 - 1;
        hsyncstart = (var->xres + var->right_margin) / 8;
@@ -905,7 +905,6 @@ static int tridentfb_set_par(struct fb_info *info)
        vblankstart = var->yres;
        vblankend = vtotal + 2;
 
-       enable_mmio();
        crtc_unlock();
        write3CE(CyberControl, 8);
 
@@ -1015,11 +1014,11 @@ static int tridentfb_set_par(struct fb_info *info)
        write3X4(Performance, 0x92);
        write3X4(PCIReg, 0x07);         /* MMIO & PCI read and write burst enable */
 
-       /* convert from picoseconds to MHz */
-       par->vclk = 1000000 / info->var.pixclock;
+       /* convert from picoseconds to kHz */
+       vclk = PICOS2KHZ(info->var.pixclock);
        if (bpp == 32)
-               par->vclk *= 2;
-       set_vclk(par->vclk);
+               vclk *= 2;
+       set_vclk(vclk);
 
        write3C4(0, 3);
        write3C4(1, 1);         /* set char clock 8 dots wide */
index b535483bc556f5f153eb434583c8dc6593377164..13866789b3561027b803797a95c985f573671fd4 100644 (file)
@@ -80,19 +80,51 @@ static void add_status(struct virtio_device *dev, unsigned status)
        dev->config->set_status(dev, dev->config->get_status(dev) | status);
 }
 
+void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
+                                        unsigned int fbit)
+{
+       unsigned int i;
+       struct virtio_driver *drv = container_of(vdev->dev.driver,
+                                                struct virtio_driver, driver);
+
+       for (i = 0; i < drv->feature_table_size; i++)
+               if (drv->feature_table[i] == fbit)
+                       return;
+       BUG();
+}
+EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature);
+
 static int virtio_dev_probe(struct device *_d)
 {
-       int err;
+       int err, i;
        struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
        struct virtio_driver *drv = container_of(dev->dev.driver,
                                                 struct virtio_driver, driver);
+       u32 device_features;
 
+       /* We have a driver! */
        add_status(dev, VIRTIO_CONFIG_S_DRIVER);
+
+       /* Figure out what features the device supports. */
+       device_features = dev->config->get_features(dev);
+
+       /* Features supported by both device and driver into dev->features. */
+       memset(dev->features, 0, sizeof(dev->features));
+       for (i = 0; i < drv->feature_table_size; i++) {
+               unsigned int f = drv->feature_table[i];
+               BUG_ON(f >= 32);
+               if (device_features & (1 << f))
+                       set_bit(f, dev->features);
+       }
+
        err = drv->probe(dev);
        if (err)
                add_status(dev, VIRTIO_CONFIG_S_FAILED);
-       else
+       else {
                add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+               /* They should never have set feature bits beyond 32 */
+               dev->config->set_features(dev, dev->features[0]);
+       }
        return err;
 }
 
@@ -114,6 +146,8 @@ static int virtio_dev_remove(struct device *_d)
 
 int register_virtio_driver(struct virtio_driver *driver)
 {
+       /* Catch this early. */
+       BUG_ON(driver->feature_table_size && !driver->feature_table);
        driver->driver.bus = &virtio_bus;
        driver->driver.probe = virtio_dev_probe;
        driver->driver.remove = virtio_dev_remove;
index 0b3efc31ee6d38620f97855a8c2d4941eea5f5b9..bfef604160d16460062f46b84f16c9320579c0d4 100644 (file)
@@ -155,9 +155,9 @@ static void virtballoon_changed(struct virtio_device *vdev)
 static inline s64 towards_target(struct virtio_balloon *vb)
 {
        u32 v;
-       __virtio_config_val(vb->vdev,
-                           offsetof(struct virtio_balloon_config, num_pages),
-                           &v);
+       vb->vdev->config->get(vb->vdev,
+                             offsetof(struct virtio_balloon_config, num_pages),
+                             &v, sizeof(v));
        return v - vb->num_pages;
 }
 
@@ -227,7 +227,7 @@ static int virtballoon_probe(struct virtio_device *vdev)
        }
 
        vb->tell_host_first
-               = vdev->config->feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
+               = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
 
        return 0;
 
@@ -259,7 +259,11 @@ static void virtballoon_remove(struct virtio_device *vdev)
        kfree(vb);
 }
 
+static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST };
+
 static struct virtio_driver virtio_balloon = {
+       .feature_table = features,
+       .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,
        .driver.owner = THIS_MODULE,
        .id_table =     id_table,
index c0df924766a7ea0daaf0bfa46ad5df4c06a2adc8..27e9fc9117cdfa69fee88e32e3636a844d803d5e 100644 (file)
@@ -87,23 +87,22 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
        return container_of(vdev, struct virtio_pci_device, vdev);
 }
 
-/* virtio config->feature() implementation */
-static bool vp_feature(struct virtio_device *vdev, unsigned bit)
+/* virtio config->get_features() implementation */
+static u32 vp_get_features(struct virtio_device *vdev)
+{
+       struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+       /* When someone needs more than 32 feature bits, we'll need to
+        * steal a bit to indicate that the rest are somewhere else. */
+       return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
+}
+
+/* virtio config->set_features() implementation */
+static void vp_set_features(struct virtio_device *vdev, u32 features)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       u32 mask;
-
-       /* Since this function is supposed to have the side effect of
-        * enabling a queried feature, we simulate that by doing a read
-        * from the host feature bitmask and then writing to the guest
-        * feature bitmask */
-       mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
-       if (mask & (1 << bit)) {
-               mask |= (1 << bit);
-               iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
-       }
 
-       return !!(mask & (1 << bit));
+       iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
 }
 
 /* virtio config->get() implementation */
@@ -145,14 +144,14 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* We should never be setting status to 0. */
        BUG_ON(status == 0);
-       return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
 static void vp_reset(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* 0 status means a reset. */
-       return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
 /* the notify function used when creating a virt queue */
@@ -293,7 +292,6 @@ static void vp_del_vq(struct virtqueue *vq)
 }
 
 static struct virtio_config_ops virtio_pci_config_ops = {
-       .feature        = vp_feature,
        .get            = vp_get,
        .set            = vp_set,
        .get_status     = vp_get_status,
@@ -301,6 +299,8 @@ static struct virtio_config_ops virtio_pci_config_ops = {
        .reset          = vp_reset,
        .find_vq        = vp_find_vq,
        .del_vq         = vp_del_vq,
+       .get_features   = vp_get_features,
+       .set_features   = vp_set_features,
 };
 
 /* the PCI probing function */
index c2fa5c6308133e5bd9c4e4c39e4a6c0b9b8b7c4b..937a49d6772cc5271d22ef48cb14df6bf56c07f7 100644 (file)
@@ -184,6 +184,11 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
 
        START_USE(vq);
 
+       if (unlikely(vq->broken)) {
+               END_USE(vq);
+               return NULL;
+       }
+
        if (!more_used(vq)) {
                pr_debug("No more buffers in queue\n");
                END_USE(vq);
index d5bd497ab9cbd5154ade0781ed3bffbe3d83aeb7..223b1917093ea357ffe68440199cddd7abdd0489 100644 (file)
@@ -48,7 +48,7 @@ struct affs_ext_key {
  * affs fs inode data in memory
  */
 struct affs_inode_info {
-       u32      i_opencnt;
+       atomic_t i_opencnt;
        struct semaphore i_link_lock;           /* Protects internal inode access. */
        struct semaphore i_ext_lock;            /* Protects internal inode access. */
 #define i_hash_lock i_ext_lock
@@ -170,8 +170,6 @@ extern int  affs_rename(struct inode *old_dir, struct dentry *old_dentry,
 extern unsigned long            affs_parent_ino(struct inode *dir);
 extern struct inode            *affs_new_inode(struct inode *dir);
 extern int                      affs_notify_change(struct dentry *dentry, struct iattr *attr);
-extern void                     affs_put_inode(struct inode *inode);
-extern void                     affs_drop_inode(struct inode *inode);
 extern void                     affs_delete_inode(struct inode *inode);
 extern void                     affs_clear_inode(struct inode *inode);
 extern struct inode            *affs_iget(struct super_block *sb,
index 1a4f092f24efdb2ab13efa4bebb85bd38e7d2678..6eac7bdeec94dc320924d7be0892fb89a23cde72 100644 (file)
@@ -48,8 +48,9 @@ affs_file_open(struct inode *inode, struct file *filp)
 {
        if (atomic_read(&filp->f_count) != 1)
                return 0;
-       pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt);
-       AFFS_I(inode)->i_opencnt++;
+       pr_debug("AFFS: open(%lu,%d)\n",
+                inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
+       atomic_inc(&AFFS_I(inode)->i_opencnt);
        return 0;
 }
 
@@ -58,10 +59,16 @@ affs_file_release(struct inode *inode, struct file *filp)
 {
        if (atomic_read(&filp->f_count) != 0)
                return 0;
-       pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt);
-       AFFS_I(inode)->i_opencnt--;
-       if (!AFFS_I(inode)->i_opencnt)
+       pr_debug("AFFS: release(%lu, %d)\n",
+                inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
+
+       if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
+               mutex_lock(&inode->i_mutex);
+               if (inode->i_size != AFFS_I(inode)->mmu_private)
+                       affs_truncate(inode);
                affs_free_prealloc(inode);
+               mutex_unlock(&inode->i_mutex);
+       }
 
        return 0;
 }
@@ -180,7 +187,7 @@ affs_get_extblock(struct inode *inode, u32 ext)
        /* inline the simplest case: same extended block as last time */
        struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
        if (ext == AFFS_I(inode)->i_ext_last)
-               atomic_inc(&bh->b_count);
+               get_bh(bh);
        else
                /* we have to do more (not inlined) */
                bh = affs_get_extblock_slow(inode, ext);
@@ -306,7 +313,7 @@ store_ext:
        affs_brelse(AFFS_I(inode)->i_ext_bh);
        AFFS_I(inode)->i_ext_last = ext;
        AFFS_I(inode)->i_ext_bh = bh;
-       atomic_inc(&bh->b_count);
+       get_bh(bh);
 
        return bh;
 
@@ -324,7 +331,6 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
 
        pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
 
-
        BUG_ON(block > (sector_t)0x7fffffffUL);
 
        if (block >= AFFS_I(inode)->i_blkcnt) {
@@ -827,6 +833,8 @@ affs_truncate(struct inode *inode)
                res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
                if (!res)
                        res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
+               else
+                       inode->i_size = AFFS_I(inode)->mmu_private;
                mark_inode_dirty(inode);
                return;
        } else if (inode->i_size == AFFS_I(inode)->mmu_private)
@@ -862,6 +870,7 @@ affs_truncate(struct inode *inode)
                blk++;
        } else
                AFFS_HEAD(ext_bh)->first_data = 0;
+       AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i);
        size = AFFS_SB(sb)->s_hashsize;
        if (size > blkcnt - blk + i)
                size = blkcnt - blk + i;
index 27fe6cbe43ae84bc1582f8e86131cebb1566eb1e..a13b334a391029a60de7426ae1f4684f1fd1f5a3 100644 (file)
@@ -58,7 +58,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
        AFFS_I(inode)->i_extcnt = 1;
        AFFS_I(inode)->i_ext_last = ~1;
        AFFS_I(inode)->i_protect = prot;
-       AFFS_I(inode)->i_opencnt = 0;
+       atomic_set(&AFFS_I(inode)->i_opencnt, 0);
        AFFS_I(inode)->i_blkcnt = 0;
        AFFS_I(inode)->i_lc = NULL;
        AFFS_I(inode)->i_lc_size = 0;
@@ -108,8 +108,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
                        inode->i_mode |= S_IFDIR;
                } else
                        inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
-               if (tail->link_chain)
-                       inode->i_nlink = 2;
                /* Maybe it should be controlled by mount parameter? */
                //inode->i_mode |= S_ISVTX;
                inode->i_op = &affs_dir_inode_operations;
@@ -244,32 +242,13 @@ out:
        return error;
 }
 
-void
-affs_put_inode(struct inode *inode)
-{
-       pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
-       affs_free_prealloc(inode);
-}
-
-void
-affs_drop_inode(struct inode *inode)
-{
-       mutex_lock(&inode->i_mutex);
-       if (inode->i_size != AFFS_I(inode)->mmu_private)
-               affs_truncate(inode);
-       mutex_unlock(&inode->i_mutex);
-
-       generic_drop_inode(inode);
-}
-
 void
 affs_delete_inode(struct inode *inode)
 {
        pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
        truncate_inode_pages(&inode->i_data, 0);
        inode->i_size = 0;
-       if (S_ISREG(inode->i_mode))
-               affs_truncate(inode);
+       affs_truncate(inode);
        clear_inode(inode);
        affs_free_block(inode->i_sb, inode->i_ino);
 }
@@ -277,9 +256,12 @@ affs_delete_inode(struct inode *inode)
 void
 affs_clear_inode(struct inode *inode)
 {
-       unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc;
+       unsigned long cache_page;
 
        pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
+
+       affs_free_prealloc(inode);
+       cache_page = (unsigned long)AFFS_I(inode)->i_lc;
        if (cache_page) {
                pr_debug("AFFS: freeing ext cache\n");
                AFFS_I(inode)->i_lc = NULL;
@@ -316,7 +298,7 @@ affs_new_inode(struct inode *dir)
        inode->i_ino     = block;
        inode->i_nlink   = 1;
        inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
-       AFFS_I(inode)->i_opencnt = 0;
+       atomic_set(&AFFS_I(inode)->i_opencnt, 0);
        AFFS_I(inode)->i_blkcnt = 0;
        AFFS_I(inode)->i_lc = NULL;
        AFFS_I(inode)->i_lc_size = 0;
@@ -369,12 +351,12 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
        switch (type) {
        case ST_LINKFILE:
        case ST_LINKDIR:
-               inode_bh = bh;
                retval = -ENOSPC;
                block = affs_alloc_block(dir, dir->i_ino);
                if (!block)
                        goto err;
                retval = -EIO;
+               inode_bh = bh;
                bh = affs_getzeroblk(sb, block);
                if (!bh)
                        goto err;
index 2218f1ee71ce1c2cc146ccd876d614c78fce94cd..cfcf1b6cf82be05dbd9001e494c55cfa26b4b790 100644 (file)
@@ -234,7 +234,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 int
 affs_unlink(struct inode *dir, struct dentry *dentry)
 {
-       pr_debug("AFFS: unlink(dir=%d, \"%.*s\")\n", (u32)dir->i_ino,
+       pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino,
+                dentry->d_inode->i_ino,
                 (int)dentry->d_name.len, dentry->d_name.name);
 
        return affs_remove_header(dentry);
@@ -302,7 +303,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 int
 affs_rmdir(struct inode *dir, struct dentry *dentry)
 {
-       pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino,
+       pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino,
+                dentry->d_inode->i_ino,
                 (int)dentry->d_name.len, dentry->d_name.name);
 
        return affs_remove_header(dentry);
index 01d25d532541bc3d698f5321923a87cf9900cfe4..d214837d5e42a868009d75084e27716f7937e0b2 100644 (file)
@@ -71,12 +71,18 @@ static struct kmem_cache * affs_inode_cachep;
 
 static struct inode *affs_alloc_inode(struct super_block *sb)
 {
-       struct affs_inode_info *ei;
-       ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
-       if (!ei)
+       struct affs_inode_info *i;
+
+       i = kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
+       if (!i)
                return NULL;
-       ei->vfs_inode.i_version = 1;
-       return &ei->vfs_inode;
+
+       i->vfs_inode.i_version = 1;
+       i->i_lc = NULL;
+       i->i_ext_bh = NULL;
+       i->i_pa_cnt = 0;
+
+       return &i->vfs_inode;
 }
 
 static void affs_destroy_inode(struct inode *inode)
@@ -114,8 +120,6 @@ static const struct super_operations affs_sops = {
        .alloc_inode    = affs_alloc_inode,
        .destroy_inode  = affs_destroy_inode,
        .write_inode    = affs_write_inode,
-       .put_inode      = affs_put_inode,
-       .drop_inode     = affs_drop_inode,
        .delete_inode   = affs_delete_inode,
        .clear_inode    = affs_clear_inode,
        .put_super      = affs_put_super,
index f42be069e085b2d212b8cc633d61f418be6801f5..977ef208c05193bbe555a4b4bce50853f0483616 100644 (file)
@@ -57,9 +57,6 @@ static struct dentry_operations anon_inodefs_dentry_operations = {
  *                    anonymous inode, and a dentry that describe the "class"
  *                    of the file
  *
- * @pfd:     [out]   pointer to the file descriptor
- * @dpinode: [out]   pointer to the inode
- * @pfile:   [out]   pointer to the file struct
  * @name:    [in]    name of the "class" of the new file
  * @fops     [in]    file operations for the new file
  * @priv     [in]    private data for the new file (will be file's private_data)
@@ -68,10 +65,9 @@ static struct dentry_operations anon_inodefs_dentry_operations = {
  * that do not need to have a full-fledged inode in order to operate correctly.
  * All the files created with anon_inode_getfd() will share a single inode,
  * hence saving memory and avoiding code duplication for the file/inode/dentry
- * setup.
+ * setup.  Returns new descriptor or -error.
  */
-int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
-                    const char *name, const struct file_operations *fops,
+int anon_inode_getfd(const char *name, const struct file_operations *fops,
                     void *priv)
 {
        struct qstr this;
@@ -125,10 +121,7 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
 
        fd_install(fd, file);
 
-       *pfd = fd;
-       *pinode = anon_inode_inode;
-       *pfile = file;
-       return 0;
+       return fd;
 
 err_dput:
        dput(dentry);
index d96e5c14a9caaaaa2c498b3e5f833176634e3b14..894fee54d4d83bd1ce22c50817871f1dc8c6f0da 100644 (file)
@@ -73,8 +73,8 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
        status = 0;
 done:
        DPRINTK("returning = %d", status);
-       mntput(mnt);
        dput(dentry);
+       mntput(mnt);
        return status;
 }
 
@@ -333,7 +333,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb,
                        /* Can we expire this guy */
                        if (autofs4_can_expire(dentry, timeout, do_now)) {
                                expired = dentry;
-                               break;
+                               goto found;
                        }
                        goto next;
                }
@@ -352,7 +352,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb,
                                inf->flags |= AUTOFS_INF_EXPIRING;
                                spin_unlock(&sbi->fs_lock);
                                expired = dentry;
-                               break;
+                               goto found;
                        }
                        spin_unlock(&sbi->fs_lock);
                /*
@@ -363,7 +363,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb,
                        expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
                        if (expired) {
                                dput(dentry);
-                               break;
+                               goto found;
                        }
                }
 next:
@@ -371,18 +371,16 @@ next:
                spin_lock(&dcache_lock);
                next = next->next;
        }
-
-       if (expired) {
-               DPRINTK("returning %p %.*s",
-                       expired, (int)expired->d_name.len, expired->d_name.name);
-               spin_lock(&dcache_lock);
-               list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
-               spin_unlock(&dcache_lock);
-               return expired;
-       }
        spin_unlock(&dcache_lock);
-
        return NULL;
+
+found:
+       DPRINTK("returning %p %.*s",
+               expired, (int)expired->d_name.len, expired->d_name.name);
+       spin_lock(&dcache_lock);
+       list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
+       spin_unlock(&dcache_lock);
+       return expired;
 }
 
 /* Perform an expiry operation */
index aa4c5ff8a40dfcf65babdd56c9e6fac056b4423f..edf5b6bddb528a43bb85e51eb834ecbdb14a7877 100644 (file)
@@ -146,17 +146,17 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
 
        if (d_mountpoint(dentry)) {
                struct file *fp = NULL;
-               struct vfsmount *fp_mnt = mntget(mnt);
-               struct dentry *fp_dentry = dget(dentry);
+               struct path fp_path = { .dentry = dentry, .mnt = mnt };
 
-               if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
-                       dput(fp_dentry);
-                       mntput(fp_mnt);
+               path_get(&fp_path);
+
+               if (!autofs4_follow_mount(&fp_path.mnt, &fp_path.dentry)) {
+                       path_put(&fp_path);
                        dcache_dir_close(inode, file);
                        goto out;
                }
 
-               fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
+               fp = dentry_open(fp_path.dentry, fp_path.mnt, file->f_flags);
                status = PTR_ERR(fp);
                if (IS_ERR(fp)) {
                        dcache_dir_close(inode, file);
@@ -242,7 +242,8 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
-       int status = 0;
+       struct dentry *new;
+       int status;
 
        /* Block on any pending expiry here; invalidate the dentry
            when expiration is done to trigger mount request with a new
@@ -318,7 +319,28 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
        spin_lock(&dentry->d_lock);
        dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
        spin_unlock(&dentry->d_lock);
-       return status;
+
+       /*
+        * The dentry that is passed in from lookup may not be the one
+        * we end up using, as mkdir can create a new one.  If this
+        * happens, and another process tries the lookup at the same time,
+        * it will set the PENDING flag on this new dentry, but add itself
+        * to our waitq.  Then, if after the lookup succeeds, the first
+        * process that requested the mount performs another lookup of the
+        * same directory, it will show up as still pending!  So, we need
+        * to redo the lookup here and clear pending on that dentry.
+        */
+       if (d_unhashed(dentry)) {
+               new = d_lookup(dentry->d_parent, &dentry->d_name);
+               if (new) {
+                       spin_lock(&new->d_lock);
+                       new->d_flags &= ~DCACHE_AUTOFS_PENDING;
+                       spin_unlock(&new->d_lock);
+                       dput(new);
+               }
+       }
+
+       return 0;
 }
 
 /* For autofs direct mounts the follow link triggers the mount */
index 1fe28e4754c2c7b44fc3516d4f633bc1c8d4351c..75e5955c3f6d4fe5cf30b3ffcc3d6bc21a9fbffb 100644 (file)
@@ -171,7 +171,7 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
        for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
                len += tmp->d_name.len + 1;
 
-       if (--len > NAME_MAX) {
+       if (!len || --len > NAME_MAX) {
                spin_unlock(&dcache_lock);
                return 0;
        }
index 799f86deff243213256103ee76ff7560098fe965..78562574cb524d87b06883bce5002542b77b5865 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -158,7 +158,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 
                bio_init(bio);
                if (likely(nr_iovecs)) {
-                       unsigned long idx = 0; /* shut up gcc */
+                       unsigned long uninitialized_var(idx);
 
                        bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
                        if (unlikely(!bvl)) {
@@ -963,6 +963,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
  *     @data: pointer to buffer to copy
  *     @len: length in bytes
  *     @gfp_mask: allocation flags for bio and page allocation
+ *     @reading: data direction is READ
  *
  *     copy the kernel address into a bio suitable for io to a block
  *     device. Returns an error pointer in case of error.
index 05c9da6181c3793cd540c803053fc2bd21e08bbc..8355e918fddf3e43d83d6fb6ac13e72bcb06c210 100644 (file)
@@ -1,3 +1,6 @@
+Version 1.53
+------------
+
 Version 1.52
 ------------
 Fix oops on second mount to server when null auth is used.
index bcda2c6b6a048db68697246a61040e41f6b35da6..cb52cbbe45ff4704790ec4ffbf0a985e3423f492 100644 (file)
@@ -460,8 +460,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
        unsigned char *sequence_end;
        unsigned long *oid = NULL;
        unsigned int cls, con, tag, oidlen, rc;
-       int use_ntlmssp = FALSE;
-       int use_kerberos = FALSE;
+       bool use_ntlmssp = false;
+       bool use_kerberos = false;
 
        *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
 
@@ -561,15 +561,15 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                                        if (compare_oid(oid, oidlen,
                                                        MSKRB5_OID,
                                                        MSKRB5_OID_LEN))
-                                               use_kerberos = TRUE;
+                                               use_kerberos = true;
                                        else if (compare_oid(oid, oidlen,
                                                             KRB5_OID,
                                                             KRB5_OID_LEN))
-                                               use_kerberos = TRUE;
+                                               use_kerberos = true;
                                        else if (compare_oid(oid, oidlen,
                                                             NTLMSSP_OID,
                                                             NTLMSSP_OID_LEN))
-                                               use_ntlmssp = TRUE;
+                                               use_ntlmssp = true;
 
                                        kfree(oid);
                                }
index 95024c066d89d6422e7a1adb233a7fb38e76473a..f6fdecf6598c7dbe634e9515f3aa1926bc3d9b87 100644 (file)
@@ -93,15 +93,11 @@ static char *cifs_get_share_name(const char *node_name)
        /* find sharename end */
        pSep++;
        pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
-       if (!pSep) {
-               cERROR(1, ("%s:2 cant find share name in node name: %s",
-                       __func__, node_name));
-               kfree(UNC);
-               return NULL;
+       if (pSep) {
+               /* trim path up to sharename end
+                * now we have share name in UNC */
+               *pSep = 0;
        }
-       /* trim path up to sharename end
-        *          * now we have share name in UNC */
-       *pSep = 0;
 
        return UNC;
 }
@@ -188,7 +184,7 @@ static char *compose_mount_options(const char *sb_mountdata,
                tkn_e = strchr(tkn_e+1, '\\');
                if (tkn_e) {
                        strcat(mountdata, ",prefixpath=");
-                       strcat(mountdata, tkn_e);
+                       strcat(mountdata, tkn_e+1);
                }
        }
 
@@ -244,7 +240,8 @@ static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
                return NULL;
 
        if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
-               /* we should use full path name to correct working with DFS */
+               int i;
+               /* we should use full path name for correct working with DFS */
                l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
                                        strnlen(search_path, MAX_PATHCONF) + 1;
                tmp_path = kmalloc(l_max_len, GFP_KERNEL);
@@ -253,8 +250,14 @@ static char *build_full_dfs_path_from_dentry(struct dentry *dentry)
                        return NULL;
                }
                strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
-               strcat(tmp_path, search_path);
                tmp_path[l_max_len-1] = 0;
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
+                       for (i = 0; i < l_max_len; i++) {
+                               if (tmp_path[i] == '\\')
+                                       tmp_path[i] = '/';
+                       }
+               strncat(tmp_path, search_path, l_max_len - strlen(tmp_path));
+
                full_path = tmp_path;
                kfree(search_path);
        } else {
index e99d4faf5f022e5c3315dbd38b63e12e85ccf0e7..34902cff540059988efa9e014b76cc63a8b10d15 100644 (file)
@@ -559,7 +559,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
                                       const char *path, const __u16 *pfid)
 {
        struct cifsFileInfo *open_file = NULL;
-       int unlock_file = FALSE;
+       bool unlock_file = false;
        int xid;
        int rc = -EIO;
        __u16 fid;
@@ -586,10 +586,10 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
        cifs_sb = CIFS_SB(sb);
 
        if (open_file) {
-               unlock_file = TRUE;
+               unlock_file = true;
                fid = open_file->netfid;
        } else if (pfid == NULL) {
-               int oplock = FALSE;
+               int oplock = 0;
                /* open file */
                rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
                                READ_CONTROL, 0, &fid, &oplock, NULL,
@@ -604,7 +604,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
 
        rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
        cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
-       if (unlock_file == TRUE) /* find_readable_file increments ref count */
+       if (unlock_file == true) /* find_readable_file increments ref count */
                atomic_dec(&open_file->wrtPending);
        else if (pfid == NULL) /* if opened above we have to close the handle */
                CIFSSMBClose(xid, cifs_sb->tcon, fid);
@@ -619,7 +619,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
                                struct inode *inode, const char *path)
 {
        struct cifsFileInfo *open_file;
-       int unlock_file = FALSE;
+       bool unlock_file = false;
        int xid;
        int rc = -EIO;
        __u16 fid;
@@ -640,10 +640,10 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 
        open_file = find_readable_file(CIFS_I(inode));
        if (open_file) {
-               unlock_file = TRUE;
+               unlock_file = true;
                fid = open_file->netfid;
        } else {
-               int oplock = FALSE;
+               int oplock = 0;
                /* open file */
                rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
                                WRITE_DAC, 0, &fid, &oplock, NULL,
@@ -658,7 +658,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 
        rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
        cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
-       if (unlock_file == TRUE)
+       if (unlock_file)
                atomic_dec(&open_file->wrtPending);
        else
                CIFSSMBClose(xid, cifs_sb->tcon, fid);
index 39c2cbdface7b52e27ef8f79820caa6e1d350eff..427a7c695896ff87c1d463d595e29126d5aa5a44 100644 (file)
@@ -222,50 +222,50 @@ static int
 cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct super_block *sb = dentry->d_sb;
-       int xid;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       struct cifsTconInfo *tcon = cifs_sb->tcon;
        int rc = -EOPNOTSUPP;
-       struct cifs_sb_info *cifs_sb;
-       struct cifsTconInfo *pTcon;
+       int xid;
 
        xid = GetXid();
 
-       cifs_sb = CIFS_SB(sb);
-       pTcon = cifs_sb->tcon;
-
        buf->f_type = CIFS_MAGIC_NUMBER;
 
-       /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
-       buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
-                                     presumably be total path, but note
-                                     that some servers (includinng Samba 3)
-                                     have a shorter maximum path */
+       /*
+        * PATH_MAX may be too long - it would presumably be total path,
+        * but note that some servers (includinng Samba 3) have a shorter
+        * maximum path.
+        *
+        * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
+        */
+       buf->f_namelen = PATH_MAX;
        buf->f_files = 0;       /* undefined */
        buf->f_ffree = 0;       /* unlimited */
 
-/* BB we could add a second check for a QFS Unix capability bit */
-/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
-    if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
-                       le64_to_cpu(pTcon->fsUnixInfo.Capability)))
-           rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
-
-    /* Only need to call the old QFSInfo if failed
-    on newer one */
-    if (rc)
-       if (pTcon->ses->capabilities & CAP_NT_SMBS)
-               rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
-
-       /* Some old Windows servers also do not support level 103, retry with
-          older level one if old server failed the previous call or we
-          bypassed it because we detected that this was an older LANMAN sess */
+       /*
+        * We could add a second check for a QFS Unix capability bit
+        */
+       if ((tcon->ses->capabilities & CAP_UNIX) &&
+           (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
+               rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
+
+       /*
+        * Only need to call the old QFSInfo if failed on newer one,
+        * e.g. by OS/2.
+        **/
+       if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
+               rc = CIFSSMBQFSInfo(xid, tcon, buf);
+
+       /*
+        * Some old Windows servers also do not support level 103, retry with
+        * older level one if old server failed the previous call or we
+        * bypassed it because we detected that this was an older LANMAN sess
+        */
        if (rc)
-               rc = SMBOldQFSInfo(xid, pTcon, buf);
-       /* int f_type;
-          __fsid_t f_fsid;
-          int f_namelen;  */
-       /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
+               rc = SMBOldQFSInfo(xid, tcon, buf);
+
        FreeXid(xid);
-       return 0;               /* always return success? what if volume is no
-                                  longer available? */
+       return 0;
 }
 
 static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
@@ -306,8 +306,8 @@ cifs_alloc_inode(struct super_block *sb)
        /* Until the file is open and we have gotten oplock
        info back from the server, can not assume caching of
        file data or metadata */
-       cifs_inode->clientCanCacheRead = FALSE;
-       cifs_inode->clientCanCacheAll = FALSE;
+       cifs_inode->clientCanCacheRead = false;
+       cifs_inode->clientCanCacheAll = false;
        cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
 
        /* Can not set i_flags here - they get immediately overwritten
@@ -940,7 +940,7 @@ static int cifs_oplock_thread(void *dummyarg)
                                    rc = CIFSSMBLock(0, pTcon, netfid,
                                            0 /* len */ , 0 /* offset */, 0,
                                            0, LOCKING_ANDX_OPLOCK_RELEASE,
-                                           0 /* wait flag */);
+                                           false /* wait flag */);
                                        cFYI(1, ("Oplock release rc = %d", rc));
                                }
                        } else
index e1dd9f32e1d7600610ed084fa44548f7d153acb5..cd1301a09b3b5a3886d8a7ee1eee1923a8cd1027 100644 (file)
 
 #define ROOT_I 2
 
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
 extern struct file_system_type cifs_fs_type;
 extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
@@ -110,5 +102,5 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep,
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.52"
+#define CIFS_VERSION   "1.53"
 #endif                         /* _CIFSFS_H */
index 69a2e1942542e1601e9e66078a1c052b86d51742..b7d9f698e63ec5e04ace67469025be11053b423f 100644 (file)
 
 #include "cifspdu.h"
 
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
 #ifndef XATTR_DOS_ATTRIB
 #define XATTR_DOS_ATTRIB "user.DOSATTRIB"
 #endif
@@ -147,7 +139,7 @@ struct TCP_Server_Info {
        enum protocolEnum protocolType;
        char versionMajor;
        char versionMinor;
-       unsigned svlocal:1;     /* local server or remote */
+       bool svlocal:1;                 /* local server or remote */
        atomic_t socketUseCount; /* number of open cifs sessions on socket */
        atomic_t inFlight;  /* number of requests on the wire to server */
 #ifdef CONFIG_CIFS_STATS2
@@ -286,10 +278,10 @@ struct cifsTconInfo {
        FILE_SYSTEM_DEVICE_INFO fsDevInfo;
        FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
        FILE_SYSTEM_UNIX_INFO fsUnixInfo;
-       unsigned ipc:1;         /* set if connection to IPC$ eg for RPC/PIPES */
-       unsigned retry:1;
-       unsigned nocase:1;
-       unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
+       bool ipc:1;             /* set if connection to IPC$ eg for RPC/PIPES */
+       bool retry:1;
+       bool nocase:1;
+       bool unix_ext:1;  /* if false disable Linux extensions to CIFS protocol
                                for this mount even if server would support */
        /* BB add field for back pointer to sb struct(s)? */
 };
@@ -317,10 +309,10 @@ struct cifs_search_info {
        char *srch_entries_start;
        char *presume_name;
        unsigned int resume_name_len;
-       unsigned endOfSearch:1;
-       unsigned emptyDir:1;
-       unsigned unicode:1;
-       unsigned smallBuf:1; /* so we know which buf_release function to call */
+       bool endOfSearch:1;
+       bool emptyDir:1;
+       bool unicode:1;
+       bool smallBuf:1; /* so we know which buf_release function to call */
 };
 
 struct cifsFileInfo {
@@ -335,9 +327,9 @@ struct cifsFileInfo {
        struct inode *pInode; /* needed for oplock break */
        struct mutex lock_mutex;
        struct list_head llist; /* list of byte range locks we have. */
-       unsigned closePend:1;   /* file is marked to close */
-       unsigned invalidHandle:1;  /* file closed via session abend */
-       unsigned messageMode:1;    /* for pipes: message vs byte mode */
+       bool closePend:1;       /* file is marked to close */
+       bool invalidHandle:1;   /* file closed via session abend */
+       bool messageMode:1;     /* for pipes: message vs byte mode */
        atomic_t wrtPending;   /* handle in use - defer close */
        struct semaphore fh_sem; /* prevents reopen race after dead ses*/
        char *search_resume_name; /* BB removeme BB */
@@ -356,9 +348,9 @@ struct cifsInodeInfo {
        __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
        atomic_t inUse;  /* num concurrent users (local openers cifs) of file*/
        unsigned long time;     /* jiffies of last update/check of inode */
-       unsigned clientCanCacheRead:1; /* read oplock */
-       unsigned clientCanCacheAll:1;  /* read and writebehind oplock */
-       unsigned oplockPending:1;
+       bool clientCanCacheRead:1;      /* read oplock */
+       bool clientCanCacheAll:1;       /* read and writebehind oplock */
+       bool oplockPending:1;
        struct inode vfs_inode;
 };
 
@@ -426,9 +418,9 @@ struct mid_q_entry {
        struct smb_hdr *resp_buf;       /* response buffer */
        int midState;   /* wish this were enum but can not pass to wait_event */
        __u8 command;   /* smb command code */
-       unsigned largeBuf:1;    /* if valid response, is pointer to large buf */
-       unsigned multiRsp:1;   /* multiple trans2 responses for one request  */
-       unsigned multiEnd:1; /* both received */
+       bool largeBuf:1;        /* if valid response, is pointer to large buf */
+       bool multiRsp:1;        /* multiple trans2 responses for one request  */
+       bool multiEnd:1;        /* both received */
 };
 
 struct oplock_q_entry {
index 9f49c2f3582c03bfa6f217776548605370cd00a4..c43bf4b7a5563e0bb63cb03768b35a434658d1bd 100644 (file)
 #define OPEN_NO_RECALL          0x00400000
 #define OPEN_FREE_SPACE_QUERY   0x00800000     /* should be zero */
 #define CREATE_OPTIONS_MASK     0x007FFFFF
+#define CREATE_OPTION_READONLY 0x10000000
 #define CREATE_OPTION_SPECIAL   0x20000000   /* system. NB not sent over wire */
 
 /* ImpersonationLevel flags */
@@ -2050,7 +2051,7 @@ typedef struct {
                                                      to 0xFFFF00 */
 #define CIFS_UNIX_LARGE_WRITE_CAP       0x00000080
 #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */
-#define CIFS_UNIX_TRANPSORT_ENCRYPTION_MANDATORY_CAP  0x00000200 /* must do  */
+#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP  0x00000200 /* must do  */
 #define CIFS_UNIX_PROXY_CAP             0x00000400 /* Proxy cap: 0xACE ioctl and
                                                      QFS PROXY call */
 #ifdef CONFIG_CIFS_POSIX
index 50f9fdae19b3d7c97a5638120b56201af3630312..d481f6c5a2be9e5ba76b2ea9af2b3a7657fa772c 100644 (file)
@@ -59,8 +59,9 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
                        struct smb_hdr *out_buf,
                        int *bytes_returned);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
-extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
-extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
+extern bool is_valid_oplock_break(struct smb_hdr *smb,
+                                 struct TCP_Server_Info *);
+extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
@@ -69,7 +70,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
                        enum securityEnum *secType);
-extern int cifs_inet_pton(int, char *source, void *dst);
+extern int cifs_inet_pton(const int, const char *source, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
                            const struct cifsTconInfo *, int /* length of
@@ -187,12 +188,12 @@ extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
 #endif /* possibly unneeded function */
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
                        const char *fileName, __u64 size,
-                       int setAllocationSizeFlag,
+                       bool setAllocationSizeFlag,
                        const struct nls_table *nls_codepage,
                        int remap_special_chars);
 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
                         __u64 size, __u16 fileHandle, __u32 opener_pid,
-                       int AllocSizeFlag);
+                       bool AllocSizeFlag);
 extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
                        char *full_path, __u64 mode, __u64 uid,
                        __u64 gid, dev_t dev,
@@ -291,11 +292,11 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
                        const __u16 netfid, const __u64 len,
                        const __u64 offset, const __u32 numUnlock,
                        const __u32 numLock, const __u8 lockType,
-                       const int waitFlag);
+                       const bool waitFlag);
 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                        const __u16 smb_file_id, const int get_flag,
                        const __u64 len, struct file_lock *,
-                       const __u16 lock_type, const int waitFlag);
+                       const __u16 lock_type, const bool waitFlag);
 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
 
index 4728fa982a4ed965237427b7386b838266ec497b..95fbba4ea7d47213fd9de11536fb02c6bb0c5bfa 100644 (file)
@@ -95,7 +95,7 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
        list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
                open_file = list_entry(tmp, struct cifsFileInfo, tlist);
                if (open_file)
-                       open_file->invalidHandle = TRUE;
+                       open_file->invalidHandle = true;
        }
        write_unlock(&GlobalSMBSeslock);
        /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
@@ -141,7 +141,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                                if (tcon->ses->server->tcpStatus ==
                                                        CifsNeedReconnect) {
                                        /* on "soft" mounts we wait once */
-                                       if ((tcon->retry == FALSE) ||
+                                       if (!tcon->retry ||
                                           (tcon->ses->status == CifsExiting)) {
                                                cFYI(1, ("gave up waiting on "
                                                      "reconnect in smb_init"));
@@ -289,7 +289,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
                                if (tcon->ses->server->tcpStatus ==
                                                CifsNeedReconnect) {
                                        /* on "soft" mounts we wait once */
-                                       if ((tcon->retry == FALSE) ||
+                                       if (!tcon->retry ||
                                           (tcon->ses->status == CifsExiting)) {
                                                cFYI(1, ("gave up waiting on "
                                                      "reconnect in smb_init"));
@@ -1224,11 +1224,8 @@ OldOpenRetry:
        else /* BB FIXME BB */
                pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
 
-       /* if ((omode & S_IWUGO) == 0)
-               pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
-       /*  Above line causes problems due to vfs splitting create into two
-           pieces - need to set mode after file created not while it is
-           being created */
+       if (create_options & CREATE_OPTION_READONLY)
+               pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
 
        /* BB FIXME BB */
 /*     pSMB->CreateOptions = cpu_to_le32(create_options &
@@ -1331,17 +1328,16 @@ openRetry:
                pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
        else
                pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
+
        /* XP does not handle ATTR_POSIX_SEMANTICS */
        /* but it helps speed up case sensitive checks for other
        servers such as Samba */
        if (tcon->ses->capabilities & CAP_UNIX)
                pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
 
-       /* if ((omode & S_IWUGO) == 0)
-               pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
-       /*  Above line causes problems due to vfs splitting create into two
-               pieces - need to set mode after file created not while it is
-               being created */
+       if (create_options & CREATE_OPTION_READONLY)
+               pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
+
        pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
        pSMB->CreateDisposition = cpu_to_le32(openDisposition);
        pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
@@ -1686,7 +1682,7 @@ int
 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
            const __u16 smb_file_id, const __u64 len,
            const __u64 offset, const __u32 numUnlock,
-           const __u32 numLock, const __u8 lockType, const int waitFlag)
+           const __u32 numLock, const __u8 lockType, const bool waitFlag)
 {
        int rc = 0;
        LOCK_REQ *pSMB = NULL;
@@ -1695,7 +1691,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        int timeout = 0;
        __u16 count;
 
-       cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
+       cFYI(1, ("CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock));
        rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
 
        if (rc)
@@ -1706,7 +1702,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
                timeout = CIFS_ASYNC_OP; /* no response expected */
                pSMB->Timeout = 0;
-       } else if (waitFlag == TRUE) {
+       } else if (waitFlag) {
                timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
                pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
        } else {
@@ -1756,7 +1752,7 @@ int
 CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                const __u16 smb_file_id, const int get_flag, const __u64 len,
                struct file_lock *pLockData, const __u16 lock_type,
-               const int waitFlag)
+               const bool waitFlag)
 {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
        struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -3581,9 +3577,9 @@ findFirstRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                if (rc == 0) {
                        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-                               psrch_inf->unicode = TRUE;
+                               psrch_inf->unicode = true;
                        else
-                               psrch_inf->unicode = FALSE;
+                               psrch_inf->unicode = false;
 
                        psrch_inf->ntwrk_buf_start = (char *)pSMBr;
                        psrch_inf->smallBuf = 0;
@@ -3594,9 +3590,9 @@ findFirstRetry:
                               le16_to_cpu(pSMBr->t2.ParameterOffset));
 
                        if (parms->EndofSearch)
-                               psrch_inf->endOfSearch = TRUE;
+                               psrch_inf->endOfSearch = true;
                        else
-                               psrch_inf->endOfSearch = FALSE;
+                               psrch_inf->endOfSearch = false;
 
                        psrch_inf->entries_in_buffer =
                                        le16_to_cpu(parms->SearchCount);
@@ -3624,7 +3620,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
 
        cFYI(1, ("In FindNext"));
 
-       if (psrch_inf->endOfSearch == TRUE)
+       if (psrch_inf->endOfSearch)
                return -ENOENT;
 
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3682,7 +3678,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
        cifs_stats_inc(&tcon->num_fnext);
        if (rc) {
                if (rc == -EBADF) {
-                       psrch_inf->endOfSearch = TRUE;
+                       psrch_inf->endOfSearch = true;
                        rc = 0; /* search probably was closed at end of search*/
                } else
                        cFYI(1, ("FindNext returned = %d", rc));
@@ -3692,9 +3688,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                if (rc == 0) {
                        /* BB fixme add lock for file (srch_info) struct here */
                        if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-                               psrch_inf->unicode = TRUE;
+                               psrch_inf->unicode = true;
                        else
-                               psrch_inf->unicode = FALSE;
+                               psrch_inf->unicode = false;
                        response_data = (char *) &pSMBr->hdr.Protocol +
                               le16_to_cpu(pSMBr->t2.ParameterOffset);
                        parms = (T2_FNEXT_RSP_PARMS *)response_data;
@@ -3709,9 +3705,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                        psrch_inf->ntwrk_buf_start = (char *)pSMB;
                        psrch_inf->smallBuf = 0;
                        if (parms->EndofSearch)
-                               psrch_inf->endOfSearch = TRUE;
+                               psrch_inf->endOfSearch = true;
                        else
-                               psrch_inf->endOfSearch = FALSE;
+                               psrch_inf->endOfSearch = false;
                        psrch_inf->entries_in_buffer =
                                                le16_to_cpu(parms->SearchCount);
                        psrch_inf->index_of_last_entry +=
@@ -4586,7 +4582,7 @@ QFSPosixRetry:
 
 int
 CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
-             __u64 size, int SetAllocation,
+             __u64 size, bool SetAllocation,
              const struct nls_table *nls_codepage, int remap)
 {
        struct smb_com_transaction2_spi_req *pSMB = NULL;
@@ -4675,7 +4671,7 @@ SetEOFRetry:
 
 int
 CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
-                  __u16 fid, __u32 pid_of_opener, int SetAllocation)
+                  __u16 fid, __u32 pid_of_opener, bool SetAllocation)
 {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
        char *data_offset;
index e171067301689dee90ed97de96fc2fcb7eb3f518..f428bf3bf1a96a3026754119fb4c40b0a37606a9 100644 (file)
@@ -49,8 +49,6 @@
 #define CIFS_PORT 445
 #define RFC1001_PORT 139
 
-static DECLARE_COMPLETION(cifsd_complete);
-
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
                         unsigned char *p24);
 
@@ -71,23 +69,23 @@ struct smb_vol {
        mode_t file_mode;
        mode_t dir_mode;
        unsigned secFlg;
-       unsigned rw:1;
-       unsigned retry:1;
-       unsigned intr:1;
-       unsigned setuids:1;
-       unsigned override_uid:1;
-       unsigned override_gid:1;
-       unsigned noperm:1;
-       unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
-       unsigned cifs_acl:1;
-       unsigned no_xattr:1;   /* set if xattr (EA) support should be disabled*/
-       unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
-       unsigned direct_io:1;
-       unsigned remap:1;   /* set to remap seven reserved chars in filenames */
-       unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
-       unsigned no_linux_ext:1;
-       unsigned sfu_emul:1;
-       unsigned nullauth:1; /* attempt to authenticate with null user */
+       bool rw:1;
+       bool retry:1;
+       bool intr:1;
+       bool setuids:1;
+       bool override_uid:1;
+       bool override_gid:1;
+       bool noperm:1;
+       bool no_psx_acl:1; /* set if posix acl support should be disabled */
+       bool cifs_acl:1;
+       bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
+       bool server_ino:1; /* use inode numbers from server ie UniqueId */
+       bool direct_io:1;
+       bool remap:1;     /* set to remap seven reserved chars in filenames */
+       bool posix_paths:1;   /* unset to not ask for posix pathnames. */
+       bool no_linux_ext:1;
+       bool sfu_emul:1;
+       bool nullauth:1; /* attempt to authenticate with null user */
        unsigned nocase;     /* request case insensitive filenames */
        unsigned nobrl;      /* disable sending byte range locks to srv */
        unsigned int rsize;
@@ -345,18 +343,16 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
        struct task_struct *task_to_wake = NULL;
        struct mid_q_entry *mid_entry;
        char temp;
-       int isLargeBuf = FALSE;
-       int isMultiRsp;
+       bool isLargeBuf = false;
+       bool isMultiRsp;
        int reconnect;
 
        current->flags |= PF_MEMALLOC;
-       server->tsk = current;  /* save process info to wake at shutdown */
        cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
        write_lock(&GlobalSMBSeslock);
        atomic_inc(&tcpSesAllocCount);
        length = tcpSesAllocCount.counter;
        write_unlock(&GlobalSMBSeslock);
-       complete(&cifsd_complete);
        if (length  > 1)
                mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
                                GFP_KERNEL);
@@ -390,8 +386,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                } else /* if existing small buf clear beginning */
                        memset(smallbuf, 0, sizeof(struct smb_hdr));
 
-               isLargeBuf = FALSE;
-               isMultiRsp = FALSE;
+               isLargeBuf = false;
+               isMultiRsp = false;
                smb_buffer = smallbuf;
                iov.iov_base = smb_buffer;
                iov.iov_len = 4;
@@ -517,7 +513,7 @@ incomplete_rcv:
                reconnect = 0;
 
                if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
-                       isLargeBuf = TRUE;
+                       isLargeBuf = true;
                        memcpy(bigbuf, smallbuf, 4);
                        smb_buffer = bigbuf;
                }
@@ -582,16 +578,18 @@ incomplete_rcv:
                            (mid_entry->command == smb_buffer->Command)) {
                                if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
                                        /* We have a multipart transact2 resp */
-                                       isMultiRsp = TRUE;
+                                       isMultiRsp = true;
                                        if (mid_entry->resp_buf) {
                                                /* merge response - fix up 1st*/
                                                if (coalesce_t2(smb_buffer,
                                                        mid_entry->resp_buf)) {
-                                                       mid_entry->multiRsp = 1;
+                                                       mid_entry->multiRsp =
+                                                                true;
                                                        break;
                                                } else {
                                                        /* all parts received */
-                                                       mid_entry->multiEnd = 1;
+                                                       mid_entry->multiEnd =
+                                                                true;
                                                        goto multi_t2_fnd;
                                                }
                                        } else {
@@ -603,17 +601,15 @@ incomplete_rcv:
                                                        /* Have first buffer */
                                                        mid_entry->resp_buf =
                                                                 smb_buffer;
-                                                       mid_entry->largeBuf = 1;
+                                                       mid_entry->largeBuf =
+                                                                true;
                                                        bigbuf = NULL;
                                                }
                                        }
                                        break;
                                }
                                mid_entry->resp_buf = smb_buffer;
-                               if (isLargeBuf)
-                                       mid_entry->largeBuf = 1;
-                               else
-                                       mid_entry->largeBuf = 0;
+                               mid_entry->largeBuf = isLargeBuf;
 multi_t2_fnd:
                                task_to_wake = mid_entry->tsk;
                                mid_entry->midState = MID_RESPONSE_RECEIVED;
@@ -638,8 +634,8 @@ multi_t2_fnd:
                                        smallbuf = NULL;
                        }
                        wake_up_process(task_to_wake);
-               } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
-                   && (isMultiRsp == FALSE)) {
+               } else if (!is_valid_oplock_break(smb_buffer, server) &&
+                          !isMultiRsp) {
                        cERROR(1, ("No task to wake, unknown frame received! "
                                   "NumMids %d", midCount.counter));
                        cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
@@ -654,10 +650,20 @@ multi_t2_fnd:
 
        spin_lock(&GlobalMid_Lock);
        server->tcpStatus = CifsExiting;
-       server->tsk = NULL;
+       spin_unlock(&GlobalMid_Lock);
+
+       /* don't exit until kthread_stop is called */
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       while (!kthread_should_stop()) {
+               schedule();
+               set_current_state(TASK_UNINTERRUPTIBLE);
+       }
+       set_current_state(TASK_RUNNING);
+
        /* check if we have blocked requests that need to free */
        /* Note that cifs_max_pending is normally 50, but
        can be set at module install time to as little as two */
+       spin_lock(&GlobalMid_Lock);
        if (atomic_read(&server->inFlight) >= cifs_max_pending)
                atomic_set(&server->inFlight, cifs_max_pending - 1);
        /* We do not want to set the max_pending too low or we
@@ -825,7 +831,7 @@ cifs_parse_mount_options(char *options, const char *devname,
        vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
 
        /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
-       vol->rw = TRUE;
+       vol->rw = true;
        /* default is always to request posix paths. */
        vol->posix_paths = 1;
 
@@ -1181,7 +1187,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                } else if (strnicmp(data, "guest", 5) == 0) {
                        /* ignore */
                } else if (strnicmp(data, "rw", 2) == 0) {
-                       vol->rw = TRUE;
+                       vol->rw = true;
                } else if ((strnicmp(data, "suid", 4) == 0) ||
                                   (strnicmp(data, "nosuid", 6) == 0) ||
                                   (strnicmp(data, "exec", 4) == 0) ||
@@ -1197,7 +1203,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                            is ok to just ignore them */
                        continue;
                } else if (strnicmp(data, "ro", 2) == 0) {
-                       vol->rw = FALSE;
+                       vol->rw = false;
                } else if (strnicmp(data, "hard", 4) == 0) {
                        vol->retry = 1;
                } else if (strnicmp(data, "soft", 4) == 0) {
@@ -1305,6 +1311,9 @@ cifs_parse_mount_options(char *options, const char *devname,
                                                    "begin with // or \\\\ \n");
                                return 1;
                        }
+                       value = strpbrk(vol->UNC+2, "/\\");
+                       if (value)
+                               *value = '\\';
                } else {
                        printk(KERN_WARNING "CIFS: UNC name too long\n");
                        return 1;
@@ -1318,42 +1327,43 @@ cifs_parse_mount_options(char *options, const char *devname,
 
 static struct cifsSesInfo *
 cifs_find_tcp_session(struct in_addr *target_ip_addr,
-               struct in6_addr *target_ip6_addr,
-                char *userName, struct TCP_Server_Info **psrvTcp)
+                     struct in6_addr *target_ip6_addr,
+                     char *userName, struct TCP_Server_Info **psrvTcp)
 {
        struct list_head *tmp;
        struct cifsSesInfo *ses;
+
        *psrvTcp = NULL;
-       read_lock(&GlobalSMBSeslock);
 
+       read_lock(&GlobalSMBSeslock);
        list_for_each(tmp, &GlobalSMBSessionList) {
                ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-               if (ses->server) {
-                       if ((target_ip_addr &&
-                               (ses->server->addr.sockAddr.sin_addr.s_addr
-                                 == target_ip_addr->s_addr)) || (target_ip6_addr
-                               && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
-                                       target_ip6_addr, sizeof(*target_ip6_addr)))) {
-                               /* BB lock server and tcp session and increment
-                                     use count here?? */
-
-                               /* found a match on the TCP session */
-                               *psrvTcp = ses->server;
-
-                               /* BB check if reconnection needed */
-                               if (strncmp
-                                   (ses->userName, userName,
-                                    MAX_USERNAME_SIZE) == 0){
-                                       read_unlock(&GlobalSMBSeslock);
-                                       /* Found exact match on both TCP and
-                                          SMB sessions */
-                                       return ses;
-                               }
-                       }
+               if (!ses->server)
+                       continue;
+
+               if (target_ip_addr &&
+                   ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
+                               continue;
+               else if (target_ip6_addr &&
+                        memcmp(&ses->server->addr.sockAddr6.sin6_addr,
+                               target_ip6_addr, sizeof(*target_ip6_addr)))
+                               continue;
+               /* BB lock server and tcp session; increment use count here?? */
+
+               /* found a match on the TCP session */
+               *psrvTcp = ses->server;
+
+               /* BB check if reconnection needed */
+               if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
+                       read_unlock(&GlobalSMBSeslock);
+                       /* Found exact match on both TCP and
+                          SMB sessions */
+                       return ses;
                }
                /* else tcp and smb sessions need reconnection */
        }
        read_unlock(&GlobalSMBSeslock);
+
        return NULL;
 }
 
@@ -1362,45 +1372,43 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
 {
        struct list_head *tmp;
        struct cifsTconInfo *tcon;
+       __be32 old_ip;
 
        read_lock(&GlobalSMBSeslock);
+
        list_for_each(tmp, &GlobalTreeConnectionList) {
                cFYI(1, ("Next tcon"));
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-               if (tcon->ses) {
-                       if (tcon->ses->server) {
-                               cFYI(1,
-                                    ("old ip addr: %x == new ip %x ?",
-                                     tcon->ses->server->addr.sockAddr.sin_addr.
-                                     s_addr, new_target_ip_addr));
-                               if (tcon->ses->server->addr.sockAddr.sin_addr.
-                                   s_addr == new_target_ip_addr) {
-       /* BB lock tcon, server and tcp session and increment use count here? */
-                                       /* found a match on the TCP session */
-                                       /* BB check if reconnection needed */
-                                       cFYI(1,
-                                             ("IP match, old UNC: %s new: %s",
-                                             tcon->treeName, uncName));
-                                       if (strncmp
-                                           (tcon->treeName, uncName,
-                                            MAX_TREE_SIZE) == 0) {
-                                               cFYI(1,
-                                                    ("and old usr: %s new: %s",
-                                                     tcon->treeName, uncName));
-                                               if (strncmp
-                                                   (tcon->ses->userName,
-                                                    userName,
-                                                    MAX_USERNAME_SIZE) == 0) {
-                                                       read_unlock(&GlobalSMBSeslock);
-                                                       /* matched smb session
-                                                       (user name */
-                                                       return tcon;
-                                               }
-                                       }
-                               }
-                       }
-               }
+               if (!tcon->ses || !tcon->ses->server)
+                       continue;
+
+               old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
+               cFYI(1, ("old ip addr: %x == new ip %x ?",
+                       old_ip, new_target_ip_addr));
+
+               if (old_ip != new_target_ip_addr)
+                       continue;
+
+               /* BB lock tcon, server, tcp session and increment use count? */
+               /* found a match on the TCP session */
+               /* BB check if reconnection needed */
+               cFYI(1, ("IP match, old UNC: %s new: %s",
+                       tcon->treeName, uncName));
+
+               if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
+                       continue;
+
+               cFYI(1, ("and old usr: %s new: %s",
+                       tcon->treeName, uncName));
+
+               if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
+                       continue;
+
+               /* matched smb session (user name) */
+               read_unlock(&GlobalSMBSeslock);
+               return tcon;
        }
+
        read_unlock(&GlobalSMBSeslock);
        return NULL;
 }
@@ -1982,7 +1990,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                kfree(srvTcp->hostname);
                                goto out;
                        }
-                       wait_for_completion(&cifsd_complete);
                        rc = 0;
                        memcpy(srvTcp->workstation_RFC1001_name,
                                volume_info.source_rfc1001_name, 16);
@@ -2189,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        srvTcp->tcpStatus = CifsExiting;
                        spin_unlock(&GlobalMid_Lock);
                        if (srvTcp->tsk) {
-                               struct task_struct *tsk;
                                /* If we could verify that kthread_stop would
                                   always wake up processes blocked in
                                   tcp in recv_mesg then we could remove the
                                   send_sig call */
                                force_sig(SIGKILL, srvTcp->tsk);
-                               tsk = srvTcp->tsk;
-                               if (tsk)
-                                       kthread_stop(tsk);
+                               kthread_stop(srvTcp->tsk);
                        }
                }
                 /* If find_unc succeeded then rc == 0 so we can not end */
@@ -2213,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                        if ((temp_rc == -ESHUTDOWN) &&
                                            (pSesInfo->server) &&
                                            (pSesInfo->server->tsk)) {
-                                               struct task_struct *tsk;
                                                force_sig(SIGKILL,
                                                        pSesInfo->server->tsk);
-                                               tsk = pSesInfo->server->tsk;
-                                               if (tsk)
-                                                       kthread_stop(tsk);
+                                               kthread_stop(pSesInfo->server->tsk);
                                        }
                                } else {
                                        cFYI(1, ("No session or bad tcon"));
                                        if ((pSesInfo->server) &&
                                            (pSesInfo->server->tsk)) {
-                                               struct task_struct *tsk;
                                                force_sig(SIGKILL,
                                                        pSesInfo->server->tsk);
-                                               tsk = pSesInfo->server->tsk;
-                                               if (tsk)
-                                                       kthread_stop(tsk);
+                                               kthread_stop(pSesInfo->server->tsk);
                                        }
                                }
                                sesInfoFree(pSesInfo);
@@ -2602,7 +2600,7 @@ sesssetup_nomem:  /* do not return an error on nomem for the info strings,
 
 static int
 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
-                             struct cifsSesInfo *ses, int *pNTLMv2_flag,
+                             struct cifsSesInfo *ses, bool *pNTLMv2_flag,
                              const struct nls_table *nls_codepage)
 {
        struct smb_hdr *smb_buffer;
@@ -2625,7 +2623,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
        if (ses == NULL)
                return -EINVAL;
        domain = ses->domainName;
-       *pNTLMv2_flag = FALSE;
+       *pNTLMv2_flag = false;
        smb_buffer = cifs_buf_get();
        if (smb_buffer == NULL) {
                return -ENOMEM;
@@ -2778,7 +2776,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                       CIFS_CRYPTO_KEY_SIZE);
                                if (SecurityBlob2->NegotiateFlags &
                                        cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
-                                       *pNTLMv2_flag = TRUE;
+                                       *pNTLMv2_flag = true;
 
                                if ((SecurityBlob2->NegotiateFlags &
                                        cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
@@ -2939,7 +2937,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
 }
 static int
 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-                       char *ntlm_session_key, int ntlmv2_flag,
+                       char *ntlm_session_key, bool ntlmv2_flag,
                        const struct nls_table *nls_codepage)
 {
        struct smb_hdr *smb_buffer;
@@ -3555,8 +3553,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        cifs_sb->prepathlen = 0;
        cifs_sb->prepath = NULL;
        kfree(tmp);
-       if (ses)
-               schedule_timeout_interruptible(msecs_to_jiffies(500));
        if (ses)
                sesInfoFree(ses);
 
@@ -3569,7 +3565,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
 {
        int rc = 0;
        char ntlm_session_key[CIFS_SESS_KEY_SIZE];
-       int ntlmv2_flag = FALSE;
+       bool ntlmv2_flag = false;
        int first_time = 0;
 
        /* what if server changes its buffer size after dropping the session? */
index 0f5c62ba403868048732d69a1d1f55c1e3e098f3..e4e0078a0526c90b9fed67f7a3c2128085902b57 100644 (file)
@@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 {
        int rc = -ENOENT;
        int xid;
+       int create_options = CREATE_NOT_DIR;
        int oplock = 0;
        int desiredAccess = GENERIC_READ | GENERIC_WRITE;
        __u16 fileHandle;
@@ -130,7 +131,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        struct cifsFileInfo *pCifsFile = NULL;
        struct cifsInodeInfo *pCifsInode;
        int disposition = FILE_OVERWRITE_IF;
-       int write_only = FALSE;
+       bool write_only = false;
 
        xid = GetXid();
 
@@ -152,7 +153,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                if (oflags & FMODE_WRITE) {
                        desiredAccess |= GENERIC_WRITE;
                        if (!(oflags & FMODE_READ))
-                               write_only = TRUE;
+                               write_only = true;
                }
 
                if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                FreeXid(xid);
                return -ENOMEM;
        }
+
+       mode &= ~current->fs->umask;
+
+       /*
+        * if we're not using unix extensions, see if we need to set
+        * ATTR_READONLY on the create call
+        */
+       if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
+               create_options |= CREATE_OPTION_READONLY;
+
        if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
                rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
-                        desiredAccess, CREATE_NOT_DIR,
+                        desiredAccess, create_options,
                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        else
@@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        if (rc == -EIO) {
                /* old server, retry the open legacy style */
                rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
-                       desiredAccess, CREATE_NOT_DIR,
+                       desiredAccess, create_options,
                        &fileHandle, &oplock, buf, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                /* If Open reported that we actually created a file
                then we now have to set the mode if possible */
                if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
-                       mode &= ~current->fs->umask;
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
                                        (__u64)current->fsuid,
@@ -254,7 +264,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        d_instantiate(direntry, newinode);
                }
                if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
-                       ((nd->flags & LOOKUP_OPEN) == FALSE)) {
+                       (!(nd->flags & LOOKUP_OPEN))) {
                        /* mknod case - do not leave file open */
                        CIFSSMBClose(xid, pTcon, fileHandle);
                } else if (newinode) {
@@ -266,8 +276,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        pCifsFile->netfid = fileHandle;
                        pCifsFile->pid = current->tgid;
                        pCifsFile->pInode = newinode;
-                       pCifsFile->invalidHandle = FALSE;
-                       pCifsFile->closePend     = FALSE;
+                       pCifsFile->invalidHandle = false;
+                       pCifsFile->closePend     = false;
                        init_MUTEX(&pCifsFile->fh_sem);
                        mutex_init(&pCifsFile->lock_mutex);
                        INIT_LIST_HEAD(&pCifsFile->llist);
@@ -280,7 +290,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        pCifsInode = CIFS_I(newinode);
                        if (pCifsInode) {
                                /* if readable file instance put first in list*/
-                               if (write_only == TRUE) {
+                               if (write_only) {
                                        list_add_tail(&pCifsFile->flist,
                                                &pCifsInode->openFileList);
                                } else {
@@ -288,12 +298,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                                                &pCifsInode->openFileList);
                                }
                                if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-                                       pCifsInode->clientCanCacheAll = TRUE;
-                                       pCifsInode->clientCanCacheRead = TRUE;
+                                       pCifsInode->clientCanCacheAll = true;
+                                       pCifsInode->clientCanCacheRead = true;
                                        cFYI(1, ("Exclusive Oplock inode %p",
                                                newinode));
                                } else if ((oplock & 0xF) == OPLOCK_READ)
-                                       pCifsInode->clientCanCacheRead = TRUE;
+                                       pCifsInode->clientCanCacheRead = true;
                        }
                        write_unlock(&GlobalSMBSeslock);
                }
index 7cc86c418182f261954dbcd18e8efd09b08df108..939e256f84975995341da88b38e2c60201e2aaa5 100644 (file)
@@ -55,6 +55,32 @@ struct key_type key_type_dns_resolver = {
        .match       = user_match,
 };
 
+/* Checks if supplied name is IP address
+ * returns:
+ *             1 - name is IP
+ *             0 - name is not IP
+ */
+static int is_ip(const char *name)
+{
+       int rc;
+       struct sockaddr_in sin_server;
+       struct sockaddr_in6 sin_server6;
+
+       rc = cifs_inet_pton(AF_INET, name,
+                       &sin_server.sin_addr.s_addr);
+
+       if (rc <= 0) {
+               /* not ipv4 address, try ipv6 */
+               rc = cifs_inet_pton(AF_INET6, name,
+                               &sin_server6.sin6_addr.in6_u);
+               if (rc > 0)
+                       return 1;
+       } else {
+               return 1;
+       }
+       /* we failed translating address */
+       return 0;
+}
 
 /* Resolves server name to ip address.
  * input:
@@ -67,8 +93,9 @@ int
 dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 {
        int rc = -EAGAIN;
-       struct key *rkey;
+       struct key *rkey = ERR_PTR(-EAGAIN);
        char *name;
+       char *data = NULL;
        int len;
 
        if (!ip_addr || !unc)
@@ -97,26 +124,41 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        memcpy(name, unc+2, len);
        name[len] = 0;
 
+       if (is_ip(name)) {
+               cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
+                                       __func__, name));
+               data = name;
+               goto skip_upcall;
+       }
+
        rkey = request_key(&key_type_dns_resolver, name, "");
        if (!IS_ERR(rkey)) {
-               len = strlen(rkey->payload.data);
-               *ip_addr = kmalloc(len+1, GFP_KERNEL);
-               if (*ip_addr) {
-                       memcpy(*ip_addr, rkey->payload.data, len);
-                       (*ip_addr)[len] = '\0';
-                       cFYI(1, ("%s: resolved: %s to %s", __func__,
+               data = rkey->payload.data;
+               cFYI(1, ("%s: resolved: %s to %s", __func__,
                                        rkey->description,
                                        *ip_addr
                                ));
+       } else {
+               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               goto out;
+       }
+
+skip_upcall:
+       if (data) {
+               len = strlen(data);
+               *ip_addr = kmalloc(len+1, GFP_KERNEL);
+               if (*ip_addr) {
+                       memcpy(*ip_addr, data, len);
+                       (*ip_addr)[len] = '\0';
                        rc = 0;
                } else {
                        rc = -ENOMEM;
                }
-               key_put(rkey);
-       } else {
-               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               if (!IS_ERR(rkey))
+                       key_put(rkey);
        }
 
+out:
        kfree(name);
        return rc;
 }
index 7d1d5aa4c430b6c904c08a5c65c8be32ba0a0298..5a57581eb4b2a6a803c5cdb01f98216d7d34c12a 100644 (file)
@@ -68,7 +68,7 @@ int cifs_dir_notify(struct file *file, unsigned long arg)
 {
        int xid;
        int rc = -EINVAL;
-       int oplock = FALSE;
+       int oplock = 0;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        char *full_path = NULL;
index 40b690073fc1432f165c1c0dfb208b22a1863bde..31a0a33b9d95450ea0fe8d6461f2249bf68d0f88 100644 (file)
@@ -51,8 +51,8 @@ static inline struct cifsFileInfo *cifs_init_private(
        INIT_LIST_HEAD(&private_data->llist);
        private_data->pfile = file; /* needed for writepage */
        private_data->pInode = inode;
-       private_data->invalidHandle = FALSE;
-       private_data->closePend = FALSE;
+       private_data->invalidHandle = false;
+       private_data->closePend = false;
        /* we have to track num writers to the inode, since writepages
        does not tell us which handle the write is for so there can
        be a close (overlapping with write) of the filehandle that
@@ -148,12 +148,12 @@ client_can_cache:
                        full_path, buf, inode->i_sb, xid, NULL);
 
        if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-               pCifsInode->clientCanCacheAll = TRUE;
-               pCifsInode->clientCanCacheRead = TRUE;
+               pCifsInode->clientCanCacheAll = true;
+               pCifsInode->clientCanCacheRead = true;
                cFYI(1, ("Exclusive Oplock granted on inode %p",
                         file->f_path.dentry->d_inode));
        } else if ((*oplock & 0xF) == OPLOCK_READ)
-               pCifsInode->clientCanCacheRead = TRUE;
+               pCifsInode->clientCanCacheRead = true;
 
        return rc;
 }
@@ -247,7 +247,7 @@ int cifs_open(struct inode *inode, struct file *file)
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
        else
-               oplock = FALSE;
+               oplock = 0;
 
        /* BB pass O_SYNC flag through on file attributes .. BB */
 
@@ -339,7 +339,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile)
        return rc;
 }
 
-static int cifs_reopen_file(struct file *file, int can_flush)
+static int cifs_reopen_file(struct file *file, bool can_flush)
 {
        int rc = -EACCES;
        int xid, oplock;
@@ -360,7 +360,7 @@ static int cifs_reopen_file(struct file *file, int can_flush)
 
        xid = GetXid();
        down(&pCifsFile->fh_sem);
-       if (pCifsFile->invalidHandle == FALSE) {
+       if (!pCifsFile->invalidHandle) {
                up(&pCifsFile->fh_sem);
                FreeXid(xid);
                return 0;
@@ -404,7 +404,7 @@ reopen_error_exit:
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
        else
-               oplock = FALSE;
+               oplock = 0;
 
        /* Can not refresh inode by passing in file_info buf to be returned
           by SMBOpen and then calling get_inode_info with returned buf
@@ -422,7 +422,7 @@ reopen_error_exit:
                cFYI(1, ("oplock: %d", oplock));
        } else {
                pCifsFile->netfid = netfid;
-               pCifsFile->invalidHandle = FALSE;
+               pCifsFile->invalidHandle = false;
                up(&pCifsFile->fh_sem);
                pCifsInode = CIFS_I(inode);
                if (pCifsInode) {
@@ -432,8 +432,8 @@ reopen_error_exit:
                                        CIFS_I(inode)->write_behind_rc = rc;
                        /* temporarily disable caching while we
                           go to server to get inode info */
-                               pCifsInode->clientCanCacheAll = FALSE;
-                               pCifsInode->clientCanCacheRead = FALSE;
+                               pCifsInode->clientCanCacheAll = false;
+                               pCifsInode->clientCanCacheRead = false;
                                if (pTcon->unix_ext)
                                        rc = cifs_get_inode_info_unix(&inode,
                                                full_path, inode->i_sb, xid);
@@ -448,16 +448,16 @@ reopen_error_exit:
                             we can not go to the server to get the new inod
                             info */
                        if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-                               pCifsInode->clientCanCacheAll = TRUE;
-                               pCifsInode->clientCanCacheRead = TRUE;
+                               pCifsInode->clientCanCacheAll = true;
+                               pCifsInode->clientCanCacheRead = true;
                                cFYI(1, ("Exclusive Oplock granted on inode %p",
                                         file->f_path.dentry->d_inode));
                        } else if ((oplock & 0xF) == OPLOCK_READ) {
-                               pCifsInode->clientCanCacheRead = TRUE;
-                               pCifsInode->clientCanCacheAll = FALSE;
+                               pCifsInode->clientCanCacheRead = true;
+                               pCifsInode->clientCanCacheAll = false;
                        } else {
-                               pCifsInode->clientCanCacheRead = FALSE;
-                               pCifsInode->clientCanCacheAll = FALSE;
+                               pCifsInode->clientCanCacheRead = false;
+                               pCifsInode->clientCanCacheAll = false;
                        }
                        cifs_relock_file(pCifsFile);
                }
@@ -484,7 +484,7 @@ int cifs_close(struct inode *inode, struct file *file)
        if (pSMBFile) {
                struct cifsLockInfo *li, *tmp;
 
-               pSMBFile->closePend = TRUE;
+               pSMBFile->closePend = true;
                if (pTcon) {
                        /* no sense reconnecting to close a file that is
                           already closed */
@@ -553,8 +553,8 @@ int cifs_close(struct inode *inode, struct file *file)
                cFYI(1, ("closing last open instance for inode %p", inode));
                /* if the file is not open we do not know if we can cache info
                   on this inode, much less write behind and read ahead */
-               CIFS_I(inode)->clientCanCacheRead = FALSE;
-               CIFS_I(inode)->clientCanCacheAll  = FALSE;
+               CIFS_I(inode)->clientCanCacheRead = false;
+               CIFS_I(inode)->clientCanCacheAll  = false;
        }
        read_unlock(&GlobalSMBSeslock);
        if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
@@ -583,9 +583,9 @@ int cifs_closedir(struct inode *inode, struct file *file)
                pTcon = cifs_sb->tcon;
 
                cFYI(1, ("Freeing private data in close dir"));
-               if ((pCFileStruct->srch_inf.endOfSearch == FALSE) &&
-                  (pCFileStruct->invalidHandle == FALSE)) {
-                       pCFileStruct->invalidHandle = TRUE;
+               if (!pCFileStruct->srch_inf.endOfSearch &&
+                   !pCFileStruct->invalidHandle) {
+                       pCFileStruct->invalidHandle = true;
                        rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
                        cFYI(1, ("Closing uncompleted readdir with rc %d",
                                 rc));
@@ -637,12 +637,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
        __u32 numLock = 0;
        __u32 numUnlock = 0;
        __u64 length;
-       int wait_flag = FALSE;
+       bool wait_flag = false;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        __u16 netfid;
        __u8 lockType = LOCKING_ANDX_LARGE_FILES;
-       int posix_locking;
+       bool posix_locking;
 
        length = 1 + pfLock->fl_end - pfLock->fl_start;
        rc = -EACCES;
@@ -659,7 +659,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                cFYI(1, ("Flock"));
        if (pfLock->fl_flags & FL_SLEEP) {
                cFYI(1, ("Blocking lock"));
-               wait_flag = TRUE;
+               wait_flag = true;
        }
        if (pfLock->fl_flags & FL_ACCESS)
                cFYI(1, ("Process suspended by mandatory locking - "
@@ -794,7 +794,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                        stored_rc = CIFSSMBLock(xid, pTcon,
                                                        netfid,
                                                        li->length, li->offset,
-                                                       1, 0, li->type, FALSE);
+                                                       1, 0, li->type, false);
                                        if (stored_rc)
                                                rc = stored_rc;
 
@@ -866,7 +866,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
                                   filemap_fdatawait from here so tell
                                   reopen_file not to flush data to server
                                   now */
-                               rc = cifs_reopen_file(file, FALSE);
+                               rc = cifs_reopen_file(file, false);
                                if (rc != 0)
                                        break;
                        }
@@ -966,7 +966,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                   filemap_fdatawait from here so tell
                                   reopen_file not to flush data to
                                   server now */
-                               rc = cifs_reopen_file(file, FALSE);
+                               rc = cifs_reopen_file(file, false);
                                if (rc != 0)
                                        break;
                        }
@@ -1093,7 +1093,7 @@ refind_writable:
 
                        read_unlock(&GlobalSMBSeslock);
                        /* Had to unlock since following call can block */
-                       rc = cifs_reopen_file(open_file->pfile, FALSE);
+                       rc = cifs_reopen_file(open_file->pfile, false);
                        if (!rc) {
                                if (!open_file->closePend)
                                        return open_file;
@@ -1608,7 +1608,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
                        int buf_type = CIFS_NO_BUFFER;
                        if ((open_file->invalidHandle) &&
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file, TRUE);
+                               rc = cifs_reopen_file(file, true);
                                if (rc != 0)
                                        break;
                        }
@@ -1693,7 +1693,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) &&
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file, TRUE);
+                               rc = cifs_reopen_file(file, true);
                                if (rc != 0)
                                        break;
                        }
@@ -1850,7 +1850,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) &&
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file, TRUE);
+                               rc = cifs_reopen_file(file, true);
                                if (rc != 0)
                                        break;
                        }
@@ -2009,10 +2009,10 @@ static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
    refreshing the inode only on increases in the file size
    but this is tricky to do without racing with writebehind
    page caching in the current Linux kernel design */
-int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
+bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
 {
        if (!cifsInode)
-               return 1;
+               return true;
 
        if (is_inode_writable(cifsInode)) {
                /* This inode is open for write at least once */
@@ -2022,15 +2022,15 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
                        /* since no page cache to corrupt on directio
                        we can change size safely */
-                       return 1;
+                       return true;
                }
 
                if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
-                       return 1;
+                       return true;
 
-               return 0;
+               return false;
        } else
-               return 1;
+               return true;
 }
 
 static int cifs_prepare_write(struct file *file, struct page *page,
index e1031b9e2c55ccfb13182e89c899ba6e49c89f7d..fcbdbb6ad7bfb45f9ea5606d9f5c7f078980d467 100644 (file)
@@ -281,7 +281,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
                            struct cifs_sb_info *cifs_sb, int xid)
 {
        int rc;
-       int oplock = FALSE;
+       int oplock = 0;
        __u16 netfid;
        struct cifsTconInfo *pTcon = cifs_sb->tcon;
        char buf[24];
@@ -389,7 +389,7 @@ int cifs_get_inode_info(struct inode **pinode,
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        const unsigned char *full_path = NULL;
        char *buf = NULL;
-       int adjustTZ = FALSE;
+       bool adjustTZ = false;
        bool is_dfs_referral = false;
 
        pTcon = cifs_sb->tcon;
@@ -425,7 +425,7 @@ try_again_CIFSSMBQPathInfo:
                                        pfindData, cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                          CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       adjustTZ = TRUE;
+                       adjustTZ = true;
                }
        }
        /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
@@ -703,7 +703,7 @@ psx_del_no_retry:
        } else if (rc == -ENOENT) {
                d_drop(direntry);
        } else if (rc == -ETXTBSY) {
-               int oplock = FALSE;
+               int oplock = 0;
                __u16 netfid;
 
                rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
@@ -736,7 +736,7 @@ psx_del_no_retry:
                                rc = -EOPNOTSUPP;
 
                        if (rc == -EOPNOTSUPP) {
-                               int oplock = FALSE;
+                               int oplock = 0;
                                __u16 netfid;
                        /*      rc = CIFSSMBSetAttrLegacy(xid, pTcon,
                                                          full_path,
@@ -774,7 +774,7 @@ psx_del_no_retry:
                                if (direntry->d_inode)
                                        drop_nlink(direntry->d_inode);
                        } else if (rc == -ETXTBSY) {
-                               int oplock = FALSE;
+                               int oplock = 0;
                                __u16 netfid;
 
                                rc = CIFSSMBOpen(xid, pTcon, full_path,
@@ -974,8 +974,8 @@ mkdir_get_info:
                  * failed to get it from the server or was set bogus */
                if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
                                direntry->d_inode->i_nlink = 2;
+               mode &= ~current->fs->umask;
                if (pTcon->unix_ext) {
-                       mode &= ~current->fs->umask;
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path,
                                                    mode,
@@ -994,9 +994,16 @@ mkdir_get_info:
                                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
                        }
                } else {
-                       /* BB to be implemented via Windows secrty descriptors
-                          eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
-                                                -1, -1, local_nls); */
+                       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
+                           (mode & S_IWUGO) == 0) {
+                               FILE_BASIC_INFO pInfo;
+                               memset(&pInfo, 0, sizeof(pInfo));
+                               pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
+                               CIFSSMBSetTimes(xid, pTcon, full_path,
+                                               &pInfo, cifs_sb->local_nls,
+                                               cifs_sb->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       }
                        if (direntry->d_inode) {
                                direntry->d_inode->i_mode = mode;
                                direntry->d_inode->i_mode |= S_IFDIR;
@@ -1149,7 +1156,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
                cFYI(1, ("rename rc %d", rc));
 
        if ((rc == -EIO) || (rc == -EEXIST)) {
-               int oplock = FALSE;
+               int oplock = 0;
                __u16 netfid;
 
                /* BB FIXME Is Generic Read correct for rename? */
@@ -1186,7 +1193,7 @@ int cifs_revalidate(struct dentry *direntry)
        struct cifsInodeInfo *cifsInode;
        loff_t local_size;
        struct timespec local_mtime;
-       int invalidate_inode = FALSE;
+       bool invalidate_inode = false;
 
        if (direntry->d_inode == NULL)
                return -ENOENT;
@@ -1268,7 +1275,7 @@ int cifs_revalidate(struct dentry *direntry)
                           only ones who could have modified the file and the
                           server copy is staler than ours */
                } else {
-                       invalidate_inode = TRUE;
+                       invalidate_inode = true;
                }
        }
 
@@ -1402,24 +1409,25 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        int rc = -EACCES;
        struct cifsFileInfo *open_file = NULL;
        FILE_BASIC_INFO time_buf;
-       int set_time = FALSE;
-       int set_dosattr = FALSE;
+       bool set_time = false;
+       bool set_dosattr = false;
        __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
        __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
        __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
        struct cifsInodeInfo *cifsInode;
+       struct inode *inode = direntry->d_inode;
 
        xid = GetXid();
 
        cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
                 direntry->d_name.name, attrs->ia_valid));
 
-       cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
+       cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
        if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
                /* check if we have permission to change attrs */
-               rc = inode_change_ok(direntry->d_inode, attrs);
+               rc = inode_change_ok(inode, attrs);
                if (rc < 0) {
                        FreeXid(xid);
                        return rc;
@@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                FreeXid(xid);
                return -ENOMEM;
        }
-       cifsInode = CIFS_I(direntry->d_inode);
+       cifsInode = CIFS_I(inode);
 
        if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
                /*
@@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                   will be truncated anyway? Also, should we error out here if
                   the flush returns error?
                 */
-               rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
+               rc = filemap_write_and_wait(inode->i_mapping);
                if (rc != 0) {
-                       CIFS_I(direntry->d_inode)->write_behind_rc = rc;
+                       cifsInode->write_behind_rc = rc;
                        rc = 0;
                }
        }
@@ -1464,7 +1472,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        __u16 nfid = open_file->netfid;
                        __u32 npid = open_file->pid;
                        rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
-                                               nfid, npid, FALSE);
+                                               nfid, npid, false);
                        atomic_dec(&open_file->wrtPending);
                        cFYI(1, ("SetFSize for attrs rc = %d", rc));
                        if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
@@ -1484,14 +1492,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                           it was found or because there was an error setting
                           it by handle */
                        rc = CIFSSMBSetEOF(xid, pTcon, full_path,
-                                          attrs->ia_size, FALSE,
+                                          attrs->ia_size, false,
                                           cifs_sb->local_nls,
                                           cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
                        if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                                __u16 netfid;
-                               int oplock = FALSE;
+                               int oplock = 0;
 
                                rc = SMBLegacyOpen(xid, pTcon, full_path,
                                        FILE_OPEN,
@@ -1516,14 +1524,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 
                /* Server is ok setting allocation size implicitly - no need
                   to call:
-               CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE,
+               CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true,
                         cifs_sb->local_nls);
                   */
 
                if (rc == 0) {
-                       rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
-                       cifs_truncate_page(direntry->d_inode->i_mapping,
-                                          direntry->d_inode->i_size);
+                       rc = cifs_vmtruncate(inode, attrs->ia_size);
+                       cifs_truncate_page(inode->i_mapping, inode->i_size);
                } else
                        goto cifs_setattr_exit;
        }
@@ -1557,14 +1564,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                rc = 0;
 #ifdef CONFIG_CIFS_EXPERIMENTAL
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-                       rc = mode_to_acl(direntry->d_inode, full_path, mode);
+                       rc = mode_to_acl(inode, full_path, mode);
                else if ((mode & S_IWUGO) == 0) {
 #else
                if ((mode & S_IWUGO) == 0) {
 #endif
                        /* not writeable */
                        if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
-                               set_dosattr = TRUE;
+                               set_dosattr = true;
                                time_buf.Attributes =
                                        cpu_to_le32(cifsInode->cifsAttrs |
                                                    ATTR_READONLY);
@@ -1574,28 +1581,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        not be able to write to it - so if any write
                        bit is enabled for user or group or other we
                        need to at least try to remove r/o dos attr */
-                       set_dosattr = TRUE;
+                       set_dosattr = true;
                        time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
                                            (~ATTR_READONLY));
                        /* Windows ignores set to zero */
                        if (time_buf.Attributes == 0)
                                time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
                }
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-                       mode_to_acl(direntry->d_inode, full_path, mode);
-#endif
        }
 
        if (attrs->ia_valid & ATTR_ATIME) {
-               set_time = TRUE;
+               set_time = true;
                time_buf.LastAccessTime =
                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
        } else
                time_buf.LastAccessTime = 0;
 
        if (attrs->ia_valid & ATTR_MTIME) {
-               set_time = TRUE;
+               set_time = true;
                time_buf.LastWriteTime =
                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
        } else
@@ -1606,7 +1609,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
           server times */
 
        if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
-               set_time = TRUE;
+               set_time = true;
                /* Although Samba throws this field away
                it may be useful to Windows - but we do
                not want to set ctime unless some other
@@ -1630,7 +1633,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        rc = -EOPNOTSUPP;
 
                if (rc == -EOPNOTSUPP) {
-                       int oplock = FALSE;
+                       int oplock = 0;
                        __u16 netfid;
 
                        cFYI(1, ("calling SetFileInfo since SetPathInfo for "
@@ -1669,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        /* do not need local check to inode_check_ok since the server does
           that */
        if (!rc)
-               rc = inode_setattr(direntry->d_inode, attrs);
+               rc = inode_setattr(inode, attrs);
 cifs_setattr_exit:
        kfree(full_path);
        FreeXid(xid);
index d4e7ec93285f1ab51b1727c60abcf9ddadab3bac..1c2c3ce5020b6ccc7d31eb90bfe2166da5555070 100644 (file)
@@ -230,7 +230,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
        struct inode *inode = direntry->d_inode;
        int rc = -EACCES;
        int xid;
-       int oplock = FALSE;
+       int oplock = 0;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        char *full_path = NULL;
index 2a42d9fedbb266751f7f9e96dd4fb4a079d75b7e..1d69b8014e0bac116ab0f83220605db48e56ad20 100644 (file)
@@ -496,7 +496,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
        }
        return 0;
 }
-int
+
+bool
 is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 {
        struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
@@ -522,17 +523,17 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                pnotify->Action));  /* BB removeme BB */
                        /*   cifs_dump_mem("Rcvd notify Data: ",buf,
                                sizeof(struct smb_hdr)+60); */
-                       return TRUE;
+                       return true;
                }
                if (pSMBr->hdr.Status.CifsError) {
                        cFYI(1, ("notify err 0x%d",
                                pSMBr->hdr.Status.CifsError));
-                       return TRUE;
+                       return true;
                }
-               return FALSE;
+               return false;
        }
        if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
-               return FALSE;
+               return false;
        if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
                /* no sense logging error on invalid handle on oplock
                   break - harmless race between close request and oplock
@@ -541,21 +542,21 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                if ((NT_STATUS_INVALID_HANDLE) ==
                   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
                        cFYI(1, ("invalid handle on oplock break"));
-                       return TRUE;
+                       return true;
                } else if (ERRbadfid ==
                   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
-                       return TRUE;
+                       return true;
                } else {
-                       return FALSE; /* on valid oplock brk we get "request" */
+                       return false; /* on valid oplock brk we get "request" */
                }
        }
        if (pSMB->hdr.WordCount != 8)
-               return FALSE;
+               return false;
 
        cFYI(1, ("oplock type 0x%d level 0x%d",
                 pSMB->LockType, pSMB->OplockLevel));
        if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
-               return FALSE;
+               return false;
 
        /* look up tcon based on tid & uid */
        read_lock(&GlobalSMBSeslock);
@@ -573,11 +574,11 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                            ("file id match, oplock break"));
                                        pCifsInode =
                                                CIFS_I(netfile->pInode);
-                                       pCifsInode->clientCanCacheAll = FALSE;
+                                       pCifsInode->clientCanCacheAll = false;
                                        if (pSMB->OplockLevel == 0)
                                                pCifsInode->clientCanCacheRead
-                                                       = FALSE;
-                                       pCifsInode->oplockPending = TRUE;
+                                                       = false;
+                                       pCifsInode->oplockPending = true;
                                        AllocOplockQEntry(netfile->pInode,
                                                          netfile->netfid,
                                                          tcon);
@@ -585,17 +586,17 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                            ("about to wake up oplock thread"));
                                        if (oplockThread)
                                            wake_up_process(oplockThread);
-                                       return TRUE;
+                                       return true;
                                }
                        }
                        read_unlock(&GlobalSMBSeslock);
                        cFYI(1, ("No matching file for oplock break"));
-                       return TRUE;
+                       return true;
                }
        }
        read_unlock(&GlobalSMBSeslock);
        cFYI(1, ("Can not process oplock break for non-existent connection"));
-       return TRUE;
+       return true;
 }
 
 void
index 3b5a5ce882b63083f492c34a3e1b007fe54be87f..00f4cff400b39c3f2fafbecbee5d5a74b65cba57 100644 (file)
@@ -132,47 +132,17 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
        {0, 0}
 };
 
-
-/* if the mount helper is missing we need to reverse the 1st slash
-   from '/' to backslash in order to format the UNC properly for
-   ip address parsing and for tree connect (unless the user
-   remembered to put the UNC name in properly). Fortunately we do
-   not have to call this twice (we check for IPv4 addresses
-   first, so it is already converted by the time we
-   try IPv6 addresses */
-static int canonicalize_unc(char *cp)
-{
-       int i;
-
-       for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) {
-               if (cp[i] == 0)
-                       break;
-               if (cp[i] == '\\')
-                       break;
-               if (cp[i] == '/') {
-                       cFYI(DBG2, ("change slash to \\ in malformed UNC"));
-                       cp[i] = '\\';
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 /* Convert string containing dotted ip address to binary form */
 /* returns 0 if invalid address */
 
 int
-cifs_inet_pton(int address_family, char *cp, void *dst)
+cifs_inet_pton(const int address_family, const char *cp, void *dst)
 {
        int ret = 0;
 
        /* calculate length by finding first slash or NULL */
        if (address_family == AF_INET) {
                ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
-               if (ret == 0) {
-                       if (canonicalize_unc(cp))
-                               ret = in4_pton(cp, -1, dst, '\\', NULL);
-               }
        } else if (address_family == AF_INET6) {
                ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
        }
index 32b445edc88282d2ce55ab1bd5a8f7bc2b9d7b3d..34ec32100c7242a68039533e0360985277edded8 100644 (file)
@@ -447,8 +447,8 @@ static int initiate_cifs_search(const int xid, struct file *file)
        if (file->private_data == NULL)
                return -ENOMEM;
        cifsFile = file->private_data;
-       cifsFile->invalidHandle = TRUE;
-       cifsFile->srch_inf.endOfSearch = FALSE;
+       cifsFile->invalidHandle = true;
+       cifsFile->srch_inf.endOfSearch = false;
 
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        if (cifs_sb == NULL)
@@ -485,7 +485,7 @@ ffirst_retry:
                cifs_sb->mnt_cifs_flags &
                        CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
        if (rc == 0)
-               cifsFile->invalidHandle = FALSE;
+               cifsFile->invalidHandle = false;
        if ((rc == -EOPNOTSUPP) &&
                (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
                cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
@@ -670,7 +670,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
           (index_to_find < first_entry_in_buffer)) {
                /* close and restart search */
                cFYI(1, ("search backing up - close and restart search"));
-               cifsFile->invalidHandle = TRUE;
+               cifsFile->invalidHandle = true;
                CIFSFindClose(xid, pTcon, cifsFile->netfid);
                kfree(cifsFile->search_resume_name);
                cifsFile->search_resume_name = NULL;
@@ -692,7 +692,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
        }
 
        while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
-             (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
+             (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
                cFYI(1, ("calling findnext2"));
                rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
                                  &cifsFile->srch_inf);
@@ -1038,7 +1038,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                                break;
                        }
                } /* else {
-                       cifsFile->invalidHandle = TRUE;
+                       cifsFile->invalidHandle = true;
                        CIFSFindClose(xid, pTcon, cifsFile->netfid);
                }
                kfree(cifsFile->search_resume_name);
index 58bbfd992cc0f4afe26f057752aeddfbd3da53ba..ff3232fa1015b4bebdcfeaa5d49a4bc365b21276 100644 (file)
 #include "cifs_debug.h"
 #include "cifsencrypt.h"
 
-#ifndef FALSE
-#define FALSE 0
+#ifndef false
+#define false 0
 #endif
-#ifndef TRUE
-#define TRUE 1
+#ifndef true
+#define true 1
 #endif
 
 /* following came from the other byteorder.h to avoid include conflicts */
index 8cd6a445b017ae62c2028b083dce8593d5c894fc..e9527eedc6396f9afd8dd25720a78730142a14b5 100644 (file)
@@ -264,7 +264,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
                else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                        __u16 fid;
-                       int oplock = FALSE;
+                       int oplock = 0;
                        struct cifs_ntsd *pacl = NULL;
                        __u32 buflen = 0;
                        if (experimEnabled)
index 139dc93c092d697b10d540a12020bd92e2e84b41..332a869d2c53e80a6bfb75c5e2bd3009802eca58 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/fcntl.h>
 #include <linux/namei.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/vfs.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
index eaecc4cfe5402584c6e3b9510628170c3be463bf..676073b8dda57659202b123dde8adb90e0fb416b 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/file.h>
+#include <linux/fdtable.h>
 
 int dir_notify_enable __read_mostly = 1;
 
index dfba1623cccb27a8d79a5098ace72b729ae45669..5ac77da19959f9f15792d16669d0b4110674cc3e 100644 (file)
@@ -1491,6 +1491,16 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
 
        /* We need to serialize quota_off() for device */
        mutex_lock(&dqopt->dqonoff_mutex);
+
+       /*
+        * Skip everything if there's nothing to do. We have to do this because
+        * sometimes we are called when fill_super() failed and calling
+        * sync_fs() in such cases does no good.
+        */
+       if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) {
+               mutex_unlock(&dqopt->dqonoff_mutex);
+               return 0;
+       }
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                toputinode[cnt] = NULL;
                if (type != -1 && cnt != type)
index 0a1397335a8eb49a245e81b1826607a5158a2685..c92cc1c00aae9a845911011f091480d9cbe4ffca 100644 (file)
@@ -37,17 +37,11 @@ static struct dentry *lock_parent(struct dentry *dentry)
 {
        struct dentry *dir;
 
-       dir = dget(dentry->d_parent);
+       dir = dget_parent(dentry);
        mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
        return dir;
 }
 
-static void unlock_parent(struct dentry *dentry)
-{
-       mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
-       dput(dentry->d_parent);
-}
-
 static void unlock_dir(struct dentry *dir)
 {
        mutex_unlock(&dir->d_inode->i_mutex);
@@ -426,8 +420,9 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
        int rc = 0;
        struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
        struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+       struct dentry *lower_dir_dentry;
 
-       lock_parent(lower_dentry);
+       lower_dir_dentry = lock_parent(lower_dentry);
        rc = vfs_unlink(lower_dir_inode, lower_dentry);
        if (rc) {
                printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
@@ -439,7 +434,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
        dentry->d_inode->i_ctime = dir->i_ctime;
        d_drop(dentry);
 out_unlock:
-       unlock_parent(lower_dentry);
+       unlock_dir(lower_dir_dentry);
        return rc;
 }
 
index 788995efd1d3247298a3107935a8a54fccd80cfd..6560da1a58ce7a885f4624cd663d4d70a8eb3475 100644 (file)
@@ -257,12 +257,14 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
        mutex_lock(&daemon->mux);
        if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
                rc = 0;
+               mutex_unlock(&ecryptfs_daemon_hash_mux);
                printk(KERN_WARNING "%s: Attempt to read from zombified "
                       "daemon\n", __func__);
                goto out_unlock_daemon;
        }
        if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) {
                rc = 0;
+               mutex_unlock(&ecryptfs_daemon_hash_mux);
                goto out_unlock_daemon;
        }
        /* This daemon will not go away so long as this flag is set */
index a9f130cd50ac2be6009ed2091fce0ec21d134fdd..343942deeec138b1925e7815d0ac819e41f1214e 100644 (file)
@@ -200,10 +200,8 @@ struct file *eventfd_fget(int fd)
 
 asmlinkage long sys_eventfd(unsigned int count)
 {
-       int error, fd;
+       int fd;
        struct eventfd_ctx *ctx;
-       struct file *file;
-       struct inode *inode;
 
        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
@@ -216,12 +214,9 @@ asmlinkage long sys_eventfd(unsigned int count)
         * When we call this, the initialization must be complete, since
         * anon_inode_getfd() will install the fd.
         */
-       error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]",
-                                &eventfd_fops, ctx);
-       if (!error)
-               return fd;
-
-       kfree(ctx);
-       return error;
+       fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx);
+       if (fd < 0)
+               kfree(ctx);
+       return fd;
 }
 
index 221086fef1743545c143a270bd1bc228cfb33561..990c01d2d66bcce64a1c2a993cd6cc01ea5951d5 100644 (file)
@@ -1050,8 +1050,6 @@ asmlinkage long sys_epoll_create(int size)
 {
        int error, fd = -1;
        struct eventpoll *ep;
-       struct inode *inode;
-       struct file *file;
 
        DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
                     current, size));
@@ -1061,29 +1059,24 @@ asmlinkage long sys_epoll_create(int size)
         * structure ( "struct eventpoll" ).
         */
        error = -EINVAL;
-       if (size <= 0 || (error = ep_alloc(&ep)) != 0)
+       if (size <= 0 || (error = ep_alloc(&ep)) < 0) {
+               fd = error;
                goto error_return;
+       }
 
        /*
         * Creates all the items needed to setup an eventpoll file. That is,
-        * a file structure, and inode and a free file descriptor.
+        * a file structure and a free file descriptor.
         */
-       error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]",
-                                &eventpoll_fops, ep);
-       if (error)
-               goto error_free;
+       fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep);
+       if (fd < 0)
+               ep_free(ep);
 
+error_return:
        DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
                     current, size, fd));
 
        return fd;
-
-error_free:
-       ep_free(ep);
-error_return:
-       DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
-                    current, size, error));
-       return error;
 }
 
 /*
index 9f9f931ef949987e29ba89204387c1428e491c66..1f8a24aa1f8bbbf4a88235cfdb0d1341b29fa79a 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -24,6 +24,7 @@
 
 #include <linux/slab.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/mman.h>
 #include <linux/a.out.h>
 #include <linux/stat.h>
@@ -735,7 +736,7 @@ static int exec_mmap(struct mm_struct *mm)
        tsk->active_mm = mm;
        activate_mm(active_mm, mm);
        task_unlock(tsk);
-       mm_update_next_owner(mm);
+       mm_update_next_owner(old_mm);
        arch_pick_mmap_layout(mm);
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
index fbec2ef93797efb9bf6ac16f2a9465fc198dc018..b128bdc0f55cccf067dca2e1aecb991ee9a120c3 100644 (file)
@@ -2639,8 +2639,7 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb)
        struct proc_dir_entry *proc;
        char devname[64];
 
-       snprintf(devname, sizeof(devname) - 1, "%s",
-               bdevname(sb->s_bdev, devname));
+       bdevname(sb->s_bdev, devname);
        sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
 
        MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
@@ -2674,8 +2673,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
        if (sbi->s_mb_proc == NULL)
                return -EINVAL;
 
-       snprintf(devname, sizeof(devname) - 1, "%s",
-               bdevname(sb->s_bdev, devname));
+       bdevname(sb->s_bdev, devname);
        remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
        remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
        remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
index 3f3ac630ccde701992caf5edf69a5f717c424f0c..bfd776509a7271e324c5559397542c36c4564a34 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/capability.h>
 #include <linux/dnotify.h>
 #include <linux/smp_lock.h>
index 5110acb1c9ef59bb046a69f79fa601a07218b61a..4c6f0ea12c419c52154558c271586b7887dabf13 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
@@ -149,8 +150,16 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
        nr /= (1024 / sizeof(struct file *));
        nr = roundup_pow_of_two(nr + 1);
        nr *= (1024 / sizeof(struct file *));
-       if (nr > sysctl_nr_open)
-               nr = sysctl_nr_open;
+       /*
+        * Note that this can drive nr *below* what we had passed if sysctl_nr_open
+        * had been set lower between the check in expand_files() and here.  Deal
+        * with that in caller, it's cheaper that way.
+        *
+        * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise
+        * bitmaps handling below becomes unpleasant, to put it mildly...
+        */
+       if (unlikely(nr > sysctl_nr_open))
+               nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1;
 
        fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL);
        if (!fdt)
@@ -198,6 +207,16 @@ static int expand_fdtable(struct files_struct *files, int nr)
        spin_lock(&files->file_lock);
        if (!new_fdt)
                return -ENOMEM;
+       /*
+        * extremely unlikely race - sysctl_nr_open decreased between the check in
+        * caller and alloc_fdtable().  Cheaper to catch it here...
+        */
+       if (unlikely(new_fdt->max_fds <= nr)) {
+               free_fdarr(new_fdt);
+               free_fdset(new_fdt);
+               kfree(new_fdt);
+               return -EMFILE;
+       }
        /*
         * Check again since another task may have expanded the fd table while
         * we dropped the lock
index 7a0a9b8722513faae34fc0f145c06f241f2630f7..83084225b4c3b3195520d5a7a441360046d6f230 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs.h>
index 9ced35b006867e1445af3f9fe010906ac0684f87..8092f0d9fd1fa590ac87f7f0ec7a79331760acb6 100644 (file)
@@ -804,6 +804,8 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                if (offset == PAGE_CACHE_SIZE)
                        offset = 0;
 
+               if (!fc->big_writes)
+                       break;
        } while (iov_iter_count(ii) && count < fc->max_write &&
                 req->num_pages < FUSE_MAX_PAGES_PER_REQ && offset == 0);
 
@@ -934,7 +936,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
 
        nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
        npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
+       npages = clamp(npages, 1, FUSE_MAX_PAGES_PER_REQ);
        down_read(&current->mm->mmap_sem);
        npages = get_user_pages(current, current->mm, user_addr, npages, write,
                                0, req->pages, NULL);
index dadffa21a206d220307e9b3e1212b09080bf5741..bae948657c4fdfd268e86912c6b4fa6c1f944851 100644 (file)
@@ -404,6 +404,9 @@ struct fuse_conn {
        /** Is bmap not implemented by fs? */
        unsigned no_bmap : 1;
 
+       /** Do multi-page cached writes */
+       unsigned big_writes : 1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
index 79b61587383832f7a7ff2187642f0fdcc509f047..fb77e0962132ea5ee1d2f9dc28f97206335f9125 100644 (file)
@@ -576,6 +576,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->no_lock = 1;
                        if (arg->flags & FUSE_ATOMIC_O_TRUNC)
                                fc->atomic_o_trunc = 1;
+                       if (arg->flags & FUSE_BIG_WRITES)
+                               fc->big_writes = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -599,7 +601,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
        arg->major = FUSE_KERNEL_VERSION;
        arg->minor = FUSE_KERNEL_MINOR_VERSION;
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC;
+       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
+               FUSE_BIG_WRITES;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index d53b2af91c25d78e39c17a692733224753e1905f..67e1c8b467c496565359331e79ca7c706166a30d 100644 (file)
@@ -65,6 +65,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask)
                BUG();
                return 0;
        }
+       if (!tree)
+               return 0;
        if (tree->node_size >= PAGE_CACHE_SIZE) {
                nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
                spin_lock(&tree->hash_lock);
index 6890433f7595c7514c0dd9ee8fb5cbc1ba103b11..8a1f50344368a9e1c1a3efab4120effd5d7e70da 100644 (file)
@@ -1,9 +1,9 @@
 #
-# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 # Licensed under the GPL
 #
 
-hppfs-objs := hppfs_kern.o
+hppfs-objs := hppfs.o
 
 obj-y =
-obj-$(CONFIG_HPPFS) += hppfs.o
+obj-$(CONFIG_HPPFS) += $(hppfs-objs)
similarity index 92%
rename from fs/hppfs/hppfs_kern.c
rename to fs/hppfs/hppfs.c
index 8601d8ef3b550d1c803c3a5bb7cd37f831717fd2..65077aa90f0a74ea405d25ff5796fe3ef3442be1 100644 (file)
@@ -33,7 +33,7 @@ struct hppfs_private {
 };
 
 struct hppfs_inode_info {
-        struct dentry *proc_dentry;
+       struct dentry *proc_dentry;
        struct inode vfs_inode;
 };
 
@@ -52,7 +52,7 @@ static int is_pid(struct dentry *dentry)
        int i;
 
        sb = dentry->d_sb;
-       if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
+       if (dentry->d_parent != sb->s_root)
                return 0;
 
        for (i = 0; i < dentry->d_name.len; i++) {
@@ -136,7 +136,7 @@ static int file_removed(struct dentry *dentry, const char *file)
 }
 
 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
-                                  struct nameidata *nd)
+                                  struct nameidata *nd)
 {
        struct dentry *proc_dentry, *new, *parent;
        struct inode *inode;
@@ -254,6 +254,8 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
        int err;
 
        if (hppfs->contents != NULL) {
+               int rem;
+
                if (*ppos >= hppfs->len)
                        return 0;
 
@@ -267,8 +269,10 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
 
                if (off + count > hppfs->len)
                        count = hppfs->len - off;
-               copy_to_user(buf, &data->contents[off], count);
-               *ppos += count;
+               rem = copy_to_user(buf, &data->contents[off], count);
+               *ppos += count - rem;
+               if (rem > 0)
+                       return -EFAULT;
        } else if (hppfs->host_fd != -1) {
                err = os_seek_file(hppfs->host_fd, *ppos);
                if (err) {
@@ -285,21 +289,15 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
        return count;
 }
 
-static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
-                          loff_t *ppos)
+static ssize_t hppfs_write(struct file *file, const char __user *buf,
+                          size_t len, loff_t *ppos)
 {
        struct hppfs_private *data = file->private_data;
        struct file *proc_file = data->proc_file;
        ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
-       int err;
 
        write = proc_file->f_path.dentry->d_inode->i_fop->write;
-
-       proc_file->f_pos = file->f_pos;
-       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
-       file->f_pos = proc_file->f_pos;
-
-       return err;
+       return (*write)(proc_file, buf, len, ppos);
 }
 
 static int open_host_sock(char *host_file, int *filter_out)
@@ -357,7 +355,7 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter,
 
        if (filter) {
                while ((n = read_proc(proc_file, data->contents,
-                                    sizeof(data->contents), NULL, 0)) > 0)
+                                     sizeof(data->contents), NULL, 0)) > 0)
                        os_write_file(fd, data->contents, n);
                err = os_shutdown_socket(fd, 0, 1);
                if (err) {
@@ -429,8 +427,8 @@ static int file_mode(int fmode)
 static int hppfs_open(struct inode *inode, struct file *file)
 {
        struct hppfs_private *data;
-       struct dentry *proc_dentry;
        struct vfsmount *proc_mnt;
+       struct dentry *proc_dentry;
        char *host_file;
        int err, fd, type, filter;
 
@@ -492,8 +490,8 @@ static int hppfs_open(struct inode *inode, struct file *file)
 static int hppfs_dir_open(struct inode *inode, struct file *file)
 {
        struct hppfs_private *data;
-       struct dentry *proc_dentry;
        struct vfsmount *proc_mnt;
+       struct dentry *proc_dentry;
        int err;
 
        err = -ENOMEM;
@@ -620,6 +618,9 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb)
 
 void hppfs_delete_inode(struct inode *ino)
 {
+       dput(HPPFS_I(ino)->proc_dentry);
+       mntput(ino->i_sb->s_fs_info);
+
        clear_inode(ino);
 }
 
@@ -628,69 +629,46 @@ static void hppfs_destroy_inode(struct inode *inode)
        kfree(HPPFS_I(inode));
 }
 
-static void hppfs_put_super(struct super_block *sb)
-{
-       mntput(sb->s_fs_info);
-}
-
 static const struct super_operations hppfs_sbops = {
        .alloc_inode    = hppfs_alloc_inode,
        .destroy_inode  = hppfs_destroy_inode,
        .delete_inode   = hppfs_delete_inode,
        .statfs         = hppfs_statfs,
-       .put_super      = hppfs_put_super,
 };
 
 static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
                          int buflen)
 {
-       struct file *proc_file;
        struct dentry *proc_dentry;
-       struct vfsmount *proc_mnt;
-       int ret;
 
        proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-       proc_mnt = dentry->d_sb->s_fs_info;
-
-       proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
-       if (IS_ERR(proc_file))
-               return PTR_ERR(proc_file);
-
-       ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
-
-       fput(proc_file);
-
-       return ret;
+       return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer,
+                                                   buflen);
 }
 
-static voidhppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-       struct file *proc_file;
        struct dentry *proc_dentry;
-       struct vfsmount *proc_mnt;
-       void *ret;
 
        proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-       proc_mnt = dentry->d_sb->s_fs_info;
-
-       proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
-       if (IS_ERR(proc_file))
-               return proc_file;
-
-       ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
 
-       fput(proc_file);
+       return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
+}
 
-       return ret;
+int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+       return generic_permission(inode, mask, NULL);
 }
 
 static const struct inode_operations hppfs_dir_iops = {
        .lookup         = hppfs_lookup,
+       .permission     = hppfs_permission,
 };
 
 static const struct inode_operations hppfs_link_iops = {
        .readlink       = hppfs_readlink,
        .follow_link    = hppfs_follow_link,
+       .permission     = hppfs_permission,
 };
 
 static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
@@ -712,7 +690,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
                inode->i_fop = &hppfs_file_fops;
        }
 
-       HPPFS_I(inode)->proc_dentry = dentry;
+       HPPFS_I(inode)->proc_dentry = dget(dentry);
 
        inode->i_uid = proc_ino->i_uid;
        inode->i_gid = proc_ino->i_gid;
@@ -725,7 +703,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
        inode->i_size = proc_ino->i_size;
        inode->i_blocks = proc_ino->i_blocks;
 
-       return 0;
+       return inode;
 }
 
 static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
index bf64781304243f62cc1ff52f9f395724651103d7..c36d9480335c6fc8a099aa1551910b0ce55a539f 100644 (file)
@@ -1149,13 +1149,8 @@ static inline void iput_final(struct inode *inode)
 void iput(struct inode *inode)
 {
        if (inode) {
-               const struct super_operations *op = inode->i_sb->s_op;
-
                BUG_ON(inode->i_state == I_CLEAR);
 
-               if (op && op->put_inode)
-                       op->put_inode(inode);
-
                if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
                        iput_final(inode);
        }
index 53632e3e8457e6227a182b28ea0d75a49880c5f6..2e24567c4a797ddf5c18c481bf53eef8bc01ad50 100644 (file)
@@ -901,7 +901,7 @@ static void jbd2_stats_proc_init(journal_t *journal)
 {
        char name[BDEVNAME_SIZE];
 
-       snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
+       bdevname(journal->j_dev, name);
        journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
        if (journal->j_proc_entry) {
                proc_create_data("history", S_IRUGO, journal->j_proc_entry,
@@ -915,7 +915,7 @@ static void jbd2_stats_proc_exit(journal_t *journal)
 {
        char name[BDEVNAME_SIZE];
 
-       snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
+       bdevname(journal->j_dev, name);
        remove_proc_entry("info", journal->j_proc_entry);
        remove_proc_entry("history", journal->j_proc_entry);
        remove_proc_entry(name, proc_jbd2_stats);
index d58f845ccb85984666d2e6ef0d1d6d9339c10d67..c5e1450d79f9d311ea5e797554227230200db4c7 100644 (file)
@@ -46,7 +46,7 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
 
 
 static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
-                                       struct jffs2_inode_cache *ic)
+                                   struct jffs2_inode_cache *ic)
 {
        struct jffs2_full_dirent *fd;
 
@@ -68,11 +68,17 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
                        continue;
                }
 
-               if (child_ic->nlink++ && fd->type == DT_DIR) {
-                       JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
-                               fd->name, fd->ino, ic->ino);
-                       /* TODO: What do we do about it? */
-               }
+               if (fd->type == DT_DIR) {
+                       if (child_ic->pino_nlink) {
+                               JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
+                                           fd->name, fd->ino, ic->ino);
+                               /* TODO: What do we do about it? */
+                       } else {
+                               child_ic->pino_nlink = ic->ino;
+                       }
+               } else
+                       child_ic->pino_nlink++;
+
                dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
                /* Can't free scan_dents so far. We might need them in pass 2 */
        }
@@ -125,7 +131,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
        dbg_fsbuild("pass 2 starting\n");
 
        for_each_inode(i, c, ic) {
-               if (ic->nlink)
+               if (ic->pino_nlink)
                        continue;
 
                jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
@@ -232,16 +238,19 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
                        /* Reduce nlink of the child. If it's now zero, stick it on the
                           dead_fds list to be cleaned up later. Else just free the fd */
 
-                       child_ic->nlink--;
+                       if (fd->type == DT_DIR)
+                               child_ic->pino_nlink = 0;
+                       else
+                               child_ic->pino_nlink--;
 
-                       if (!child_ic->nlink) {
-                               dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
+                       if (!child_ic->pino_nlink) {
+                               dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n",
                                          fd->ino, fd->name);
                                fd->next = *dead_fds;
                                *dead_fds = fd;
                        } else {
                                dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
-                                         fd->ino, fd->name, child_ic->nlink);
+                                         fd->ino, fd->name, child_ic->pino_nlink);
                                jffs2_free_full_dirent(fd);
                        }
                }
index c63e7a96af0dd025996c80b707b710213d7bdb1d..c0c141f6fde11c5e9367698494471e2462f181a3 100644 (file)
@@ -208,6 +208,13 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
        f = JFFS2_INODE_INFO(inode);
        dir_f = JFFS2_INODE_INFO(dir_i);
 
+       /* jffs2_do_create() will want to lock it, _after_ reserving
+          space and taking c-alloc_sem. If we keep it locked here,
+          lockdep gets unhappy (although it's a false positive;
+          nothing else will be looking at this inode yet so there's
+          no chance of AB-BA deadlock involving its f->sem). */
+       mutex_unlock(&f->sem);
+
        ret = jffs2_do_create(c, dir_f, f, ri,
                              dentry->d_name.name, dentry->d_name.len);
        if (ret)
@@ -219,7 +226,8 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
        d_instantiate(dentry, inode);
 
        D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
-                 inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
+                 inode->i_ino, inode->i_mode, inode->i_nlink,
+                 f->inocache->pino_nlink, inode->i_mapping->nrpages));
        return 0;
 
  fail:
@@ -243,7 +251,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
        ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
                              dentry->d_name.len, dead_f, now);
        if (dead_f->inocache)
-               dentry->d_inode->i_nlink = dead_f->inocache->nlink;
+               dentry->d_inode->i_nlink = dead_f->inocache->pino_nlink;
        if (!ret)
                dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
        return ret;
@@ -276,7 +284,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
 
        if (!ret) {
                mutex_lock(&f->sem);
-               old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
+               old_dentry->d_inode->i_nlink = ++f->inocache->pino_nlink;
                mutex_unlock(&f->sem);
                d_instantiate(dentry, old_dentry->d_inode);
                dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
@@ -493,11 +501,14 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
 
        inode->i_op = &jffs2_dir_inode_operations;
        inode->i_fop = &jffs2_dir_operations;
-       /* Directories get nlink 2 at start */
-       inode->i_nlink = 2;
 
        f = JFFS2_INODE_INFO(inode);
 
+       /* Directories get nlink 2 at start */
+       inode->i_nlink = 2;
+       /* but ic->pino_nlink is the parent ino# */
+       f->inocache->pino_nlink = dir_i->i_ino;
+
        ri->data_crc = cpu_to_je32(0);
        ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
 
@@ -594,17 +605,25 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
 
 static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
 {
+       struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
+       struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
        struct jffs2_full_dirent *fd;
        int ret;
+       uint32_t now = get_seconds();
 
        for (fd = f->dents ; fd; fd = fd->next) {
                if (fd->ino)
                        return -ENOTEMPTY;
        }
-       ret = jffs2_unlink(dir_i, dentry);
-       if (!ret)
+
+       ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
+                             dentry->d_name.len, f, now);
+       if (!ret) {
+               dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
+               clear_nlink(dentry->d_inode);
                drop_nlink(dir_i);
+       }
        return ret;
 }
 
@@ -817,7 +836,10 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
                   inode which didn't exist. */
                if (victim_f->inocache) {
                        mutex_lock(&victim_f->sem);
-                       victim_f->inocache->nlink--;
+                       if (S_ISDIR(new_dentry->d_inode->i_mode))
+                               victim_f->inocache->pino_nlink = 0;
+                       else
+                               victim_f->inocache->pino_nlink--;
                        mutex_unlock(&victim_f->sem);
                }
        }
@@ -838,8 +860,8 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
                struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
                mutex_lock(&f->sem);
                inc_nlink(old_dentry->d_inode);
-               if (f->inocache)
-                       f->inocache->nlink++;
+               if (f->inocache && !S_ISDIR(old_dentry->d_inode->i_mode))
+                       f->inocache->pino_nlink++;
                mutex_unlock(&f->sem);
 
                printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
index 25a640e566d3d6d47ae9310b12b3e222f7bbed52..dddb2a6c9e2cfc087b6becc7f88d9e85ab1d02b4 100644 (file)
@@ -294,7 +294,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
                        break;
 #endif
                default:
-                       if (ic->nodes == (void *)ic && ic->nlink == 0)
+                       if (ic->nodes == (void *)ic && ic->pino_nlink == 0)
                                jffs2_del_ino_cache(c, ic);
        }
 }
@@ -332,7 +332,8 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
        if (c->mtd->point) {
                unsigned long *wordebuf;
 
-               ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf);
+               ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size,
+                                   &retlen, &ebuf, NULL);
                if (ret) {
                        D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
                        goto do_flash_read;
@@ -340,7 +341,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
                if (retlen < c->sector_size) {
                        /* Don't muck about if it won't let us point to the whole erase sector */
                        D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
-                       c->mtd->unpoint(c->mtd, ebuf, jeb->offset, retlen);
+                       c->mtd->unpoint(c->mtd, jeb->offset, retlen);
                        goto do_flash_read;
                }
                wordebuf = ebuf-sizeof(*wordebuf);
@@ -349,7 +350,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
                   if (*++wordebuf != ~0)
                           break;
                } while(--retlen);
-               c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
+               c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size);
                if (retlen) {
                        printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
                               *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
index 3eb1c84b0a33289b62dfef1dd21d774647302d64..086c4383022181f3624f333143daf9d5ddf99081 100644 (file)
@@ -273,7 +273,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
        inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
        inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
 
-       inode->i_nlink = f->inocache->nlink;
+       inode->i_nlink = f->inocache->pino_nlink;
 
        inode->i_blocks = (inode->i_size + 511) >> 9;
 
@@ -286,13 +286,12 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
        case S_IFDIR:
        {
                struct jffs2_full_dirent *fd;
+               inode->i_nlink = 2; /* parent and '.' */
 
                for (fd=f->dents; fd; fd = fd->next) {
                        if (fd->type == DT_DIR && fd->ino)
                                inc_nlink(inode);
                }
-               /* and '..' */
-               inc_nlink(inode);
                /* Root dir gets i_nlink 3 for some reason */
                if (inode->i_ino == 1)
                        inc_nlink(inode);
@@ -586,11 +585,12 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c,
 }
 
 struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-                                                    int inum, int nlink)
+                                             int inum, int unlinked)
 {
        struct inode *inode;
        struct jffs2_inode_cache *ic;
-       if (!nlink) {
+
+       if (unlinked) {
                /* The inode has zero nlink but its nodes weren't yet marked
                   obsolete. This has to be because we're still waiting for
                   the final (close() and) iput() to happen.
@@ -638,8 +638,8 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
                        return ERR_CAST(inode);
        }
        if (is_bad_inode(inode)) {
-               printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
-                      inum, nlink);
+               printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. unlinked %d\n",
+                      inum, unlinked);
                /* NB. This will happen again. We need to do something appropriate here. */
                iput(inode);
                return ERR_PTR(-EIO);
index bad005664e308b1fd2f30e49ccad91d7afd57b91..090c556ffed28c7861b957efacf30099716ac465 100644 (file)
@@ -161,8 +161,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
                        continue;
                }
 
-               if (!ic->nlink) {
-                       D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",
+               if (!ic->pino_nlink) {
+                       D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink/pino zero\n",
                                  ic->ino));
                        spin_unlock(&c->inocache_lock);
                        jffs2_xattr_delete_inode(c, ic);
@@ -398,10 +398,10 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
           it's vaguely possible. */
 
        inum = ic->ino;
-       nlink = ic->nlink;
+       nlink = ic->pino_nlink;
        spin_unlock(&c->inocache_lock);
 
-       f = jffs2_gc_fetch_inode(c, inum, nlink);
+       f = jffs2_gc_fetch_inode(c, inum, !nlink);
        if (IS_ERR(f)) {
                ret = PTR_ERR(f);
                goto release_sem;
index 8219df6eb6d8c4191c78745c285272e5ce06f636..1750445556c313dbb9ddf716a52cce14fe6deac9 100644 (file)
@@ -177,7 +177,10 @@ struct jffs2_inode_cache {
 #ifdef CONFIG_JFFS2_FS_XATTR
        struct jffs2_xattr_ref *xref;
 #endif
-       int nlink;
+       uint32_t pino_nlink;    /* Directories store parent inode
+                                  here; other inodes store nlink.
+                                  Zero always means that it's
+                                  completely unlinked. */
 };
 
 /* Inode states for 'state' above. We need the 'GC' state to prevent
index 9df8f3ef20dfd8d8a39d59ee02d4e14ea2713927..a9bf9603c1ba0cca4fac8d56ea2dae4bbfe33b91 100644 (file)
@@ -709,7 +709,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
                                break;
 #endif
                        default:
-                               if (ic->nodes == (void *)ic && ic->nlink == 0)
+                               if (ic->nodes == (void *)ic && ic->pino_nlink == 0)
                                        jffs2_del_ino_cache(c, ic);
                                break;
                }
index 1b10d2594092b87cf8505e9237e93f02abf09737..2cc866cf134f18ce26bbecdd9b70c450cc075906 100644 (file)
@@ -187,7 +187,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
 void jffs2_gc_release_inode(struct jffs2_sb_info *c,
                            struct jffs2_inode_info *f);
 struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-                                             int inum, int nlink);
+                                             int inum, int unlinked);
 
 unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
                                   struct jffs2_inode_info *f,
index 4cb4d76de07f4810771e33edb6c8021d0a7896d1..6ca08ad887c09211bf98ab57cb1ec8578bd5d632 100644 (file)
@@ -63,10 +63,11 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
        /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
         * adding and jffs2_flash_read_end() interface. */
        if (c->mtd->point) {
-               err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
+               err = c->mtd->point(c->mtd, ofs, len, &retlen,
+                                   (void **)&buffer, NULL);
                if (!err && retlen < len) {
                        JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
-                       c->mtd->unpoint(c->mtd, buffer, ofs, retlen);
+                       c->mtd->unpoint(c->mtd, ofs, retlen);
                } else if (err)
                        JFFS2_WARNING("MTD point failed: error code %d.\n", err);
                else
@@ -100,7 +101,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
                kfree(buffer);
 #ifndef __ECOS
        else
-               c->mtd->unpoint(c->mtd, buffer, ofs, len);
+               c->mtd->unpoint(c->mtd, ofs, len);
 #endif
 
        if (crc != tn->data_crc) {
@@ -136,7 +137,7 @@ free_out:
                kfree(buffer);
 #ifndef __ECOS
        else
-               c->mtd->unpoint(c->mtd, buffer, ofs, len);
+               c->mtd->unpoint(c->mtd, ofs, len);
 #endif
        return err;
 }
@@ -1123,7 +1124,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
        size_t retlen;
        int ret;
 
-       dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
+       dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino,
+                     f->inocache->pino_nlink);
 
        memset(&rii, 0, sizeof(rii));
 
@@ -1358,7 +1360,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                }
                dbg_readinode("creating inocache for root inode\n");
                memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
-               f->inocache->ino = f->inocache->nlink = 1;
+               f->inocache->ino = f->inocache->pino_nlink = 1;
                f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
                f->inocache->state = INO_STATE_READING;
                jffs2_add_ino_cache(c, f->inocache);
@@ -1401,7 +1403,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
        jffs2_clear_acl(f);
        jffs2_xattr_delete_inode(c, f->inocache);
        mutex_lock(&f->sem);
-       deleted = f->inocache && !f->inocache->nlink;
+       deleted = f->inocache && !f->inocache->pino_nlink;
 
        if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
                jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
index 272872d27fd53242cf50b487c330e112c4b59d06..1d437de1e9a8c1fa1aed3992571f8ed7c2e9bf7b 100644 (file)
@@ -97,11 +97,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
        size_t pointlen;
 
        if (c->mtd->point) {
-               ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
+               ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen,
+                                   (void **)&flashbuf, NULL);
                if (!ret && pointlen < c->mtd->size) {
                        /* Don't muck about if it won't let us point to the whole flash */
                        D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
-                       c->mtd->unpoint(c->mtd, flashbuf, 0, pointlen);
+                       c->mtd->unpoint(c->mtd, 0, pointlen);
                        flashbuf = NULL;
                }
                if (ret)
@@ -267,7 +268,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
                kfree(flashbuf);
 #ifndef __ECOS
        else
-               c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
+               c->mtd->unpoint(c->mtd, 0, c->mtd->size);
 #endif
        if (s)
                kfree(s);
@@ -940,7 +941,7 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin
        ic->nodes = (void *)ic;
        jffs2_add_ino_cache(c, ic);
        if (ino == 1)
-               ic->nlink = 1;
+               ic->pino_nlink = 1;
        return ic;
 }
 
index f3353df178e707e8072e048e46b23753e5c88d5d..7da69eae49e491267699dcd8ca50535f5af15aed 100644 (file)
@@ -31,11 +31,12 @@ static struct kmem_cache *jffs2_inode_cachep;
 
 static struct inode *jffs2_alloc_inode(struct super_block *sb)
 {
-       struct jffs2_inode_info *ei;
-       ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL);
-       if (!ei)
+       struct jffs2_inode_info *f;
+
+       f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL);
+       if (!f)
                return NULL;
-       return &ei->vfs_inode;
+       return &f->vfs_inode;
 }
 
 static void jffs2_destroy_inode(struct inode *inode)
@@ -45,10 +46,10 @@ static void jffs2_destroy_inode(struct inode *inode)
 
 static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo)
 {
-       struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
+       struct jffs2_inode_info *f = foo;
 
-       mutex_init(&ei->sem);
-       inode_init_once(&ei->vfs_inode);
+       mutex_init(&f->sem);
+       inode_init_once(&f->vfs_inode);
 }
 
 static int jffs2_sync_fs(struct super_block *sb, int wait)
index 8de52b6076785816abf1625fbb2b64534a7c5610..0e78b00035e47a313ba43bafba87dfffbe9cf1b4 100644 (file)
@@ -494,7 +494,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
                                /* If it's an in-core inode, then we have to adjust any
                                   full_dirent or full_dnode structure to point to the
                                   new version instead of the old */
-                               f = jffs2_gc_fetch_inode(c, ic->ino, ic->nlink);
+                               f = jffs2_gc_fetch_inode(c, ic->ino, !ic->pino_nlink);
                                if (IS_ERR(f)) {
                                        /* Should never happen; it _must_ be present */
                                        JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n",
index 665fce9797d38d4569a92056f1391bdb5c0a9279..ca29440e9435867650514303b256c54528b8c1ef 100644 (file)
@@ -19,7 +19,8 @@
 #include "compr.h"
 
 
-int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
+int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
+                      uint32_t mode, struct jffs2_raw_inode *ri)
 {
        struct jffs2_inode_cache *ic;
 
@@ -31,7 +32,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
        memset(ic, 0, sizeof(*ic));
 
        f->inocache = ic;
-       f->inocache->nlink = 1;
+       f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */
        f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
        f->inocache->state = INO_STATE_PRESENT;
 
@@ -438,10 +439,10 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
        ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
                                JFFS2_SUMMARY_INODE_SIZE);
        D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
-       if (ret) {
-               mutex_unlock(&f->sem);
+       if (ret)
                return ret;
-       }
+
+       mutex_lock(&f->sem);
 
        ri->data_crc = cpu_to_je32(0);
        ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
@@ -635,9 +636,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
                                        jffs2_mark_node_obsolete(c, fd->raw);
                                jffs2_free_full_dirent(fd);
                        }
-               }
-
-               dead_f->inocache->nlink--;
+                       dead_f->inocache->pino_nlink = 0;
+               } else
+                       dead_f->inocache->pino_nlink--;
                /* NB: Caller must set inode nlink if appropriate */
                mutex_unlock(&dead_f->sem);
        }
index 574cb7532d6c13e8b0fa6b3e1ccc1638ebfc4201..082e844ab2db1fa11ce5a86453f5bdce957df7b2 100644 (file)
@@ -592,7 +592,7 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache
           When an inode with XATTR is removed, those XATTRs must be removed. */
        struct jffs2_xattr_ref *ref, *_ref;
 
-       if (!ic || ic->nlink > 0)
+       if (!ic || ic->pino_nlink > 0)
                return;
 
        down_write(&c->xattr_sem);
@@ -829,7 +829,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
                           ref->xd and ref->ic are not valid yet. */
                        xd = jffs2_find_xattr_datum(c, ref->xid);
                        ic = jffs2_get_ino_cache(c, ref->ino);
-                       if (!xd || !ic || !ic->nlink) {
+                       if (!xd || !ic || !ic->pino_nlink) {
                                dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
                                          ref->ino, ref->xid, ref->xseqno);
                                ref->xseqno |= XREF_DELETE_MARKER;
index 44d9a6a7ec50caad376e36d721a3a42bc5028948..11dbf08651b70861d31530ef73436dc2e3beffc1 100644 (file)
 
 #include <linux/capability.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -772,7 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
         * give it the opportunity to lock the file.
         */
        if (found)
-               cond_resched();
+               cond_resched_bkl();
 
 find_conflict:
        for_each_lock(inode, before) {
@@ -1752,6 +1753,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
        struct file_lock *file_lock = locks_alloc_lock();
        struct flock flock;
        struct inode *inode;
+       struct file *f;
        int error;
 
        if (file_lock == NULL)
@@ -1824,7 +1826,15 @@ again:
         * Attempt to detect a close/fcntl race and recover by
         * releasing the lock that was just acquired.
         */
-       if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+       /*
+        * we need that spin_lock here - it prevents reordering between
+        * update of inode->i_flock and check for it done in close().
+        * rcu_read_lock() wouldn't do.
+        */
+       spin_lock(&current->files->file_lock);
+       f = fcheck(fd);
+       spin_unlock(&current->files->file_lock);
+       if (!error && f != filp && flock.l_type != F_UNLCK) {
                flock.l_type = F_UNLCK;
                goto again;
        }
@@ -1880,6 +1890,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
        struct file_lock *file_lock = locks_alloc_lock();
        struct flock64 flock;
        struct inode *inode;
+       struct file *f;
        int error;
 
        if (file_lock == NULL)
@@ -1952,7 +1963,10 @@ again:
         * Attempt to detect a close/fcntl race and recover by
         * releasing the lock that was just acquired.
         */
-       if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+       spin_lock(&current->files->file_lock);
+       f = fcheck(fd);
+       spin_unlock(&current->files->file_lock);
+       if (!error && f != filp && flock.l_type != F_UNLCK) {
                flock.l_type = F_UNLCK;
                goto again;
        }
index 98429fd684996c8b34b448f304ebc38d552f5ca7..bc702dab5d1f912be9e70ee1dd58fb8aaeb441dc 100644 (file)
@@ -65,7 +65,7 @@ int o2cb_sys_init(void)
 {
        int ret;
 
-       o2cb_kset = kset_create_and_add("o2cb", NULL, NULL);
+       o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj);
        if (!o2cb_kset)
                return -ENOMEM;
 
index 5f6d858770a2b9992a7301561467e6b3fdbbdd45..1b81dcba175d083ba5cefad5178c2c1a8a3ef271 100644 (file)
@@ -44,7 +44,8 @@
 #define MLOG_MASK_PREFIX ML_DLM
 #include "cluster/masklog.h"
 
-int stringify_lockname(const char *lockname, int locklen, char *buf, int len);
+static int stringify_lockname(const char *lockname, int locklen, char *buf,
+                             int len);
 
 void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
 {
@@ -251,7 +252,8 @@ EXPORT_SYMBOL_GPL(dlm_errname);
  *
  * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h.
  */
-int stringify_lockname(const char *lockname, int locklen, char *buf, int len)
+static int stringify_lockname(const char *lockname, int locklen, char *buf,
+                             int len)
 {
        int out = 0;
        __be64 inode_blkno_be;
@@ -368,7 +370,7 @@ static void dlm_debug_free(struct kref *kref)
        kfree(dc);
 }
 
-void dlm_debug_put(struct dlm_debug_ctxt *dc)
+static void dlm_debug_put(struct dlm_debug_ctxt *dc)
 {
        if (dc)
                kref_put(&dc->debug_refcnt, dlm_debug_free);
index 9154c82d3258e5afc4b88fde94ecc68fc0aa91e2..57e0d30cde9816e048577b69027b5d2cbb92b2ba 100644 (file)
@@ -1048,6 +1048,10 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
        mlog_entry("(0x%p, '%.*s')\n", dentry,
                   dentry->d_name.len, dentry->d_name.name);
 
+       /* ensuring we don't even attempt to truncate a symlink */
+       if (S_ISLNK(inode->i_mode))
+               attr->ia_valid &= ~ATTR_SIZE;
+
        if (attr->ia_valid & ATTR_MODE)
                mlog(0, "mode change: %d\n", attr->ia_mode);
        if (attr->ia_valid & ATTR_UID)
index ce0dc147602acdb409c339b0812027fa985731c2..be774bdc8b3658bdec41332f49a3d8d1e4df5a58 100644 (file)
@@ -260,7 +260,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
        bh = osb->local_alloc_bh;
        alloc = (struct ocfs2_dinode *) bh->b_data;
 
-       alloc_copy = kmalloc(bh->b_size, GFP_KERNEL);
+       alloc_copy = kmalloc(bh->b_size, GFP_NOFS);
        if (!alloc_copy) {
                status = -ENOMEM;
                goto out_commit;
@@ -931,7 +931,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
         * local alloc shutdown won't try to double free main bitmap
         * bits. Make a copy so the sync function knows which bits to
         * free. */
-       alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_KERNEL);
+       alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_NOFS);
        if (!alloc_copy) {
                status = -ENOMEM;
                mlog_errno(status);
index ac1d74c63bf5402cd7ee03d357e29908045801b4..bbd1667aa7d3996035fdf517dd0dd71c034ec6e5 100644 (file)
@@ -385,7 +385,7 @@ static int o2cb_cluster_this_node(unsigned int *node)
        return 0;
 }
 
-struct ocfs2_stack_operations o2cb_stack_ops = {
+static struct ocfs2_stack_operations o2cb_stack_ops = {
        .connect        = o2cb_cluster_connect,
        .disconnect     = o2cb_cluster_disconnect,
        .hangup         = o2cb_cluster_hangup,
index 7428663f9cbbf78a75dba73ea67db3ab5e6001b7..b503772cd0ec83f86a2b55aa5fa512cd8ce20c4a 100644 (file)
@@ -635,7 +635,7 @@ static const struct file_operations ocfs2_control_fops = {
        .owner   = THIS_MODULE,
 };
 
-struct miscdevice ocfs2_control_device = {
+static struct miscdevice ocfs2_control_device = {
        .minor          = MISC_DYNAMIC_MINOR,
        .name           = "ocfs2_control",
        .fops           = &ocfs2_control_fops,
index 7134007ba22fa4142f6f0f9714828bfee7174225..ba9dbb51d25b5ed120922d9192e7098d239d7f5c 100644 (file)
@@ -167,9 +167,11 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
        .readlink       = page_readlink,
        .follow_link    = ocfs2_follow_link,
        .getattr        = ocfs2_getattr,
+       .setattr        = ocfs2_setattr,
 };
 const struct inode_operations ocfs2_fast_symlink_inode_operations = {
        .readlink       = ocfs2_readlink,
        .follow_link    = ocfs2_follow_link,
        .getattr        = ocfs2_getattr,
+       .setattr        = ocfs2_setattr,
 };
index 7af1f05d59783cf3198771e9ea3945351deb7d7c..a1450086e92f87e64007351ab673bf6274037e70 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -7,6 +7,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/quotaops.h>
 #include <linux/fsnotify.h>
 #include <linux/module.h>
index f73492b6817ea37d356b63f8bdfd81a960156ca7..ec228bc9f8824128ea99c5cb24abc743063e00bb 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/audit.h>
+#include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -1075,6 +1076,26 @@ int do_pipe(int *fd)
        return error;
 }
 
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way Unix traditionally does this, though.
+ */
+asmlinkage long __weak sys_pipe(int __user *fildes)
+{
+       int fd[2];
+       int error;
+
+       error = do_pipe(fd);
+       if (!error) {
+               if (copy_to_user(fildes, fd, sizeof(fd))) {
+                       sys_close(fd[0]);
+                       sys_close(fd[1]);
+                       error = -EFAULT;
+               }
+       }
+       return error;
+}
+
 /*
  * pipefs should _never_ be mounted by userland - too much of security hassle,
  * no real gain from having the whole whorehouse mounted. So we don't need
index c135cbdd9127a550d6da103f66fa7cc47584b72e..9e3b8c33c24b65c496f815658895dd4d2afd9c00 100644 (file)
@@ -73,6 +73,7 @@
 #include <linux/signal.h>
 #include <linux/highmem.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/times.h>
 #include <linux/cpuset.h>
 #include <linux/rcupdate.h>
@@ -297,6 +298,7 @@ static inline void task_cap(struct seq_file *m, struct task_struct *p)
        render_cap_t(m, "CapInh:\t", &p->cap_inheritable);
        render_cap_t(m, "CapPrm:\t", &p->cap_permitted);
        render_cap_t(m, "CapEff:\t", &p->cap_effective);
+       render_cap_t(m, "CapBnd:\t", &p->cap_bset);
 }
 
 static inline void task_context_switch_counts(struct seq_file *m,
index fcf02f2deeba398f790a4657574cfcbed9b55bc9..808cbdc193d309572c68b03d1b81b318511a4efc 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/namei.h>
index e2b8e769f510d676997698b8fd28ef4346478d2c..88717c0f941b0b770617bf34e7f364e2e9923e04 100644 (file)
@@ -5,11 +5,9 @@
 #include <linux/highmem.h>
 #include <linux/ptrace.h>
 #include <linux/pagemap.h>
-#include <linux/ptrace.h>
 #include <linux/mempolicy.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
-#include <linux/seq_file.h>
 
 #include <asm/elf.h>
 #include <asm/uaccess.h>
index 4b733f108455273ce52ce73c4f410d74a9ea2b2e..4b4f9cc2f186a72705a2525367b8861b6889a0ad 100644 (file)
@@ -1,6 +1,7 @@
 
 #include <linux/mm.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/mount.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
index 2c292146e2464836983913d7046b3279167f2ce7..8dda969614a9163f602fa62dca53a411c3400136 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/poll.h>
 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/rcupdate.h>
 
@@ -298,7 +299,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
 #define MAX_SELECT_SECONDS \
        ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
 
-static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
+int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
                           fd_set __user *exp, s64 *timeout)
 {
        fd_set_bits fds;
index 8ead0db359339ca7f5986e3b89ff3b245938557e..619725644c75e4b30d5ba379f9d40a391466efdb 100644 (file)
@@ -207,11 +207,8 @@ static const struct file_operations signalfd_fops = {
 
 asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask)
 {
-       int error;
        sigset_t sigmask;
        struct signalfd_ctx *ctx;
-       struct file *file;
-       struct inode *inode;
 
        if (sizemask != sizeof(sigset_t) ||
            copy_from_user(&sigmask, user_mask, sizeof(sigmask)))
@@ -230,12 +227,11 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas
                 * When we call this, the initialization must be complete, since
                 * anon_inode_getfd() will install the fd.
                 */
-               error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]",
-                                        &signalfd_fops, ctx);
-               if (error)
-                       goto err_fdalloc;
+               ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx);
+               if (ufd < 0)
+                       kfree(ctx);
        } else {
-               file = fget(ufd);
+               struct file *file = fget(ufd);
                if (!file)
                        return -EBADF;
                ctx = file->private_data;
@@ -252,9 +248,4 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas
        }
 
        return ufd;
-
-err_fdalloc:
-       kfree(ctx);
-       return error;
 }
-
index 633f58ebfb72a2ad7b132adb7492f7c268daecca..78150038b58422155b2a89e47e8a228967f0ca3d 100644 (file)
@@ -811,24 +811,19 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 {
        struct address_space *mapping = out->f_mapping;
        struct inode *inode = mapping->host;
-       int killsuid, killpriv;
+       struct splice_desc sd = {
+               .total_len = len,
+               .flags = flags,
+               .pos = *ppos,
+               .u.file = out,
+       };
        ssize_t ret;
-       int err = 0;
-
-       killpriv = security_inode_need_killpriv(out->f_path.dentry);
-       killsuid = should_remove_suid(out->f_path.dentry);
-       if (unlikely(killsuid || killpriv)) {
-               mutex_lock(&inode->i_mutex);
-               if (killpriv)
-                       err = security_inode_killpriv(out->f_path.dentry);
-               if (!err && killsuid)
-                       err = __remove_suid(out->f_path.dentry, killsuid);
-               mutex_unlock(&inode->i_mutex);
-               if (err)
-                       return err;
-       }
 
-       ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
+       inode_double_lock(inode, pipe->inode);
+       ret = remove_suid(out->f_path.dentry);
+       if (likely(!ret))
+               ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
+       inode_double_unlock(inode, pipe->inode);
        if (ret > 0) {
                unsigned long nr_pages;
 
@@ -840,6 +835,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                 * sync it.
                 */
                if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
+                       int err;
+
                        mutex_lock(&inode->i_mutex);
                        err = generic_osync_inode(inode, mapping,
                                                  OSYNC_METADATA|OSYNC_DATA);
@@ -1075,7 +1072,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 
        ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
        if (ret > 0)
-               *ppos = sd.pos;
+               *ppos += ret;
 
        return ret;
 }
index 5400524e9cb1d2b2e40bf810a1282277e54eec98..d87d354ec42438a4a0794cf964999eb376053c73 100644 (file)
@@ -181,10 +181,8 @@ static struct file *timerfd_fget(int fd)
 
 asmlinkage long sys_timerfd_create(int clockid, int flags)
 {
-       int error, ufd;
+       int ufd;
        struct timerfd_ctx *ctx;
-       struct file *file;
-       struct inode *inode;
 
        if (flags)
                return -EINVAL;
@@ -200,12 +198,9 @@ asmlinkage long sys_timerfd_create(int clockid, int flags)
        ctx->clockid = clockid;
        hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
 
-       error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]",
-                                &timerfd_fops, ctx);
-       if (error) {
+       ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx);
+       if (ufd < 0)
                kfree(ctx);
-               return error;
-       }
 
        return ufd;
 }
index 2b34c8ca6c83ed2e6aa01f955664ffccf7eb1ec0..d3231947db19edc3e4e592d3feadd7ab95e2c08a 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/buffer_head.h>
 #include <linux/sched.h>
 #include <linux/crc-itu-t.h>
+#include <linux/exportfs.h>
 
 static inline int udf_match(int len1, const char *name1, int len2,
                            const char *name2)
@@ -158,6 +159,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
        sector_t offset;
        struct extent_position epos = {};
        struct udf_inode_info *dinfo = UDF_I(dir);
+       int isdotdot = dentry->d_name.len == 2 &&
+               dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.';
 
        size = udf_ext0_offset(dir) + dir->i_size;
        f_pos = udf_ext0_offset(dir);
@@ -225,6 +228,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
                                continue;
                }
 
+               if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) &&
+                   isdotdot) {
+                       brelse(epos.bh);
+                       return fi;
+               }
+
                if (!lfi)
                        continue;
 
@@ -286,9 +295,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
                }
        }
        unlock_kernel();
-       d_add(dentry, inode);
 
-       return NULL;
+       return d_splice_alias(inode, dentry);
 }
 
 static struct fileIdentDesc *udf_add_entry(struct inode *dir,
@@ -307,7 +315,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
        uint16_t liu;
        int block;
        kernel_lb_addr eloc;
-       uint32_t elen;
+       uint32_t elen = 0;
        sector_t offset;
        struct extent_position epos = {};
        struct udf_inode_info *dinfo;
@@ -398,7 +406,8 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
        }
 
 add:
-       if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
+       /* Is there any extent whose size we need to round up? */
+       if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
                elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
                if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                        epos.offset -= sizeof(short_ad);
@@ -1232,6 +1241,134 @@ end_rename:
        return retval;
 }
 
+static struct dentry *udf_get_parent(struct dentry *child)
+{
+       struct dentry *parent;
+       struct inode *inode = NULL;
+       struct dentry dotdot;
+       struct fileIdentDesc cfi;
+       struct udf_fileident_bh fibh;
+
+       dotdot.d_name.name = "..";
+       dotdot.d_name.len = 2;
+
+       lock_kernel();
+       if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
+               goto out_unlock;
+
+       if (fibh.sbh != fibh.ebh)
+               brelse(fibh.ebh);
+       brelse(fibh.sbh);
+
+       inode = udf_iget(child->d_inode->i_sb,
+                        lelb_to_cpu(cfi.icb.extLocation));
+       if (!inode)
+               goto out_unlock;
+       unlock_kernel();
+
+       parent = d_alloc_anon(inode);
+       if (!parent) {
+               iput(inode);
+               parent = ERR_PTR(-ENOMEM);
+       }
+
+       return parent;
+out_unlock:
+       unlock_kernel();
+       return ERR_PTR(-EACCES);
+}
+
+
+static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
+                                       u16 partref, __u32 generation)
+{
+       struct inode *inode;
+       struct dentry *result;
+       kernel_lb_addr loc;
+
+       if (block == 0)
+               return ERR_PTR(-ESTALE);
+
+       loc.logicalBlockNum = block;
+       loc.partitionReferenceNum = partref;
+       inode = udf_iget(sb, loc);
+
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       if (generation && inode->i_generation != generation) {
+               iput(inode);
+               return ERR_PTR(-ESTALE);
+       }
+       result = d_alloc_anon(inode);
+       if (!result) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       return result;
+}
+
+static struct dentry *udf_fh_to_dentry(struct super_block *sb,
+                                      struct fid *fid, int fh_len, int fh_type)
+{
+       if ((fh_len != 3 && fh_len != 5) ||
+           (fh_type != FILEID_UDF_WITH_PARENT &&
+            fh_type != FILEID_UDF_WITHOUT_PARENT))
+               return NULL;
+
+       return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref,
+                       fid->udf.generation);
+}
+
+static struct dentry *udf_fh_to_parent(struct super_block *sb,
+                                      struct fid *fid, int fh_len, int fh_type)
+{
+       if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT)
+               return NULL;
+
+       return udf_nfs_get_inode(sb, fid->udf.parent_block,
+                                fid->udf.parent_partref,
+                                fid->udf.parent_generation);
+}
+static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
+                        int connectable)
+{
+       int len = *lenp;
+       struct inode *inode =  de->d_inode;
+       kernel_lb_addr location = UDF_I(inode)->i_location;
+       struct fid *fid = (struct fid *)fh;
+       int type = FILEID_UDF_WITHOUT_PARENT;
+
+       if (len < 3 || (connectable && len < 5))
+               return 255;
+
+       *lenp = 3;
+       fid->udf.block = location.logicalBlockNum;
+       fid->udf.partref = location.partitionReferenceNum;
+       fid->udf.generation = inode->i_generation;
+
+       if (connectable && !S_ISDIR(inode->i_mode)) {
+               spin_lock(&de->d_lock);
+               inode = de->d_parent->d_inode;
+               location = UDF_I(inode)->i_location;
+               fid->udf.parent_block = location.logicalBlockNum;
+               fid->udf.parent_partref = location.partitionReferenceNum;
+               fid->udf.parent_generation = inode->i_generation;
+               spin_unlock(&de->d_lock);
+               *lenp = 5;
+               type = FILEID_UDF_WITH_PARENT;
+       }
+
+       return type;
+}
+
+const struct export_operations udf_export_ops = {
+       .encode_fh      = udf_encode_fh,
+       .fh_to_dentry   = udf_fh_to_dentry,
+       .fh_to_parent   = udf_fh_to_parent,
+       .get_parent     = udf_get_parent,
+};
+
 const struct inode_operations udf_dir_inode_operations = {
        .lookup                         = udf_lookup,
        .create                         = udf_create,
index 63610f026ae15046d701d3ab45ab93a04ff51371..96dfd207c3d6339f5a07377a217e5f15c01140e2 100644 (file)
@@ -27,8 +27,8 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 
-inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
-                              uint16_t partition, uint32_t offset)
+uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
+                       uint16_t partition, uint32_t offset)
 {
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct udf_part_map *map;
index 9fb18a340fc1efa95fb0acd15d50c89c90652875..7a5f69be6ac2127de968661bd6d5e134712940b3 100644 (file)
@@ -1933,6 +1933,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
 
        /* Fill in the rest of the superblock */
        sb->s_op = &udf_sb_ops;
+       sb->s_export_op = &udf_export_ops;
        sb->dq_op = NULL;
        sb->s_dirt = 0;
        sb->s_magic = UDF_SUPER_MAGIC;
index f3f45d029277a4f1b038c6baf38ca2cce8703739..8fa9c2d70911701fb6aa0abded2bc86ed439d749 100644 (file)
@@ -73,6 +73,7 @@ struct task_struct;
 struct buffer_head;
 struct super_block;
 
+extern const struct export_operations udf_export_ops;
 extern const struct inode_operations udf_dir_inode_operations;
 extern const struct file_operations udf_dir_operations;
 extern const struct inode_operations udf_file_inode_operations;
index 244a1aaa940eea43a82619ff8bde98fa27b4caed..11c035168ea6e3c1201ee8f95ed1693c72e566e2 100644 (file)
@@ -107,7 +107,6 @@ extern struct inode * ufs_new_inode (struct inode *, int);
 
 /* inode.c */
 extern struct inode *ufs_iget(struct super_block *, unsigned long);
-extern void ufs_put_inode (struct inode *);
 extern int ufs_write_inode (struct inode *, int);
 extern int ufs_sync_inode (struct inode *);
 extern void ufs_delete_inode (struct inode *);
index a2bef77dc9c9878c3f93684acf86548f443d989f..af059d5cb485df8289eda123380f4937c0c7b77c 100644 (file)
@@ -40,9 +40,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
 
 #endif
 
+static bool nsec_special(long nsec)
+{
+       return nsec == UTIME_OMIT || nsec == UTIME_NOW;
+}
+
 static bool nsec_valid(long nsec)
 {
-       if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
+       if (nsec_special(nsec))
                return true;
 
        return nsec >= 0 && nsec <= 999999999;
@@ -119,7 +124,15 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
                        newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
                        newattrs.ia_valid |= ATTR_MTIME_SET;
                }
-       } else {
+       }
+
+       /*
+        * If times is NULL or both times are either UTIME_OMIT or
+        * UTIME_NOW, then need to check permissions, because
+        * inode_change_ok() won't do it.
+        */
+       if (!times || (nsec_special(times[0].tv_nsec) &&
+                      nsec_special(times[1].tv_nsec))) {
                error = -EACCES;
                 if (IS_IMMUTABLE(inode))
                        goto mnt_drop_write_and_out;
index 384dc08d6f53d26974b87511e498719a1fe84c4f..ac78eba909bce225243a9ddb979c3b5321d3da17 100644 (file)
@@ -24,7 +24,7 @@ __asm__ __volatile__("mb": : :"memory")
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
-#define smp_read_barrier_depends()     barrier()
+#define smp_read_barrier_depends()     do { } while (0)
 #endif
 
 #define set_mb(var, value) \
index 05ce5fba43e32ef37143836f1961a5300667f30c..3f0c59f6d8aa07dc5b68f96d1e928ac7f5b222d5 100644 (file)
@@ -287,17 +287,34 @@ extern inline pte_t pte_mkspecial(pte_t pte)      { return pte; }
 #define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pgd_offset(mm, address)        ((mm)->pgd+pgd_index(address))
 
+/*
+ * The smp_read_barrier_depends() in the following functions are required to
+ * order the load of *dir (the pointer in the top level page table) with any
+ * subsequent load of the returned pmd_t *ret (ret is data dependent on *dir).
+ *
+ * If this ordering is not enforced, the CPU might load an older value of
+ * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for
+ * more details.
+ *
+ * Note that we never change the mm->pgd pointer after the task is running, so
+ * pgd_offset does not require such a barrier.
+ */
+
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
-       return (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+       pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+       smp_read_barrier_depends(); /* see above */
+       return ret;
 }
 
 /* Find an entry in the third-level page table.. */
 extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
 {
-       return (pte_t *) pmd_page_vaddr(*dir)
+       pte_t *ret = (pte_t *) pmd_page_vaddr(*dir)
                + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1));
+       smp_read_barrier_depends(); /* see above */
+       return ret;
 }
 
 #define pte_offset_map(dir,addr)       pte_offset_kernel((dir),(addr))
index f5716139ec8987216d954858dfe6229ecd542488..c1541353ccefe04e67fe183ecb2013f7cb491642 100644 (file)
@@ -8,28 +8,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-l64.h>
 
 #ifndef __ASSEMBLY__
 
 typedef unsigned int umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -41,18 +25,6 @@ typedef unsigned long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long s64;
-typedef unsigned long u64;
-
 typedef u64 dma_addr_t;
 typedef u64 dma64_addr_t;
 
index 9d9f4b54b2ce6f20013c6e5f39f69980b308288f..261e5bc958db158739c6ad45bfcd8e36b1c8ae19 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/suspend.h>
 
 struct pxa_cpu_pm_fns {
-       int     save_size;
+       int     save_count;
        void    (*save)(unsigned long *);
        void    (*restore)(unsigned long *);
        int     (*valid)(suspend_state_t state);
index a758a719180f64e5f4167eea0e9b6ca8b6ff3a75..9aa6c2e939e87938da14896651aed10f2b90dbbe 100644 (file)
@@ -22,7 +22,8 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode)
 {
-       RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+       if (cpu_is_pxa2xx())
+               RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 
        if (mode == 's') {
                /* Jump into ROM at address 0 */
index 0b5f881c3d85a252481f30dc713b60a91f5d7c9f..5001390be9582fc1c937aa562671c23cd403f957 100644 (file)
 
 #endif
 
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
-
 #endif
index 3141451a9bd62c2b553a21ebf8aff59e958c66d5..345df01534a4c9b1fbabab2c84c426c8f3945c6d 100644 (file)
@@ -1,29 +1,12 @@
 #ifndef __ASM_ARM_TYPES_H
 #define __ASM_ARM_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -35,18 +18,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index 8999a381940361b760e001182b8adbc2abb6d6ed..9cefda6f534a19f641cf467a758a0e88c0d900a8 100644 (file)
@@ -8,28 +8,12 @@
 #ifndef __ASM_AVR32_TYPES_H
 #define __ASM_AVR32_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -41,18 +25,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index 686cf83a5269bf70990e5008a3267ea1db28be3e..7f34cd384f12abbacab586bfe7417eb059e01c5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * include/asm-blackfin/dpmc.h -  Miscellaneous IOCTL commands for Dynamic Power
  *                             Management Controller Driver.
- * Copyright (C) 2004 Analog Device Inc.
+ * Copyright (C) 2004-2008 Analog Device Inc.
  *
  */
 #ifndef _BLACKFIN_DPMC_H_
@@ -65,6 +65,14 @@ void disable_wdog_timer(void);
 extern unsigned long get_cclk(void);
 extern unsigned long get_sclk(void);
 
+struct bfin_dpmc_platform_data {
+       const unsigned int *tuple_tab;
+       unsigned short tabsize;
+       unsigned short vr_settling_time; /* in us */
+};
+
+#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16))
+
 #endif /* __KERNEL__ */
 
 #endif /*_BLACKFIN_DPMC_H_*/
index 562c6d3a3232ba21f7b46ba724864384af452991..c4f721e0d00def673b14bf4febd92b342c477efb 100644 (file)
 #define        PF_DTRACE_OFF   1
 #define        PF_DTRACE_BIT   5
 
+/*
+ * NOTE!  The single-stepping code assumes that all interrupt handlers
+ * start by saving SYSCFG on the stack with their first instruction.
+ */
+
 /* This one is used for exceptions, emulation, and NMI.  It doesn't push
    RETI and doesn't do cli.  */
 #define SAVE_ALL_SYS           save_context_no_interrupts
index f0ab2736a680415f42c25fc0714233d70b32994c..26e3c8076b4e5cafe08bb5ef97468a0f0db421f2 100644 (file)
 #define UART_PUT_CHAR(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_THR), v)
 #define UART_PUT_DLL(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
 #define UART_PUT_IER(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_IER), v)
+#define UART_SET_IER(uart, v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart, v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
 #define UART_PUT_LCR(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
 #define UART_PUT_GCTL(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
index fbe88dee3e2d8d379fbd713e4a405d7366ab7daa..d016603b661518eedcad888adeadbb8e6faf005f 100644 (file)
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #ifdef CONFIG_BFIN_UART0_CTSRTS
 # define CONFIG_SERIAL_BFIN_CTSRTS
 # ifndef CONFIG_UART0_CTS_PIN
index 17e1548cec0813cd1004e57e7c19cec638a7cba5..0ab4dd7494cfe348ae7373764a64bfd12582d5ca 100644 (file)
 #define        VLEV_110                0x00B0  /*              VLEV = 1.10 V (-5% - +10% Accuracy)     */
 #define        VLEV_115                0x00C0  /*              VLEV = 1.15 V (-5% - +10% Accuracy)     */
 #define        VLEV_120                0x00D0  /*              VLEV = 1.20 V (-5% - +10% Accuracy)     */
+#define        VLEV_125                0x00E0  /*              VLEV = 1.25 V (-5% - +10% Accuracy)     */
+#define        VLEV_130                0x00F0  /*              VLEV = 1.30 V (-5% - +10% Accuracy)     */
 
 #define        WAKE                    0x0100  /* Enable RTC/Reset Wakeup From Hibernate       */
 #define        SCKELOW                 0x8000  /* Do Not Drive SCKE High During Reset After Hibernate */
index 832e6f6122da332d91072457ffbadaf56b6e9eff..5aa38e5da6b7d3a5b1d65f0ec00a7bc31ef60971 100644 (file)
@@ -66,12 +66,13 @@ Core        Emulation               **
            DMA8/9 Interrupt        IVG13       28
            DMA10/11 Interrupt      IVG13       29
            Watchdog Timer          IVG13       30
-            Software Interrupt 1    IVG14       31
-            Software Interrupt 2    --
+
+            Softirq                IVG14       31
+            System Call    --
                  (lowest priority)  IVG15       32 *
  */
-#define SYS_IRQS               32
-#define NR_PERI_INTS    24
+#define SYS_IRQS       31
+#define NR_PERI_INTS   24
 
 /* The ABSTRACT IRQ definitions */
 /** the first seven of the following are fixed, the rest you change if you need to **/
@@ -96,7 +97,7 @@ Core        Emulation               **
 #define        IRQ_SPORT0_TX           17      /*DMA2 Interrupt (SPORT0 TX) */
 #define        IRQ_SPORT1_RX           18      /*DMA3 Interrupt (SPORT1 RX) */
 #define        IRQ_SPORT1_TX           19      /*DMA4 Interrupt (SPORT1 TX) */
-#define IRQ_SPI                        20      /*DMA5 Interrupt (SPI) */
+#define        IRQ_SPI                 20      /*DMA5 Interrupt (SPI) */
 #define        IRQ_UART_RX             21      /*DMA6 Interrupt (UART RX) */
 #define        IRQ_UART_TX             22      /*DMA7 Interrupt (UART TX) */
 #define        IRQ_TMR0                23      /*Timer 0 */
@@ -108,9 +109,6 @@ Core        Emulation               **
 #define        IRQ_MEM_DMA1            29      /*DMA10/11 Interrupt (Memory DMA Stream 1) */
 #define        IRQ_WATCH               30      /*Watch Dog Timer */
 
-#define        IRQ_SW_INT1             31      /*Software Int 1 */
-#define        IRQ_SW_INT2             32      /*Software Int 2 (reserved for SYSCALL) */
-
 #define IRQ_PF0                        33
 #define IRQ_PF1                        34
 #define IRQ_PF2                        35
index fd100a415b98bb937efbc87b22ff326f997b0da5..f79d1a0e9129bb0f3e74e64d8c831227fcf460f1 100644 (file)
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
index be6f2ff77f311a0153414c428252dadfbd65b786..2e68a8a1e7309a61aae408d470615ee7b22db7f2 100644 (file)
 
 /*
  * Interrupt source definitions
-             Event Source    Core Event Name
-Core        Emulation               **
- Events         (highest priority)  EMU         0
-            Reset                   RST         1
-            NMI                     NMI         2
-            Exception               EVX         3
-            Reserved                --          4
-            Hardware Error          IVHW        5
-            Core Timer              IVTMR       6 *
-
-.....
-
-            Software Interrupt 1    IVG14       31
-            Software Interrupt 2    --
-                 (lowest priority)  IVG15       32 *
+ *            Event Source    Core Event Name
+ * Core       Emulation               **
+ * Events         (highest priority)  EMU         0
+ *            Reset                   RST         1
+ *            NMI                     NMI         2
+ *            Exception               EVX         3
+ *            Reserved                --          4
+ *            Hardware Error          IVHW        5
+ *            Core Timer              IVTMR       6
+ *  .....
+ *
+ *            Softirq                IVG14
+ *            System Call    --
+ *               (lowest priority)    IVG15
  */
 
-#define SYS_IRQS        41
+#define SYS_IRQS        39
 #define NR_PERI_INTS    32
 
 /* The ABSTRACT IRQ definitions */
@@ -95,10 +94,8 @@ Core        Emulation               **
 #define IRQ_PORTG_INTB      35 /* PF Port G (PF15:0) Interrupt B */
 #define IRQ_MEM_DMA0        36 /*(Memory DMA Stream 0) */
 #define IRQ_MEM_DMA1        37 /*(Memory DMA Stream 1) */
-#define IRQ_PROG_INTB      38  /* PF Ports F (PF15:0) Interrupt B */
+#define IRQ_PROG_INTB        38        /* PF Ports F (PF15:0) Interrupt B */
 #define IRQ_WATCH           38 /*Watch Dog Timer */
-#define IRQ_SW_INT1         40 /*Software Int 1 */
-#define IRQ_SW_INT2         41 /*Software Int 2 (reserved for SYSCALL) */
 
 #define IRQ_PPI_ERROR       42 /*PPI Error Interrupt */
 #define IRQ_CAN_ERROR       43 /*CAN Error Interrupt */
index 6547027cd3e62174a0bd5a0f9ee2aa0a6429fe5d..5eb46a77d919fd5eb2fab2caebf1ca25abce618d 100644 (file)
@@ -54,6 +54,9 @@
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 #define UART_PUT_MCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
 
+#define UART_SET_DLAB(uart)     /* MMRs not muxed on BF54x */
+#define UART_CLEAR_DLAB(uart)   /* MMRs not muxed on BF54x */
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
index 08f90c21fe8a0f6538224f171853ea847177795d..e022e896cb1839717d4ea92f6e5dca3e7b3c0b73 100644 (file)
 #define                    KPADWE  0x1000     /* Keypad Wake-Up Enable */
 #define                     ROTWE  0x2000     /* Rotary Wake-Up Enable */
 
+#define        FREQ_333                0x0001  /* Switching Frequency Is 333 kHz */
+#define        FREQ_667                0x0002  /* Switching Frequency Is 667 kHz */
+#define        FREQ_1000               0x0003  /* Switching Frequency Is 1 MHz */
+
+#define        GAIN_5                  0x0000  /* GAIN = 5*/
+#define        GAIN_10                 0x0004  /* GAIN = 1*/
+#define        GAIN_20                 0x0008  /* GAIN = 2*/
+#define        GAIN_50                 0x000C  /* GAIN = 5*/
+
+#define        VLEV_085                0x0060  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define        VLEV_090                0x0070  /* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define        VLEV_095                0x0080  /* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define        VLEV_100                0x0090  /* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define        VLEV_105                0x00A0  /* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define        VLEV_110                0x00B0  /* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define        VLEV_115                0x00C0  /* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define        VLEV_120                0x00D0  /* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define        VLEV_125                0x00E0  /* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define        VLEV_130                0x00F0  /* VLEV = 1.30 V (-5% - +10% Accuracy) */
+
 /* Bit masks for NFC_CTL */
 
 #define                    WR_DLY  0xf        /* Write Strobe Delay */
index 8a4e66d1db37aa0b80423cf3c54639833480a1c4..7a962876929619e5da8a0e3abc1f029a602a807b 100644 (file)
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #ifdef CONFIG_BFIN_UART0_CTSRTS
 # define CONFIG_SERIAL_BFIN_CTSRTS
 # ifndef CONFIG_UART0_CTS_PIN
index 366c9b9a0cb70cf2f345b2075024df35b8ea3671..1ab50e906fe7e7db351fc006aca3385d4045fd34 100644 (file)
 #define CHIPID_FAMILY          0x0FFFF000
 #define CHIPID_MANUFACTURE     0x00000FFE
 
+/* VR_CTL Masks                                                                                                                                        */
+#define        FREQ                    0x0003  /* Switching Oscillator Frequency For Regulator */
+#define        HIBERNATE               0x0000  /* Powerdown/Bypass On-Board Regulation */
+#define        FREQ_333                0x0001  /* Switching Frequency Is 333 kHz */
+#define        FREQ_667                0x0002  /* Switching Frequency Is 667 kHz */
+#define        FREQ_1000               0x0003  /* Switching Frequency Is 1 MHz */
+
+#define        GAIN                    0x000C  /* Voltage Level Gain   */
+#define        GAIN_5                  0x0000  /* GAIN = 5*/
+#define        GAIN_10                 0x0004  /* GAIN = 1*/
+#define        GAIN_20                 0x0008  /* GAIN = 2*/
+#define        GAIN_50                 0x000C  /* GAIN = 5*/
+
+#define        VLEV                    0x00F0  /* Internal Voltage Level */
+#define        VLEV_085                0x0060  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define        VLEV_090                0x0070  /* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define        VLEV_095                0x0080  /* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define        VLEV_100                0x0090  /* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define        VLEV_105                0x00A0  /* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define        VLEV_110                0x00B0  /* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define        VLEV_115                0x00C0  /* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define        VLEV_120                0x00D0  /* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define        VLEV_125                0x00E0  /* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define        VLEV_130                0x00F0  /* VLEV = 1.30 V (-5% - +10% Accuracy) */
+
+#define        WAKE                    0x0100  /* Enable RTC/Reset Wakeup From Hibernate */
+#define        SCKELOW                 0x8000  /* Do Not Drive SCKE High During Reset After Hibernate */
+
 /* PLL_DIV Masks */
 #define SCLK_DIV(x)  (x)       /* SCLK = VCO / x */
 
index 83f0383957d25e099f36e04c139bf4197e7d705c..6698389c556451c51306b9dba7ed2f029af73416 100644 (file)
            Supplemental interrupt 0            IVG7        69
            supplemental interrupt 1            IVG7        70
 
-            Software Interrupt 1               IVG14       71
-            Software Interrupt 2               IVG15       72 *
-                                               (lowest priority)
+            Softirq                            IVG14
+            System Call    --
+                 (lowest priority)             IVG15
+
  **********************************************************************/
 
-#define SYS_IRQS               72
+#define SYS_IRQS               71
 #define NR_PERI_INTS           64
 
 /*
 #define IRQ_RESERVED_2         (IVG_BASE + 61) /* Reserved interrupt       */
 #define IRQ_SUPPLE_0           (IVG_BASE + 62) /* Supplemental interrupt 0 */
 #define IRQ_SUPPLE_1           (IVG_BASE + 63) /* supplemental interrupt 1 */
-#define        IRQ_SW_INT1             71      /* Software Interrupt 1     */
-#define        IRQ_SW_INT2             72      /* Software Interrupt 2     */
-                                               /* reserved for SYSCALL */
+
 #define IRQ_PF0                        73
 #define IRQ_PF1                        74
 #define IRQ_PF2                        75
index fd0ebe1862b84c499397341b5134d7a1537363d9..c0e630edfb9a30950b92eca4101c50be14dc79ed 100644 (file)
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+/*
+ * NOTE!  The single-stepping code assumes that all interrupt handlers
+ * start by saving SYSCFG on the stack with their first instruction.
+ */
+
 /*
  * Code to save processor context.
  *  We even save the register which are preserved by a function call
index 6e5859b6ea32f234fd0019582a3518fc14885420..ddc43ce385338054a68a1c50a149c01b53185ce7 100644 (file)
@@ -24,6 +24,8 @@
 
 #ifndef CONFIG_CPU_FREQ
 #define TIME_SCALE 1
+#define __bfin_cycles_off (0)
+#define __bfin_cycles_mod (0)
 #else
 /*
  * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
@@ -31,6 +33,8 @@
  * adjust the Core Timer Presale Register. This way we don't lose time.
  */
 #define TIME_SCALE 4
+extern unsigned long long __bfin_cycles_off;
+extern unsigned int __bfin_cycles_mod;
 #endif
 
 #endif
index 9785a6d531c6c8b488d0ca55d11da642fc3ba863..8441cbc2bf9e5bc61fce772add5fe1384cfe5be8 100644 (file)
@@ -8,30 +8,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-/* HK0617   -- Changes to unsigned long temporarily */
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif                         /* __ASSEMBLY__ */
 /*
  * These aren't exported outside the kernel to avoid name space clashes
@@ -42,18 +24,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index 5a21c42bc6c593ca28c7a2afdecd73e56047d2bf..5790262cbe8ae8c0da682c622e07b0da13606e7d 100644 (file)
@@ -1,29 +1,12 @@
 #ifndef _ETRAX_TYPES_H
 #define _ETRAX_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -35,18 +18,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide, just like our other addresses.  */
  
 typedef u32 dma_addr_t;
index cb307f8a6b486406424319c89cab2ac491a5b2fa..d3a12a9079f78f672615c3b5a31ed1bb7921e37f 100644 (file)
@@ -179,7 +179,7 @@ do {                                                        \
 #define mb()                   asm volatile ("membar" : : :"memory")
 #define rmb()                  asm volatile ("membar" : : :"memory")
 #define wmb()                  asm volatile ("membar" : : :"memory")
-#define read_barrier_depends() barrier()
+#define read_barrier_depends() do { } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()                       mb()
index 767e5ed71c4ba37c718b8b5beecfe045c856ef8b..613bf1e962f07b08fdef6b512b0cfd87da468791 100644 (file)
 #ifndef _ASM_TYPES_H
 #define _ASM_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -46,19 +29,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index 64ccc736f2d87309667fae654b2d472d0ae075d3..839a2fbffa0f34c8c428b6a5793a407749e69ac8 100644 (file)
@@ -9,8 +9,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef _ASM_FRV_UNALIGNED_H
-#define _ASM_FRV_UNALIGNED_H
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
 
 #include <linux/unaligned/le_byteshift.h>
 #include <linux/unaligned/be_byteshift.h>
@@ -19,4 +19,4 @@
 #define get_unaligned  __get_unaligned_be
 #define put_unaligned  __put_unaligned_be
 
-#endif /* _ASM_FRV_UNALIGNED_H */
+#endif /* _ASM_UNALIGNED_H */
index c18110ee30f1212ddd621d073919145ae022eb35..4c9932a2503f9d465caa909f5475b9ba5e6cc194 100644 (file)
@@ -7,5 +7,7 @@ header-y += poll.h
 header-y += signal.h
 header-y += statfs.h
 
+unifdef-y += int-l64.h
+unifdef-y += int-ll64.h
 unifdef-y += resource.h
 unifdef-y += siginfo.h
index a4a49370793c49ac48a52d52b20691863d4c6483..8f4e3193342e589b8c619e8c2673c3d5544e49a9 100644 (file)
        __rem;                                                  \
  })
 
-static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor)
-{
-       return dividend / divisor;
-}
-
 #elif BITS_PER_LONG == 32
 
 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
@@ -54,8 +49,6 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
        __rem;                                          \
  })
 
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
-
 #else /* BITS_PER_LONG == ?? */
 
 # error do_div() does not yet support the C64
diff --git a/include/asm-generic/int-l64.h b/include/asm-generic/int-l64.h
new file mode 100644 (file)
index 0000000..2af9b75
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * asm-generic/int-l64.h
+ *
+ * Integer declarations for architectures which use "long"
+ * for 64-bit types.
+ */
+
+#ifndef _ASM_GENERIC_INT_L64_H
+#define _ASM_GENERIC_INT_L64_H
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long s64;
+typedef unsigned long u64;
+
+#define S8_C(x)  x
+#define U8_C(x)  x ## U
+#define S16_C(x) x
+#define U16_C(x) x ## U
+#define S32_C(x) x
+#define U32_C(x) x ## U
+#define S64_C(x) x ## L
+#define U64_C(x) x ## UL
+
+#else /* __ASSEMBLY__ */
+
+#define S8_C(x)  x
+#define U8_C(x)  x
+#define S16_C(x) x
+#define U16_C(x) x
+#define S32_C(x) x
+#define U32_C(x) x
+#define S64_C(x) x
+#define U64_C(x) x
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_GENERIC_INT_L64_H */
diff --git a/include/asm-generic/int-ll64.h b/include/asm-generic/int-ll64.h
new file mode 100644 (file)
index 0000000..2609489
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * asm-generic/int-ll64.h
+ *
+ * Integer declarations for architectures which use "long long"
+ * for 64-bit types.
+ */
+
+#ifndef _ASM_GENERIC_INT_LL64_H
+#define _ASM_GENERIC_INT_LL64_H
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#ifdef __GNUC__
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define S8_C(x)  x
+#define U8_C(x)  x ## U
+#define S16_C(x) x
+#define U16_C(x) x ## U
+#define S32_C(x) x
+#define U32_C(x) x ## U
+#define S64_C(x) x ## LL
+#define U64_C(x) x ## ULL
+
+#else /* __ASSEMBLY__ */
+
+#define S8_C(x)  x
+#define U8_C(x)  x
+#define S16_C(x) x
+#define U16_C(x) x
+#define S32_C(x) x
+#define U32_C(x) x
+#define S64_C(x) x
+#define U64_C(x) x
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_GENERIC_INT_LL64_H */
index 56566e2a09fdf847da5195a6afb56157c4b8400b..12875190b156647b430033ff61b7894b14e3f53b 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _H8300_TYPES_H
 #define _H8300_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #if !defined(__ASSEMBLY__)
 
 /*
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
 #ifdef __KERNEL__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 #define BITS_PER_LONG 32
 
 /* Dma addresses are 32-bits wide.  */
index e87fa3210a2b837c1692a12d81e1df3296ce0575..fcca30b9f110bead57460586b466912d0eb77d68 100644 (file)
@@ -14,8 +14,8 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
 
 DECLARE_PER_CPU(int, cpu_state);
 
-extern int arch_register_cpu(int num);
 #ifdef CONFIG_HOTPLUG_CPU
+extern int arch_register_cpu(int num);
 extern void arch_unregister_cpu(int);
 #endif
 
index f3efaa229525f287dcc4e27a93071c876c770f16..00eb1b130b63fb91cc6594cfa4b2046f4a8cd7d7 100644 (file)
@@ -3,4 +3,9 @@
 
 #include <asm/io.h>
 
+/* Use normal IO mappings for DMI */
+#define dmi_ioremap ioremap
+#define dmi_iounmap(x,l) iounmap(x)
+#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
+
 #endif
index 4ebed77aa4726c5263e0ff1a0ff5dfacc60daf11..260a85ac9d6a6bc4a1784520522e94a686283574 100644 (file)
@@ -423,11 +423,6 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
 extern void iounmap (volatile void __iomem *addr);
 
-/* Use normal IO mappings for DMI */
-#define dmi_ioremap ioremap
-#define dmi_iounmap(x,l) iounmap(x)
-#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
-
 /*
  * String version of IO memory access ops:
  */
index f30e05583869e8fe3431ac9f0aef20e90e0edc22..2422ac61658a6bb16f465c26acf8c58df1735c6e 100644 (file)
@@ -108,13 +108,11 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
 #define TIF_DB_DISABLED                19      /* debug trap disabled for fsyscall */
 #define TIF_FREEZE             20      /* is freezing for suspend */
 #define TIF_RESTORE_RSE                21      /* user RBS is newer than kernel RBS */
-#define TIF_RESTORE_SIGMASK    22      /* restore signal mask in do_signal() */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_SYSCALL_TRACEAUDIT        (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
@@ -131,7 +129,18 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk);
 #define TIF_WORK_MASK          (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
 
 #define TS_POLLING             1       /* true if in idle loop and not sleeping */
+#define TS_RESTORE_SIGMASK     2       /* restore signal mask in do_signal() */
 
 #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
 
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK       1
+static inline void set_restore_sigmask(void)
+{
+       struct thread_info *ti = current_thread_info();
+       ti->status |= TS_RESTORE_SIGMASK;
+       set_bit(TIF_SIGPENDING, &ti->flags);
+}
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_IA64_THREAD_INFO_H */
index 902850d12424daa1a492f569adc701b4596e96cf..e36b3716e71851493137eddc7a04702f4bc578d5 100644 (file)
@@ -13,6 +13,8 @@
  *     David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
  */
 
+#include <asm-generic/int-l64.h>
+
 #ifdef __ASSEMBLY__
 # define __IA64_UL(x)          (x)
 # define __IA64_UL_CONST(x)    x
 
 typedef unsigned int umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
 # ifdef __KERNEL__
 
-typedef __s8 s8;
-typedef __u8 u8;
-
-typedef __s16 s16;
-typedef __u16 u16;
-
-typedef __s32 s32;
-typedef __u32 u32;
-
-typedef __s64 s64;
-typedef __u64 u64;
-
 #define BITS_PER_LONG 64
 
 /* DMA addresses are 64-bits wide, in general.  */
index b64c16639a7b77c7098bea0a053c13c14340ae57..bc9f7fff0ac399da986bfc54bba6003aa9828b07 100644 (file)
@@ -1,28 +1,12 @@
 #ifndef _ASM_M32R_TYPES_H
 #define _ASM_M32R_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -34,18 +18,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* DMA addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index 33caad1628d4276619daa5b442319a386f4d17a3..8243c931b5c065f4578989361be6f9613b49eb8e 100644 (file)
@@ -25,5 +25,4 @@
        __rem;                                                  \
 })
 
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
 #endif /* _M68K_DIV64_H */
index d2e0e25d5c90692145414155300f45908650d573..35624998291c91059b368f0b813517ef6970fadb 100644 (file)
@@ -66,36 +66,6 @@ struct MAC_SCC
 # define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS))
 #endif
 
-/* hardware stuff */
-
-#define MACHW_DECLARE(name)    unsigned name : 1
-#define MACHW_SET(name)                (mac_hw_present.name = 1)
-#define MACHW_PRESENT(name)    (mac_hw_present.name)
-
-struct mac_hw_present {
-  /* video hardware */
-  /* sound hardware */
-  /* disk storage interfaces */
-  MACHW_DECLARE(MAC_SCSI_80);     /* Directly mapped NCR5380 */
-  MACHW_DECLARE(MAC_SCSI_96);     /* 53c9[46] */
-  MACHW_DECLARE(MAC_SCSI_96_2);   /* 2nd 53c9[46] Q900 and Q950 */
-  MACHW_DECLARE(IDE);             /* IDE Interface */
-  /* other I/O hardware */
-  MACHW_DECLARE(SCC);             /* Serial Communications Contr. */
-  /* DMA */
-  MACHW_DECLARE(SCSI_DMA);        /* DMA for the NCR5380 */
-  /* real time clocks */
-  MACHW_DECLARE(RTC_CLK);         /* clock chip */
-  /* supporting hardware */
-  MACHW_DECLARE(VIA1);            /* Versatile Interface Ad. 1 */
-  MACHW_DECLARE(VIA2);            /* Versatile Interface Ad. 2 */
-  MACHW_DECLARE(RBV);             /* Versatile Interface Ad. 2+ */
-  /* NUBUS */
-  MACHW_DECLARE(NUBUS);           /* NUBUS */
-};
-
-extern struct mac_hw_present mac_hw_present;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* linux/machw.h */
index c35c09d93b662d97c6f0b8be3fa1a42c2d6792f0..6441cb5f8e7c84765716a782c0974a5d692f1b3a 100644 (file)
@@ -8,30 +8,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-ll64.h>
 
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -43,18 +25,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* DMA addresses are always 32-bits wide */
 
 typedef u32 dma_addr_t;
index 3f20419c633aab478da5b587acbc10de2416aaeb..939a0205621712c1416af8036d02ff2a33c2ff12 100644 (file)
@@ -35,7 +35,8 @@
 /*
  * Set number of channels of DMA on ColdFire for different implementations.
  */
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
+#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
+       defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
 #define MAX_M68K_DMA_CHANNELS 4
 #elif defined(CONFIG_M5272)
 #define MAX_M68K_DMA_CHANNELS 1
index 96c45101832491ecbb7e0cabdb5b49d49f5fa5d2..6044397adb64f89d8923cec107ddfd5c5d04bdf2 100644 (file)
@@ -1,13 +1,16 @@
 #ifndef _M68KNOMMU_PARAM_H
 #define _M68KNOMMU_PARAM_H
 
-#define HZ CONFIG_HZ
-
 #ifdef __KERNEL__
+#define HZ CONFIG_HZ
 #define        USER_HZ         HZ
 #define        CLOCKS_PER_SEC  (USER_HZ)
 #endif
 
+#ifndef HZ
+#define HZ     100
+#endif
+
 #define EXEC_PAGESIZE  4096
 
 #ifndef NOGROUP
index c2bd126c3b4eda2613c73e26335bb0f8694abd9d..642724734eba3e2dee33fe01cdd7fb12e8648aa9 100644 (file)
@@ -558,11 +558,13 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *
        __clear_bit(nr, addr);
 }
 
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+
 /*
  * Return the bit position (0..63) of the most significant 1 bit in a word
  * Returns -1 if no 1 bit exists
  */
-static inline int __ilog2(unsigned long x)
+static inline unsigned long __fls(unsigned long x)
 {
        int lz;
 
@@ -591,13 +593,6 @@ static inline int __ilog2(unsigned long x)
        return 63 - lz;
 }
 
-static inline unsigned long __fls(unsigned long x)
-{
-       return __ilog2(x);
-}
-
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-
 /*
  * __ffs - find first bit in word.
  * @word: The word to search
@@ -607,7 +602,7 @@ static inline unsigned long __fls(unsigned long x)
  */
 static inline unsigned long __ffs(unsigned long word)
 {
-       return __ilog2(word & -word);
+       return __fls(word & -word);
 }
 
 /*
@@ -654,6 +649,7 @@ static inline int ffs(int word)
 #else
 
 #include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/__fls.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/fls64.h>
index aa6b876bbd78d153042af014979eea2af04b768a..71f5c5cfc58abbd9b893a90e19dadb132eb93260 100644 (file)
@@ -9,10 +9,10 @@
 #define _ASM_COMPILER_H
 
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-#define GCC_IMM_ASM "n"
+#define GCC_IMM_ASM() "n"
 #define GCC_REG_ACCUM "$0"
 #else
-#define GCC_IMM_ASM "rn"
+#define GCC_IMM_ASM() "rn"
 #define GCC_REG_ACCUM "accum"
 #endif
 
index 716371bd098076c7297e5ef90a2400d42387c620..d1d699105c1106b724340104786f95ce8df39188 100644 (file)
@@ -82,7 +82,6 @@
        (n) = __quot; \
        __mod; })
 
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
 #endif /* (_MIPS_SZLONG == 32) */
 
 #if (_MIPS_SZLONG == 64)
@@ -106,11 +105,6 @@ extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
        (n) = __quot; \
        __mod; })
 
-static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor)
-{
-       return dividend / divisor;
-}
-
 #endif /* (_MIPS_SZLONG == 64) */
 
 #endif /* _ASM_DIV64_H */
index a05555165d05b14192c8ed7f19411a49382dbfbf..363a14ee0ae5d2718435e5db2c57432a684075f6 100644 (file)
@@ -40,8 +40,8 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 
 /* cpu pipeline flush */
 void static inline au_sync(void)
@@ -63,32 +63,32 @@ void static inline au_sync_delay(int ms)
 
 void static inline au_writeb(u8 val, unsigned long reg)
 {
-       *(volatile u8 *)(reg) = val;
+       *(volatile u8 *)reg = val;
 }
 
 void static inline au_writew(u16 val, unsigned long reg)
 {
-       *(volatile u16 *)(reg) = val;
+       *(volatile u16 *)reg = val;
 }
 
 void static inline au_writel(u32 val, unsigned long reg)
 {
-       *(volatile u32 *)(reg) = val;
+       *(volatile u32 *)reg = val;
 }
 
 static inline u8 au_readb(unsigned long reg)
 {
-       return (*(volatile u8 *)reg);
+       return *(volatile u8 *)reg;
 }
 
 static inline u16 au_readw(unsigned long reg)
 {
-       return (*(volatile u16 *)reg);
+       return *(volatile u16 *)reg;
 }
 
 static inline u32 au_readl(unsigned long reg)
 {
-       return (*(volatile u32 *)reg);
+       return *(volatile u32 *)reg;
 }
 
 
@@ -117,76 +117,77 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 /*
- * SDRAM Register Offsets
+ * SDRAM register offsets
  */
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
-#define MEM_SDMODE0            (0x0000)
-#define MEM_SDMODE1            (0x0004)
-#define MEM_SDMODE2            (0x0008)
-#define MEM_SDADDR0            (0x000C)
-#define MEM_SDADDR1            (0x0010)
-#define MEM_SDADDR2            (0x0014)
-#define MEM_SDREFCFG   (0x0018)
-#define MEM_SDPRECMD   (0x001C)
-#define MEM_SDAUTOREF  (0x0020)
-#define MEM_SDWRMD0            (0x0024)
-#define MEM_SDWRMD1            (0x0028)
-#define MEM_SDWRMD2            (0x002C)
-#define MEM_SDSLEEP            (0x0030)
-#define MEM_SDSMCKE            (0x0034)
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+    defined(CONFIG_SOC_AU1100)
+#define MEM_SDMODE0            0x0000
+#define MEM_SDMODE1            0x0004
+#define MEM_SDMODE2            0x0008
+#define MEM_SDADDR0            0x000C
+#define MEM_SDADDR1            0x0010
+#define MEM_SDADDR2            0x0014
+#define MEM_SDREFCFG           0x0018
+#define MEM_SDPRECMD           0x001C
+#define MEM_SDAUTOREF          0x0020
+#define MEM_SDWRMD0            0x0024
+#define MEM_SDWRMD1            0x0028
+#define MEM_SDWRMD2            0x002C
+#define MEM_SDSLEEP            0x0030
+#define MEM_SDSMCKE            0x0034
 
 /*
  * MEM_SDMODE register content definitions
  */
-#define MEM_SDMODE_F           (1<<22)
-#define MEM_SDMODE_SR          (1<<21)
-#define MEM_SDMODE_BS          (1<<20)
-#define MEM_SDMODE_RS          (3<<18)
-#define MEM_SDMODE_CS          (7<<15)
-#define MEM_SDMODE_TRAS                (15<<11)
-#define MEM_SDMODE_TMRD                (3<<9)
-#define MEM_SDMODE_TWR         (3<<7)
-#define MEM_SDMODE_TRP         (3<<5)
-#define MEM_SDMODE_TRCD                (3<<3)
-#define MEM_SDMODE_TCL         (7<<0)
-
-#define MEM_SDMODE_BS_2Bank    (0<<20)
-#define MEM_SDMODE_BS_4Bank    (1<<20)
-#define MEM_SDMODE_RS_11Row    (0<<18)
-#define MEM_SDMODE_RS_12Row    (1<<18)
-#define MEM_SDMODE_RS_13Row    (2<<18)
-#define MEM_SDMODE_RS_N(N)     ((N)<<18)
-#define MEM_SDMODE_CS_7Col     (0<<15)
-#define MEM_SDMODE_CS_8Col     (1<<15)
-#define MEM_SDMODE_CS_9Col     (2<<15)
-#define MEM_SDMODE_CS_10Col    (3<<15)
-#define MEM_SDMODE_CS_11Col    (4<<15)
-#define MEM_SDMODE_CS_N(N)             ((N)<<15)
-#define MEM_SDMODE_TRAS_N(N)   ((N)<<11)
-#define MEM_SDMODE_TMRD_N(N)   ((N)<<9)
-#define MEM_SDMODE_TWR_N(N)            ((N)<<7)
-#define MEM_SDMODE_TRP_N(N)            ((N)<<5)
-#define MEM_SDMODE_TRCD_N(N)   ((N)<<3)
-#define MEM_SDMODE_TCL_N(N)            ((N)<<0)
+#define MEM_SDMODE_F           (1 << 22)
+#define MEM_SDMODE_SR          (1 << 21)
+#define MEM_SDMODE_BS          (1 << 20)
+#define MEM_SDMODE_RS          (3 << 18)
+#define MEM_SDMODE_CS          (7 << 15)
+#define MEM_SDMODE_TRAS        (15 << 11)
+#define MEM_SDMODE_TMRD        (3 << 9)
+#define MEM_SDMODE_TWR         (3 << 7)
+#define MEM_SDMODE_TRP         (3 << 5)
+#define MEM_SDMODE_TRCD        (3 << 3)
+#define MEM_SDMODE_TCL         (7 << 0)
+
+#define MEM_SDMODE_BS_2Bank    (0 << 20)
+#define MEM_SDMODE_BS_4Bank    (1 << 20)
+#define MEM_SDMODE_RS_11Row    (0 << 18)
+#define MEM_SDMODE_RS_12Row    (1 << 18)
+#define MEM_SDMODE_RS_13Row    (2 << 18)
+#define MEM_SDMODE_RS_N(N)     ((N) << 18)
+#define MEM_SDMODE_CS_7Col     (0 << 15)
+#define MEM_SDMODE_CS_8Col     (1 << 15)
+#define MEM_SDMODE_CS_9Col     (2 << 15)
+#define MEM_SDMODE_CS_10Col    (3 << 15)
+#define MEM_SDMODE_CS_11Col    (4 << 15)
+#define MEM_SDMODE_CS_N(N)     ((N) << 15)
+#define MEM_SDMODE_TRAS_N(N)   ((N) << 11)
+#define MEM_SDMODE_TMRD_N(N)   ((N) << 9)
+#define MEM_SDMODE_TWR_N(N)    ((N) << 7)
+#define MEM_SDMODE_TRP_N(N)    ((N) << 5)
+#define MEM_SDMODE_TRCD_N(N)   ((N) << 3)
+#define MEM_SDMODE_TCL_N(N)    ((N) << 0)
 
 /*
  * MEM_SDADDR register contents definitions
  */
-#define MEM_SDADDR_E                   (1<<20)
-#define MEM_SDADDR_CSBA                        (0x03FF<<10)
-#define MEM_SDADDR_CSMASK              (0x03FF<<0)
-#define MEM_SDADDR_CSBA_N(N)   ((N)&(0x03FF<<22)>>12)
-#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF<<22)>>22)
+#define MEM_SDADDR_E           (1 << 20)
+#define MEM_SDADDR_CSBA        (0x03FF << 10)
+#define MEM_SDADDR_CSMASK      (0x03FF << 0)
+#define MEM_SDADDR_CSBA_N(N)   ((N) & (0x03FF << 22) >> 12)
+#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22)
 
 /*
  * MEM_SDREFCFG register content definitions
  */
-#define MEM_SDREFCFG_TRC               (15<<28)
-#define MEM_SDREFCFG_TRPM              (3<<26)
-#define MEM_SDREFCFG_E                 (1<<25)
-#define MEM_SDREFCFG_RE                        (0x1ffffff<<0)
-#define MEM_SDREFCFG_TRC_N(N)  ((N)<<MEM_SDREFCFG_TRC)
-#define MEM_SDREFCFG_TRPM_N(N) ((N)<<MEM_SDREFCFG_TRPM)
+#define MEM_SDREFCFG_TRC       (15 << 28)
+#define MEM_SDREFCFG_TRPM      (3 << 26)
+#define MEM_SDREFCFG_E         (1 << 25)
+#define MEM_SDREFCFG_RE        (0x1ffffff << 0)
+#define MEM_SDREFCFG_TRC_N(N)  ((N) << MEM_SDREFCFG_TRC)
+#define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM)
 #define MEM_SDREFCFG_REF_N(N)  (N)
 #endif
 
@@ -199,25 +200,25 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 /***********************************************************************/
 
 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
-#define MEM_SDMODE0            (0x0800)
-#define MEM_SDMODE1            (0x0808)
-#define MEM_SDMODE2            (0x0810)
-#define MEM_SDADDR0            (0x0820)
-#define MEM_SDADDR1            (0x0828)
-#define MEM_SDADDR2            (0x0830)
-#define MEM_SDCONFIGA  (0x0840)
-#define MEM_SDCONFIGB  (0x0848)
-#define MEM_SDSTAT             (0x0850)
-#define MEM_SDERRADDR  (0x0858)
-#define MEM_SDSTRIDE0  (0x0860)
-#define MEM_SDSTRIDE1  (0x0868)
-#define MEM_SDSTRIDE2  (0x0870)
-#define MEM_SDWRMD0            (0x0880)
-#define MEM_SDWRMD1            (0x0888)
-#define MEM_SDWRMD2            (0x0890)
-#define MEM_SDPRECMD   (0x08C0)
-#define MEM_SDAUTOREF  (0x08C8)
-#define MEM_SDSREF             (0x08D0)
+#define MEM_SDMODE0            0x0800
+#define MEM_SDMODE1            0x0808
+#define MEM_SDMODE2            0x0810
+#define MEM_SDADDR0            0x0820
+#define MEM_SDADDR1            0x0828
+#define MEM_SDADDR2            0x0830
+#define MEM_SDCONFIGA          0x0840
+#define MEM_SDCONFIGB          0x0848
+#define MEM_SDSTAT             0x0850
+#define MEM_SDERRADDR          0x0858
+#define MEM_SDSTRIDE0          0x0860
+#define MEM_SDSTRIDE1          0x0868
+#define MEM_SDSTRIDE2          0x0870
+#define MEM_SDWRMD0            0x0880
+#define MEM_SDWRMD1            0x0888
+#define MEM_SDWRMD2            0x0890
+#define MEM_SDPRECMD           0x08C0
+#define MEM_SDAUTOREF          0x08C8
+#define MEM_SDSREF             0x08D0
 #define MEM_SDSLEEP            MEM_SDSREF
 
 #endif
@@ -256,9 +257,9 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #define        SSI0_PHYS_ADDR          0x11600000
 #define        SSI1_PHYS_ADDR          0x11680000
 #define        SYS_PHYS_ADDR           0x11900000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR    0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR  0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR   0xF80000000ULL
 #endif
 
 /********************************************************************/
@@ -290,13 +291,13 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #define        UART3_PHYS_ADDR         0x11400000
 #define GPIO2_PHYS_ADDR                0x11700000
 #define        SYS_PHYS_ADDR           0x11900000
-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
-#define PCI_IO_PHYS_ADDR      0x500000000ULL
-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCI_MEM_PHYS_ADDR      0x400000000ULL
+#define PCI_IO_PHYS_ADDR       0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR  0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR  0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR    0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR  0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR   0xF80000000ULL
 #endif
 
 /********************************************************************/
@@ -333,9 +334,9 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #define GPIO2_PHYS_ADDR                0x11700000
 #define        SYS_PHYS_ADDR           0x11900000
 #define LCD_PHYS_ADDR          0x15000000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR    0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR  0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR   0xF80000000ULL
 #endif
 
 /***********************************************************************/
@@ -360,17 +361,17 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #define        SYS_PHYS_ADDR           0x11900000
 #define        DDMA_PHYS_ADDR          0x14002000
 #define PE_PHYS_ADDR           0x14008000
-#define PSC0_PHYS_ADDR         0x11A00000
-#define PSC1_PHYS_ADDR         0x11B00000
-#define PSC2_PHYS_ADDR         0x10A00000
-#define PSC3_PHYS_ADDR         0x10B00000
-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
-#define PCI_IO_PHYS_ADDR      0x500000000ULL
-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PSC0_PHYS_ADDR         0x11A00000
+#define PSC1_PHYS_ADDR         0x11B00000
+#define PSC2_PHYS_ADDR         0x10A00000
+#define PSC3_PHYS_ADDR         0x10B00000
+#define PCI_MEM_PHYS_ADDR      0x400000000ULL
+#define PCI_IO_PHYS_ADDR       0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR  0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR  0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR    0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR  0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR   0xF80000000ULL
 #endif
 
 /***********************************************************************/
@@ -397,122 +398,121 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
 #define SWCNT_PHYS_ADDR                0x1110010C
 #define MAEFE_PHYS_ADDR                0x14012000
 #define MAEBE_PHYS_ADDR                0x14010000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR    0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR  0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR   0xF80000000ULL
 #endif
 
-
 /* Static Bus Controller */
-#define MEM_STCFG0                 0xB4001000
-#define MEM_STTIME0                0xB4001004
-#define MEM_STADDR0                0xB4001008
+#define MEM_STCFG0             0xB4001000
+#define MEM_STTIME0            0xB4001004
+#define MEM_STADDR0            0xB4001008
 
-#define MEM_STCFG1                 0xB4001010
-#define MEM_STTIME1                0xB4001014
-#define MEM_STADDR1                0xB4001018
+#define MEM_STCFG1             0xB4001010
+#define MEM_STTIME1            0xB4001014
+#define MEM_STADDR1            0xB4001018
 
-#define MEM_STCFG2                 0xB4001020
-#define MEM_STTIME2                0xB4001024
-#define MEM_STADDR2                0xB4001028
+#define MEM_STCFG2             0xB4001020
+#define MEM_STTIME2            0xB4001024
+#define MEM_STADDR2            0xB4001028
 
-#define MEM_STCFG3                 0xB4001030
-#define MEM_STTIME3                0xB4001034
-#define MEM_STADDR3                0xB4001038
+#define MEM_STCFG3             0xB4001030
+#define MEM_STTIME3            0xB4001034
+#define MEM_STADDR3            0xB4001038
 
 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
-#define MEM_STNDCTL                0xB4001100
-#define MEM_STSTAT                 0xB4001104
+#define MEM_STNDCTL            0xB4001100
+#define MEM_STSTAT             0xB4001104
 
-#define MEM_STNAND_CMD                  (0x0)
-#define MEM_STNAND_ADDR                 (0x4)
-#define MEM_STNAND_DATA                (0x20)
+#define MEM_STNAND_CMD         0x0
+#define MEM_STNAND_ADDR        0x4
+#define MEM_STNAND_DATA        0x20
 #endif
 
 /* Interrupt Controller 0 */
-#define IC0_CFG0RD                 0xB0400040
-#define IC0_CFG0SET                0xB0400040
-#define IC0_CFG0CLR                0xB0400044
+#define IC0_CFG0RD             0xB0400040
+#define IC0_CFG0SET            0xB0400040
+#define IC0_CFG0CLR            0xB0400044
 
-#define IC0_CFG1RD                 0xB0400048
-#define IC0_CFG1SET                0xB0400048
-#define IC0_CFG1CLR                0xB040004C
+#define IC0_CFG1RD             0xB0400048
+#define IC0_CFG1SET            0xB0400048
+#define IC0_CFG1CLR            0xB040004C
 
-#define IC0_CFG2RD                 0xB0400050
-#define IC0_CFG2SET                0xB0400050
-#define IC0_CFG2CLR                0xB0400054
+#define IC0_CFG2RD             0xB0400050
+#define IC0_CFG2SET            0xB0400050
+#define IC0_CFG2CLR            0xB0400054
 
-#define IC0_REQ0INT                0xB0400054
-#define IC0_SRCRD                  0xB0400058
-#define IC0_SRCSET                 0xB0400058
-#define IC0_SRCCLR                 0xB040005C
-#define IC0_REQ1INT                0xB040005C
+#define IC0_REQ0INT            0xB0400054
+#define IC0_SRCRD              0xB0400058
+#define IC0_SRCSET             0xB0400058
+#define IC0_SRCCLR             0xB040005C
+#define IC0_REQ1INT            0xB040005C
 
-#define IC0_ASSIGNRD               0xB0400060
-#define IC0_ASSIGNSET              0xB0400060
-#define IC0_ASSIGNCLR              0xB0400064
+#define IC0_ASSIGNRD           0xB0400060
+#define IC0_ASSIGNSET          0xB0400060
+#define IC0_ASSIGNCLR          0xB0400064
 
-#define IC0_WAKERD                 0xB0400068
-#define IC0_WAKESET                0xB0400068
-#define IC0_WAKECLR                0xB040006C
+#define IC0_WAKERD             0xB0400068
+#define IC0_WAKESET            0xB0400068
+#define IC0_WAKECLR            0xB040006C
 
-#define IC0_MASKRD                 0xB0400070
-#define IC0_MASKSET                0xB0400070
-#define IC0_MASKCLR                0xB0400074
+#define IC0_MASKRD             0xB0400070
+#define IC0_MASKSET            0xB0400070
+#define IC0_MASKCLR            0xB0400074
 
-#define IC0_RISINGRD               0xB0400078
-#define IC0_RISINGCLR              0xB0400078
-#define IC0_FALLINGRD              0xB040007C
-#define IC0_FALLINGCLR             0xB040007C
+#define IC0_RISINGRD           0xB0400078
+#define IC0_RISINGCLR          0xB0400078
+#define IC0_FALLINGRD          0xB040007C
+#define IC0_FALLINGCLR         0xB040007C
 
-#define IC0_TESTBIT                0xB0400080
+#define IC0_TESTBIT            0xB0400080
 
 /* Interrupt Controller 1 */
-#define IC1_CFG0RD                 0xB1800040
-#define IC1_CFG0SET                0xB1800040
-#define IC1_CFG0CLR                0xB1800044
+#define IC1_CFG0RD             0xB1800040
+#define IC1_CFG0SET            0xB1800040
+#define IC1_CFG0CLR            0xB1800044
 
-#define IC1_CFG1RD                 0xB1800048
-#define IC1_CFG1SET                0xB1800048
-#define IC1_CFG1CLR                0xB180004C
+#define IC1_CFG1RD             0xB1800048
+#define IC1_CFG1SET            0xB1800048
+#define IC1_CFG1CLR            0xB180004C
 
-#define IC1_CFG2RD                 0xB1800050
-#define IC1_CFG2SET                0xB1800050
-#define IC1_CFG2CLR                0xB1800054
+#define IC1_CFG2RD             0xB1800050
+#define IC1_CFG2SET            0xB1800050
+#define IC1_CFG2CLR            0xB1800054
 
-#define IC1_REQ0INT                0xB1800054
-#define IC1_SRCRD                  0xB1800058
-#define IC1_SRCSET                 0xB1800058
-#define IC1_SRCCLR                 0xB180005C
-#define IC1_REQ1INT                0xB180005C
+#define IC1_REQ0INT            0xB1800054
+#define IC1_SRCRD              0xB1800058
+#define IC1_SRCSET             0xB1800058
+#define IC1_SRCCLR             0xB180005C
+#define IC1_REQ1INT            0xB180005C
 
-#define IC1_ASSIGNRD               0xB1800060
-#define IC1_ASSIGNSET              0xB1800060
-#define IC1_ASSIGNCLR              0xB1800064
+#define IC1_ASSIGNRD            0xB1800060
+#define IC1_ASSIGNSET           0xB1800060
+#define IC1_ASSIGNCLR           0xB1800064
 
-#define IC1_WAKERD                 0xB1800068
-#define IC1_WAKESET                0xB1800068
-#define IC1_WAKECLR                0xB180006C
+#define IC1_WAKERD             0xB1800068
+#define IC1_WAKESET            0xB1800068
+#define IC1_WAKECLR            0xB180006C
 
-#define IC1_MASKRD                 0xB1800070
-#define IC1_MASKSET                0xB1800070
-#define IC1_MASKCLR                0xB1800074
+#define IC1_MASKRD             0xB1800070
+#define IC1_MASKSET            0xB1800070
+#define IC1_MASKCLR            0xB1800074
 
-#define IC1_RISINGRD               0xB1800078
-#define IC1_RISINGCLR              0xB1800078
-#define IC1_FALLINGRD              0xB180007C
-#define IC1_FALLINGCLR             0xB180007C
+#define IC1_RISINGRD           0xB1800078
+#define IC1_RISINGCLR          0xB1800078
+#define IC1_FALLINGRD          0xB180007C
+#define IC1_FALLINGCLR         0xB180007C
 
-#define IC1_TESTBIT                0xB1800080
+#define IC1_TESTBIT            0xB1800080
 
 /* Interrupt Configuration Modes */
-#define INTC_INT_DISABLED                0
-#define INTC_INT_RISE_EDGE             0x1
-#define INTC_INT_FALL_EDGE             0x2
-#define INTC_INT_RISE_AND_FALL_EDGE    0x3
-#define INTC_INT_HIGH_LEVEL            0x5
-#define INTC_INT_LOW_LEVEL             0x6
-#define INTC_INT_HIGH_AND_LOW_LEVEL    0x7
+#define INTC_INT_DISABLED              0x0
+#define INTC_INT_RISE_EDGE             0x1
+#define INTC_INT_FALL_EDGE             0x2
+#define INTC_INT_RISE_AND_FALL_EDGE    0x3
+#define INTC_INT_HIGH_LEVEL            0x5
+#define INTC_INT_LOW_LEVEL             0x6
+#define INTC_INT_HIGH_AND_LOW_LEVEL    0x7
 
 /* Interrupt Numbers */
 /* Au1000 */
@@ -579,18 +579,18 @@ enum soc_au1000_ints {
        AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART2_ADDR                0xB1300000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR             0xB1100000
+#define UART1_ADDR             0xB1200000
+#define UART2_ADDR             0xB1300000
+#define UART3_ADDR             0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE          0x10100000      /* phys addr for ioremap */
+#define USB_HOST_CONFIG        0xB017FFFC
 
-#define AU1000_ETH0_BASE      0xB0500000
-#define AU1000_ETH1_BASE      0xB0510000
-#define AU1000_MAC0_ENABLE       0xB0520000
-#define AU1000_MAC1_ENABLE       0xB0520004
+#define AU1000_ETH0_BASE       0xB0500000
+#define AU1000_ETH1_BASE       0xB0510000
+#define AU1000_MAC0_ENABLE     0xB0520000
+#define AU1000_MAC1_ENABLE     0xB0520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1000 */
 
@@ -662,16 +662,16 @@ enum soc_au1500_ints {
 #define INTC AU1000_PCI_INTC
 #define INTD AU1000_PCI_INTD
 
-#define UART0_ADDR                0xB1100000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR             0xB1100000
+#define UART3_ADDR             0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE          0x10100000      /* phys addr for ioremap */
+#define USB_HOST_CONFIG        0xB017fffc
 
-#define AU1500_ETH0_BASE         0xB1500000
-#define AU1500_ETH1_BASE         0xB1510000
-#define AU1500_MAC0_ENABLE       0xB1520000
-#define AU1500_MAC1_ENABLE       0xB1520004
+#define AU1500_ETH0_BASE       0xB1500000
+#define AU1500_ETH1_BASE       0xB1510000
+#define AU1500_MAC0_ENABLE     0xB1520000
+#define AU1500_MAC1_ENABLE     0xB1520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1500 */
 
@@ -739,15 +739,15 @@ enum soc_au1100_ints {
        AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR             0xB1100000
+#define UART1_ADDR             0xB1200000
+#define UART3_ADDR             0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE          0x10100000      /* phys addr for ioremap */
+#define USB_HOST_CONFIG        0xB017FFFC
 
-#define AU1100_ETH0_BASE         0xB0500000
-#define AU1100_MAC0_ENABLE       0xB0520000
+#define AU1100_ETH0_BASE       0xB0500000
+#define AU1100_MAC0_ENABLE     0xB0520000
 #define NUM_ETH_INTERFACES 1
 #endif /* CONFIG_SOC_AU1100 */
 
@@ -826,18 +826,18 @@ enum soc_au1550_ints {
 #define INTC AU1550_PCI_INTC
 #define INTD AU1550_PCI_INTD
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR             0xB1100000
+#define UART1_ADDR             0xB1200000
+#define UART3_ADDR             0xB1400000
 
-#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
-#define USB_OHCI_LEN              0x00060000
-#define USB_HOST_CONFIG           0xB4027ffc
+#define USB_OHCI_BASE          0x14020000      /* phys addr for ioremap */
+#define USB_OHCI_LEN           0x00060000
+#define USB_HOST_CONFIG        0xB4027ffc
 
-#define AU1550_ETH0_BASE      0xB0500000
-#define AU1550_ETH1_BASE      0xB0510000
-#define AU1550_MAC0_ENABLE       0xB0520000
-#define AU1550_MAC1_ENABLE       0xB0520004
+#define AU1550_ETH0_BASE       0xB0500000
+#define AU1550_ETH1_BASE       0xB0510000
+#define AU1550_MAC0_ENABLE     0xB0520000
+#define AU1550_MAC1_ENABLE     0xB0520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1550 */
 
@@ -911,32 +911,32 @@ enum soc_au1200_ints {
        AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-
-#define USB_UOC_BASE              0x14020020
-#define USB_UOC_LEN               0x20
-#define USB_OHCI_BASE             0x14020100
-#define USB_OHCI_LEN              0x100
-#define USB_EHCI_BASE             0x14020200
-#define USB_EHCI_LEN              0x100
-#define USB_UDC_BASE              0x14022000
-#define USB_UDC_LEN               0x2000
-#define USB_MSR_BASE                     0xB4020000
-#define USB_MSR_MCFG              4
-#define USBMSRMCFG_OMEMEN         0
-#define USBMSRMCFG_OBMEN          1
-#define USBMSRMCFG_EMEMEN         2
-#define USBMSRMCFG_EBMEN          3
-#define USBMSRMCFG_DMEMEN         4
-#define USBMSRMCFG_DBMEN          5
-#define USBMSRMCFG_GMEMEN         6
-#define USBMSRMCFG_OHCCLKEN       16
-#define USBMSRMCFG_EHCCLKEN       17
-#define USBMSRMCFG_UDCCLKEN       18
-#define USBMSRMCFG_PHYPLLEN       19
-#define USBMSRMCFG_RDCOMB         30
-#define USBMSRMCFG_PFEN           31
+#define UART0_ADDR             0xB1100000
+#define UART1_ADDR             0xB1200000
+
+#define USB_UOC_BASE           0x14020020
+#define USB_UOC_LEN            0x20
+#define USB_OHCI_BASE          0x14020100
+#define USB_OHCI_LEN           0x100
+#define USB_EHCI_BASE          0x14020200
+#define USB_EHCI_LEN           0x100
+#define USB_UDC_BASE           0x14022000
+#define USB_UDC_LEN            0x2000
+#define USB_MSR_BASE           0xB4020000
+#define USB_MSR_MCFG           4
+#define USBMSRMCFG_OMEMEN      0
+#define USBMSRMCFG_OBMEN       1
+#define USBMSRMCFG_EMEMEN      2
+#define USBMSRMCFG_EBMEN       3
+#define USBMSRMCFG_DMEMEN      4
+#define USBMSRMCFG_DBMEN       5
+#define USBMSRMCFG_GMEMEN      6
+#define USBMSRMCFG_OHCCLKEN    16
+#define USBMSRMCFG_EHCCLKEN    17
+#define USBMSRMCFG_UDCCLKEN    18
+#define USBMSRMCFG_PHYPLLEN    19
+#define USBMSRMCFG_RDCOMB      30
+#define USBMSRMCFG_PFEN        31
 
 #endif /* CONFIG_SOC_AU1200 */
 
@@ -949,259 +949,258 @@ enum soc_au1200_ints {
 #define INTX                   0xFF                    /* not valid */
 
 /* Programmable Counters 0 and 1 */
-#define SYS_BASE                   0xB1900000
-#define SYS_COUNTER_CNTRL          (SYS_BASE + 0x14)
-#  define SYS_CNTRL_E1S            (1<<23)
-#  define SYS_CNTRL_T1S            (1<<20)
-#  define SYS_CNTRL_M21            (1<<19)
-#  define SYS_CNTRL_M11            (1<<18)
-#  define SYS_CNTRL_M01            (1<<17)
-#  define SYS_CNTRL_C1S            (1<<16)
-#  define SYS_CNTRL_BP             (1<<14)
-#  define SYS_CNTRL_EN1            (1<<13)
-#  define SYS_CNTRL_BT1            (1<<12)
-#  define SYS_CNTRL_EN0            (1<<11)
-#  define SYS_CNTRL_BT0            (1<<10)
-#  define SYS_CNTRL_E0             (1<<8)
-#  define SYS_CNTRL_E0S            (1<<7)
-#  define SYS_CNTRL_32S            (1<<5)
-#  define SYS_CNTRL_T0S            (1<<4)
-#  define SYS_CNTRL_M20            (1<<3)
-#  define SYS_CNTRL_M10            (1<<2)
-#  define SYS_CNTRL_M00            (1<<1)
-#  define SYS_CNTRL_C0S            (1<<0)
+#define SYS_BASE               0xB1900000
+#define SYS_COUNTER_CNTRL      (SYS_BASE + 0x14)
+#  define SYS_CNTRL_E1S        (1 << 23)
+#  define SYS_CNTRL_T1S        (1 << 20)
+#  define SYS_CNTRL_M21        (1 << 19)
+#  define SYS_CNTRL_M11        (1 << 18)
+#  define SYS_CNTRL_M01        (1 << 17)
+#  define SYS_CNTRL_C1S        (1 << 16)
+#  define SYS_CNTRL_BP         (1 << 14)
+#  define SYS_CNTRL_EN1        (1 << 13)
+#  define SYS_CNTRL_BT1        (1 << 12)
+#  define SYS_CNTRL_EN0        (1 << 11)
+#  define SYS_CNTRL_BT0        (1 << 10)
+#  define SYS_CNTRL_E0         (1 << 8)
+#  define SYS_CNTRL_E0S        (1 << 7)
+#  define SYS_CNTRL_32S        (1 << 5)
+#  define SYS_CNTRL_T0S        (1 << 4)
+#  define SYS_CNTRL_M20        (1 << 3)
+#  define SYS_CNTRL_M10        (1 << 2)
+#  define SYS_CNTRL_M00        (1 << 1)
+#  define SYS_CNTRL_C0S        (1 << 0)
 
 /* Programmable Counter 0 Registers */
-#define SYS_TOYTRIM                 (SYS_BASE + 0)
-#define SYS_TOYWRITE                (SYS_BASE + 4)
-#define SYS_TOYMATCH0               (SYS_BASE + 8)
-#define SYS_TOYMATCH1               (SYS_BASE + 0xC)
-#define SYS_TOYMATCH2               (SYS_BASE + 0x10)
-#define SYS_TOYREAD                 (SYS_BASE + 0x40)
+#define SYS_TOYTRIM            (SYS_BASE + 0)
+#define SYS_TOYWRITE           (SYS_BASE + 4)
+#define SYS_TOYMATCH0          (SYS_BASE + 8)
+#define SYS_TOYMATCH1          (SYS_BASE + 0xC)
+#define SYS_TOYMATCH2          (SYS_BASE + 0x10)
+#define SYS_TOYREAD            (SYS_BASE + 0x40)
 
 /* Programmable Counter 1 Registers */
-#define SYS_RTCTRIM                 (SYS_BASE + 0x44)
-#define SYS_RTCWRITE                (SYS_BASE + 0x48)
-#define SYS_RTCMATCH0               (SYS_BASE + 0x4C)
-#define SYS_RTCMATCH1               (SYS_BASE + 0x50)
-#define SYS_RTCMATCH2               (SYS_BASE + 0x54)
-#define SYS_RTCREAD                 (SYS_BASE + 0x58)
+#define SYS_RTCTRIM            (SYS_BASE + 0x44)
+#define SYS_RTCWRITE           (SYS_BASE + 0x48)
+#define SYS_RTCMATCH0          (SYS_BASE + 0x4C)
+#define SYS_RTCMATCH1          (SYS_BASE + 0x50)
+#define SYS_RTCMATCH2          (SYS_BASE + 0x54)
+#define SYS_RTCREAD            (SYS_BASE + 0x58)
 
 /* I2S Controller */
-#define I2S_DATA                    0xB1000000
-#  define I2S_DATA_MASK        (0xffffff)
-#define I2S_CONFIG                0xB1000004
-#  define I2S_CONFIG_XU        (1<<25)
-#  define I2S_CONFIG_XO        (1<<24)
-#  define I2S_CONFIG_RU        (1<<23)
-#  define I2S_CONFIG_RO        (1<<22)
-#  define I2S_CONFIG_TR        (1<<21)
-#  define I2S_CONFIG_TE        (1<<20)
-#  define I2S_CONFIG_TF        (1<<19)
-#  define I2S_CONFIG_RR        (1<<18)
-#  define I2S_CONFIG_RE        (1<<17)
-#  define I2S_CONFIG_RF        (1<<16)
-#  define I2S_CONFIG_PD        (1<<11)
-#  define I2S_CONFIG_LB        (1<<10)
-#  define I2S_CONFIG_IC        (1<<9)
-#  define I2S_CONFIG_FM_BIT    7
-#  define I2S_CONFIG_FM_MASK     (0x3 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_I2S    (0x0 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_LJ     (0x1 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_RJ     (0x2 << I2S_CONFIG_FM_BIT)
-#  define I2S_CONFIG_TN        (1<<6)
-#  define I2S_CONFIG_RN        (1<<5)
-#  define I2S_CONFIG_SZ_BIT    0
-#  define I2S_CONFIG_SZ_MASK     (0x1F << I2S_CONFIG_SZ_BIT)
-
-#define I2S_CONTROL                0xB1000008
-#  define I2S_CONTROL_D         (1<<1)
-#  define I2S_CONTROL_CE        (1<<0)
+#define I2S_DATA               0xB1000000
+#  define I2S_DATA_MASK        0xffffff
+#define I2S_CONFIG             0xB1000004
+#  define I2S_CONFIG_XU        (1 << 25)
+#  define I2S_CONFIG_XO        (1 << 24)
+#  define I2S_CONFIG_RU        (1 << 23)
+#  define I2S_CONFIG_RO        (1 << 22)
+#  define I2S_CONFIG_TR        (1 << 21)
+#  define I2S_CONFIG_TE        (1 << 20)
+#  define I2S_CONFIG_TF        (1 << 19)
+#  define I2S_CONFIG_RR        (1 << 18)
+#  define I2S_CONFIG_RE        (1 << 17)
+#  define I2S_CONFIG_RF        (1 << 16)
+#  define I2S_CONFIG_PD        (1 << 11)
+#  define I2S_CONFIG_LB        (1 << 10)
+#  define I2S_CONFIG_IC        (1 << 9)
+#  define I2S_CONFIG_FM_BIT    7
+#  define I2S_CONFIG_FM_MASK   (0x3 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_I2S  (0x0 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_LJ   (0x1 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_RJ   (0x2 << I2S_CONFIG_FM_BIT)
+#  define I2S_CONFIG_TN        (1 << 6)
+#  define I2S_CONFIG_RN        (1 << 5)
+#  define I2S_CONFIG_SZ_BIT    0
+#  define I2S_CONFIG_SZ_MASK   (0x1F << I2S_CONFIG_SZ_BIT)
+
+#define I2S_CONTROL            0xB1000008
+#  define I2S_CONTROL_D        (1 << 1)
+#  define I2S_CONTROL_CE       (1 << 0)
 
 /* USB Host Controller */
 #ifndef USB_OHCI_LEN
-#define USB_OHCI_LEN              0x00100000
+#define USB_OHCI_LEN           0x00100000
 #endif
 
 #ifndef CONFIG_SOC_AU1200
 
 /* USB Device Controller */
-#define USBD_EP0RD                0xB0200000
-#define USBD_EP0WR                0xB0200004
-#define USBD_EP2WR                0xB0200008
-#define USBD_EP3WR                0xB020000C
-#define USBD_EP4RD                0xB0200010
-#define USBD_EP5RD                0xB0200014
-#define USBD_INTEN                0xB0200018
-#define USBD_INTSTAT              0xB020001C
-#  define USBDEV_INT_SOF       (1<<12)
-#  define USBDEV_INT_HF_BIT    6
-#  define USBDEV_INT_HF_MASK   (0x3f << USBDEV_INT_HF_BIT)
-#  define USBDEV_INT_CMPLT_BIT  0
+#define USBD_EP0RD             0xB0200000
+#define USBD_EP0WR             0xB0200004
+#define USBD_EP2WR             0xB0200008
+#define USBD_EP3WR             0xB020000C
+#define USBD_EP4RD             0xB0200010
+#define USBD_EP5RD             0xB0200014
+#define USBD_INTEN             0xB0200018
+#define USBD_INTSTAT           0xB020001C
+#  define USBDEV_INT_SOF       (1 << 12)
+#  define USBDEV_INT_HF_BIT    6
+#  define USBDEV_INT_HF_MASK   0x3f << USBDEV_INT_HF_BIT)
+#  define USBDEV_INT_CMPLT_BIT 0
 #  define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
-#define USBD_CONFIG               0xB0200020
-#define USBD_EP0CS                0xB0200024
-#define USBD_EP2CS                0xB0200028
-#define USBD_EP3CS                0xB020002C
-#define USBD_EP4CS                0xB0200030
-#define USBD_EP5CS                0xB0200034
-#  define USBDEV_CS_SU         (1<<14)
-#  define USBDEV_CS_NAK        (1<<13)
-#  define USBDEV_CS_ACK        (1<<12)
-#  define USBDEV_CS_BUSY       (1<<11)
-#  define USBDEV_CS_TSIZE_BIT  1
-#  define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
-#  define USBDEV_CS_STALL      (1<<0)
-#define USBD_EP0RDSTAT            0xB0200040
-#define USBD_EP0WRSTAT            0xB0200044
-#define USBD_EP2WRSTAT            0xB0200048
-#define USBD_EP3WRSTAT            0xB020004C
-#define USBD_EP4RDSTAT            0xB0200050
-#define USBD_EP5RDSTAT            0xB0200054
-#  define USBDEV_FSTAT_FLUSH     (1<<6)
-#  define USBDEV_FSTAT_UF        (1<<5)
-#  define USBDEV_FSTAT_OF        (1<<4)
-#  define USBDEV_FSTAT_FCNT_BIT  0
+#define USBD_CONFIG            0xB0200020
+#define USBD_EP0CS             0xB0200024
+#define USBD_EP2CS             0xB0200028
+#define USBD_EP3CS             0xB020002C
+#define USBD_EP4CS             0xB0200030
+#define USBD_EP5CS             0xB0200034
+#  define USBDEV_CS_SU         (1 << 14)
+#  define USBDEV_CS_NAK        (1 << 13)
+#  define USBDEV_CS_ACK        (1 << 12)
+#  define USBDEV_CS_BUSY       (1 << 11)
+#  define USBDEV_CS_TSIZE_BIT  1
+#  define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
+#  define USBDEV_CS_STALL      (1 << 0)
+#define USBD_EP0RDSTAT         0xB0200040
+#define USBD_EP0WRSTAT         0xB0200044
+#define USBD_EP2WRSTAT         0xB0200048
+#define USBD_EP3WRSTAT         0xB020004C
+#define USBD_EP4RDSTAT         0xB0200050
+#define USBD_EP5RDSTAT         0xB0200054
+#  define USBDEV_FSTAT_FLUSH   (1 << 6)
+#  define USBDEV_FSTAT_UF      (1 << 5)
+#  define USBDEV_FSTAT_OF      (1 << 4)
+#  define USBDEV_FSTAT_FCNT_BIT 0
 #  define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
-#define USBD_ENABLE               0xB0200058
-#  define USBDEV_ENABLE (1<<1)
-#  define USBDEV_CE     (1<<0)
+#define USBD_ENABLE            0xB0200058
+#  define USBDEV_ENABLE        (1 << 1)
+#  define USBDEV_CE            (1 << 0)
 
 #endif /* !CONFIG_SOC_AU1200 */
 
 /* Ethernet Controllers  */
 
 /* 4 byte offsets from AU1000_ETH_BASE */
-#define MAC_CONTROL                     0x0
-#  define MAC_RX_ENABLE               (1<<2)
-#  define MAC_TX_ENABLE               (1<<3)
-#  define MAC_DEF_CHECK               (1<<5)
-#  define MAC_SET_BL(X)       (((X)&0x3)<<6)
-#  define MAC_AUTO_PAD                (1<<8)
-#  define MAC_DISABLE_RETRY          (1<<10)
-#  define MAC_DISABLE_BCAST          (1<<11)
-#  define MAC_LATE_COL               (1<<12)
-#  define MAC_HASH_MODE              (1<<13)
-#  define MAC_HASH_ONLY              (1<<15)
-#  define MAC_PASS_ALL               (1<<16)
-#  define MAC_INVERSE_FILTER         (1<<17)
-#  define MAC_PROMISCUOUS            (1<<18)
-#  define MAC_PASS_ALL_MULTI         (1<<19)
-#  define MAC_FULL_DUPLEX            (1<<20)
-#  define MAC_NORMAL_MODE                 0
-#  define MAC_INT_LOOPBACK           (1<<21)
-#  define MAC_EXT_LOOPBACK           (1<<22)
-#  define MAC_DISABLE_RX_OWN         (1<<23)
-#  define MAC_BIG_ENDIAN             (1<<30)
-#  define MAC_RX_ALL                 (1<<31)
-#define MAC_ADDRESS_HIGH                0x4
-#define MAC_ADDRESS_LOW                 0x8
-#define MAC_MCAST_HIGH                  0xC
-#define MAC_MCAST_LOW                  0x10
-#define MAC_MII_CNTRL                  0x14
-#  define MAC_MII_BUSY                (1<<0)
-#  define MAC_MII_READ                     0
-#  define MAC_MII_WRITE               (1<<1)
-#  define MAC_SET_MII_SELECT_REG(X)   (((X)&0x1f)<<6)
-#  define MAC_SET_MII_SELECT_PHY(X)   (((X)&0x1f)<<11)
-#define MAC_MII_DATA                   0x18
-#define MAC_FLOW_CNTRL                 0x1C
-#  define MAC_FLOW_CNTRL_BUSY         (1<<0)
-#  define MAC_FLOW_CNTRL_ENABLE       (1<<1)
-#  define MAC_PASS_CONTROL            (1<<2)
-#  define MAC_SET_PAUSE(X)        (((X)&0xffff)<<16)
-#define MAC_VLAN1_TAG                  0x20
-#define MAC_VLAN2_TAG                  0x24
+#define MAC_CONTROL            0x0
+#  define MAC_RX_ENABLE        (1 << 2)
+#  define MAC_TX_ENABLE        (1 << 3)
+#  define MAC_DEF_CHECK        (1 << 5)
+#  define MAC_SET_BL(X)        (((X) & 0x3) << 6)
+#  define MAC_AUTO_PAD         (1 << 8)
+#  define MAC_DISABLE_RETRY    (1 << 10)
+#  define MAC_DISABLE_BCAST    (1 << 11)
+#  define MAC_LATE_COL         (1 << 12)
+#  define MAC_HASH_MODE        (1 << 13)
+#  define MAC_HASH_ONLY        (1 << 15)
+#  define MAC_PASS_ALL         (1 << 16)
+#  define MAC_INVERSE_FILTER   (1 << 17)
+#  define MAC_PROMISCUOUS      (1 << 18)
+#  define MAC_PASS_ALL_MULTI   (1 << 19)
+#  define MAC_FULL_DUPLEX      (1 << 20)
+#  define MAC_NORMAL_MODE      0
+#  define MAC_INT_LOOPBACK     (1 << 21)
+#  define MAC_EXT_LOOPBACK     (1 << 22)
+#  define MAC_DISABLE_RX_OWN   (1 << 23)
+#  define MAC_BIG_ENDIAN       (1 << 30)
+#  define MAC_RX_ALL           (1 << 31)
+#define MAC_ADDRESS_HIGH       0x4
+#define MAC_ADDRESS_LOW                0x8
+#define MAC_MCAST_HIGH         0xC
+#define MAC_MCAST_LOW          0x10
+#define MAC_MII_CNTRL          0x14
+#  define MAC_MII_BUSY         (1 << 0)
+#  define MAC_MII_READ         0
+#  define MAC_MII_WRITE                (1 << 1)
+#  define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6)
+#  define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11)
+#define MAC_MII_DATA           0x18
+#define MAC_FLOW_CNTRL         0x1C
+#  define MAC_FLOW_CNTRL_BUSY  (1 << 0)
+#  define MAC_FLOW_CNTRL_ENABLE (1 << 1)
+#  define MAC_PASS_CONTROL     (1 << 2)
+#  define MAC_SET_PAUSE(X)     (((X) & 0xffff) << 16)
+#define MAC_VLAN1_TAG          0x20
+#define MAC_VLAN2_TAG          0x24
 
 /* Ethernet Controller Enable */
 
-#  define MAC_EN_CLOCK_ENABLE         (1<<0)
-#  define MAC_EN_RESET0               (1<<1)
-#  define MAC_EN_TOSS                 (0<<2)
-#  define MAC_EN_CACHEABLE            (1<<3)
-#  define MAC_EN_RESET1               (1<<4)
-#  define MAC_EN_RESET2               (1<<5)
-#  define MAC_DMA_RESET               (1<<6)
+#  define MAC_EN_CLOCK_ENABLE  (1 << 0)
+#  define MAC_EN_RESET0                (1 << 1)
+#  define MAC_EN_TOSS          (0 << 2)
+#  define MAC_EN_CACHEABLE     (1 << 3)
+#  define MAC_EN_RESET1        (1 << 4)
+#  define MAC_EN_RESET2        (1 << 5)
+#  define MAC_DMA_RESET        (1 << 6)
 
 /* Ethernet Controller DMA Channels */
 
-#define MAC0_TX_DMA_ADDR         0xB4004000
-#define MAC1_TX_DMA_ADDR         0xB4004200
+#define MAC0_TX_DMA_ADDR       0xB4004000
+#define MAC1_TX_DMA_ADDR       0xB4004200
 /* offsets from MAC_TX_RING_ADDR address */
-#define MAC_TX_BUFF0_STATUS             0x0
-#  define TX_FRAME_ABORTED            (1<<0)
-#  define TX_JAB_TIMEOUT              (1<<1)
-#  define TX_NO_CARRIER               (1<<2)
-#  define TX_LOSS_CARRIER             (1<<3)
-#  define TX_EXC_DEF                  (1<<4)
-#  define TX_LATE_COLL_ABORT          (1<<5)
-#  define TX_EXC_COLL                 (1<<6)
-#  define TX_UNDERRUN                 (1<<7)
-#  define TX_DEFERRED                 (1<<8)
-#  define TX_LATE_COLL                (1<<9)
-#  define TX_COLL_CNT_MASK         (0xF<<10)
-#  define TX_PKT_RETRY               (1<<31)
-#define MAC_TX_BUFF0_ADDR                0x4
-#  define TX_DMA_ENABLE               (1<<0)
-#  define TX_T_DONE                   (1<<1)
-#  define TX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
-#define MAC_TX_BUFF0_LEN                 0x8
-#define MAC_TX_BUFF1_STATUS             0x10
-#define MAC_TX_BUFF1_ADDR               0x14
-#define MAC_TX_BUFF1_LEN                0x18
-#define MAC_TX_BUFF2_STATUS             0x20
-#define MAC_TX_BUFF2_ADDR               0x24
-#define MAC_TX_BUFF2_LEN                0x28
-#define MAC_TX_BUFF3_STATUS             0x30
-#define MAC_TX_BUFF3_ADDR               0x34
-#define MAC_TX_BUFF3_LEN                0x38
-
-#define MAC0_RX_DMA_ADDR         0xB4004100
-#define MAC1_RX_DMA_ADDR         0xB4004300
+#define MAC_TX_BUFF0_STATUS    0x0
+#  define TX_FRAME_ABORTED     (1 << 0)
+#  define TX_JAB_TIMEOUT       (1 << 1)
+#  define TX_NO_CARRIER        (1 << 2)
+#  define TX_LOSS_CARRIER      (1 << 3)
+#  define TX_EXC_DEF           (1 << 4)
+#  define TX_LATE_COLL_ABORT   (1 << 5)
+#  define TX_EXC_COLL          (1 << 6)
+#  define TX_UNDERRUN          (1 << 7)
+#  define TX_DEFERRED          (1 << 8)
+#  define TX_LATE_COLL         (1 << 9)
+#  define TX_COLL_CNT_MASK     (0xF << 10)
+#  define TX_PKT_RETRY         (1 << 31)
+#define MAC_TX_BUFF0_ADDR      0x4
+#  define TX_DMA_ENABLE        (1 << 0)
+#  define TX_T_DONE            (1 << 1)
+#  define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+#define MAC_TX_BUFF0_LEN       0x8
+#define MAC_TX_BUFF1_STATUS    0x10
+#define MAC_TX_BUFF1_ADDR      0x14
+#define MAC_TX_BUFF1_LEN       0x18
+#define MAC_TX_BUFF2_STATUS    0x20
+#define MAC_TX_BUFF2_ADDR      0x24
+#define MAC_TX_BUFF2_LEN       0x28
+#define MAC_TX_BUFF3_STATUS    0x30
+#define MAC_TX_BUFF3_ADDR      0x34
+#define MAC_TX_BUFF3_LEN       0x38
+
+#define MAC0_RX_DMA_ADDR       0xB4004100
+#define MAC1_RX_DMA_ADDR       0xB4004300
 /* offsets from MAC_RX_RING_ADDR */
-#define MAC_RX_BUFF0_STATUS              0x0
-#  define RX_FRAME_LEN_MASK           0x3fff
-#  define RX_WDOG_TIMER              (1<<14)
-#  define RX_RUNT                    (1<<15)
-#  define RX_OVERLEN                 (1<<16)
-#  define RX_COLL                    (1<<17)
-#  define RX_ETHER                   (1<<18)
-#  define RX_MII_ERROR               (1<<19)
-#  define RX_DRIBBLING               (1<<20)
-#  define RX_CRC_ERROR               (1<<21)
-#  define RX_VLAN1                   (1<<22)
-#  define RX_VLAN2                   (1<<23)
-#  define RX_LEN_ERROR               (1<<24)
-#  define RX_CNTRL_FRAME             (1<<25)
-#  define RX_U_CNTRL_FRAME           (1<<26)
-#  define RX_MCAST_FRAME             (1<<27)
-#  define RX_BCAST_FRAME             (1<<28)
-#  define RX_FILTER_FAIL             (1<<29)
-#  define RX_PACKET_FILTER           (1<<30)
-#  define RX_MISSED_FRAME            (1<<31)
+#define MAC_RX_BUFF0_STATUS    0x0
+#  define RX_FRAME_LEN_MASK    0x3fff
+#  define RX_WDOG_TIMER        (1 << 14)
+#  define RX_RUNT              (1 << 15)
+#  define RX_OVERLEN           (1 << 16)
+#  define RX_COLL              (1 << 17)
+#  define RX_ETHER             (1 << 18)
+#  define RX_MII_ERROR         (1 << 19)
+#  define RX_DRIBBLING         (1 << 20)
+#  define RX_CRC_ERROR         (1 << 21)
+#  define RX_VLAN1             (1 << 22)
+#  define RX_VLAN2             (1 << 23)
+#  define RX_LEN_ERROR         (1 << 24)
+#  define RX_CNTRL_FRAME       (1 << 25)
+#  define RX_U_CNTRL_FRAME     (1 << 26)
+#  define RX_MCAST_FRAME       (1 << 27)
+#  define RX_BCAST_FRAME       (1 << 28)
+#  define RX_FILTER_FAIL       (1 << 29)
+#  define RX_PACKET_FILTER     (1 << 30)
+#  define RX_MISSED_FRAME      (1 << 31)
 
 #  define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN |  \
-                    RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
-                    RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
-#define MAC_RX_BUFF0_ADDR                0x4
-#  define RX_DMA_ENABLE               (1<<0)
-#  define RX_T_DONE                   (1<<1)
-#  define RX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
-#  define RX_SET_BUFF_ADDR(X)     ((X)&0xffffffc0)
-#define MAC_RX_BUFF1_STATUS              0x10
-#define MAC_RX_BUFF1_ADDR                0x14
-#define MAC_RX_BUFF2_STATUS              0x20
-#define MAC_RX_BUFF2_ADDR                0x24
-#define MAC_RX_BUFF3_STATUS              0x30
-#define MAC_RX_BUFF3_ADDR                0x34
-
+                   RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
+                   RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
+#define MAC_RX_BUFF0_ADDR      0x4
+#  define RX_DMA_ENABLE        (1 << 0)
+#  define RX_T_DONE            (1 << 1)
+#  define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+#  define RX_SET_BUFF_ADDR(X)  ((X) & 0xffffffc0)
+#define MAC_RX_BUFF1_STATUS    0x10
+#define MAC_RX_BUFF1_ADDR      0x14
+#define MAC_RX_BUFF2_STATUS    0x20
+#define MAC_RX_BUFF2_ADDR      0x24
+#define MAC_RX_BUFF3_STATUS    0x30
+#define MAC_RX_BUFF3_ADDR      0x34
 
 /* UARTS 0-3 */
-#define UART_BASE                 UART0_ADDR
+#define UART_BASE              UART0_ADDR
 #ifdef CONFIG_SOC_AU1200
-#define UART_DEBUG_BASE           UART1_ADDR
+#define UART_DEBUG_BASE        UART1_ADDR
 #else
-#define UART_DEBUG_BASE           UART3_ADDR
+#define UART_DEBUG_BASE        UART3_ADDR
 #endif
 
 #define UART_RX                0       /* Receive buffer */
@@ -1294,341 +1293,337 @@ enum soc_au1200_ints {
 #define UART_MSR_DCTS  0x01    /* Delta CTS */
 #define UART_MSR_ANY_DELTA 0x0F        /* Any of the delta bits! */
 
-
-
 /* SSIO */
-#define SSI0_STATUS                0xB1600000
-#  define SSI_STATUS_BF              (1<<4)
-#  define SSI_STATUS_OF              (1<<3)
-#  define SSI_STATUS_UF              (1<<2)
-#  define SSI_STATUS_D               (1<<1)
-#  define SSI_STATUS_B               (1<<0)
-#define SSI0_INT                   0xB1600004
-#  define SSI_INT_OI                 (1<<3)
-#  define SSI_INT_UI                 (1<<2)
-#  define SSI_INT_DI                 (1<<1)
-#define SSI0_INT_ENABLE            0xB1600008
-#  define SSI_INTE_OIE               (1<<3)
-#  define SSI_INTE_UIE               (1<<2)
-#  define SSI_INTE_DIE               (1<<1)
-#define SSI0_CONFIG                0xB1600020
-#  define SSI_CONFIG_AO              (1<<24)
-#  define SSI_CONFIG_DO              (1<<23)
-#  define SSI_CONFIG_ALEN_BIT        20
-#    define SSI_CONFIG_ALEN_MASK       (0x7<<20)
-#  define SSI_CONFIG_DLEN_BIT        16
-#    define SSI_CONFIG_DLEN_MASK       (0x7<<16)
-#  define SSI_CONFIG_DD              (1<<11)
-#  define SSI_CONFIG_AD              (1<<10)
-#  define SSI_CONFIG_BM_BIT          8
-#    define SSI_CONFIG_BM_MASK         (0x3<<8)
-#  define SSI_CONFIG_CE              (1<<7)
-#  define SSI_CONFIG_DP              (1<<6)
-#  define SSI_CONFIG_DL              (1<<5)
-#  define SSI_CONFIG_EP              (1<<4)
-#define SSI0_ADATA                 0xB1600024
-#  define SSI_AD_D                   (1<<24)
-#  define SSI_AD_ADDR_BIT            16
-#    define SSI_AD_ADDR_MASK           (0xff<<16)
-#  define SSI_AD_DATA_BIT            0
-#    define SSI_AD_DATA_MASK           (0xfff<<0)
-#define SSI0_CLKDIV                0xB1600028
-#define SSI0_CONTROL               0xB1600100
-#  define SSI_CONTROL_CD             (1<<1)
-#  define SSI_CONTROL_E              (1<<0)
+#define SSI0_STATUS            0xB1600000
+#  define SSI_STATUS_BF        (1 << 4)
+#  define SSI_STATUS_OF        (1 << 3)
+#  define SSI_STATUS_UF        (1 << 2)
+#  define SSI_STATUS_D         (1 << 1)
+#  define SSI_STATUS_B         (1 << 0)
+#define SSI0_INT               0xB1600004
+#  define SSI_INT_OI           (1 << 3)
+#  define SSI_INT_UI           (1 << 2)
+#  define SSI_INT_DI           (1 << 1)
+#define SSI0_INT_ENABLE        0xB1600008
+#  define SSI_INTE_OIE         (1 << 3)
+#  define SSI_INTE_UIE         (1 << 2)
+#  define SSI_INTE_DIE         (1 << 1)
+#define SSI0_CONFIG            0xB1600020
+#  define SSI_CONFIG_AO        (1 << 24)
+#  define SSI_CONFIG_DO        (1 << 23)
+#  define SSI_CONFIG_ALEN_BIT  20
+#  define SSI_CONFIG_ALEN_MASK (0x7 << 20)
+#  define SSI_CONFIG_DLEN_BIT  16
+#  define SSI_CONFIG_DLEN_MASK (0x7 << 16)
+#  define SSI_CONFIG_DD        (1 << 11)
+#  define SSI_CONFIG_AD        (1 << 10)
+#  define SSI_CONFIG_BM_BIT    8
+#  define SSI_CONFIG_BM_MASK   (0x3 << 8)
+#  define SSI_CONFIG_CE        (1 << 7)
+#  define SSI_CONFIG_DP        (1 << 6)
+#  define SSI_CONFIG_DL        (1 << 5)
+#  define SSI_CONFIG_EP        (1 << 4)
+#define SSI0_ADATA             0xB1600024
+#  define SSI_AD_D             (1 << 24)
+#  define SSI_AD_ADDR_BIT      16
+#  define SSI_AD_ADDR_MASK     (0xff << 16)
+#  define SSI_AD_DATA_BIT      0
+#  define SSI_AD_DATA_MASK     (0xfff << 0)
+#define SSI0_CLKDIV            0xB1600028
+#define SSI0_CONTROL           0xB1600100
+#  define SSI_CONTROL_CD       (1 << 1)
+#  define SSI_CONTROL_E        (1 << 0)
 
 /* SSI1 */
-#define SSI1_STATUS                0xB1680000
-#define SSI1_INT                   0xB1680004
-#define SSI1_INT_ENABLE            0xB1680008
-#define SSI1_CONFIG                0xB1680020
-#define SSI1_ADATA                 0xB1680024
-#define SSI1_CLKDIV                0xB1680028
-#define SSI1_ENABLE                0xB1680100
+#define SSI1_STATUS            0xB1680000
+#define SSI1_INT               0xB1680004
+#define SSI1_INT_ENABLE        0xB1680008
+#define SSI1_CONFIG            0xB1680020
+#define SSI1_ADATA             0xB1680024
+#define SSI1_CLKDIV            0xB1680028
+#define SSI1_ENABLE            0xB1680100
 
 /*
  * Register content definitions
  */
-#define SSI_STATUS_BF                          (1<<4)
-#define SSI_STATUS_OF                          (1<<3)
-#define SSI_STATUS_UF                          (1<<2)
-#define SSI_STATUS_D                           (1<<1)
-#define SSI_STATUS_B                           (1<<0)
+#define SSI_STATUS_BF          (1 << 4)
+#define SSI_STATUS_OF          (1 << 3)
+#define SSI_STATUS_UF          (1 << 2)
+#define SSI_STATUS_D           (1 << 1)
+#define SSI_STATUS_B           (1 << 0)
 
 /* SSI_INT */
-#define SSI_INT_OI                                     (1<<3)
-#define SSI_INT_UI                                     (1<<2)
-#define SSI_INT_DI                                     (1<<1)
+#define SSI_INT_OI             (1 << 3)
+#define SSI_INT_UI             (1 << 2)
+#define SSI_INT_DI             (1 << 1)
 
 /* SSI_INTEN */
-#define SSI_INTEN_OIE                          (1<<3)
-#define SSI_INTEN_UIE                          (1<<2)
-#define SSI_INTEN_DIE                          (1<<1)
-
-#define SSI_CONFIG_AO                          (1<<24)
-#define SSI_CONFIG_DO                          (1<<23)
-#define SSI_CONFIG_ALEN                                (7<<20)
-#define SSI_CONFIG_DLEN                                (15<<16)
-#define SSI_CONFIG_DD                          (1<<11)
-#define SSI_CONFIG_AD                          (1<<10)
-#define SSI_CONFIG_BM                          (3<<8)
-#define SSI_CONFIG_CE                          (1<<7)
-#define SSI_CONFIG_DP                          (1<<6)
-#define SSI_CONFIG_DL                          (1<<5)
-#define SSI_CONFIG_EP                          (1<<4)
-#define SSI_CONFIG_ALEN_N(N)           ((N-1)<<20)
-#define SSI_CONFIG_DLEN_N(N)           ((N-1)<<16)
-#define SSI_CONFIG_BM_HI                       (0<<8)
-#define SSI_CONFIG_BM_LO                       (1<<8)
-#define SSI_CONFIG_BM_CY                       (2<<8)
-
-#define SSI_ADATA_D                                    (1<<24)
-#define SSI_ADATA_ADDR                         (0xFF<<16)
-#define SSI_ADATA_DATA                         (0x0FFF)
-#define SSI_ADATA_ADDR_N(N)                    (N<<16)
-
-#define SSI_ENABLE_CD                          (1<<1)
-#define SSI_ENABLE_E                           (1<<0)
-
+#define SSI_INTEN_OIE          (1 << 3)
+#define SSI_INTEN_UIE          (1 << 2)
+#define SSI_INTEN_DIE          (1 << 1)
+
+#define SSI_CONFIG_AO          (1 << 24)
+#define SSI_CONFIG_DO          (1 << 23)
+#define SSI_CONFIG_ALEN        (7 << 20)
+#define SSI_CONFIG_DLEN        (15 << 16)
+#define SSI_CONFIG_DD          (1 << 11)
+#define SSI_CONFIG_AD          (1 << 10)
+#define SSI_CONFIG_BM          (3 << 8)
+#define SSI_CONFIG_CE          (1 << 7)
+#define SSI_CONFIG_DP          (1 << 6)
+#define SSI_CONFIG_DL          (1 << 5)
+#define SSI_CONFIG_EP          (1 << 4)
+#define SSI_CONFIG_ALEN_N(N)   ((N-1) << 20)
+#define SSI_CONFIG_DLEN_N(N)   ((N-1) << 16)
+#define SSI_CONFIG_BM_HI       (0 << 8)
+#define SSI_CONFIG_BM_LO       (1 << 8)
+#define SSI_CONFIG_BM_CY       (2 << 8)
+
+#define SSI_ADATA_D            (1 << 24)
+#define SSI_ADATA_ADDR         (0xFF << 16)
+#define SSI_ADATA_DATA         0x0FFF
+#define SSI_ADATA_ADDR_N(N)    (N << 16)
+
+#define SSI_ENABLE_CD          (1 << 1)
+#define SSI_ENABLE_E           (1 << 0)
 
 /* IrDA Controller */
-#define IRDA_BASE                 0xB0300000
-#define IR_RING_PTR_STATUS        (IRDA_BASE+0x00)
-#define IR_RING_BASE_ADDR_H       (IRDA_BASE+0x04)
-#define IR_RING_BASE_ADDR_L       (IRDA_BASE+0x08)
-#define IR_RING_SIZE              (IRDA_BASE+0x0C)
-#define IR_RING_PROMPT            (IRDA_BASE+0x10)
-#define IR_RING_ADDR_CMPR         (IRDA_BASE+0x14)
-#define IR_INT_CLEAR              (IRDA_BASE+0x18)
-#define IR_CONFIG_1               (IRDA_BASE+0x20)
-#  define IR_RX_INVERT_LED        (1<<0)
-#  define IR_TX_INVERT_LED        (1<<1)
-#  define IR_ST                   (1<<2)
-#  define IR_SF                   (1<<3)
-#  define IR_SIR                  (1<<4)
-#  define IR_MIR                  (1<<5)
-#  define IR_FIR                  (1<<6)
-#  define IR_16CRC                (1<<7)
-#  define IR_TD                   (1<<8)
-#  define IR_RX_ALL               (1<<9)
-#  define IR_DMA_ENABLE           (1<<10)
-#  define IR_RX_ENABLE            (1<<11)
-#  define IR_TX_ENABLE            (1<<12)
-#  define IR_LOOPBACK             (1<<14)
-#  define IR_SIR_MODE            (IR_SIR | IR_DMA_ENABLE | \
-                                  IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
-#define IR_SIR_FLAGS              (IRDA_BASE+0x24)
-#define IR_ENABLE                 (IRDA_BASE+0x28)
-#  define IR_RX_STATUS            (1<<9)
-#  define IR_TX_STATUS            (1<<10)
-#define IR_READ_PHY_CONFIG        (IRDA_BASE+0x2C)
-#define IR_WRITE_PHY_CONFIG       (IRDA_BASE+0x30)
-#define IR_MAX_PKT_LEN            (IRDA_BASE+0x34)
-#define IR_RX_BYTE_CNT            (IRDA_BASE+0x38)
-#define IR_CONFIG_2               (IRDA_BASE+0x3C)
-#  define IR_MODE_INV             (1<<0)
-#  define IR_ONE_PIN              (1<<1)
-#define IR_INTERFACE_CONFIG       (IRDA_BASE+0x40)
+#define IRDA_BASE              0xB0300000
+#define IR_RING_PTR_STATUS     (IRDA_BASE + 0x00)
+#define IR_RING_BASE_ADDR_H    (IRDA_BASE + 0x04)
+#define IR_RING_BASE_ADDR_L    (IRDA_BASE + 0x08)
+#define IR_RING_SIZE           (IRDA_BASE + 0x0C)
+#define IR_RING_PROMPT         (IRDA_BASE + 0x10)
+#define IR_RING_ADDR_CMPR      (IRDA_BASE + 0x14)
+#define IR_INT_CLEAR           (IRDA_BASE + 0x18)
+#define IR_CONFIG_1            (IRDA_BASE + 0x20)
+#  define IR_RX_INVERT_LED     (1 << 0)
+#  define IR_TX_INVERT_LED     (1 << 1)
+#  define IR_ST                (1 << 2)
+#  define IR_SF                (1 << 3)
+#  define IR_SIR               (1 << 4)
+#  define IR_MIR               (1 << 5)
+#  define IR_FIR               (1 << 6)
+#  define IR_16CRC             (1 << 7)
+#  define IR_TD                (1 << 8)
+#  define IR_RX_ALL            (1 << 9)
+#  define IR_DMA_ENABLE        (1 << 10)
+#  define IR_RX_ENABLE         (1 << 11)
+#  define IR_TX_ENABLE         (1 << 12)
+#  define IR_LOOPBACK          (1 << 14)
+#  define IR_SIR_MODE          (IR_SIR | IR_DMA_ENABLE | \
+                                IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
+#define IR_SIR_FLAGS           (IRDA_BASE + 0x24)
+#define IR_ENABLE              (IRDA_BASE + 0x28)
+#  define IR_RX_STATUS         (1 << 9)
+#  define IR_TX_STATUS         (1 << 10)
+#define IR_READ_PHY_CONFIG     (IRDA_BASE + 0x2C)
+#define IR_WRITE_PHY_CONFIG    (IRDA_BASE + 0x30)
+#define IR_MAX_PKT_LEN         (IRDA_BASE + 0x34)
+#define IR_RX_BYTE_CNT         (IRDA_BASE + 0x38)
+#define IR_CONFIG_2            (IRDA_BASE + 0x3C)
+#  define IR_MODE_INV          (1 << 0)
+#  define IR_ONE_PIN           (1 << 1)
+#define IR_INTERFACE_CONFIG    (IRDA_BASE + 0x40)
 
 /* GPIO */
-#define SYS_PINFUNC               0xB190002C
-#  define SYS_PF_USB                   (1<<15) /* 2nd USB device/host */
-#  define SYS_PF_U3                    (1<<14) /* GPIO23/U3TXD */
-#  define SYS_PF_U2                    (1<<13) /* GPIO22/U2TXD */
-#  define SYS_PF_U1                    (1<<12) /* GPIO21/U1TXD */
-#  define SYS_PF_SRC                   (1<<11) /* GPIO6/SROMCKE */
-#  define SYS_PF_CK5                   (1<<10) /* GPIO3/CLK5 */
-#  define SYS_PF_CK4                   (1<<9)  /* GPIO2/CLK4 */
-#  define SYS_PF_IRF                   (1<<8)  /* GPIO15/IRFIRSEL */
-#  define SYS_PF_UR3                   (1<<7)  /* GPIO[14:9]/UART3 */
-#  define SYS_PF_I2D                   (1<<6)  /* GPIO8/I2SDI */
-#  define SYS_PF_I2S                   (1<<5)  /* I2S/GPIO[29:31] */
-#  define SYS_PF_NI2                   (1<<4)  /* NI2/GPIO[24:28] */
-#  define SYS_PF_U0                    (1<<3)  /* U0TXD/GPIO20 */
-#  define SYS_PF_RD                    (1<<2)  /* IRTXD/GPIO19 */
-#  define SYS_PF_A97                   (1<<1)  /* AC97/SSL1 */
-#  define SYS_PF_S0                    (1<<0)  /* SSI_0/GPIO[16:18] */
-
-/* Au1100 Only */
-#  define SYS_PF_PC                    (1<<18) /* PCMCIA/GPIO[207:204] */
-#  define SYS_PF_LCD                   (1<<17) /* extern lcd/GPIO[203:200] */
-#  define SYS_PF_CS                    (1<<16) /* EXTCLK0/32khz to gpio2 */
-#  define SYS_PF_EX0                   (1<<9)  /* gpio2/clock */
-
-/* Au1550 Only.  Redefines lots of pins */
-#  define SYS_PF_PSC2_MASK             (7 << 17)
-#  define SYS_PF_PSC2_AC97             (0)
-#  define SYS_PF_PSC2_SPI              (0)
-#  define SYS_PF_PSC2_I2S              (1 << 17)
-#  define SYS_PF_PSC2_SMBUS            (3 << 17)
-#  define SYS_PF_PSC2_GPIO             (7 << 17)
-#  define SYS_PF_PSC3_MASK             (7 << 20)
-#  define SYS_PF_PSC3_AC97             (0)
-#  define SYS_PF_PSC3_SPI              (0)
-#  define SYS_PF_PSC3_I2S              (1 << 20)
-#  define SYS_PF_PSC3_SMBUS            (3 << 20)
-#  define SYS_PF_PSC3_GPIO             (7 << 20)
-#  define SYS_PF_PSC1_S1               (1 << 1)
-#  define SYS_PF_MUST_BE_SET           ((1 << 5) | (1 << 2))
-
-/* Au1200 Only */
+#define SYS_PINFUNC            0xB190002C
+#  define SYS_PF_USB           (1 << 15)       /* 2nd USB device/host */
+#  define SYS_PF_U3            (1 << 14)       /* GPIO23/U3TXD */
+#  define SYS_PF_U2            (1 << 13)       /* GPIO22/U2TXD */
+#  define SYS_PF_U1            (1 << 12)       /* GPIO21/U1TXD */
+#  define SYS_PF_SRC           (1 << 11)       /* GPIO6/SROMCKE */
+#  define SYS_PF_CK5           (1 << 10)       /* GPIO3/CLK5 */
+#  define SYS_PF_CK4           (1 << 9)        /* GPIO2/CLK4 */
+#  define SYS_PF_IRF           (1 << 8)        /* GPIO15/IRFIRSEL */
+#  define SYS_PF_UR3           (1 << 7)        /* GPIO[14:9]/UART3 */
+#  define SYS_PF_I2D           (1 << 6)        /* GPIO8/I2SDI */
+#  define SYS_PF_I2S           (1 << 5)        /* I2S/GPIO[29:31] */
+#  define SYS_PF_NI2           (1 << 4)        /* NI2/GPIO[24:28] */
+#  define SYS_PF_U0            (1 << 3)        /* U0TXD/GPIO20 */
+#  define SYS_PF_RD            (1 << 2)        /* IRTXD/GPIO19 */
+#  define SYS_PF_A97           (1 << 1)        /* AC97/SSL1 */
+#  define SYS_PF_S0            (1 << 0)        /* SSI_0/GPIO[16:18] */
+
+/* Au1100 only */
+#  define SYS_PF_PC            (1 << 18)       /* PCMCIA/GPIO[207:204] */
+#  define SYS_PF_LCD           (1 << 17)       /* extern lcd/GPIO[203:200] */
+#  define SYS_PF_CS            (1 << 16)       /* EXTCLK0/32KHz to gpio2 */
+#  define SYS_PF_EX0           (1 << 9)        /* GPIO2/clock */
+
+/* Au1550 only.  Redefines lots of pins */
+#  define SYS_PF_PSC2_MASK     (7 << 17)
+#  define SYS_PF_PSC2_AC97     0
+#  define SYS_PF_PSC2_SPI      0
+#  define SYS_PF_PSC2_I2S      (1 << 17)
+#  define SYS_PF_PSC2_SMBUS    (3 << 17)
+#  define SYS_PF_PSC2_GPIO     (7 << 17)
+#  define SYS_PF_PSC3_MASK     (7 << 20)
+#  define SYS_PF_PSC3_AC97     0
+#  define SYS_PF_PSC3_SPI      0
+#  define SYS_PF_PSC3_I2S      (1 << 20)
+#  define SYS_PF_PSC3_SMBUS    (3 << 20)
+#  define SYS_PF_PSC3_GPIO     (7 << 20)
+#  define SYS_PF_PSC1_S1       (1 << 1)
+#  define SYS_PF_MUST_BE_SET   ((1 << 5) | (1 << 2))
+
+/* Au1200 only */
 #ifdef CONFIG_SOC_AU1200
-#define SYS_PINFUNC_DMA                (1<<31)
-#define SYS_PINFUNC_S0A                (1<<30)
-#define SYS_PINFUNC_S1A                (1<<29)
-#define SYS_PINFUNC_LP0                (1<<28)
-#define SYS_PINFUNC_LP1                (1<<27)
-#define SYS_PINFUNC_LD16       (1<<26)
-#define SYS_PINFUNC_LD8                (1<<25)
-#define SYS_PINFUNC_LD1                (1<<24)
-#define SYS_PINFUNC_LD0                (1<<23)
-#define SYS_PINFUNC_P1A                (3<<21)
-#define SYS_PINFUNC_P1B                (1<<20)
-#define SYS_PINFUNC_FS3                (1<<19)
-#define SYS_PINFUNC_P0A                (3<<17)
-#define SYS_PINFUNC_CS         (1<<16)
-#define SYS_PINFUNC_CIM                (1<<15)
-#define SYS_PINFUNC_P1C                (1<<14)
-#define SYS_PINFUNC_U1T                (1<<12)
-#define SYS_PINFUNC_U1R                (1<<11)
-#define SYS_PINFUNC_EX1                (1<<10)
-#define SYS_PINFUNC_EX0                (1<<9)
-#define SYS_PINFUNC_U0R                (1<<8)
-#define SYS_PINFUNC_MC         (1<<7)
-#define SYS_PINFUNC_S0B                (1<<6)
-#define SYS_PINFUNC_S0C                (1<<5)
-#define SYS_PINFUNC_P0B                (1<<4)
-#define SYS_PINFUNC_U0T                (1<<3)
-#define SYS_PINFUNC_S1B                (1<<2)
+#define SYS_PINFUNC_DMA        (1 << 31)
+#define SYS_PINFUNC_S0A        (1 << 30)
+#define SYS_PINFUNC_S1A        (1 << 29)
+#define SYS_PINFUNC_LP0        (1 << 28)
+#define SYS_PINFUNC_LP1        (1 << 27)
+#define SYS_PINFUNC_LD16       (1 << 26)
+#define SYS_PINFUNC_LD8        (1 << 25)
+#define SYS_PINFUNC_LD1        (1 << 24)
+#define SYS_PINFUNC_LD0        (1 << 23)
+#define SYS_PINFUNC_P1A        (3 << 21)
+#define SYS_PINFUNC_P1B        (1 << 20)
+#define SYS_PINFUNC_FS3        (1 << 19)
+#define SYS_PINFUNC_P0A        (3 << 17)
+#define SYS_PINFUNC_CS         (1 << 16)
+#define SYS_PINFUNC_CIM        (1 << 15)
+#define SYS_PINFUNC_P1C        (1 << 14)
+#define SYS_PINFUNC_U1T        (1 << 12)
+#define SYS_PINFUNC_U1R        (1 << 11)
+#define SYS_PINFUNC_EX1        (1 << 10)
+#define SYS_PINFUNC_EX0        (1 << 9)
+#define SYS_PINFUNC_U0R        (1 << 8)
+#define SYS_PINFUNC_MC         (1 << 7)
+#define SYS_PINFUNC_S0B        (1 << 6)
+#define SYS_PINFUNC_S0C        (1 << 5)
+#define SYS_PINFUNC_P0B        (1 << 4)
+#define SYS_PINFUNC_U0T        (1 << 3)
+#define SYS_PINFUNC_S1B        (1 << 2)
 #endif
 
-#define SYS_TRIOUTRD              0xB1900100
-#define SYS_TRIOUTCLR             0xB1900100
-#define SYS_OUTPUTRD              0xB1900108
-#define SYS_OUTPUTSET             0xB1900108
-#define SYS_OUTPUTCLR             0xB190010C
-#define SYS_PINSTATERD            0xB1900110
-#define SYS_PININPUTEN            0xB1900110
+#define SYS_TRIOUTRD           0xB1900100
+#define SYS_TRIOUTCLR          0xB1900100
+#define SYS_OUTPUTRD           0xB1900108
+#define SYS_OUTPUTSET          0xB1900108
+#define SYS_OUTPUTCLR          0xB190010C
+#define SYS_PINSTATERD         0xB1900110
+#define SYS_PININPUTEN         0xB1900110
 
 /* GPIO2, Au1500, Au1550 only */
-#define GPIO2_BASE                0xB1700000
-#define GPIO2_DIR                 (GPIO2_BASE + 0)
-#define GPIO2_OUTPUT              (GPIO2_BASE + 8)
-#define GPIO2_PINSTATE            (GPIO2_BASE + 0xC)
-#define GPIO2_INTENABLE           (GPIO2_BASE + 0x10)
-#define GPIO2_ENABLE              (GPIO2_BASE + 0x14)
+#define GPIO2_BASE             0xB1700000
+#define GPIO2_DIR              (GPIO2_BASE + 0)
+#define GPIO2_OUTPUT           (GPIO2_BASE + 8)
+#define GPIO2_PINSTATE         (GPIO2_BASE + 0xC)
+#define GPIO2_INTENABLE        (GPIO2_BASE + 0x10)
+#define GPIO2_ENABLE           (GPIO2_BASE + 0x14)
 
 /* Power Management */
-#define SYS_SCRATCH0              0xB1900018
-#define SYS_SCRATCH1              0xB190001C
-#define SYS_WAKEMSK               0xB1900034
-#define SYS_ENDIAN                0xB1900038
-#define SYS_POWERCTRL             0xB190003C
-#define SYS_WAKESRC               0xB190005C
-#define SYS_SLPPWR                0xB1900078
-#define SYS_SLEEP                 0xB190007C
+#define SYS_SCRATCH0           0xB1900018
+#define SYS_SCRATCH1           0xB190001C
+#define SYS_WAKEMSK            0xB1900034
+#define SYS_ENDIAN             0xB1900038
+#define SYS_POWERCTRL          0xB190003C
+#define SYS_WAKESRC            0xB190005C
+#define SYS_SLPPWR             0xB1900078
+#define SYS_SLEEP              0xB190007C
 
 /* Clock Controller */
-#define SYS_FREQCTRL0             0xB1900020
-#  define SYS_FC_FRDIV2_BIT         22
-#  define SYS_FC_FRDIV2_MASK        (0xff << SYS_FC_FRDIV2_BIT)
-#  define SYS_FC_FE2                (1<<21)
-#  define SYS_FC_FS2                (1<<20)
-#  define SYS_FC_FRDIV1_BIT         12
-#  define SYS_FC_FRDIV1_MASK        (0xff << SYS_FC_FRDIV1_BIT)
-#  define SYS_FC_FE1                (1<<11)
-#  define SYS_FC_FS1                (1<<10)
-#  define SYS_FC_FRDIV0_BIT         2
-#  define SYS_FC_FRDIV0_MASK        (0xff << SYS_FC_FRDIV0_BIT)
-#  define SYS_FC_FE0                (1<<1)
-#  define SYS_FC_FS0                (1<<0)
-#define SYS_FREQCTRL1             0xB1900024
-#  define SYS_FC_FRDIV5_BIT         22
-#  define SYS_FC_FRDIV5_MASK        (0xff << SYS_FC_FRDIV5_BIT)
-#  define SYS_FC_FE5                (1<<21)
-#  define SYS_FC_FS5                (1<<20)
-#  define SYS_FC_FRDIV4_BIT         12
-#  define SYS_FC_FRDIV4_MASK        (0xff << SYS_FC_FRDIV4_BIT)
-#  define SYS_FC_FE4                (1<<11)
-#  define SYS_FC_FS4                (1<<10)
-#  define SYS_FC_FRDIV3_BIT         2
-#  define SYS_FC_FRDIV3_MASK        (0xff << SYS_FC_FRDIV3_BIT)
-#  define SYS_FC_FE3                (1<<1)
-#  define SYS_FC_FS3                (1<<0)
-#define SYS_CLKSRC                0xB1900028
-#  define SYS_CS_ME1_BIT            27
-#  define SYS_CS_ME1_MASK           (0x7<<SYS_CS_ME1_BIT)
-#  define SYS_CS_DE1                (1<<26)
-#  define SYS_CS_CE1                (1<<25)
-#  define SYS_CS_ME0_BIT            22
-#  define SYS_CS_ME0_MASK           (0x7<<SYS_CS_ME0_BIT)
-#  define SYS_CS_DE0                (1<<21)
-#  define SYS_CS_CE0                (1<<20)
-#  define SYS_CS_MI2_BIT            17
-#  define SYS_CS_MI2_MASK           (0x7<<SYS_CS_MI2_BIT)
-#  define SYS_CS_DI2                (1<<16)
-#  define SYS_CS_CI2                (1<<15)
+#define SYS_FREQCTRL0          0xB1900020
+#  define SYS_FC_FRDIV2_BIT    22
+#  define SYS_FC_FRDIV2_MASK   (0xff << SYS_FC_FRDIV2_BIT)
+#  define SYS_FC_FE2           (1 << 21)
+#  define SYS_FC_FS2           (1 << 20)
+#  define SYS_FC_FRDIV1_BIT    12
+#  define SYS_FC_FRDIV1_MASK   (0xff << SYS_FC_FRDIV1_BIT)
+#  define SYS_FC_FE1           (1 << 11)
+#  define SYS_FC_FS1           (1 << 10)
+#  define SYS_FC_FRDIV0_BIT    2
+#  define SYS_FC_FRDIV0_MASK   (0xff << SYS_FC_FRDIV0_BIT)
+#  define SYS_FC_FE0           (1 << 1)
+#  define SYS_FC_FS0           (1 << 0)
+#define SYS_FREQCTRL1          0xB1900024
+#  define SYS_FC_FRDIV5_BIT    22
+#  define SYS_FC_FRDIV5_MASK   (0xff << SYS_FC_FRDIV5_BIT)
+#  define SYS_FC_FE5           (1 << 21)
+#  define SYS_FC_FS5           (1 << 20)
+#  define SYS_FC_FRDIV4_BIT    12
+#  define SYS_FC_FRDIV4_MASK   (0xff << SYS_FC_FRDIV4_BIT)
+#  define SYS_FC_FE4           (1 << 11)
+#  define SYS_FC_FS4           (1 << 10)
+#  define SYS_FC_FRDIV3_BIT    2
+#  define SYS_FC_FRDIV3_MASK   (0xff << SYS_FC_FRDIV3_BIT)
+#  define SYS_FC_FE3           (1 << 1)
+#  define SYS_FC_FS3           (1 << 0)
+#define SYS_CLKSRC             0xB1900028
+#  define SYS_CS_ME1_BIT       27
+#  define SYS_CS_ME1_MASK      (0x7 << SYS_CS_ME1_BIT)
+#  define SYS_CS_DE1           (1 << 26)
+#  define SYS_CS_CE1           (1 << 25)
+#  define SYS_CS_ME0_BIT       22
+#  define SYS_CS_ME0_MASK      (0x7 << SYS_CS_ME0_BIT)
+#  define SYS_CS_DE0           (1 << 21)
+#  define SYS_CS_CE0           (1 << 20)
+#  define SYS_CS_MI2_BIT       17
+#  define SYS_CS_MI2_MASK      (0x7 << SYS_CS_MI2_BIT)
+#  define SYS_CS_DI2           (1 << 16)
+#  define SYS_CS_CI2           (1 << 15)
 #ifdef CONFIG_SOC_AU1100
-#  define SYS_CS_ML_BIT             7
-#  define SYS_CS_ML_MASK            (0x7<<SYS_CS_ML_BIT)
-#  define SYS_CS_DL                 (1<<6)
-#  define SYS_CS_CL                 (1<<5)
+#  define SYS_CS_ML_BIT        7
+#  define SYS_CS_ML_MASK       (0x7 << SYS_CS_ML_BIT)
+#  define SYS_CS_DL            (1 << 6)
+#  define SYS_CS_CL            (1 << 5)
 #else
-#  define SYS_CS_MUH_BIT            12
-#  define SYS_CS_MUH_MASK           (0x7<<SYS_CS_MUH_BIT)
-#  define SYS_CS_DUH                (1<<11)
-#  define SYS_CS_CUH                (1<<10)
-#  define SYS_CS_MUD_BIT            7
-#  define SYS_CS_MUD_MASK           (0x7<<SYS_CS_MUD_BIT)
-#  define SYS_CS_DUD                (1<<6)
-#  define SYS_CS_CUD                (1<<5)
+#  define SYS_CS_MUH_BIT       12
+#  define SYS_CS_MUH_MASK      (0x7 << SYS_CS_MUH_BIT)
+#  define SYS_CS_DUH           (1 << 11)
+#  define SYS_CS_CUH           (1 << 10)
+#  define SYS_CS_MUD_BIT       7
+#  define SYS_CS_MUD_MASK      (0x7 << SYS_CS_MUD_BIT)
+#  define SYS_CS_DUD           (1 << 6)
+#  define SYS_CS_CUD           (1 << 5)
 #endif
-#  define SYS_CS_MIR_BIT            2
-#  define SYS_CS_MIR_MASK           (0x7<<SYS_CS_MIR_BIT)
-#  define SYS_CS_DIR                (1<<1)
-#  define SYS_CS_CIR                (1<<0)
-
-#  define SYS_CS_MUX_AUX            0x1
-#  define SYS_CS_MUX_FQ0            0x2
-#  define SYS_CS_MUX_FQ1            0x3
-#  define SYS_CS_MUX_FQ2            0x4
-#  define SYS_CS_MUX_FQ3            0x5
-#  define SYS_CS_MUX_FQ4            0x6
-#  define SYS_CS_MUX_FQ5            0x7
-#define SYS_CPUPLL                0xB1900060
-#define SYS_AUXPLL                0xB1900064
+#  define SYS_CS_MIR_BIT       2
+#  define SYS_CS_MIR_MASK      (0x7 << SYS_CS_MIR_BIT)
+#  define SYS_CS_DIR           (1 << 1)
+#  define SYS_CS_CIR           (1 << 0)
+
+#  define SYS_CS_MUX_AUX       0x1
+#  define SYS_CS_MUX_FQ0       0x2
+#  define SYS_CS_MUX_FQ1       0x3
+#  define SYS_CS_MUX_FQ2       0x4
+#  define SYS_CS_MUX_FQ3       0x5
+#  define SYS_CS_MUX_FQ4       0x6
+#  define SYS_CS_MUX_FQ5       0x7
+#define SYS_CPUPLL             0xB1900060
+#define SYS_AUXPLL             0xB1900064
 
 /* AC97 Controller */
-#define AC97C_CONFIG              0xB0000000
-#  define AC97C_RECV_SLOTS_BIT  13
+#define AC97C_CONFIG           0xB0000000
+#  define AC97C_RECV_SLOTS_BIT 13
 #  define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
-#  define AC97C_XMIT_SLOTS_BIT  3
+#  define AC97C_XMIT_SLOTS_BIT 3
 #  define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT)
-#  define AC97C_SG              (1<<2)
-#  define AC97C_SYNC            (1<<1)
-#  define AC97C_RESET           (1<<0)
-#define AC97C_STATUS              0xB0000004
-#  define AC97C_XU              (1<<11)
-#  define AC97C_XO              (1<<10)
-#  define AC97C_RU              (1<<9)
-#  define AC97C_RO              (1<<8)
-#  define AC97C_READY           (1<<7)
-#  define AC97C_CP              (1<<6)
-#  define AC97C_TR              (1<<5)
-#  define AC97C_TE              (1<<4)
-#  define AC97C_TF              (1<<3)
-#  define AC97C_RR              (1<<2)
-#  define AC97C_RE              (1<<1)
-#  define AC97C_RF              (1<<0)
-#define AC97C_DATA                0xB0000008
-#define AC97C_CMD                 0xB000000C
-#  define AC97C_WD_BIT          16
-#  define AC97C_READ            (1<<7)
-#  define AC97C_INDEX_MASK      0x7f
-#define AC97C_CNTRL               0xB0000010
-#  define AC97C_RS              (1<<1)
-#  define AC97C_CE              (1<<0)
-
+#  define AC97C_SG             (1 << 2)
+#  define AC97C_SYNC           (1 << 1)
+#  define AC97C_RESET          (1 << 0)
+#define AC97C_STATUS           0xB0000004
+#  define AC97C_XU             (1 << 11)
+#  define AC97C_XO             (1 << 10)
+#  define AC97C_RU             (1 << 9)
+#  define AC97C_RO             (1 << 8)
+#  define AC97C_READY          (1 << 7)
+#  define AC97C_CP             (1 << 6)
+#  define AC97C_TR             (1 << 5)
+#  define AC97C_TE             (1 << 4)
+#  define AC97C_TF             (1 << 3)
+#  define AC97C_RR             (1 << 2)
+#  define AC97C_RE             (1 << 1)
+#  define AC97C_RF             (1 << 0)
+#define AC97C_DATA             0xB0000008
+#define AC97C_CMD              0xB000000C
+#  define AC97C_WD_BIT         16
+#  define AC97C_READ           (1 << 7)
+#  define AC97C_INDEX_MASK     0x7f
+#define AC97C_CNTRL            0xB0000010
+#  define AC97C_RS             (1 << 1)
+#  define AC97C_CE             (1 << 0)
 
 /* Secure Digital (SD) Controller */
 #define SD0_XMIT_FIFO  0xB0600000
@@ -1638,73 +1633,74 @@ enum soc_au1200_ints {
 
 #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
 /* Au1500 PCI Controller */
-#define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
-#define Au1500_PCI_CMEM           (Au1500_CFG_BASE + 0)
-#define Au1500_PCI_CFG            (Au1500_CFG_BASE + 4)
-#  define PCI_ERROR ((1<<22) | (1<<23) | (1<<24) | (1<<25) | (1<<26) | (1<<27))
-#define Au1500_PCI_B2BMASK_CCH    (Au1500_CFG_BASE + 8)
-#define Au1500_PCI_B2B0_VID       (Au1500_CFG_BASE + 0xC)
-#define Au1500_PCI_B2B1_ID        (Au1500_CFG_BASE + 0x10)
-#define Au1500_PCI_MWMASK_DEV     (Au1500_CFG_BASE + 0x14)
+#define Au1500_CFG_BASE        0xB4005000      /* virtual, KSEG1 addr */
+#define Au1500_PCI_CMEM        (Au1500_CFG_BASE + 0)
+#define Au1500_PCI_CFG         (Au1500_CFG_BASE + 4)
+#  define PCI_ERROR            ((1 << 22) | (1 << 23) | (1 << 24) | \
+                                (1 << 25) | (1 << 26) | (1 << 27))
+#define Au1500_PCI_B2BMASK_CCH (Au1500_CFG_BASE + 8)
+#define Au1500_PCI_B2B0_VID    (Au1500_CFG_BASE + 0xC)
+#define Au1500_PCI_B2B1_ID     (Au1500_CFG_BASE + 0x10)
+#define Au1500_PCI_MWMASK_DEV  (Au1500_CFG_BASE + 0x14)
 #define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
-#define Au1500_PCI_ERR_ADDR       (Au1500_CFG_BASE + 0x1C)
-#define Au1500_PCI_SPEC_INTACK    (Au1500_CFG_BASE + 0x20)
-#define Au1500_PCI_ID             (Au1500_CFG_BASE + 0x100)
-#define Au1500_PCI_STATCMD        (Au1500_CFG_BASE + 0x104)
-#define Au1500_PCI_CLASSREV       (Au1500_CFG_BASE + 0x108)
-#define Au1500_PCI_HDRTYPE        (Au1500_CFG_BASE + 0x10C)
-#define Au1500_PCI_MBAR           (Au1500_CFG_BASE + 0x110)
+#define Au1500_PCI_ERR_ADDR    (Au1500_CFG_BASE + 0x1C)
+#define Au1500_PCI_SPEC_INTACK (Au1500_CFG_BASE + 0x20)
+#define Au1500_PCI_ID          (Au1500_CFG_BASE + 0x100)
+#define Au1500_PCI_STATCMD     (Au1500_CFG_BASE + 0x104)
+#define Au1500_PCI_CLASSREV    (Au1500_CFG_BASE + 0x108)
+#define Au1500_PCI_HDRTYPE     (Au1500_CFG_BASE + 0x10C)
+#define Au1500_PCI_MBAR        (Au1500_CFG_BASE + 0x110)
 
-#define Au1500_PCI_HDR            0xB4005100 // virtual, kseg0 addr
+#define Au1500_PCI_HDR         0xB4005100      /* virtual, KSEG1 addr */
 
-/* All of our structures, like pci resource, have 32 bit members.
+/*
+ * All of our structures, like PCI resource, have 32-bit members.
  * Drivers are expected to do an ioremap on the PCI MEM resource, but it's
- * hard to store 0x4 0000 0000 in a 32 bit type.  We require a small patch
+ * hard to store 0x4 0000 0000 in a 32-bit type.  We require a small patch
  * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
- * (u32)Au1500_PCI_MEM_END and change those to the full 36 bit PCI MEM
- * addresses.  For PCI IO, it's simpler because we get to do the ioremap
+ * (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM
+ * addresses.  For PCI I/O, it's simpler because we get to do the ioremap
  * ourselves and then adjust the device's resources.
  */
-#define Au1500_EXT_CFG            0x600000000ULL
-#define Au1500_EXT_CFG_TYPE1      0x680000000ULL
-#define Au1500_PCI_IO_START       0x500000000ULL
-#define Au1500_PCI_IO_END         0x5000FFFFFULL
-#define Au1500_PCI_MEM_START      0x440000000ULL
-#define Au1500_PCI_MEM_END        0x44FFFFFFFULL
+#define Au1500_EXT_CFG         0x600000000ULL
+#define Au1500_EXT_CFG_TYPE1   0x680000000ULL
+#define Au1500_PCI_IO_START    0x500000000ULL
+#define Au1500_PCI_IO_END      0x5000FFFFFULL
+#define Au1500_PCI_MEM_START   0x440000000ULL
+#define Au1500_PCI_MEM_END     0x44FFFFFFFULL
 
 #define PCI_IO_START   0x00001000
 #define PCI_IO_END     0x000FFFFF
 #define PCI_MEM_START  0x40000000
 #define PCI_MEM_END    0x4FFFFFFF
 
-#define PCI_FIRST_DEVFN (0<<3)
-#define PCI_LAST_DEVFN  (19<<3)
+#define PCI_FIRST_DEVFN (0 << 3)
+#define PCI_LAST_DEVFN (19 << 3)
 
-#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */
-#define IOPORT_RESOURCE_END   0xffffffff
-#define IOMEM_RESOURCE_START  0x10000000
-#define IOMEM_RESOURCE_END    0xffffffff
+#define IOPORT_RESOURCE_START  0x00001000      /* skip legacy probing */
+#define IOPORT_RESOURCE_END    0xffffffff
+#define IOMEM_RESOURCE_START   0x10000000
+#define IOMEM_RESOURCE_END     0xffffffff
 
 #else /* Au1000 and Au1100 and Au1200 */
 
-/* don't allow any legacy ports probing */
-#define IOPORT_RESOURCE_START 0x10000000
-#define IOPORT_RESOURCE_END   0xffffffff
-#define IOMEM_RESOURCE_START  0x10000000
-#define IOMEM_RESOURCE_END    0xffffffff
+/* Don't allow any legacy ports probing */
+#define IOPORT_RESOURCE_START  0x10000000
+#define IOPORT_RESOURCE_END    0xffffffff
+#define IOMEM_RESOURCE_START   0x10000000
+#define IOMEM_RESOURCE_END     0xffffffff
 
-#define PCI_IO_START    0
-#define PCI_IO_END      0
-#define PCI_MEM_START   0
-#define PCI_MEM_END     0
+#define PCI_IO_START   0
+#define PCI_IO_END     0
+#define PCI_MEM_START  0
+#define PCI_MEM_END    0
 #define PCI_FIRST_DEVFN 0
-#define PCI_LAST_DEVFN  0
+#define PCI_LAST_DEVFN 0
 
 #endif
 
 #ifndef _LANGUAGE_ASSEMBLY
-typedef volatile struct
-{
+typedef volatile struct {
        /* 0x0000 */ u32 toytrim;
        /* 0x0004 */ u32 toywrite;
        /* 0x0008 */ u32 toymatch0;
@@ -1746,13 +1742,14 @@ typedef volatile struct
        /* 0x010C */ u32 outputclr;
        /* 0x0110 */ u32 pinstaterd;
 #define pininputen pinstaterd
-
 } AU1X00_SYS;
 
-static AU1X00_SYS* const sys  = (AU1X00_SYS *)SYS_BASE;
+static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
 
 #endif
-/* Processor information base on prid.
+
+/*
+ * Processor information based on PRID.
  * Copied from PowerPC.
  */
 #ifndef _LANGUAGE_ASSEMBLY
@@ -1767,9 +1764,8 @@ struct cpu_spec {
        unsigned char   cpu_pll_wo;     /* sys_cpupll reg. write-only */
 };
 
-extern struct cpu_spec         cpu_specs[];
-extern struct cpu_spec         *cur_cpu_spec[];
+extern struct cpu_spec cpu_specs[];
+extern struct cpu_spec *cur_cpu_spec[];
 #endif
 
 #endif
-
index 9f29520e8fb0a2514f79a2cf5e34f54c78d4ce7e..c333b4e1cd4472020ecebcd268db20605e887f75 100644 (file)
@@ -1,11 +1,10 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *     Defines for using and allocating dma channels on the Alchemy
- *      Au1000 mips processor.
+ *     Defines for using and allocating DMA channels on the Alchemy
+ *      Au1x00 MIPS processors.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -31,7 +30,7 @@
 #ifndef __ASM_AU1000_DMA_H
 #define __ASM_AU1000_DMA_H
 
-#include <asm/io.h>            /* need byte IO */
+#include <linux/io.h>          /* need byte IO */
 #include <linux/spinlock.h>    /* And spinlocks */
 #include <linux/delay.h>
 #include <asm/system.h>
 #define DMA_DAH_MASK           (0x0f << 20)
 #define DMA_DID_BIT            16
 #define DMA_DID_MASK           (0x0f << DMA_DID_BIT)
-#define DMA_DS                 (1<<15)
-#define DMA_BE                 (1<<13)
-#define DMA_DR                 (1<<12)
-#define DMA_TS8                        (1<<11)
+#define DMA_DS                 (1 << 15)
+#define DMA_BE                 (1 << 13)
+#define DMA_DR                 (1 << 12)
+#define DMA_TS8                (1 << 11)
 #define DMA_DW_BIT             9
 #define DMA_DW_MASK            (0x03 << DMA_DW_BIT)
 #define DMA_DW8                        (0 << DMA_DW_BIT)
 #define DMA_DW16               (1 << DMA_DW_BIT)
 #define DMA_DW32               (2 << DMA_DW_BIT)
-#define DMA_NC                 (1<<8)
-#define DMA_IE                 (1<<7)
-#define DMA_HALT               (1<<6)
-#define DMA_GO                 (1<<5)
-#define DMA_AB                 (1<<4)
-#define DMA_D1                 (1<<3)
-#define DMA_BE1                        (1<<2)
-#define DMA_D0                 (1<<1)
-#define DMA_BE0                        (1<<0)
-
-#define DMA_PERIPHERAL_ADDR       0x00000008
-#define DMA_BUFFER0_START         0x0000000C
-#define DMA_BUFFER1_START         0x00000014
-#define DMA_BUFFER0_COUNT         0x00000010
-#define DMA_BUFFER1_COUNT         0x00000018
-#define DMA_BAH_BIT 16
-#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
-#define DMA_COUNT_BIT 0
-#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
-
-/* DMA Device ID's follow */
+#define DMA_NC                 (1 << 8)
+#define DMA_IE                 (1 << 7)
+#define DMA_HALT               (1 << 6)
+#define DMA_GO                 (1 << 5)
+#define DMA_AB                 (1 << 4)
+#define DMA_D1                 (1 << 3)
+#define DMA_BE1                (1 << 2)
+#define DMA_D0                 (1 << 1)
+#define DMA_BE0                (1 << 0)
+
+#define DMA_PERIPHERAL_ADDR    0x00000008
+#define DMA_BUFFER0_START      0x0000000C
+#define DMA_BUFFER1_START      0x00000014
+#define DMA_BUFFER0_COUNT      0x00000010
+#define DMA_BUFFER1_COUNT      0x00000018
+#define DMA_BAH_BIT    16
+#define DMA_BAH_MASK   (0x0f << DMA_BAH_BIT)
+#define DMA_COUNT_BIT  0
+#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
+
+/* DMA Device IDs follow */
 enum {
        DMA_ID_UART0_TX = 0,
        DMA_ID_UART0_RX,
@@ -110,7 +109,8 @@ enum {
 };
 
 struct dma_chan {
-       int dev_id;             // this channel is allocated if >=0, free otherwise
+       int dev_id;             /* this channel is allocated if >= 0, */
+                               /* free otherwise */
        unsigned int io;
        const char *dev_str;
        int irq;
@@ -132,23 +132,23 @@ extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
 extern void dump_au1000_dma_channel(unsigned int dmanr);
 extern spinlock_t au1000_dma_spin_lock;
 
-
-static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
+static inline struct dma_chan *get_dma_chan(unsigned int dmanr)
 {
-       if (dmanr >= NUM_AU1000_DMA_CHANNELS
-           || au1000_dma_table[dmanr].dev_id < 0)
+       if (dmanr >= NUM_AU1000_DMA_CHANNELS ||
+           au1000_dma_table[dmanr].dev_id < 0)
                return NULL;
        return &au1000_dma_table[dmanr];
 }
 
-static __inline__ unsigned long claim_dma_lock(void)
+static inline unsigned long claim_dma_lock(void)
 {
        unsigned long flags;
+
        spin_lock_irqsave(&au1000_dma_spin_lock, flags);
        return flags;
 }
 
-static __inline__ void release_dma_lock(unsigned long flags)
+static inline void release_dma_lock(unsigned long flags)
 {
        spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
 }
@@ -156,48 +156,53 @@ static __inline__ void release_dma_lock(unsigned long flags)
 /*
  * Set the DMA buffer enable bits in the mode register.
  */
-static __inline__ void enable_dma_buffer0(unsigned int dmanr)
+static inline void enable_dma_buffer0(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
 }
-static __inline__ void enable_dma_buffer1(unsigned int dmanr)
+
+static inline void enable_dma_buffer1(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
 }
-static __inline__ void enable_dma_buffers(unsigned int dmanr)
+static inline void enable_dma_buffers(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
 }
 
-static __inline__ void start_dma(unsigned int dmanr)
+static inline void start_dma(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
-
        au_writel(DMA_GO, chan->io + DMA_MODE_SET);
 }
 
 #define DMA_HALT_POLL 0x5000
 
-static __inline__ void halt_dma(unsigned int dmanr)
+static inline void halt_dma(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
        int i;
+
        if (!chan)
                return;
-
        au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
-       // poll the halt bit
+
+       /* Poll the halt bit */
        for (i = 0; i < DMA_HALT_POLL; i++)
                if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
                        break;
@@ -205,55 +210,57 @@ static __inline__ void halt_dma(unsigned int dmanr)
                printk(KERN_INFO "halt_dma: HALT poll expired!\n");
 }
 
-
-static __inline__ void disable_dma(unsigned int dmanr)
+static inline void disable_dma(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
 
        halt_dma(dmanr);
 
-       // now we can disable the buffers
+       /* Now we can disable the buffers */
        au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
 }
 
-static __inline__ int dma_halted(unsigned int dmanr)
+static inline int dma_halted(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return 1;
        return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
 }
 
-/* initialize a DMA channel */
-static __inline__ void init_dma(unsigned int dmanr)
+/* Initialize a DMA channel. */
+static inline void init_dma(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
        u32 mode;
+
        if (!chan)
                return;
 
        disable_dma(dmanr);
 
-       // set device FIFO address
-       au_writel(CPHYSADDR(chan->fifo_addr),
-                 chan->io + DMA_PERIPHERAL_ADDR);
+       /* Set device FIFO address */
+       au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
 
        mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
        if (chan->irq)
                mode |= DMA_IE;
 
        au_writel(~mode, chan->io + DMA_MODE_CLEAR);
-       au_writel(mode, chan->io + DMA_MODE_SET);
+       au_writel(mode,  chan->io + DMA_MODE_SET);
 }
 
 /*
- * set mode for a specific DMA channel
+ * Set mode for a specific DMA channel
  */
-static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
+static inline void set_dma_mode(unsigned int dmanr, unsigned int mode)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        /*
@@ -266,36 +273,37 @@ static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
        chan->mode |= mode;
 }
 
-static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+static inline unsigned int get_dma_mode(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return 0;
        return chan->mode;
 }
 
-static __inline__ int get_dma_active_buffer(unsigned int dmanr)
+static inline int get_dma_active_buffer(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return -1;
        return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
 }
 
-
 /*
- * set the device FIFO address for a specific DMA channel - only
+ * Set the device FIFO address for a specific DMA channel - only
  * applicable to GPO4 and GPO5. All the other devices have fixed
  * FIFO addresses.
  */
-static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
-                                        unsigned int a)
+static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
 
-       if (chan->mode & DMA_DS)        /* second bank of device ids */
+       if (chan->mode & DMA_DS)        /* second bank of device IDs */
                return;
 
        if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
@@ -307,16 +315,19 @@ static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
 /*
  * Clear the DMA buffer done bits in the mode register.
  */
-static __inline__ void clear_dma_done0(unsigned int dmanr)
+static inline void clear_dma_done0(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
 }
-static __inline__ void clear_dma_done1(unsigned int dmanr)
+
+static inline void clear_dma_done1(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
@@ -325,16 +336,17 @@ static __inline__ void clear_dma_done1(unsigned int dmanr)
 /*
  * This does nothing - not applicable to Au1000 DMA.
  */
-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+static inline void set_dma_page(unsigned int dmanr, char pagenr)
 {
 }
 
 /*
  * Set Buffer 0 transfer address for specific DMA channel.
  */
-static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
+static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(a, chan->io + DMA_BUFFER0_START);
@@ -343,9 +355,10 @@ static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
 /*
  * Set Buffer 1 transfer address for specific DMA channel.
  */
-static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
+static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        au_writel(a, chan->io + DMA_BUFFER1_START);
@@ -355,10 +368,10 @@ static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
 /*
  * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count0(unsigned int dmanr,
-                                     unsigned int count)
+static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        count &= DMA_COUNT_MASK;
@@ -368,10 +381,10 @@ static __inline__ void set_dma_count0(unsigned int dmanr,
 /*
  * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count1(unsigned int dmanr,
-                                     unsigned int count)
+static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        count &= DMA_COUNT_MASK;
@@ -381,10 +394,10 @@ static __inline__ void set_dma_count1(unsigned int dmanr,
 /*
  * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count(unsigned int dmanr,
-                                    unsigned int count)
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return;
        count &= DMA_COUNT_MASK;
@@ -396,35 +409,36 @@ static __inline__ void set_dma_count(unsigned int dmanr,
  * Returns which buffer has its done bit set in the mode register.
  * Returns -1 if neither or both done bits set.
  */
-static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr)
+static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return 0;
-
-    return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
+       return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
 }
 
 
 /*
  * Returns the DMA channel's Buffer Done IRQ number.
  */
-static __inline__ int get_dma_done_irq(unsigned int dmanr)
+static inline int get_dma_done_irq(unsigned int dmanr)
 {
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return -1;
-
        return chan->irq;
 }
 
 /*
  * Get DMA residue count. Returns the number of _bytes_ left to transfer.
  */
-static __inline__ int get_dma_residue(unsigned int dmanr)
+static inline int get_dma_residue(unsigned int dmanr)
 {
        int curBufCntReg, count;
        struct dma_chan *chan = get_dma_chan(dmanr);
+
        if (!chan)
                return 0;
 
@@ -442,4 +456,3 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
 }
 
 #endif /* __ASM_AU1000_DMA_H */
-
index 298f92012e8eedc40ac39b05e83165e524a72020..d8c96fda5549fd7309f41cb60846d9135e0f0da5 100644 (file)
@@ -2,12 +2,12 @@
  * FILE NAME au1000_gpio.h
  *
  * BRIEF MODULE DESCRIPTION
- *     API to Alchemy Au1000 GPIO device.
+ *     API to Alchemy Au1xx0 GPIO device.
  *
  *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Steve Longerbeam <stevel@mvista.com>
+ *          Steve Longerbeam
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2001, 2008 MontaVista Software Inc.
  *
  *  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
 
 #define AU1000GPIO_IOC_MAGIC 'A'
 
-#define AU1000GPIO_IN          _IOR (AU1000GPIO_IOC_MAGIC, 0, int)
-#define AU1000GPIO_SET         _IOW (AU1000GPIO_IOC_MAGIC, 1, int)
-#define AU1000GPIO_CLEAR       _IOW (AU1000GPIO_IOC_MAGIC, 2, int)
-#define AU1000GPIO_OUT         _IOW (AU1000GPIO_IOC_MAGIC, 3, int)
-#define AU1000GPIO_TRISTATE    _IOW (AU1000GPIO_IOC_MAGIC, 4, int)
-#define AU1000GPIO_AVAIL_MASK  _IOR (AU1000GPIO_IOC_MAGIC, 5, int)
+#define AU1000GPIO_IN          _IOR(AU1000GPIO_IOC_MAGIC, 0, int)
+#define AU1000GPIO_SET         _IOW(AU1000GPIO_IOC_MAGIC, 1, int)
+#define AU1000GPIO_CLEAR       _IOW(AU1000GPIO_IOC_MAGIC, 2, int)
+#define AU1000GPIO_OUT         _IOW(AU1000GPIO_IOC_MAGIC, 3, int)
+#define AU1000GPIO_TRISTATE    _IOW(AU1000GPIO_IOC_MAGIC, 4, int)
+#define AU1000GPIO_AVAIL_MASK  _IOR(AU1000GPIO_IOC_MAGIC, 5, int)
 
 #ifdef __KERNEL__
 extern u32 get_au1000_avail_gpio_mask(void);
index c2f0466523ec6f8bafbcadb2a676aa5bccf79de3..40e6c489833a06ae628460dfbe11326d2541cc6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * au1550_spi.h - au1550 psc spi controller driver - platform data struct
+ * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure
  */
 
 #ifndef _AU1550_SPI_H_
index 947135941033ec94ac2649579551063340e99055..1b3655090ed3adb6c5074166bb4a3f9d191ed112 100644 (file)
 #ifndef _AU1XXX_H_
 #define _AU1XXX_H_
 
-
 #include <asm/mach-au1x00/au1000.h>
 
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
+    defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
 #include <asm/mach-db1x00/db1x00.h>
 
 #elif defined(CONFIG_MIPS_PB1550)
index 93d507cea518351302ac4304eea3da7109193c3c..ad17d7ce516abcad29e894f4cdd8172ad8892dd0 100644 (file)
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* Specifics for the Au1xxx Descriptor-Based DMA Controllers, first
- * seen in the AU1550 part.
+/*
+ * Specifics for the Au1xxx Descriptor-Based DMA Controller,
+ * first seen in the AU1550 part.
  */
 #ifndef _AU1000_DBDMA_H_
 #define _AU1000_DBDMA_H_
 
-
 #ifndef _LANGUAGE_ASSEMBLY
 
-/* The DMA base addresses.
- * The Channels are every 256 bytes (0x0100) from the channel 0 base.
+/*
+ * The DMA base addresses.
+ * The channels are every 256 bytes (0x0100) from the channel 0 base.
  * Interrupt status/enable is bits 15:0 for channels 15 to zero.
  */
 #define DDMA_GLOBAL_BASE       0xb4003000
@@ -51,16 +52,14 @@ typedef volatile struct dbdma_global {
        u32     ddma_inten;
 } dbdma_global_t;
 
-/* General Configuration.
-*/
+/* General Configuration. */
 #define DDMA_CONFIG_AF         (1 << 2)
 #define DDMA_CONFIG_AH         (1 << 1)
 #define DDMA_CONFIG_AL         (1 << 0)
 
 #define DDMA_THROTTLE_EN       (1 << 31)
 
-/* The structure of a DMA Channel.
-*/
+/* The structure of a DMA Channel. */
 typedef volatile struct au1xxx_dma_channel {
        u32     ddma_cfg;       /* See below */
        u32     ddma_desptr;    /* 32-byte aligned pointer to descriptor */
@@ -69,8 +68,7 @@ typedef volatile struct au1xxx_dma_channel {
        u32     ddma_irq;       /* If bit 0 set, interrupt pending */
        u32     ddma_stat;      /* See below */
        u32     ddma_bytecnt;   /* Byte count, valid only when chan idle */
-       /* Remainder, up to the 256 byte boundary, is reserved.
-       */
+       /* Remainder, up to the 256 byte boundary, is reserved. */
 } au1x_dma_chan_t;
 
 #define DDMA_CFG_SED   (1 << 9)        /* source DMA level/edge detect */
@@ -84,7 +82,8 @@ typedef volatile struct au1xxx_dma_channel {
 #define DDMA_CFG_DBE   (1 << 1)        /* Destination big endian */
 #define DDMA_CFG_EN    (1 << 0)        /* Channel enable */
 
-/* Always set when descriptor processing done, regardless of
+/*
+ * Always set when descriptor processing done, regardless of
  * interrupt enable state.  Reflected in global intstat, don't
  * clear this until global intstat is read/used.
  */
@@ -94,7 +93,8 @@ typedef volatile struct au1xxx_dma_channel {
 #define DDMA_STAT_V    (1 << 1)        /* Descriptor valid */
 #define DDMA_STAT_H    (1 << 0)        /* Channel Halted */
 
-/* "Standard" DDMA Descriptor.
+/*
+ * "Standard" DDMA Descriptor.
  * Must be 32-byte aligned.
  */
 typedef volatile struct au1xxx_ddma_desc {
@@ -106,8 +106,9 @@ typedef volatile struct au1xxx_ddma_desc {
        u32     dscr_dest1;             /* See below */
        u32     dscr_stat;              /* completion status */
        u32     dscr_nxtptr;            /* Next descriptor pointer (mostly) */
-       /* First 32bytes are HW specific!!!
-          Lets have some SW data following.. make sure its 32bytes
+       /*
+        * First 32 bytes are HW specific!!!
+        * Lets have some SW data following -- make sure it's 32 bytes.
         */
        u32     sw_status;
        u32     sw_context;
@@ -130,10 +131,9 @@ typedef volatile struct au1xxx_ddma_desc {
 #define DSCR_CMD0_CV           (0x1 << 2)      /* Clear Valid when done */
 #define DSCR_CMD0_ST_MASK      (0x3 << 0)      /* Status instruction */
 
-#define SW_STATUS_INUSE                (1<<0)
+#define SW_STATUS_INUSE        (1 << 0)
 
-/* Command 0 device IDs.
-*/
+/* Command 0 device IDs. */
 #ifdef CONFIG_SOC_AU1550
 #define DSCR_CMD0_UART0_TX     0
 #define DSCR_CMD0_UART0_RX     1
@@ -198,16 +198,15 @@ typedef volatile struct au1xxx_ddma_desc {
 #define DSCR_CMD0_THROTTLE     30
 #define DSCR_CMD0_ALWAYS       31
 #define DSCR_NDEV_IDS          32
-/* THis macro is used to find/create custom device types */
-#define DSCR_DEV2CUSTOM_ID(x, d)       (((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
-#define DSCR_CUSTOM2DEV_ID(x)  ((x)&0xFF)
-
+/* This macro is used to find/create custom device types */
+#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \
+                                 ((d) & 0xFF))
+#define DSCR_CUSTOM2DEV_ID(x)  ((x) & 0xFF)
 
 #define DSCR_CMD0_SID(x)       (((x) & 0x1f) << 25)
 #define DSCR_CMD0_DID(x)       (((x) & 0x1f) << 20)
 
-/* Source/Destination transfer width.
-*/
+/* Source/Destination transfer width. */
 #define DSCR_CMD0_BYTE         0
 #define DSCR_CMD0_HALFWORD     1
 #define DSCR_CMD0_WORD         2
@@ -215,16 +214,14 @@ typedef volatile struct au1xxx_ddma_desc {
 #define DSCR_CMD0_SW(x)                (((x) & 0x3) << 18)
 #define DSCR_CMD0_DW(x)                (((x) & 0x3) << 16)
 
-/* DDMA Descriptor Type.
-*/
+/* DDMA Descriptor Type. */
 #define DSCR_CMD0_STANDARD     0
 #define DSCR_CMD0_LITERAL      1
 #define DSCR_CMD0_CMP_BRANCH   2
 
 #define DSCR_CMD0_DT(x)                (((x) & 0x3) << 13)
 
-/* Status Instruction.
-*/
+/* Status Instruction. */
 #define DSCR_CMD0_ST_NOCHANGE  0       /* Don't change */
 #define DSCR_CMD0_ST_CURRENT   1       /* Write current status */
 #define DSCR_CMD0_ST_CMD0      2       /* Write cmd0 with V cleared */
@@ -232,23 +229,20 @@ typedef volatile struct au1xxx_ddma_desc {
 
 #define DSCR_CMD0_ST(x)                (((x) & 0x3) << 0)
 
-/* Descriptor Command 1
-*/
+/* Descriptor Command 1. */
 #define DSCR_CMD1_SUPTR_MASK   (0xf << 28)     /* upper 4 bits of src addr */
 #define DSCR_CMD1_DUPTR_MASK   (0xf << 24)     /* upper 4 bits of dest addr */
 #define DSCR_CMD1_FL_MASK      (0x3 << 22)     /* Flag bits */
 #define DSCR_CMD1_BC_MASK      (0x3fffff)      /* Byte count */
 
-/* Flag description.
-*/
+/* Flag description. */
 #define DSCR_CMD1_FL_MEM_STRIDE0       0
 #define DSCR_CMD1_FL_MEM_STRIDE1       1
 #define DSCR_CMD1_FL_MEM_STRIDE2       2
 
 #define DSCR_CMD1_FL(x)                (((x) & 0x3) << 22)
 
-/* Source1, 1-dimensional stride.
-*/
+/* Source1, 1-dimensional stride. */
 #define DSCR_SRC1_STS_MASK     (3 << 30)       /* Src xfer size */
 #define DSCR_SRC1_SAM_MASK     (3 << 28)       /* Src xfer movement */
 #define DSCR_SRC1_SB_MASK      (0x3fff << 14)  /* Block size */
@@ -256,8 +250,7 @@ typedef volatile struct au1xxx_ddma_desc {
 #define DSCR_SRC1_SS_MASK      (0x3fff << 0)   /* Stride */
 #define DSCR_SRC1_SS(x)                (((x) & 0x3fff) << 0)
 
-/* Dest1, 1-dimensional stride.
-*/
+/* Dest1, 1-dimensional stride. */
 #define DSCR_DEST1_DTS_MASK    (3 << 30)       /* Dest xfer size */
 #define DSCR_DEST1_DAM_MASK    (3 << 28)       /* Dest xfer movement */
 #define DSCR_DEST1_DB_MASK     (0x3fff << 14)  /* Block size */
@@ -279,29 +272,27 @@ typedef volatile struct au1xxx_ddma_desc {
 #define DSCR_SRC1_SAM(x)       (((x) & 3) << 28)
 #define DSCR_DEST1_DAM(x)      (((x) & 3) << 28)
 
-/* The next descriptor pointer.
-*/
+/* The next descriptor pointer. */
 #define DSCR_NXTPTR_MASK       (0x07ffffff)
 #define DSCR_NXTPTR(x)         ((x) >> 5)
 #define DSCR_GET_NXTPTR(x)     ((x) << 5)
 #define DSCR_NXTPTR_MS         (1 << 27)
 
-/* The number of DBDMA channels.
-*/
+/* The number of DBDMA channels. */
 #define NUM_DBDMA_CHANS        16
 
 /*
- * Ddma API definitions
+ * DDMA API definitions
  * FIXME: may not fit to this header file
  */
 typedef struct dbdma_device_table {
-       u32             dev_id;
-       u32             dev_flags;
-       u32             dev_tsize;
-       u32             dev_devwidth;
-       u32             dev_physaddr;           /* If FIFO */
-       u32             dev_intlevel;
-       u32             dev_intpolarity;
+       u32     dev_id;
+       u32     dev_flags;
+       u32     dev_tsize;
+       u32     dev_devwidth;
+       u32     dev_physaddr;           /* If FIFO */
+       u32     dev_intlevel;
+       u32     dev_intpolarity;
 } dbdev_tab_t;
 
 
@@ -316,44 +307,41 @@ typedef struct dbdma_chan_config {
        au1x_ddma_desc_t        *chan_desc_base;
        au1x_ddma_desc_t        *get_ptr, *put_ptr, *cur_ptr;
        void                    *chan_callparam;
-       void (*chan_callback)(int, void *);
+       void                    (*chan_callback)(int, void *);
 } chan_tab_t;
 
 #define DEV_FLAGS_INUSE                (1 << 0)
 #define DEV_FLAGS_ANYUSE       (1 << 1)
 #define DEV_FLAGS_OUT          (1 << 2)
 #define DEV_FLAGS_IN           (1 << 3)
-#define DEV_FLAGS_BURSTABLE (1 << 4)
+#define DEV_FLAGS_BURSTABLE    (1 << 4)
 #define DEV_FLAGS_SYNC         (1 << 5)
-/* end Ddma API definitions */
+/* end DDMA API definitions */
 
-/* External functions for drivers to use.
-*/
-/* Use this to allocate a dbdma channel.  The device ids are one of the
- * DSCR_CMD0 devices IDs, which is usually redefined to a more
- * meaningful name.  The 'callback' is called during dma completion
+/*
+ * External functions for drivers to use.
+ * Use this to allocate a DBDMA channel.  The device IDs are one of
+ * the DSCR_CMD0 devices IDs, which is usually redefined to a more
+ * meaningful name.  The 'callback' is called during DMA completion
  * interrupt.
  */
 extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
-       void (*callback)(int, void *), void *callparam);
+                                  void (*callback)(int, void *),
+                                  void *callparam);
 
 #define DBDMA_MEM_CHAN DSCR_CMD0_ALWAYS
 
-/* Set the device width of a in/out fifo.
-*/
+/* Set the device width of an in/out FIFO. */
 u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
 
-/* Allocate a ring of descriptors for dbdma.
-*/
+/* Allocate a ring of descriptors for DBDMA. */
 u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
 
-/* Put buffers on source/destination descriptors.
-*/
+/* Put buffers on source/destination descriptors. */
 u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
 u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
 
-/* Get a buffer from the destination descriptor.
-*/
+/* Get a buffer from the destination descriptor. */
 u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
 
 void au1xxx_dbdma_stop(u32 chanid);
@@ -364,29 +352,34 @@ u32 au1xxx_get_dma_residue(u32 chanid);
 void au1xxx_dbdma_chan_free(u32 chanid);
 void au1xxx_dbdma_dump(u32 chanid);
 
-u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
 
-u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
 
 /*
-       Some compatibilty macros --
-               Needed to make changes to API without breaking existing drivers
-*/
-#define        au1xxx_dbdma_put_source(chanid, buf, nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define        au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
-#define        put_source_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
-
-
-#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define        au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
-#define        put_dest_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
+ * Some compatibilty macros -- needed to make changes to API
+ * without breaking existing drivers.
+ */
+#define au1xxx_dbdma_put_source(chanid, buf, nbytes)                   \
+       _au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)      \
+       _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+#define put_source_flags(chanid, buf, nbytes, flags)                   \
+       au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
+
+#define au1xxx_dbdma_put_dest(chanid, buf, nbytes)                     \
+       _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)        \
+       _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+#define put_dest_flags(chanid, buf, nbytes, flags)                     \
+       au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
 
 /*
  *     Flags for the put_source/put_dest functions.
  */
-#define DDMA_FLAGS_IE  (1<<0)
-#define DDMA_FLAGS_NOIE (1<<1)
+#define DDMA_FLAGS_IE  (1 << 0)
+#define DDMA_FLAGS_NOIE (1 << 1)
 
 #endif /* _LANGUAGE_ASSEMBLY */
 #endif /* _AU1000_DBDMA_H_ */
index b493a5e46c639598f9066f0591a6d983b0073c57..60638b8969ba47e86ceab2f8b7a5bff730cec503 100644 (file)
  */
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        #define DMA_WAIT_TIMEOUT        100
-        #define NUM_DESCRIPTORS         PRD_ENTRIES
+#define DMA_WAIT_TIMEOUT       100
+#define NUM_DESCRIPTORS        PRD_ENTRIES
 #else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
-        #define NUM_DESCRIPTORS         2
+#define NUM_DESCRIPTORS        2
 #endif
 
 #ifndef AU1XXX_ATA_RQSIZE
-        #define AU1XXX_ATA_RQSIZE       128
+#define AU1XXX_ATA_RQSIZE      128
 #endif
 
 /* Disable Burstable-Support for DBDMA */
 #ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
-        #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON  0
+#define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0
 #endif
 
 #ifdef CONFIG_PM
 /*
-* This will enable the device to be powered up when write() or read()
-* is called. If this is not defined, the driver will return -EBUSY.
-*/
+ * This will enable the device to be powered up when write() or read()
+ * is called. If this is not defined, the driver will return -EBUSY.
+ */
 #define WAKE_ON_ACCESS 1
 
-typedef struct
-{
-        spinlock_t         lock;       /* Used to block on state transitions */
-        au1xxx_power_dev_t *dev;       /* Power Managers device structure */
-        unsigned          stopped;    /* USed to signaling device is stopped */
+typedef struct {
+       spinlock_t              lock;   /* Used to block on state transitions */
+       au1xxx_power_dev_t      *dev;   /* Power Managers device structure */
+       unsigned                stopped; /* Used to signal device is stopped */
 } pm_state;
 #endif
 
-
-typedef struct
-{
-        u32                     tx_dev_id, rx_dev_id, target_dev_id;
-        u32                     tx_chan, rx_chan;
-        void                    *tx_desc_head, *rx_desc_head;
-        ide_hwif_t              *hwif;
+typedef struct {
+       u32                     tx_dev_id, rx_dev_id, target_dev_id;
+       u32                     tx_chan, rx_chan;
+       void                    *tx_desc_head, *rx_desc_head;
+       ide_hwif_t              *hwif;
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        ide_drive_t             *drive;
-        struct dbdma_cmd        *dma_table_cpu;
-        dma_addr_t              dma_table_dma;
+       ide_drive_t             *drive;
+       struct dbdma_cmd        *dma_table_cpu;
+       dma_addr_t              dma_table_dma;
 #endif
        int                     irq;
        u32                     regbase;
 #ifdef CONFIG_PM
-        pm_state                pm;
+       pm_state                pm;
 #endif
 } _auide_hwif;
 
-/*******************************************************************************
-* PIO Mode timing calculation :                                                *
-*                                                                              *
-* Static Bus Spec   ATA Spec                                                   *
-*      Tcsoe      =   t1                                                       *
-*      Toecs      =   t9                                                       *
-*      Twcs       =   t9                                                       *
-*      Tcsh       =   t2i | t2                                                 *
-*      Tcsoff     =   t2i | t2                                                 *
-*      Twp        =   t2                                                       *
-*      Tcsw       =   t1                                                       *
-*      Tpm        =   0                                                        *
-*      Ta         =   t1+t2                                                    *
-*******************************************************************************/
+/******************************************************************************/
+/* PIO Mode timing calculation :                                             */
+/*                                                                           */
+/* Static Bus Spec   ATA Spec                                                */
+/*     Tcsoe      =    t1                                                    */
+/*     Toecs      =    t9                                                    */
+/*     Twcs       =    t9                                                    */
+/*     Tcsh       =    t2i | t2                                              */
+/*     Tcsoff     =    t2i | t2                                              */
+/*     Twp        =    t2                                                    */
+/*     Tcsw       =    t1                                                    */
+/*     Tpm        =    0                                                     */
+/*     Ta         =    t1+t2                                                 */
+/******************************************************************************/
 
-#define TCSOE_MASK            (0x07<<29)
-#define TOECS_MASK            (0x07<<26)
-#define TWCS_MASK             (0x07<<28)
-#define TCSH_MASK             (0x0F<<24)
-#define TCSOFF_MASK           (0x07<<20)
-#define TWP_MASK              (0x3F<<14)
-#define TCSW_MASK             (0x0F<<10)
-#define TPM_MASK              (0x0F<<6)
-#define TA_MASK               (0x3F<<0)
-#define TS_MASK               (1<<8)
+#define TCSOE_MASK             (0x07 << 29)
+#define TOECS_MASK             (0x07 << 26)
+#define TWCS_MASK              (0x07 << 28)
+#define TCSH_MASK              (0x0F << 24)
+#define TCSOFF_MASK            (0x07 << 20)
+#define TWP_MASK               (0x3F << 14)
+#define TCSW_MASK              (0x0F << 10)
+#define TPM_MASK               (0x0F << 6)
+#define TA_MASK                (0x3F << 0)
+#define TS_MASK                (1 << 8)
 
 /* Timing parameters PIO mode 0 */
-#define SBC_IDE_PIO0_TCSOE    (0x04<<29)
-#define SBC_IDE_PIO0_TOECS    (0x01<<26)
-#define SBC_IDE_PIO0_TWCS     (0x02<<28)
-#define SBC_IDE_PIO0_TCSH     (0x08<<24)
-#define SBC_IDE_PIO0_TCSOFF   (0x07<<20)
-#define SBC_IDE_PIO0_TWP      (0x10<<14)
-#define SBC_IDE_PIO0_TCSW     (0x04<<10)
-#define SBC_IDE_PIO0_TPM      (0x0<<6)
-#define SBC_IDE_PIO0_TA       (0x15<<0)
+#define SBC_IDE_PIO0_TCSOE     (0x04 << 29)
+#define SBC_IDE_PIO0_TOECS     (0x01 << 26)
+#define SBC_IDE_PIO0_TWCS      (0x02 << 28)
+#define SBC_IDE_PIO0_TCSH      (0x08 << 24)
+#define SBC_IDE_PIO0_TCSOFF    (0x07 << 20)
+#define SBC_IDE_PIO0_TWP       (0x10 << 14)
+#define SBC_IDE_PIO0_TCSW      (0x04 << 10)
+#define SBC_IDE_PIO0_TPM       (0x00 << 6)
+#define SBC_IDE_PIO0_TA        (0x15 << 0)
 /* Timing parameters PIO mode 1 */
-#define SBC_IDE_PIO1_TCSOE    (0x03<<29)
-#define SBC_IDE_PIO1_TOECS    (0x01<<26)
-#define SBC_IDE_PIO1_TWCS     (0x01<<28)
-#define SBC_IDE_PIO1_TCSH     (0x06<<24)
-#define SBC_IDE_PIO1_TCSOFF   (0x06<<20)
-#define SBC_IDE_PIO1_TWP      (0x08<<14)
-#define SBC_IDE_PIO1_TCSW     (0x03<<10)
-#define SBC_IDE_PIO1_TPM      (0x00<<6)
-#define SBC_IDE_PIO1_TA       (0x0B<<0)
+#define SBC_IDE_PIO1_TCSOE     (0x03 << 29)
+#define SBC_IDE_PIO1_TOECS     (0x01 << 26)
+#define SBC_IDE_PIO1_TWCS      (0x01 << 28)
+#define SBC_IDE_PIO1_TCSH      (0x06 << 24)
+#define SBC_IDE_PIO1_TCSOFF    (0x06 << 20)
+#define SBC_IDE_PIO1_TWP       (0x08 << 14)
+#define SBC_IDE_PIO1_TCSW      (0x03 << 10)
+#define SBC_IDE_PIO1_TPM       (0x00 << 6)
+#define SBC_IDE_PIO1_TA        (0x0B << 0)
 /* Timing parameters PIO mode 2 */
-#define SBC_IDE_PIO2_TCSOE    (0x05<<29)
-#define SBC_IDE_PIO2_TOECS    (0x01<<26)
-#define SBC_IDE_PIO2_TWCS     (0x01<<28)
-#define SBC_IDE_PIO2_TCSH     (0x07<<24)
-#define SBC_IDE_PIO2_TCSOFF   (0x07<<20)
-#define SBC_IDE_PIO2_TWP      (0x1F<<14)
-#define SBC_IDE_PIO2_TCSW     (0x05<<10)
-#define SBC_IDE_PIO2_TPM      (0x00<<6)
-#define SBC_IDE_PIO2_TA       (0x22<<0)
+#define SBC_IDE_PIO2_TCSOE     (0x05 << 29)
+#define SBC_IDE_PIO2_TOECS     (0x01 << 26)
+#define SBC_IDE_PIO2_TWCS      (0x01 << 28)
+#define SBC_IDE_PIO2_TCSH      (0x07 << 24)
+#define SBC_IDE_PIO2_TCSOFF    (0x07 << 20)
+#define SBC_IDE_PIO2_TWP       (0x1F << 14)
+#define SBC_IDE_PIO2_TCSW      (0x05 << 10)
+#define SBC_IDE_PIO2_TPM       (0x00 << 6)
+#define SBC_IDE_PIO2_TA        (0x22 << 0)
 /* Timing parameters PIO mode 3 */
-#define SBC_IDE_PIO3_TCSOE    (0x05<<29)
-#define SBC_IDE_PIO3_TOECS    (0x01<<26)
-#define SBC_IDE_PIO3_TWCS     (0x01<<28)
-#define SBC_IDE_PIO3_TCSH     (0x0D<<24)
-#define SBC_IDE_PIO3_TCSOFF   (0x0D<<20)
-#define SBC_IDE_PIO3_TWP      (0x15<<14)
-#define SBC_IDE_PIO3_TCSW     (0x05<<10)
-#define SBC_IDE_PIO3_TPM      (0x00<<6)
-#define SBC_IDE_PIO3_TA       (0x1A<<0)
+#define SBC_IDE_PIO3_TCSOE     (0x05 << 29)
+#define SBC_IDE_PIO3_TOECS     (0x01 << 26)
+#define SBC_IDE_PIO3_TWCS      (0x01 << 28)
+#define SBC_IDE_PIO3_TCSH      (0x0D << 24)
+#define SBC_IDE_PIO3_TCSOFF    (0x0D << 20)
+#define SBC_IDE_PIO3_TWP       (0x15 << 14)
+#define SBC_IDE_PIO3_TCSW      (0x05 << 10)
+#define SBC_IDE_PIO3_TPM       (0x00 << 6)
+#define SBC_IDE_PIO3_TA        (0x1A << 0)
 /* Timing parameters PIO mode 4 */
-#define SBC_IDE_PIO4_TCSOE    (0x04<<29)
-#define SBC_IDE_PIO4_TOECS    (0x01<<26)
-#define SBC_IDE_PIO4_TWCS     (0x01<<28)
-#define SBC_IDE_PIO4_TCSH     (0x04<<24)
-#define SBC_IDE_PIO4_TCSOFF   (0x04<<20)
-#define SBC_IDE_PIO4_TWP      (0x0D<<14)
-#define SBC_IDE_PIO4_TCSW     (0x03<<10)
-#define SBC_IDE_PIO4_TPM      (0x00<<6)
-#define SBC_IDE_PIO4_TA       (0x12<<0)
+#define SBC_IDE_PIO4_TCSOE     (0x04 << 29)
+#define SBC_IDE_PIO4_TOECS     (0x01 << 26)
+#define SBC_IDE_PIO4_TWCS      (0x01 << 28)
+#define SBC_IDE_PIO4_TCSH      (0x04 << 24)
+#define SBC_IDE_PIO4_TCSOFF    (0x04 << 20)
+#define SBC_IDE_PIO4_TWP       (0x0D << 14)
+#define SBC_IDE_PIO4_TCSW      (0x03 << 10)
+#define SBC_IDE_PIO4_TPM       (0x00 << 6)
+#define SBC_IDE_PIO4_TA        (0x12 << 0)
 /* Timing parameters MDMA mode 0 */
-#define SBC_IDE_MDMA0_TCSOE   (0x03<<29)
-#define SBC_IDE_MDMA0_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA0_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA0_TCSH    (0x07<<24)
-#define SBC_IDE_MDMA0_TCSOFF  (0x07<<20)
-#define SBC_IDE_MDMA0_TWP     (0x0C<<14)
-#define SBC_IDE_MDMA0_TCSW    (0x03<<10)
-#define SBC_IDE_MDMA0_TPM     (0x00<<6)
-#define SBC_IDE_MDMA0_TA      (0x0F<<0)
+#define SBC_IDE_MDMA0_TCSOE    (0x03 << 29)
+#define SBC_IDE_MDMA0_TOECS    (0x01 << 26)
+#define SBC_IDE_MDMA0_TWCS     (0x01 << 28)
+#define SBC_IDE_MDMA0_TCSH     (0x07 << 24)
+#define SBC_IDE_MDMA0_TCSOFF   (0x07 << 20)
+#define SBC_IDE_MDMA0_TWP      (0x0C << 14)
+#define SBC_IDE_MDMA0_TCSW     (0x03 << 10)
+#define SBC_IDE_MDMA0_TPM      (0x00 << 6)
+#define SBC_IDE_MDMA0_TA       (0x0F << 0)
 /* Timing parameters MDMA mode 1 */
-#define SBC_IDE_MDMA1_TCSOE   (0x05<<29)
-#define SBC_IDE_MDMA1_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA1_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA1_TCSH    (0x05<<24)
-#define SBC_IDE_MDMA1_TCSOFF  (0x05<<20)
-#define SBC_IDE_MDMA1_TWP     (0x0F<<14)
-#define SBC_IDE_MDMA1_TCSW    (0x05<<10)
-#define SBC_IDE_MDMA1_TPM     (0x00<<6)
-#define SBC_IDE_MDMA1_TA      (0x15<<0)
+#define SBC_IDE_MDMA1_TCSOE    (0x05 << 29)
+#define SBC_IDE_MDMA1_TOECS    (0x01 << 26)
+#define SBC_IDE_MDMA1_TWCS     (0x01 << 28)
+#define SBC_IDE_MDMA1_TCSH     (0x05 << 24)
+#define SBC_IDE_MDMA1_TCSOFF   (0x05 << 20)
+#define SBC_IDE_MDMA1_TWP      (0x0F << 14)
+#define SBC_IDE_MDMA1_TCSW     (0x05 << 10)
+#define SBC_IDE_MDMA1_TPM      (0x00 << 6)
+#define SBC_IDE_MDMA1_TA       (0x15 << 0)
 /* Timing parameters MDMA mode 2 */
-#define SBC_IDE_MDMA2_TCSOE   (0x04<<29)
-#define SBC_IDE_MDMA2_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA2_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA2_TCSH    (0x04<<24)
-#define SBC_IDE_MDMA2_TCSOFF  (0x04<<20)
-#define SBC_IDE_MDMA2_TWP     (0x0D<<14)
-#define SBC_IDE_MDMA2_TCSW    (0x04<<10)
-#define SBC_IDE_MDMA2_TPM     (0x00<<6)
-#define SBC_IDE_MDMA2_TA      (0x12<<0)
+#define SBC_IDE_MDMA2_TCSOE    (0x04 << 29)
+#define SBC_IDE_MDMA2_TOECS    (0x01 << 26)
+#define SBC_IDE_MDMA2_TWCS     (0x01 << 28)
+#define SBC_IDE_MDMA2_TCSH     (0x04 << 24)
+#define SBC_IDE_MDMA2_TCSOFF   (0x04 << 20)
+#define SBC_IDE_MDMA2_TWP      (0x0D << 14)
+#define SBC_IDE_MDMA2_TCSW     (0x04 << 10)
+#define SBC_IDE_MDMA2_TPM      (0x00 << 6)
+#define SBC_IDE_MDMA2_TA       (0x12 << 0)
 
 #define SBC_IDE_TIMING(mode) \
-         SBC_IDE_##mode##_TWCS | \
-         SBC_IDE_##mode##_TCSH | \
-         SBC_IDE_##mode##_TCSOFF | \
-         SBC_IDE_##mode##_TWP | \
-         SBC_IDE_##mode##_TCSW | \
-         SBC_IDE_##mode##_TPM | \
-         SBC_IDE_##mode##_TA
+       (SBC_IDE_##mode##_TWCS | \
+        SBC_IDE_##mode##_TCSH | \
+        SBC_IDE_##mode##_TCSOFF | \
+        SBC_IDE_##mode##_TWP | \
+        SBC_IDE_##mode##_TCSW | \
+        SBC_IDE_##mode##_TPM | \
+        SBC_IDE_##mode##_TA)
index 1bd4e27caf6b70ee4ecbc1b2df29846e124e9969..dae4eca2417e847fd47a3eb8f2009814f8c07a77 100644 (file)
@@ -33,7 +33,6 @@
 #ifndef _AU1000_PSC_H_
 #define _AU1000_PSC_H_
 
-
 /* The PSC base addresses.  */
 #ifdef CONFIG_SOC_AU1550
 #define PSC0_BASE_ADDR         0xb1a00000
@@ -47,8 +46,8 @@
 #define PSC1_BASE_ADDR         0xb1b00000
 #endif
 
-/* The PSC select and control registers are common to
- * all protocols.
+/*
+ * The PSC select and control registers are common to all protocols.
  */
 #define PSC_SEL_OFFSET         0x00000000
 #define PSC_CTRL_OFFSET                0x00000004
 #define PSC_SEL_CLK_SERCLK     (2 << 4)
 
 #define PSC_SEL_PS_MASK                0x00000007
-#define PSC_SEL_PS_DISABLED    (0)
-#define PSC_SEL_PS_SPIMODE     (2)
-#define PSC_SEL_PS_I2SMODE     (3)
-#define PSC_SEL_PS_AC97MODE    (4)
-#define PSC_SEL_PS_SMBUSMODE   (5)
-
-#define PSC_CTRL_DISABLE       (0)
-#define PSC_CTRL_SUSPEND       (2)
-#define PSC_CTRL_ENABLE                (3)
-
-/* AC97 Registers.
-*/
+#define PSC_SEL_PS_DISABLED    0
+#define PSC_SEL_PS_SPIMODE     2
+#define PSC_SEL_PS_I2SMODE     3
+#define PSC_SEL_PS_AC97MODE    4
+#define PSC_SEL_PS_SMBUSMODE   5
+
+#define PSC_CTRL_DISABLE       0
+#define PSC_CTRL_SUSPEND       2
+#define PSC_CTRL_ENABLE        3
+
+/* AC97 Registers. */
 #define PSC_AC97CFG_OFFSET     0x00000008
 #define PSC_AC97MSK_OFFSET     0x0000000c
 #define PSC_AC97PCR_OFFSET     0x00000010
@@ -95,8 +93,7 @@
 #define PSC_AC97GPO            (AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
 #define PSC_AC97GPI            (AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
 
-/* AC97 Config Register.
-*/
+/* AC97 Config Register. */
 #define PSC_AC97CFG_RT_MASK    (3 << 30)
 #define PSC_AC97CFG_RT_FIFO1   (0 << 30)
 #define PSC_AC97CFG_RT_FIFO2   (1 << 30)
 #define PSC_AC97CFG_RXSLOT_MASK        (0x3ff << 1)
 #define PSC_AC97CFG_GE_ENABLE  (1)
 
-/* Enable slots 3-12.
-*/
+/* Enable slots 3-12. */
 #define PSC_AC97CFG_TXSLOT_ENA(x)      (1 << (((x) - 3) + 11))
 #define PSC_AC97CFG_RXSLOT_ENA(x)      (1 << (((x) - 3) + 1))
 
-/* The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
+/*
+ * The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
  * The only sensible numbers are 7, 9, or possibly 11.  Nah, just do the
  * arithmetic in the macro.
  */
-#define PSC_AC97CFG_SET_LEN(x) (((((x)-2)/2) & 0xf) << 21)
+#define PSC_AC97CFG_SET_LEN(x) (((((x) - 2) / 2) & 0xf) << 21)
 #define PSC_AC97CFG_GET_LEN(x) (((((x) >> 21) & 0xf) * 2) + 2)
 
-/* AC97 Mask Register.
-*/
+/* AC97 Mask Register. */
 #define PSC_AC97MSK_GR         (1 << 25)
 #define PSC_AC97MSK_CD         (1 << 24)
 #define PSC_AC97MSK_RR         (1 << 13)
                                 PSC_AC97MSK_TO | PSC_AC97MSK_TU | \
                                 PSC_AC97MSK_RD | PSC_AC97MSK_TD)
 
-/* AC97 Protocol Control Register.
-*/
+/* AC97 Protocol Control Register. */
 #define PSC_AC97PCR_RC         (1 << 6)
 #define PSC_AC97PCR_RP         (1 << 5)
 #define PSC_AC97PCR_RS         (1 << 4)
 #define PSC_AC97PCR_TP         (1 << 1)
 #define PSC_AC97PCR_TS         (1 << 0)
 
-/* AC97 Status register (read only).
-*/
+/* AC97 Status register (read only). */
 #define PSC_AC97STAT_CB                (1 << 26)
 #define PSC_AC97STAT_CP                (1 << 25)
 #define PSC_AC97STAT_CR                (1 << 24)
 #define PSC_AC97STAT_DR                (1 << 1)
 #define PSC_AC97STAT_SR                (1 << 0)
 
-/* AC97 Event Register.
-*/
+/* AC97 Event Register. */
 #define PSC_AC97EVNT_GR                (1 << 25)
 #define PSC_AC97EVNT_CD                (1 << 24)
 #define PSC_AC97EVNT_RR                (1 << 13)
 #define PSC_AC97EVNT_RD                (1 << 5)
 #define PSC_AC97EVNT_TD                (1 << 4)
 
-/* CODEC Command Register.
-*/
+/* CODEC Command Register. */
 #define PSC_AC97CDC_RD         (1 << 25)
 #define PSC_AC97CDC_ID_MASK    (3 << 23)
 #define PSC_AC97CDC_INDX_MASK  (0x7f << 16)
-#define PSC_AC97CDC_ID(x)      (((x) & 0x3) << 23)
+#define PSC_AC97CDC_ID(x)      (((x) & 0x03) << 23)
 #define PSC_AC97CDC_INDX(x)    (((x) & 0x7f) << 16)
 
-/* AC97 Reset Control Register.
-*/
+/* AC97 Reset Control Register. */
 #define PSC_AC97RST_RST                (1 << 1)
 #define PSC_AC97RST_SNC                (1 << 0)
 
-
-/* PSC in I2S Mode.
-*/
+/* PSC in I2S Mode. */
 typedef struct psc_i2s {
        u32     psc_sel;
        u32     psc_ctrl;
@@ -215,8 +204,7 @@ typedef struct      psc_i2s {
        u32     psc_i2sudf;
 } psc_i2s_t;
 
-/* I2S Config Register.
-*/
+/* I2S Config Register. */
 #define PSC_I2SCFG_RT_MASK     (3 << 30)
 #define PSC_I2SCFG_RT_FIFO1    (0 << 30)
 #define PSC_I2SCFG_RT_FIFO2    (1 << 30)
@@ -247,8 +235,7 @@ typedef struct      psc_i2s {
 #define PSC_I2SCFG_MLJ         (1 << 10)
 #define PSC_I2SCFG_XM          (1 << 9)
 
-/* The word length equation is simply LEN+1.
- */
+/* The word length equation is simply LEN+1. */
 #define PSC_I2SCFG_SET_LEN(x)  ((((x) - 1) & 0x1f) << 4)
 #define PSC_I2SCFG_GET_LEN(x)  ((((x) >> 4) & 0x1f) + 1)
 
@@ -256,8 +243,7 @@ typedef struct      psc_i2s {
 #define PSC_I2SCFG_MLF         (1 << 1)
 #define PSC_I2SCFG_MS          (1 << 0)
 
-/* I2S Mask Register.
-*/
+/* I2S Mask Register. */
 #define PSC_I2SMSK_RR          (1 << 13)
 #define PSC_I2SMSK_RO          (1 << 12)
 #define PSC_I2SMSK_RU          (1 << 11)
@@ -271,8 +257,7 @@ typedef struct      psc_i2s {
                                 PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
                                 PSC_I2SMSK_RD | PSC_I2SMSK_TD)
 
-/* I2S Protocol Control Register.
-*/
+/* I2S Protocol Control Register. */
 #define PSC_I2SPCR_RC          (1 << 6)
 #define PSC_I2SPCR_RP          (1 << 5)
 #define PSC_I2SPCR_RS          (1 << 4)
@@ -280,8 +265,7 @@ typedef struct      psc_i2s {
 #define PSC_I2SPCR_TP          (1 << 1)
 #define PSC_I2SPCR_TS          (1 << 0)
 
-/* I2S Status register (read only).
-*/
+/* I2S Status register (read only). */
 #define PSC_I2SSTAT_RF         (1 << 13)
 #define PSC_I2SSTAT_RE         (1 << 12)
 #define PSC_I2SSTAT_RR         (1 << 11)
@@ -294,8 +278,7 @@ typedef struct      psc_i2s {
 #define PSC_I2SSTAT_DR         (1 << 1)
 #define PSC_I2SSTAT_SR         (1 << 0)
 
-/* I2S Event Register.
-*/
+/* I2S Event Register. */
 #define PSC_I2SEVNT_RR         (1 << 13)
 #define PSC_I2SEVNT_RO         (1 << 12)
 #define PSC_I2SEVNT_RU         (1 << 11)
@@ -305,8 +288,7 @@ typedef struct      psc_i2s {
 #define PSC_I2SEVNT_RD         (1 << 5)
 #define PSC_I2SEVNT_TD         (1 << 4)
 
-/* PSC in SPI Mode.
-*/
+/* PSC in SPI Mode. */
 typedef struct psc_spi {
        u32     psc_sel;
        u32     psc_ctrl;
@@ -318,8 +300,7 @@ typedef struct      psc_spi {
        u32     psc_spitxrx;
 } psc_spi_t;
 
-/* SPI Config Register.
-*/
+/* SPI Config Register. */
 #define PSC_SPICFG_RT_MASK     (3 << 30)
 #define PSC_SPICFG_RT_FIFO1    (0 << 30)
 #define PSC_SPICFG_RT_FIFO2    (1 << 30)
@@ -355,8 +336,7 @@ typedef struct      psc_spi {
 #define PSC_SPICFG_MLF         (1 << 1)
 #define PSC_SPICFG_MO          (1 << 0)
 
-/* SPI Mask Register.
-*/
+/* SPI Mask Register. */
 #define PSC_SPIMSK_MM          (1 << 16)
 #define PSC_SPIMSK_RR          (1 << 13)
 #define PSC_SPIMSK_RO          (1 << 12)
@@ -371,16 +351,14 @@ typedef struct    psc_spi {
                                 PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
                                 PSC_SPIMSK_MD)
 
-/* SPI Protocol Control Register.
-*/
+/* SPI Protocol Control Register. */
 #define PSC_SPIPCR_RC          (1 << 6)
 #define PSC_SPIPCR_SP          (1 << 5)
 #define PSC_SPIPCR_SS          (1 << 4)
 #define PSC_SPIPCR_TC          (1 << 2)
 #define PSC_SPIPCR_MS          (1 << 0)
 
-/* SPI Status register (read only).
-*/
+/* SPI Status register (read only). */
 #define PSC_SPISTAT_RF         (1 << 13)
 #define PSC_SPISTAT_RE         (1 << 12)
 #define PSC_SPISTAT_RR         (1 << 11)
@@ -393,8 +371,7 @@ typedef struct      psc_spi {
 #define PSC_SPISTAT_DR         (1 << 1)
 #define PSC_SPISTAT_SR         (1 << 0)
 
-/* SPI Event Register.
-*/
+/* SPI Event Register. */
 #define PSC_SPIEVNT_MM         (1 << 16)
 #define PSC_SPIEVNT_RR         (1 << 13)
 #define PSC_SPIEVNT_RO         (1 << 12)
@@ -405,13 +382,11 @@ typedef struct    psc_spi {
 #define PSC_SPIEVNT_SD         (1 << 5)
 #define PSC_SPIEVNT_MD         (1 << 4)
 
-/* Transmit register control.
-*/
+/* Transmit register control. */
 #define PSC_SPITXRX_LC         (1 << 29)
 #define PSC_SPITXRX_SR         (1 << 28)
 
-/* PSC in SMBus (I2C) Mode.
-*/
+/* PSC in SMBus (I2C) Mode. */
 typedef struct psc_smb {
        u32     psc_sel;
        u32     psc_ctrl;
@@ -424,8 +399,7 @@ typedef struct      psc_smb {
        u32     psc_smbtmr;
 } psc_smb_t;
 
-/* SMBus Config Register.
-*/
+/* SMBus Config Register. */
 #define PSC_SMBCFG_RT_MASK     (3 << 30)
 #define PSC_SMBCFG_RT_FIFO1    (0 << 30)
 #define PSC_SMBCFG_RT_FIFO2    (1 << 30)
@@ -452,8 +426,7 @@ typedef struct      psc_smb {
 
 #define PSC_SMBCFG_SET_SLV(x)  (((x) & 0x7f) << 1)
 
-/* SMBus Mask Register.
-*/
+/* SMBus Mask Register. */
 #define PSC_SMBMSK_DN          (1 << 30)
 #define PSC_SMBMSK_AN          (1 << 29)
 #define PSC_SMBMSK_AL          (1 << 28)
@@ -471,13 +444,11 @@ typedef struct    psc_smb {
                                 PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
                                 PSC_SMBMSK_MD)
 
-/* SMBus Protocol Control Register.
-*/
+/* SMBus Protocol Control Register. */
 #define PSC_SMBPCR_DC          (1 << 2)
 #define PSC_SMBPCR_MS          (1 << 0)
 
-/* SMBus Status register (read only).
-*/
+/* SMBus Status register (read only). */
 #define PSC_SMBSTAT_BB         (1 << 28)
 #define PSC_SMBSTAT_RF         (1 << 13)
 #define PSC_SMBSTAT_RE         (1 << 12)
@@ -491,8 +462,7 @@ typedef struct      psc_smb {
 #define PSC_SMBSTAT_DR         (1 << 1)
 #define PSC_SMBSTAT_SR         (1 << 0)
 
-/* SMBus Event Register.
-*/
+/* SMBus Event Register. */
 #define PSC_SMBEVNT_DN         (1 << 30)
 #define PSC_SMBEVNT_AN         (1 << 29)
 #define PSC_SMBEVNT_AL         (1 << 28)
@@ -510,15 +480,13 @@ typedef struct    psc_smb {
                                 PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
                                 PSC_SMBEVNT_MD)
 
-/* Transmit register control.
-*/
+/* Transmit register control. */
 #define PSC_SMBTXRX_RSR                (1 << 28)
 #define PSC_SMBTXRX_STP                (1 << 29)
-#define PSC_SMBTXRX_DATAMASK   (0xff)
+#define PSC_SMBTXRX_DATAMASK   0xff
 
-/* SMBus protocol timers register.
-*/
-#define PSC_SMBTMR_SET_TH(x)   (((x) & 0x3) << 30)
+/* SMBus protocol timers register. */
+#define PSC_SMBTMR_SET_TH(x)   (((x) & 0x03) << 30)
 #define PSC_SMBTMR_SET_PS(x)   (((x) & 0x1f) << 25)
 #define PSC_SMBTMR_SET_PU(x)   (((x) & 0x1f) << 20)
 #define PSC_SMBTMR_SET_SH(x)   (((x) & 0x1f) << 15)
@@ -526,5 +494,4 @@ typedef struct      psc_smb {
 #define PSC_SMBTMR_SET_CL(x)   (((x) & 0x1f) << 5)
 #define PSC_SMBTMR_SET_CH(x)   (((x) & 0x1f) << 0)
 
-
 #endif /* _AU1000_PSC_H_ */
index eedd048a7261d958c3eda305267b2a5c0f74f37c..27f26102b1bb374d982527b95bedc1e8b848aa72 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * AMD Alchemy DB1200 Referrence Board
- * Board Registers defines.
+ * AMD Alchemy DBAu1200 Reference Board
+ * Board register defines.
  *
  * ########################################################################
  *
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-// This is defined in au1000.h with bogus value
-#undef AU1X00_EXTERNAL_INT
+#define DBDMA_AC97_TX_CHAN     DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN     DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN      DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN      DSCR_CMD0_PSC1_RX
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
-
-/* SPI and SMB are muxed on the Pb1200 board.
-   Refer to board documentation.
+/*
+ * SPI and SMB are muxed on the DBAu1200 board.
+ * Refer to board documentation.
  */
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
-/* AC97 and I2S are muxed on the Pb1200 board.
-   Refer to board documentation.
+#define SPI_PSC_BASE           PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE         PSC0_BASE_ADDR
+/*
+ * AC'97 and I2S are muxed on the DBAu1200 board.
+ * Refer to board documentation.
  */
-#define AC97_PSC_BASE       PSC1_BASE_ADDR
+#define AC97_PSC_BASE          PSC1_BASE_ADDR
 #define I2S_PSC_BASE           PSC1_BASE_ADDR
 
-#define BCSR_KSEG1_ADDR 0xB9800000
+#define BCSR_KSEG1_ADDR        0xB9800000
 
 typedef volatile struct
 {
@@ -102,9 +101,9 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_STATUS_SWAPBOOT   0x0040
 #define BCSR_STATUS_FLASHBUSY  0x0100
 #define BCSR_STATUS_IDECBLID   0x0200
-#define BCSR_STATUS_SD0WP              0x0400
-#define BCSR_STATUS_U0RXD              0x1000
-#define BCSR_STATUS_U1RXD              0x2000
+#define BCSR_STATUS_SD0WP      0x0400
+#define BCSR_STATUS_U0RXD      0x1000
+#define BCSR_STATUS_U1RXD      0x2000
 
 #define BCSR_SWITCHES_OCTAL    0x00FF
 #define BCSR_SWITCHES_DIP_1    0x0080
@@ -122,8 +121,8 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_RESETS_DC         0x0004
 #define BCSR_RESETS_IDE                0x0008
 #define BCSR_RESETS_TV         0x0010
-/* not resets but in the same register */
-#define BCSR_RESETS_PWMR1mUX 0x0800
+/* Not resets but in the same register */
+#define BCSR_RESETS_PWMR1MUX   0x0800
 #define BCSR_RESETS_PCS0MUX    0x1000
 #define BCSR_RESETS_PCS1MUX    0x2000
 #define BCSR_RESETS_SPISEL     0x4000
@@ -160,7 +159,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_INT_PC0STSCHG     0x0008
 #define BCSR_INT_PC1           0x0010
 #define BCSR_INT_PC1STSCHG     0x0020
-#define BCSR_INT_DC                    0x0040
+#define BCSR_INT_DC            0x0040
 #define BCSR_INT_FLASHBUSY     0x0080
 #define BCSR_INT_PC0INSERT     0x0100
 #define BCSR_INT_PC0EJECT      0x0200
@@ -179,10 +178,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define IDE_DDMA_REQ           DSCR_CMD0_DMA_REQ1
 #define IDE_RQSIZE             128
 
-#define NAND_PHYS_ADDR   0x20000000
+#define NAND_PHYS_ADDR         0x20000000
 
 /*
- * External Interrupts for Pb1200 as of 8/6/2004.
+ * External Interrupts for DBAu1200 as of 8/6/2004.
  * Bit positions in the CPLD registers can be calculated by taking
  * the interrupt define and subtracting the DB1200_INT_BEGIN value.
  *
@@ -211,23 +210,21 @@ enum external_pb1200_ints {
 };
 
 
-/* For drivers/pcmcia/au1000_db1x00.c */
-
-/* PCMCIA Db1x00 specific defines */
-
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/*
+ * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+ */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-       ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+       ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
-#define BOARD_PC0_INT DB1200_PC0_INT
-#define BOARD_PC1_INT DB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+#define BOARD_PC0_INT  DB1200_PC0_INT
+#define BOARD_PC1_INT  DB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
 
-/* Nand chip select */
+/* NAND chip select */
 #define NAND_CS 1
 
 #endif /* __ASM_DB1200_H */
-
index e7a88ba358333800231730ad3f3b8bc318dfd889..612ae90dbcb8ea29451d7cd2034ef3c3a3fd2b5d 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * AMD Alchemy DB1x00 Reference Boards
+ * AMD Alchemy DBAu1x00 Reference Boards
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  * ########################################################################
 
 #ifdef CONFIG_MIPS_DB1550
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN  DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN  DSCR_CMD0_PSC3_RX
+#define DBDMA_AC97_TX_CHAN     DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN     DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN      DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN      DSCR_CMD0_PSC3_RX
 
-#define SPI_PSC_BASE       PSC0_BASE_ADDR
-#define AC97_PSC_BASE      PSC1_BASE_ADDR
-#define SMBUS_PSC_BASE     PSC2_BASE_ADDR
-#define I2S_PSC_BASE       PSC3_BASE_ADDR
+#define SPI_PSC_BASE           PSC0_BASE_ADDR
+#define AC97_PSC_BASE          PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE         PSC2_BASE_ADDR
+#define I2S_PSC_BASE           PSC3_BASE_ADDR
 
-#define BCSR_KSEG1_ADDR 0xAF000000
-#define NAND_PHYS_ADDR  0x20000000
+#define BCSR_KSEG1_ADDR        0xAF000000
+#define NAND_PHYS_ADDR         0x20000000
 
 #else
 #define BCSR_KSEG1_ADDR 0xAE000000
 #endif
 
 /*
- * Overlay data structure of the Db1x00 board registers.
- * Registers located at physical 0E0000xx, KSEG1 0xAE0000xx
+ * Overlay data structure of the DBAu1x00 board registers.
+ * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx.
  */
 typedef volatile struct
 {
@@ -138,18 +137,19 @@ typedef volatile struct
 
 #define BCSR_SWRESET_RESET             0x0080
 
-/* PCMCIA Db1x00 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA DBAu1x00 specific defines */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
 #define SET_VCC_VPP(VCC, VPP, SLOT)\
-       ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+       ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
-/* SD controller macros */
 /*
- * Detect card.
+ * SD controller macros
  */
+
+/* Detect card. */
 #define mmc_card_inserted(_n_, _res_) \
        do { \
                BCSR * const bcsr = (BCSR *)0xAE000000; \
@@ -176,10 +176,10 @@ typedef volatile struct
                unsigned long mmc_pwr, mmc_wp, board_specific; \
                if ((_n_)) { \
                        mmc_pwr = BCSR_BOARD_SD1_PWR; \
-                       mmc_wp = BCSR_BOARD_SD1_WP; \
+                       mmc_wp  = BCSR_BOARD_SD1_WP; \
                } else { \
                        mmc_pwr = BCSR_BOARD_SD0_PWR; \
-                       mmc_wp = BCSR_BOARD_SD0_WP; \
+                       mmc_wp  = BCSR_BOARD_SD0_WP; \
                } \
                board_specific = au_readl((unsigned long)(&bcsr->specific)); \
                if (!(board_specific & mmc_wp)) {/* low means card present */ \
@@ -190,17 +190,19 @@ typedef volatile struct
        } while (0)
 
 
-/* NAND defines */
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * NAND defines
+ *
+ * Timing values as described in databook, * ns value stripped of the
  * lower 2 bits.
- * These defines are here rather than an SOC1550 generic file because
+ * These defines are here rather than an Au1550 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H                       (18 >> 2)
-#define NAND_T_PUL                     (30 >> 2)
-#define NAND_T_SU                      (30 >> 2)
-#define NAND_T_WH                      (30 >> 2)
+#define NAND_T_H               (18 >> 2)
+#define NAND_T_PUL             (30 >> 2)
+#define NAND_T_SU              (30 >> 2)
+#define NAND_T_WH              (30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT         0
@@ -208,16 +210,15 @@ typedef volatile struct
 #define NAND_T_SU_SHIFT                8
 #define NAND_T_WH_SHIFT                12
 
-#define NAND_TIMING    ((NAND_T_H   & 0xF)     << NAND_T_H_SHIFT)   | \
-                       ((NAND_T_PUL & 0xF)     << NAND_T_PUL_SHIFT) | \
-                       ((NAND_T_SU  & 0xF)     << NAND_T_SU_SHIFT)  | \
-                       ((NAND_T_WH  & 0xF)     << NAND_T_WH_SHIFT)
-#define NAND_CS 1
+#define NAND_TIMING    (((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+                        ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+                        ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+                        ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
+#define NAND_CS        1
 
-/* should be done by yamon */
-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+/* Should be done by YAMON */
+#define NAND_STCFG     0x00400005 /* 8-bit NAND */
+#define NAND_STTIME    0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR    0x12000FFF /* physical address 0x20000000 */
 
 #endif /* __ASM_DB1X00_H */
-
index b52e0e7ee3fb7502ee0ac847ee6e2505aa61eec5..6d1ff9060e4486d049d85ee66996436c58f6bfd0 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1000 Referrence Board
+ * Alchemy Semi Pb1000 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
 #define __ASM_PB1000_H
 
 /* PCMCIA PB1000 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
-
-#define PB1000_PCR     0xBE000000
-#  define PCR_SLOT_0_VPP0  (1<<0)
-#  define PCR_SLOT_0_VPP1  (1<<1)
-#  define PCR_SLOT_0_VCC0  (1<<2)
-#  define PCR_SLOT_0_VCC1  (1<<3)
-#  define PCR_SLOT_0_RST   (1<<4)
-
-#  define PCR_SLOT_1_VPP0  (1<<8)
-#  define PCR_SLOT_1_VPP1  (1<<9)
-#  define PCR_SLOT_1_VCC0  (1<<10)
-#  define PCR_SLOT_1_VCC1  (1<<11)
-#  define PCR_SLOT_1_RST   (1<<12)
-
-#define PB1000_MDR     0xBE000004
-#  define MDR_PI        (1<<5)  /* pcmcia int latch  */
-#  define MDR_EPI      (1<<14)  /* enable pcmcia int */
-#  define MDR_CPI      (1<<15)  /* clear pcmcia int  */
-
-#define PB1000_ACR1    0xBE000008
-#  define ACR1_SLOT_0_CD1    (1<<0)  /* card detect 1     */
-#  define ACR1_SLOT_0_CD2    (1<<1)  /* card detect 2     */
-#  define ACR1_SLOT_0_READY  (1<<2)  /* ready             */
-#  define ACR1_SLOT_0_STATUS (1<<3)  /* status change     */
-#  define ACR1_SLOT_0_VS1    (1<<4)  /* voltage sense 1   */
-#  define ACR1_SLOT_0_VS2    (1<<5)  /* voltage sense 2   */
-#  define ACR1_SLOT_0_INPACK (1<<6)  /* inpack pin status */
-#  define ACR1_SLOT_1_CD1    (1<<8)  /* card detect 1     */
-#  define ACR1_SLOT_1_CD2    (1<<9)  /* card detect 2     */
-#  define ACR1_SLOT_1_READY  (1<<10) /* ready             */
-#  define ACR1_SLOT_1_STATUS (1<<11) /* status change     */
-#  define ACR1_SLOT_1_VS1    (1<<12) /* voltage sense 1   */
-#  define ACR1_SLOT_1_VS2    (1<<13) /* voltage sense 2   */
-#  define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */
-
-#define CPLD_AUX0      0xBE00000C
-#define CPLD_AUX1      0xBE000010
-#define CPLD_AUX2      0xBE000014
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+
+#define PB1000_PCR             0xBE000000
+#  define PCR_SLOT_0_VPP0      (1 << 0)
+#  define PCR_SLOT_0_VPP1      (1 << 1)
+#  define PCR_SLOT_0_VCC0      (1 << 2)
+#  define PCR_SLOT_0_VCC1      (1 << 3)
+#  define PCR_SLOT_0_RST       (1 << 4)
+#  define PCR_SLOT_1_VPP0      (1 << 8)
+#  define PCR_SLOT_1_VPP1      (1 << 9)
+#  define PCR_SLOT_1_VCC0      (1 << 10)
+#  define PCR_SLOT_1_VCC1      (1 << 11)
+#  define PCR_SLOT_1_RST       (1 << 12)
+
+#define PB1000_MDR             0xBE000004
+#  define MDR_PI               (1 << 5)        /* PCMCIA int latch  */
+#  define MDR_EPI              (1 << 14)       /* enable PCMCIA int */
+#  define MDR_CPI              (1 << 15)       /* clear  PCMCIA int  */
+
+#define PB1000_ACR1            0xBE000008
+#  define ACR1_SLOT_0_CD1      (1 << 0)        /* card detect 1        */
+#  define ACR1_SLOT_0_CD2      (1 << 1)        /* card detect 2        */
+#  define ACR1_SLOT_0_READY    (1 << 2)        /* ready                */
+#  define ACR1_SLOT_0_STATUS   (1 << 3)        /* status change        */
+#  define ACR1_SLOT_0_VS1      (1 << 4)        /* voltage sense 1      */
+#  define ACR1_SLOT_0_VS2      (1 << 5)        /* voltage sense 2      */
+#  define ACR1_SLOT_0_INPACK   (1 << 6)        /* inpack pin status    */
+#  define ACR1_SLOT_1_CD1      (1 << 8)        /* card detect 1        */
+#  define ACR1_SLOT_1_CD2      (1 << 9)        /* card detect 2        */
+#  define ACR1_SLOT_1_READY    (1 << 10)       /* ready                */
+#  define ACR1_SLOT_1_STATUS   (1 << 11)       /* status change        */
+#  define ACR1_SLOT_1_VS1      (1 << 12)       /* voltage sense 1      */
+#  define ACR1_SLOT_1_VS2      (1 << 13)       /* voltage sense 2      */
+#  define ACR1_SLOT_1_INPACK   (1 << 14)       /* inpack pin status    */
+
+#define CPLD_AUX0              0xBE00000C
+#define CPLD_AUX1              0xBE000010
+#define CPLD_AUX2              0xBE000014
 
 /* Voltage levels */
 
 /* VPPEN1 - VPPEN0 */
-#define VPP_GND ((0<<1) | (0<<0))
-#define VPP_5V  ((1<<1) | (0<<0))
-#define VPP_3V  ((0<<1) | (1<<0))
-#define VPP_12V ((0<<1) | (1<<0))
-#define VPP_HIZ ((1<<1) | (1<<0))
+#define VPP_GND ((0 << 1) | (0 << 0))
+#define VPP_5V ((1 << 1) | (0 << 0))
+#define VPP_3V ((0 << 1) | (1 << 0))
+#define VPP_12V ((0 << 1) | (1 << 0))
+#define VPP_HIZ ((1 << 1) | (1 << 0))
 
 /* VCCEN1 - VCCEN0 */
-#define VCC_3V  ((0<<1) | (1<<0))
-#define VCC_5V  ((1<<1) | (0<<0))
-#define VCC_HIZ ((0<<1) | (0<<0))
+#define VCC_3V ((0 << 1) | (1 << 0))
+#define VCC_5V ((1 << 1) | (0 << 0))
+#define VCC_HIZ ((0 << 1) | (0 << 0))
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-       ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
-
-
-/* PCI PB1000 specific defines */
-/* The reason these defines are here instead of au1000.h is because
- * the Au1000 does not have a PCI bus controller so the PCI implementation
- * on the some of the older Pb1000 boards was very board specific.
- */
-#define PCI_CONFIG_BASE   0xBA020000 /* the only external slot */
-
-#define SDRAM_DEVID       0xBA010000
-#define SDRAM_CMD         0xBA010004
-#define SDRAM_CLASS       0xBA010008
-#define SDRAM_MISC        0xBA01000C
-#define SDRAM_MBAR        0xBA010010
-
-#define PCI_IO_DATA_PORT  0xBA800000
-
-#define PCI_IO_ADDR       0xBE00001C
-#define PCI_INT_ACK       0xBBC00000
-#define PCI_IO_READ       0xBBC00020
-#define PCI_IO_WRITE      0xBBC00030
-
-#define PCI_BRIDGE_CONFIG 0xBE000018
-
-#define PCI_IO_START      0x10000000
-#define PCI_IO_END        0x1000ffff
-#define PCI_MEM_START     0x18000000
-#define PCI_MEM_END       0x18ffffff
-
-#define PCI_FIRST_DEVFN   0
-#define PCI_LAST_DEVFN    1
-
-static inline u8 au_pci_io_readb(u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
-       return (readl(PCI_IO_DATA_PORT) & 0xff);
-}
-
-static inline u16 au_pci_io_readw(u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
-       return (readl(PCI_IO_DATA_PORT) & 0xffff);
-}
-
-static inline u32 au_pci_io_readl(u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG);
-       return readl(PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writeb(u8 val, u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
-       writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writew(u16 val, u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
-       writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writel(u32 val, u32 addr)
-{
-       writel(addr, PCI_IO_ADDR);
-       writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG);
-       writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void set_sdram_extbyte(void)
-{
-       writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG);
-}
-
-static inline void set_slot_extbyte(void)
-{
-       writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG);
-}
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+       ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 #endif /* __ASM_PB1000_H */
index 63aa3926b297f68db9aa26feb7ac1922f1802b4a..b1a60f1cbd021446bf6c91625e2f0e17f7e8b474 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1100 Referrence Board
+ * Alchemy Semi Pb1100 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
 #ifndef __ASM_PB1100_H
 #define __ASM_PB1100_H
 
-#define PB1100_IDENT          0xAE000000
-#define BOARD_STATUS_REG      0xAE000004
-#  define PB1100_ROM_SEL         (1<<15)
-#  define PB1100_ROM_SIZ         (1<<14)
-#  define PB1100_SWAP_BOOT       (1<<13)
-#  define PB1100_FLASH_WP        (1<<12)
-#  define PB1100_ROM_H_STS       (1<<11)
-#  define PB1100_ROM_L_STS       (1<<10)
-#  define PB1100_FLASH_H_STS      (1<<9)
-#  define PB1100_FLASH_L_STS      (1<<8)
-#  define PB1100_SRAM_SIZ         (1<<7)
-#  define PB1100_TSC_BUSY         (1<<6)
-#  define PB1100_PCMCIA_VS_MASK   (3<<4)
-#  define PB1100_RS232_CD         (1<<3)
-#  define PB1100_RS232_CTS        (1<<2)
-#  define PB1100_RS232_DSR        (1<<1)
-#  define PB1100_RS232_RI         (1<<0)
+#define PB1100_IDENT           0xAE000000
+#define BOARD_STATUS_REG       0xAE000004
+#  define PB1100_ROM_SEL       (1 << 15)
+#  define PB1100_ROM_SIZ       (1 << 14)
+#  define PB1100_SWAP_BOOT     (1 << 13)
+#  define PB1100_FLASH_WP      (1 << 12)
+#  define PB1100_ROM_H_STS     (1 << 11)
+#  define PB1100_ROM_L_STS     (1 << 10)
+#  define PB1100_FLASH_H_STS   (1 << 9)
+#  define PB1100_FLASH_L_STS   (1 << 8)
+#  define PB1100_SRAM_SIZ      (1 << 7)
+#  define PB1100_TSC_BUSY      (1 << 6)
+#  define PB1100_PCMCIA_VS_MASK (3 << 4)
+#  define PB1100_RS232_CD      (1 << 3)
+#  define PB1100_RS232_CTS     (1 << 2)
+#  define PB1100_RS232_DSR     (1 << 1)
+#  define PB1100_RS232_RI      (1 << 0)
 
-#define PB1100_IRDA_RS232     0xAE00000C
-#  define PB1100_IRDA_FULL       (0<<14) /* full power */
-#  define PB1100_IRDA_SHUTDOWN   (1<<14)
-#  define PB1100_IRDA_TT         (2<<14) /* 2/3 power */
-#  define PB1100_IRDA_OT         (3<<14) /* 1/3 power */
-#  define PB1100_IRDA_FIR        (1<<13)
+#define PB1100_IRDA_RS232      0xAE00000C
+#  define PB1100_IRDA_FULL     (0 << 14)       /* full power           */
+#  define PB1100_IRDA_SHUTDOWN (1 << 14)
+#  define PB1100_IRDA_TT       (2 << 14)       /* 2/3 power            */
+#  define PB1100_IRDA_OT       (3 << 14)       /* 1/3 power            */
+#  define PB1100_IRDA_FIR      (1 << 13)
 
-#define PCMCIA_BOARD_REG     0xAE000010
-#  define PB1100_SD_WP1_RO       (1<<15) /* read only */
-#  define PB1100_SD_WP0_RO       (1<<14) /* read only */
-#  define PB1100_SD_PWR1         (1<<11) /* applies power to SD1 */
-#  define PB1100_SD_PWR0         (1<<10) /* applies power to SD0 */
-#  define PB1100_SEL_SD_CONN1     (1<<9)
-#  define PB1100_SEL_SD_CONN0     (1<<8)
-#  define PC_DEASSERT_RST         (1<<7)
-#  define PC_DRV_EN               (1<<4)
+#define PCMCIA_BOARD_REG       0xAE000010
+#  define PB1100_SD_WP1_RO     (1 << 15)       /* read only            */
+#  define PB1100_SD_WP0_RO     (1 << 14)       /* read only            */
+#  define PB1100_SD_PWR1       (1 << 11)       /* applies power to SD1 */
+#  define PB1100_SD_PWR0       (1 << 10)       /* applies power to SD0 */
+#  define PB1100_SEL_SD_CONN1  (1 << 9)
+#  define PB1100_SEL_SD_CONN0  (1 << 8)
+#  define PC_DEASSERT_RST      (1 << 7)
+#  define PC_DRV_EN            (1 << 4)
 
-#define PB1100_G_CONTROL      0xAE000014 /* graphics control */
+#define PB1100_G_CONTROL       0xAE000014      /* graphics control     */
 
-#define PB1100_RST_VDDI       0xAE00001C
-#  define PB1100_SOFT_RESET      (1<<15) /* clear to reset the board */
-#  define PB1100_VDDI_MASK        (0x1F)
+#define PB1100_RST_VDDI        0xAE00001C
+#  define PB1100_SOFT_RESET    (1 << 15)       /* clear to reset the board */
+#  define PB1100_VDDI_MASK     0x1F
 
-#define PB1100_LEDS           0xAE000018
+#define PB1100_LEDS            0xAE000018
 
-/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
- * 7:0 is the LED Display's decimal points.
+/*
+ * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+ * 7:0  is the LED Display's decimal points.
  */
-#define PB1100_HEX_LED        0xAE000018
+#define PB1100_HEX_LED         0xAE000018
 
-/* PCMCIA PB1100 specific defines */
-#define PCMCIA_MAX_SOCK 0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA Pb1100 specific defines */
+#define PCMCIA_MAX_SOCK  0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
 
 #endif /* __ASM_PB1100_H */
index e2c6bcac3b4279933ed4b1419f92f35f972f4ddb..c8618df88cb51abedc40b29cd4468f61d2505f6c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * AMD Alchemy PB1200 Referrence Board
+ * AMD Alchemy Pb1200 Referrence Board
  * Board Registers defines.
  *
  * ########################################################################
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-// This is defined in au1000.h with bogus value
-#undef AU1X00_EXTERNAL_INT
+#define DBDMA_AC97_TX_CHAN     DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN     DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN      DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN      DSCR_CMD0_PSC1_RX
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
-
-/* SPI and SMB are muxed on the Pb1200 board.
-   Refer to board documentation.
+/*
+ * SPI and SMB are muxed on the Pb1200 board.
+ * Refer to board documentation.
  */
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
-/* AC97 and I2S are muxed on the Pb1200 board.
-   Refer to board documentation.
+#define SPI_PSC_BASE           PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE         PSC0_BASE_ADDR
+/*
+ * AC97 and I2S are muxed on the Pb1200 board.
+ * Refer to board documentation.
  */
 #define AC97_PSC_BASE       PSC1_BASE_ADDR
 #define I2S_PSC_BASE           PSC1_BASE_ADDR
@@ -102,10 +101,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_STATUS_SWAPBOOT   0x0040
 #define BCSR_STATUS_FLASHBUSY  0x0100
 #define BCSR_STATUS_IDECBLID   0x0200
-#define BCSR_STATUS_SD0WP              0x0400
-#define BCSR_STATUS_SD1WP              0x0800
-#define BCSR_STATUS_U0RXD              0x1000
-#define BCSR_STATUS_U1RXD              0x2000
+#define BCSR_STATUS_SD0WP      0x0400
+#define BCSR_STATUS_SD1WP      0x0800
+#define BCSR_STATUS_U0RXD      0x1000
+#define BCSR_STATUS_U1RXD      0x2000
 
 #define BCSR_SWITCHES_OCTAL    0x00FF
 #define BCSR_SWITCHES_DIP_1    0x0080
@@ -123,11 +122,11 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_RESETS_DC         0x0004
 #define BCSR_RESETS_IDE                0x0008
 /* not resets but in the same register */
-#define BCSR_RESETS_WSCFSM  0x0800
+#define BCSR_RESETS_WSCFSM     0x0800
 #define BCSR_RESETS_PCS0MUX    0x1000
 #define BCSR_RESETS_PCS1MUX    0x2000
 #define BCSR_RESETS_SPISEL     0x4000
-#define BCSR_RESETS_SD1MUX  0x8000
+#define BCSR_RESETS_SD1MUX     0x8000
 
 #define BCSR_PCMCIA_PC0VPP     0x0003
 #define BCSR_PCMCIA_PC0VCC     0x000C
@@ -163,7 +162,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_INT_PC0STSCHG     0x0008
 #define BCSR_INT_PC1           0x0010
 #define BCSR_INT_PC1STSCHG     0x0020
-#define BCSR_INT_DC                    0x0040
+#define BCSR_INT_DC            0x0040
 #define BCSR_INT_FLASHBUSY     0x0080
 #define BCSR_INT_PC0INSERT     0x0100
 #define BCSR_INT_PC0EJECT      0x0200
@@ -174,14 +173,6 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define BCSR_INT_SD1INSERT     0x4000
 #define BCSR_INT_SD1EJECT      0x8000
 
-/* PCMCIA Db1x00 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-       ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
-
 #define SMC91C111_PHYS_ADDR    0x0D000300
 #define SMC91C111_INT          PB1200_ETH_INT
 
@@ -192,18 +183,19 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define IDE_DDMA_REQ           DSCR_CMD0_DMA_REQ1
 #define IDE_RQSIZE             128
 
-#define NAND_PHYS_ADDR   0x1C000000
+#define NAND_PHYS_ADDR         0x1C000000
 
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * Timing values as described in databook, * ns value stripped of
  * lower 2 bits.
- * These defines are here rather than an SOC1200 generic file because
+ * These defines are here rather than an Au1200 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H                       (18 >> 2)
-#define NAND_T_PUL                     (30 >> 2)
-#define NAND_T_SU                      (30 >> 2)
-#define NAND_T_WH                      (30 >> 2)
+#define NAND_T_H               (18 >> 2)
+#define NAND_T_PUL             (30 >> 2)
+#define NAND_T_SU              (30 >> 2)
+#define NAND_T_WH              (30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT         0
@@ -211,11 +203,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define NAND_T_SU_SHIFT                8
 #define NAND_T_WH_SHIFT                12
 
-#define NAND_TIMING    ((NAND_T_H   & 0xF)     << NAND_T_H_SHIFT)   | \
-                       ((NAND_T_PUL & 0xF)     << NAND_T_PUL_SHIFT) | \
-                       ((NAND_T_SU  & 0xF)     << NAND_T_SU_SHIFT)  | \
-                       ((NAND_T_WH  & 0xF)     << NAND_T_WH_SHIFT)
-
+#define NAND_TIMING    (((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+                        ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+                        ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+                        ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
 
 /*
  * External Interrupts for Pb1200 as of 8/6/2004.
@@ -248,13 +239,21 @@ enum external_pb1200_ints {
        PB1200_INT_END          = PB1200_INT_BEGIN + 15
 };
 
-/* For drivers/pcmcia/au1000_db1x00.c */
-#define BOARD_PC0_INT PB1200_PC0_INT
-#define BOARD_PC1_INT PB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+/*
+ * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+ */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
-/* Nand chip select */
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+       ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+
+#define BOARD_PC0_INT  PB1200_PC0_INT
+#define BOARD_PC1_INT  PB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
+
+/* NAND chip select */
 #define NAND_CS 1
 
 #endif /* __ASM_PB1200_H */
-
index ff6d40c87a25b0859e8782d35ca99e089faa25da..da51a2eb7b82659a792cabda87c0b46f37487752 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1500 Referrence Board
+ * Alchemy Semi Pb1500 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
 #ifndef __ASM_PB1500_H
 #define __ASM_PB1500_H
 
+#define IDENT_BOARD_REG        0xAE000000
+#define BOARD_STATUS_REG       0xAE000004
+#define PCI_BOARD_REG          0xAE000010
+#define PCMCIA_BOARD_REG       0xAE000010
+#  define PC_DEASSERT_RST            0x80
+#  define PC_DRV_EN                  0x10
+#define PB1500_G_CONTROL       0xAE000014
+#define PB1500_RST_VDDI        0xAE00001C
+#define PB1500_LEDS            0xAE000018
 
-#define IDENT_BOARD_REG           0xAE000000
-#define BOARD_STATUS_REG          0xAE000004
-#define PCI_BOARD_REG             0xAE000010
-#define PCMCIA_BOARD_REG          0xAE000010
-  #define PC_DEASSERT_RST               0x80
-  #define PC_DRV_EN                     0x10
-#define PB1500_G_CONTROL          0xAE000014
-#define PB1500_RST_VDDI           0xAE00001C
-#define PB1500_LEDS               0xAE000018
+#define PB1500_HEX_LED         0xAF000004
+#define PB1500_HEX_LED_BLANK   0xAF000008
 
-#define PB1500_HEX_LED            0xAF000004
-#define PB1500_HEX_LED_BLANK      0xAF000008
-
-/* PCMCIA PB1500 specific defines */
-#define PCMCIA_MAX_SOCK 0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA Pb1500 specific defines */
+#define PCMCIA_MAX_SOCK  0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
 
 #endif /* __ASM_PB1500_H */
index c2ab0e2df4ae1f20d3d1ec294ef8dfb7bea0455b..6704a11497dbd701cccb62bdc822625ade559ac6 100644 (file)
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+#define DBDMA_AC97_TX_CHAN     DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN     DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN      DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN      DSCR_CMD0_PSC3_RX
 
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define AC97_PSC_BASE       PSC1_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
-#define I2S_PSC_BASE        PSC3_BASE_ADDR
+#define SPI_PSC_BASE           PSC0_BASE_ADDR
+#define AC97_PSC_BASE          PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE         PSC2_BASE_ADDR
+#define I2S_PSC_BASE           PSC3_BASE_ADDR
 
 #define BCSR_PHYS_ADDR 0xAF000000
 
@@ -129,12 +129,12 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
 #define BCSR_SYSTEM_POWEROFF   0x4000
 #define BCSR_SYSTEM_RESET      0x8000
 
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-       ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+       ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
 #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
 #define PB1550_BOTH_BANKS
@@ -144,16 +144,17 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
 #define PB1550_USER_ONLY
 #endif
 
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * Timing values as described in databook, * ns value stripped of
  * lower 2 bits.
  * These defines are here rather than an SOC1550 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H                       (18 >> 2)
-#define NAND_T_PUL                     (30 >> 2)
-#define NAND_T_SU                      (30 >> 2)
-#define NAND_T_WH                      (30 >> 2)
+#define NAND_T_H               (18 >> 2)
+#define NAND_T_PUL             (30 >> 2)
+#define NAND_T_SU              (30 >> 2)
+#define NAND_T_WH              (30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT         0
@@ -161,16 +162,16 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
 #define NAND_T_SU_SHIFT                8
 #define NAND_T_WH_SHIFT                12
 
-#define NAND_TIMING    ((NAND_T_H   & 0xF)     << NAND_T_H_SHIFT)   | \
-                       ((NAND_T_PUL & 0xF)     << NAND_T_PUL_SHIFT) | \
-                       ((NAND_T_SU  & 0xF)     << NAND_T_SU_SHIFT)  | \
-                       ((NAND_T_WH  & 0xF)     << NAND_T_WH_SHIFT)
+#define NAND_TIMING    (((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+                        ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+                        ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+                        ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
 
 #define NAND_CS 1
 
-/* should be done by yamon */
-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+/* Should be done by YAMON */
+#define NAND_STCFG     0x00400005 /* 8-bit NAND */
+#define NAND_STTIME    0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR    0x12000FFF /* physical address 0x20000000 */
 
 #endif /* __ASM_PB1550_H */
index 65778c890a62ef4ed3b06a673d7ce552ca616e2a..20b666022dcbdd08c66519ef76a9543ed7dc5487 100644 (file)
@@ -29,13 +29,13 @@ extern unsigned int rtlx_read_poll(int index, int can_sleep);
 extern unsigned int rtlx_write_poll(int index);
 
 enum rtlx_state {
-       RTLX_STATE_UNUSED,
+       RTLX_STATE_UNUSED = 0,
        RTLX_STATE_INITIALISED,
        RTLX_STATE_REMOTE_READY,
        RTLX_STATE_OPENED
 };
 
-#define RTLX_BUFFER_SIZE 1024
+#define RTLX_BUFFER_SIZE 2048
 
 /* each channel supports read and write.
    linux (vpe0) reads lx_buffer  and writes rt_buffer
index 2dd147f519d15ea5f7b9f0b1b68964c2d3eadea7..bcbb8d675af5ffdd51bd1a8ddb2b45985c5a6e49 100644 (file)
@@ -9,37 +9,15 @@
 #ifndef _ASM_TYPES_H
 #define _ASM_TYPES_H
 
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if (_MIPS_SZLONG == 64)
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
+#if _MIPS_SZLONG == 64
+# include <asm-generic/int-l64.h>
 #else
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
+# include <asm-generic/int-ll64.h>
 #endif
 
-#endif
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
 
 #endif /* __ASSEMBLY__ */
 
@@ -52,30 +30,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-
-typedef __signed char s8;
-typedef unsigned char u8;
-
-typedef __signed short s16;
-typedef unsigned short u16;
-
-typedef __signed int s32;
-typedef unsigned int u32;
-
-#if (_MIPS_SZLONG == 64)
-
-typedef __signed__ long s64;
-typedef unsigned long u64;
-
-#else
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long s64;
-typedef unsigned long long u64;
-#endif
-
-#endif
-
 #if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \
     || defined(CONFIG_64BIT)
 typedef u64 dma_addr_t;
index bf9c515a998c8e0bc613952229f41ebe967fd4c4..3a8329b3e8694493c6b018eea7820873d04110f8 100644 (file)
@@ -97,7 +97,4 @@ signed __muldiv64s(signed val, signed mult, signed div)
        return result;
 }
 
-extern __attribute__((const))
-uint64_t div64_64(uint64_t dividend, uint64_t divisor);
-
 #endif /* _ASM_DIV64 */
index f1b081f53468b0713aef094f3abaaab338c4a72f..73239271873da304c88fe396eda7074686c3185a 100644 (file)
@@ -58,7 +58,7 @@ extern struct mn10300_cpuinfo boot_cpu_data;
 extern void identify_cpu(struct mn10300_cpuinfo *);
 extern void print_cpu_info(struct mn10300_cpuinfo *);
 extern void dodgy_tsc(void);
-#define cpu_relax() do {} while (0)
+#define cpu_relax() barrier()
 
 /*
  * User space process size: 1.75GB (default).
index d40ea7628bfc936d3400a93dc2e0025d141920c0..7b9f01042fd4e6da98f59a1fbc91e586470a4ea6 100644 (file)
 #ifndef _ASM_TYPES_H
 #define _ASM_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -45,18 +28,6 @@ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 typedef u32 dma_addr_t;
 
index 56c84802da59b395132f5e691bea2c485b9fa16e..7f5a39bfb4ce1eabecfed3e1cc88f27d3cee078f 100644 (file)
@@ -1,29 +1,12 @@
 #ifndef _PARISC_TYPES_H
 #define _PARISC_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -41,18 +24,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index afae0697e8ce441b60d219b17530391591fe0484..e0062d73db1c0bcaee98eafcc18a253d0048b33c 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-/* 
+/*
  * 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
@@ -18,6 +18,9 @@ extern int check_legacy_ioport(unsigned long base_port);
 #define _PNPWRP                0xa79
 #define PNPBIOS_BASE   0xf000
 
+#include <linux/device.h>
+#include <linux/io.h>
+
 #include <linux/compiler.h>
 #include <asm/page.h>
 #include <asm/byteorder.h>
@@ -744,6 +747,9 @@ static inline void * bus_to_virt(unsigned long address)
 
 #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
 
+void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
+                               size_t size, unsigned long flags);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_IO_H */
index 04ffbb8e0a357f972e8743c61891c314eb7962c2..81a69d7110171bc5bc51fda14d8704de28af4b11 100644 (file)
@@ -59,6 +59,7 @@ struct kvm_vcpu_stat {
        u32 emulated_inst_exits;
        u32 dec_exits;
        u32 ext_intr_exits;
+       u32 halt_wakeup;
 };
 
 struct tlbe {
index 7ac820308a7e19c2e397d399e38fefe0d7ae361b..b35a7e3ef9782b0579072ee8492013f5dd7519f1 100644 (file)
@@ -77,12 +77,17 @@ static inline void kvmppc_clear_exception(struct kvm_vcpu *vcpu, int exception)
        clear_bit(priority, &vcpu->arch.pending_exceptions);
 }
 
+/* Helper function for "full" MSR writes. No need to call this if only EE is
+ * changing. */
 static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
 {
        if ((new_msr & MSR_PR) != (vcpu->arch.msr & MSR_PR))
                kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR);
 
        vcpu->arch.msr = new_msr;
+
+       if (vcpu->arch.msr & MSR_WE)
+               kvm_vcpu_block(vcpu);
 }
 
 #endif /* __POWERPC_KVM_PPC_H__ */
index 7c97b5a08d082782807d33467c5864ce0a2a6db6..c08e714d0c42880dd785df64a93f3b8ad3a1c838 100644 (file)
@@ -209,6 +209,13 @@ extern int icache_44x_need_flush;
  *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
  *
+ * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
+ * TLB2 storage attibute fields. Those are:
+ *
+ *   TLB2:
+ *   0...10    11   12   13   14   15   16...31
+ *   no change WL1  IL1I IL1D IL2I IL2D no change
+ *
  * There are some constrains and options, to decide mapping software bits
  * into TLB entry.
  *
index 9e8ed6824e152e24a12a0cdfa3705aeafef97ecc..81ffe3b3c1ce771b29062d5111d1c23d5aa94875 100644 (file)
@@ -178,9 +178,6 @@ enum ps3_cpu_binding {
        PS3_BINDING_CPU_1 = 1,
 };
 
-int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
-       unsigned int *virq);
-int ps3_virq_destroy(unsigned int virq);
 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
        unsigned int *virq);
 int ps3_irq_plug_destroy(unsigned int virq);
index e3c845b0f76438af611c8450c36e4660b076207b..6abead6e681aacd732efc40c5fd0431824af8f37 100644 (file)
 
 /* Flag indicating progress during context switch. */
 #define SPU_CONTEXT_SWITCH_PENDING     0UL
+#define SPU_CONTEXT_FAULT_PENDING      1UL
 
 struct spu_context;
 struct spu_runqueue;
@@ -128,9 +129,11 @@ struct spu {
        unsigned int irqs[3];
        u32 node;
        u64 flags;
-       u64 dar;
-       u64 dsisr;
        u64 class_0_pending;
+       u64 class_0_dar;
+       u64 class_0_dsisr;
+       u64 class_1_dar;
+       u64 class_1_dsisr;
        size_t ls_size;
        unsigned int slb_replace;
        struct mm_struct *mm;
@@ -143,7 +146,7 @@ struct spu {
 
        void (* wbox_callback)(struct spu *spu);
        void (* ibox_callback)(struct spu *spu);
-       void (* stop_callback)(struct spu *spu);
+       void (* stop_callback)(struct spu *spu, int irq);
        void (* mfc_callback)(struct spu *spu);
 
        char irq_c0[8];
index 0ab6bff86078e955dd10c3da1c282fe29773f33f..129ec148d4512b1a63ac6dbcbf3321ac07712ba9 100644 (file)
@@ -254,7 +254,8 @@ struct spu_state {
        u64 spu_chnldata_RW[32];
        u32 spu_mailbox_data[4];
        u32 pu_mailbox_data[1];
-       u64 dar, dsisr, class_0_pending;
+       u64 class_0_dar, class_0_dsisr, class_0_pending;
+       u64 class_1_dar, class_1_dsisr;
        unsigned long suspend_time;
        spinlock_t register_lock;
 };
index b3ca41fc8bb149c78667f132a855f2a1a28ad029..2b8a458f990a8b73e72ac2da42322812f9094bba 100644 (file)
@@ -30,7 +30,7 @@ asmlinkage int sys_fork(unsigned long p1, unsigned long p2,
 asmlinkage int sys_vfork(unsigned long p1, unsigned long p2,
                unsigned long p3, unsigned long p4, unsigned long p5,
                unsigned long p6, struct pt_regs *regs);
-asmlinkage int sys_pipe(int __user *fildes);
+asmlinkage long sys_pipe(int __user *fildes);
 asmlinkage long sys_rt_sigaction(int sig,
                const struct sigaction __user *act,
                struct sigaction __user *oact, size_t sigsetsize);
index c243a6ac60e528506b9c4fc48bea7f6146d818b5..d3374bc865ba565c803056ed33cc57d64241d670 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef _ASM_POWERPC_TYPES_H
 #define _ASM_POWERPC_TYPES_H
 
+#ifdef __powerpc64__
+# include <asm-generic/int-l64.h>
+#else
+# include <asm-generic/int-ll64.h>
+#endif
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -22,30 +28,6 @@ typedef unsigned int umode_t;
 typedef unsigned short umode_t;
 #endif
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifdef __powerpc64__
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-#else
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-#endif /* __powerpc64__ */
-
 typedef struct {
        __u32 u[4];
 } __attribute__((aligned(16))) __vector128;
@@ -64,24 +46,6 @@ typedef struct {
 
 #ifndef __ASSEMBLY__
 
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-#ifdef __powerpc64__
-typedef signed long s64;
-typedef unsigned long u64;
-#else
-typedef signed long long s64;
-typedef unsigned long long u64;
-#endif
-
 typedef __vector128 vector128;
 
 /* Physical address used by some IO functions */
index 0593cb889d45306cf6dac6f5b837ccbca081935f..70ebd333c55b24f474a7349f43047566f198b67e 100644 (file)
@@ -178,7 +178,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
 
 }
 
-extern inline void * xchg_ptr(void * m, void * val)
+static inline void * xchg_ptr(void * m, void * val)
 {
        return (void *) xchg_u32(m, (unsigned long) val);
 }
index f8204a4f2e0260917655a7877f126e9a53cd2186..18cbd8a39796c126fb9e1609f333c516d86a2e9d 100644 (file)
@@ -104,6 +104,7 @@ struct sie_block {
 
 struct kvm_vcpu_stat {
        u32 exit_userspace;
+       u32 exit_null;
        u32 exit_external_request;
        u32 exit_external_interrupt;
        u32 exit_stop_request;
index f0f4579eac13144b01f43eaf401428dfb2d8c5db..12fd9c4f0f154fe86baaed66c71103d24b15f65a 100644 (file)
@@ -125,6 +125,17 @@ page_get_storage_key(unsigned long addr)
        return skey;
 }
 
+#ifdef CONFIG_PAGE_STATES
+
+struct page;
+void arch_free_page(struct page *page, int order);
+void arch_alloc_page(struct page *page, int order);
+
+#define HAVE_ARCH_FREE_PAGE
+#define HAVE_ARCH_ALLOC_PAGE
+
+#endif
+
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
index 441d7c260857845cd6e0e1b557277565c448a2cd..d7d4e2eb3e6f327b8528387d2f1a3822fc8820c6 100644 (file)
@@ -471,6 +471,8 @@ struct task_struct;
 extern void user_enable_single_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define regs_return_value(regs)((regs)->gprs[2])
index c819ae25a8425ddfd72136dda4d674bf0f8b0ac1..e0d4500d5f95c14478205c60269849a8d5852ace 100644 (file)
@@ -116,6 +116,12 @@ extern void pfault_fini(void);
 #define pfault_fini()          do { } while (0)
 #endif /* CONFIG_PFAULT */
 
+#ifdef CONFIG_PAGE_STATES
+extern void cmma_init(void);
+#else
+static inline void cmma_init(void) { }
+#endif
+
 #define finish_arch_switch(prev) do {                                       \
        set_fs(current->thread.mm_segment);                                  \
        account_vtime(prev);                                                 \
index 2c5879ae90ca1864ea286b6e79c01d604314422f..0e959e20e9a310fa84812b824c5a64fb3229bf1d 100644 (file)
@@ -9,34 +9,16 @@
 #ifndef _S390_TYPES_H
 #define _S390_TYPES_H
 
+#ifndef __s390x__
+# include <asm-generic/int-ll64.h>
+#else
+# include <asm-generic/int-l64.h>
+#endif
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifndef __s390x__
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-#else /* __s390x__ */
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-#endif
-
 /* A address type so that arithmetic can be done on it & it can be upgraded to
    64 bit when necessary 
 */
@@ -58,24 +40,6 @@ typedef __signed__ long saddr_t;
 
 #ifndef __ASSEMBLY__
 
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-#ifndef __s390x__
-typedef signed long long s64;
-typedef unsigned long long u64;
-#else /* __s390x__ */
-typedef signed long s64;
-typedef unsigned  long u64;
-#endif /* __s390x__ */
-
 typedef u32 dma_addr_t;
 
 #ifndef __s390x__
index 092ff9d872c3e6cf352236e82e32466c116defb6..6813c3220a1d7a6693d2481d7dccda4cd7b3e76b 100644 (file)
@@ -3,19 +3,19 @@
 
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
+    defined(CONFIG_CPU_SUBTYPE_SH7721)
 #define SH_DMAC_BASE   0xa4010020
+#else
+#define SH_DMAC_BASE   0xa4000020
+#endif
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 #define DMTE0_IRQ      48
 #define DMTE1_IRQ      49
 #define DMTE2_IRQ      50
 #define DMTE3_IRQ      51
 #define DMTE4_IRQ      76
 #define DMTE5_IRQ      77
-
-#else
-#define SH_DMAC_BASE   0xa4000020
 #endif
 
 /* Definitions for the SuperH DMAC */
index c958fdaa00957ec835f2b7b1803baef4f5eb12d7..7438d1e21bc9b91feb4186d00ef996acb6dd50b6 100644 (file)
@@ -79,6 +79,10 @@ struct intc_desc {
        struct intc_sense_reg *sense_regs;
        unsigned int nr_sense_regs;
        char *name;
+#ifdef CONFIG_CPU_SH3
+       struct intc_mask_reg *ack_regs;
+       unsigned int nr_ack_regs;
+#endif
 };
 
 #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
@@ -91,10 +95,25 @@ struct intc_desc symbol __initdata = {                                      \
        chipname,                                                       \
 }
 
+#ifdef CONFIG_CPU_SH3
+#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups,       \
+       mask_regs, prio_regs, sense_regs, ack_regs)                     \
+struct intc_desc symbol __initdata = {                                 \
+       _INTC_ARRAY(vectors), _INTC_ARRAY(groups),                      \
+       _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs),                 \
+       _INTC_ARRAY(sense_regs),                                        \
+       chipname,                                                       \
+       _INTC_ARRAY(ack_regs),                                          \
+}
+#endif
+
 void __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
 void __init plat_irq_setup(void);
+#ifdef CONFIG_CPU_SH3
+void __init plat_irq_setup_sh3(void);
+#endif
 
 enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210,
        IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK,
index 356e50d067456ccbdd1cd9e2fefa37af5f5ee2b9..a4fbf0c84fb14aecf694379038d2d579c6607e2a 100644 (file)
@@ -268,11 +268,6 @@ unsigned long long peek_real_address_q(unsigned long long addr);
 unsigned long long poke_real_address_q(unsigned long long addr,
                                       unsigned long long val);
 
-/* arch/sh/mm/ioremap_64.c */
-unsigned long onchip_remap(unsigned long addr, unsigned long size,
-                          const char *name);
-extern void onchip_unmap(unsigned long vaddr);
-
 #if !defined(CONFIG_MMU)
 #define virt_to_phys(address)  ((unsigned long)(address))
 #define phys_to_virt(address)  ((void *)(address))
@@ -302,9 +297,16 @@ extern void onchip_unmap(unsigned long vaddr);
 void __iomem *__ioremap(unsigned long offset, unsigned long size,
                        unsigned long flags);
 void __iounmap(void __iomem *addr);
+
+/* arch/sh/mm/ioremap_64.c */
+unsigned long onchip_remap(unsigned long addr, unsigned long size,
+                          const char *name);
+extern void onchip_unmap(unsigned long vaddr);
 #else
 #define __ioremap(offset, size, flags) ((void __iomem *)(offset))
 #define __iounmap(addr)                        do { } while (0)
+#define onchip_remap(addr, size, name) (addr)
+#define onchip_unmap(addr)             do { } while (0)
 #endif /* CONFIG_MMU */
 
 static inline void __iomem *
diff --git a/include/asm-sh/keyboard.h b/include/asm-sh/keyboard.h
deleted file mode 100644 (file)
index 31dcc4f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef        __ASM_SH_KEYBOARD_H
-#define        __ASM_SH_KEYBOARD_H
-/*
- *     $Id: keyboard.h,v 1.1.1.1 2001/10/15 20:45:09 mrbrown Exp $
- */
-
-#include <linux/kd.h>
-#include <asm/machvec.h>
-
-#ifdef CONFIG_SH_MPC1211
-#include <asm/mpc1211/keyboard-mpc1211.h>
-#endif
-#endif
index fe58d00b250ce177e05512d4eaa8f1c9f8eb0273..87e812f68bb06d11c83b5ecca25b72d5cb35366b 100644 (file)
@@ -27,6 +27,7 @@
 /* ASID is 8-bit value, so it can't be 0x100 */
 #define MMU_NO_ASID                    0x100
 
+#ifdef CONFIG_MMU
 #define asid_cache(cpu)                (cpu_data[cpu].asid_cache)
 #define cpu_context(cpu, mm)   ((mm)->context.id[cpu])
 
@@ -38,7 +39,6 @@
  */
 #define MMU_VPN_MASK   0xfffff000
 
-#ifdef CONFIG_MMU
 #if defined(CONFIG_SUPERH32)
 #include "mmu_context_32.h"
 #else
@@ -129,6 +129,8 @@ static inline void switch_mm(struct mm_struct *prev,
 #define destroy_context(mm)            do { } while (0)
 #define set_asid(asid)                 do { } while (0)
 #define get_asid()                     (0)
+#define cpu_asid(cpu, mm)              ({ (void)cpu; 0; })
+#define switch_and_save_asid(asid)     (0)
 #define set_TTB(pgd)                   do { } while (0)
 #define get_TTB()                      (0)
 #define activate_context(mm,cpu)       do { } while (0)
index 7969f381dff2122133ac1f8ad4a399dc2124bc82..2969253c40421a90d2da89b7856c35cf2405138d 100644 (file)
@@ -41,6 +41,8 @@ void __init plat_mem_setup(void);
 
 /* arch/sh/kernel/setup.c */
 void __init setup_bootmem_allocator(unsigned long start_pfn);
+void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
+                              unsigned long end_pfn);
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_MMZONE_H */
diff --git a/include/asm-sh/mpc1211/dma.h b/include/asm-sh/mpc1211/dma.h
deleted file mode 100644 (file)
index e506d1a..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- */
-
-#ifndef _ASM_MPC1211_DMA_H
-#define _ASM_MPC1211_DMA_H
-
-#include <linux/spinlock.h>    /* And spinlocks */
-#include <asm/io.h>            /* need byte IO */
-#include <linux/delay.h>
-
-
-#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
-#define dma_outb       outb_p
-#else
-#define dma_outb       outb
-#endif
-
-#define dma_inb                inb
-
-/*
- * NOTES about DMA transfers:
- *
- *  controller 1: channels 0-3, byte operations, ports 00-1F
- *  controller 2: channels 4-7, word operations, ports C0-DF
- *
- *  - ALL registers are 8 bits only, regardless of transfer size
- *  - channel 4 is not used - cascades 1 into 2.
- *  - channels 0-3 are byte - addresses/counts are for physical bytes
- *  - channels 5-7 are word - addresses/counts are for physical words
- *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- *  - transfer count loaded to registers is 1 less than actual count
- *  - controller 2 offsets are all even (2x offsets for controller 1)
- *  - page registers for 5-7 don't use data bit 0, represent 128K pages
- *  - page registers for 0-3 use bit 0, represent 64K pages
- *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.  
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- *  Address mapping for channels 0-3:
- *
- *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *   P7  ...  P0  A7 ... A0  A7 ... A0   
- * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
- *
- *  Address mapping for channels 5-7:
- *
- *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
- *    |  ...  |   \   \   ... \  \  \  ... \  \
- *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
- *    |  ...  |     \   \   ... \  \  \  ... \
- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
- * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
- *
- */
-
-#define MAX_DMA_CHANNELS       8
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x10000000)
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE   0xC0    /* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG           0x08    /* command register (w) */
-#define DMA1_STAT_REG          0x08    /* status register (r) */
-#define DMA1_REQ_REG            0x09    /* request register (w) */
-#define DMA1_MASK_REG          0x0A    /* single-channel mask (w) */
-#define DMA1_MODE_REG          0x0B    /* mode register (w) */
-#define DMA1_CLEAR_FF_REG      0x0C    /* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
-#define DMA1_RESET_REG         0x0D    /* Master Clear (w) */
-#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
-#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
-
-#define DMA2_CMD_REG           0xD0    /* command register (w) */
-#define DMA2_STAT_REG          0xD0    /* status register (r) */
-#define DMA2_REQ_REG            0xD2    /* request register (w) */
-#define DMA2_MASK_REG          0xD4    /* single-channel mask (w) */
-#define DMA2_MODE_REG          0xD6    /* mode register (w) */
-#define DMA2_CLEAR_FF_REG      0xD8    /* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
-#define DMA2_RESET_REG         0xDA    /* Master Clear (w) */
-#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
-#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
-
-#define DMA_ADDR_0              0x00    /* DMA address registers */
-#define DMA_ADDR_1              0x02
-#define DMA_ADDR_2              0x04
-#define DMA_ADDR_3              0x06
-#define DMA_ADDR_4              0xC0
-#define DMA_ADDR_5              0xC4
-#define DMA_ADDR_6              0xC8
-#define DMA_ADDR_7              0xCC
-
-#define DMA_CNT_0               0x01    /* DMA count registers */
-#define DMA_CNT_1               0x03
-#define DMA_CNT_2               0x05
-#define DMA_CNT_3               0x07
-#define DMA_CNT_4               0xC2
-#define DMA_CNT_5               0xC6
-#define DMA_CNT_6               0xCA
-#define DMA_CNT_7               0xCE
-
-#define DMA_PAGE_0              0x87    /* DMA page registers */
-#define DMA_PAGE_1              0x83
-#define DMA_PAGE_2              0x81
-#define DMA_PAGE_3              0x82
-#define DMA_PAGE_5              0x8B
-#define DMA_PAGE_6              0x89
-#define DMA_PAGE_7              0x8A
-
-#define DMA_MODE_READ  0x44    /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE 0x48    /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-#define DMA_AUTOINIT   0x10
-
-
-extern spinlock_t  dma_spin_lock;
-
-static __inline__ unsigned long claim_dma_lock(void)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&dma_spin_lock, flags);
-       return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
-       spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(dmanr,  DMA1_MASK_REG);
-       else
-               dma_outb(dmanr & 3,  DMA2_MASK_REG);
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(dmanr | 4,  DMA1_MASK_REG);
-       else
-               dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
-}
-
-/* Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while holding the DMA lock ! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-       if (dmanr<=3)
-               dma_outb(0,  DMA1_CLEAR_FF_REG);
-       else
-               dma_outb(0,  DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-       if (dmanr<=3)
-               dma_outb(mode | dmanr,  DMA1_MODE_REG);
-       else
-               dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
-}
-
-/* Set only the page register bits of the transfer address.
- * This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
- */
-static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr)
-{
-       switch(dmanr) {
-               case 0:
-                       dma_outb( pagenr       & 0xff, DMA_PAGE_0);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_0 + 0x400);
-                       break;
-               case 1:
-                       dma_outb( pagenr       & 0xff, DMA_PAGE_1);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_1 + 0x400);
-                       break;
-               case 2:
-                       dma_outb( pagenr       & 0xff, DMA_PAGE_2);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_2 + 0x400);
-                       break;
-               case 3:
-                       dma_outb( pagenr       & 0xff, DMA_PAGE_3);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_3 + 0x400);
-                       break;
-               case 5:
-                       dma_outb( pagenr       & 0xfe, DMA_PAGE_5);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_5 + 0x400);
-                       break;
-               case 6:
-                       dma_outb( pagenr       & 0xfe, DMA_PAGE_6);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_6 + 0x400);
-                       break;
-               case 7:
-                       dma_outb( pagenr       & 0xfe, DMA_PAGE_7);
-                       dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_7 + 0x400);
-                       break;
-               }
-}
-
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-       set_dma_page(dmanr, a>>16);
-       if (dmanr <= 3)  {
-           dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-       }  else  {
-           dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-           dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-       }
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-        count--;
-       if (dmanr <= 3)  {
-           dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-           dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-        } else {
-           dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-           dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-        }
-}
-
-
-/* Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-       unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
-                                        : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
-       /* using short to get 16-bit wrap around */
-       unsigned short count;
-
-       count = 1 + dma_inb(io_port);
-       count += dma_inb(io_port) << 8;
-       return (dmanr<=3)? count : (count<<1);
-}
-
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);      /* release it again */
-
-/* From PCI */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy   (0)
-#endif
-
-#endif /* _ASM_MPC1211_DMA_H */
diff --git a/include/asm-sh/mpc1211/io.h b/include/asm-sh/mpc1211/io.h
deleted file mode 100644 (file)
index 6298370..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * include/asm-sh/mpc1211/io.h
- *
- * Copyright 2001 Saito.K & Jeanne
- *
- * IO functions for an Interface MPC-1211
- */
-
-#ifndef _ASM_SH_IO_MPC1211_H
-#define _ASM_SH_IO_MPC1211_H
-
-#include <linux/time.h>
-
-extern int mpc1211_irq_demux(int irq);
-
-extern void init_mpc1211_IRQ(void);
-extern void heartbeat_mpc1211(void);
-
-extern void mpc1211_rtc_gettimeofday(struct timeval *tv);
-extern int mpc1211_rtc_settimeofday(const struct timeval *tv);
-
-#endif /* _ASM_SH_IO_MPC1211_H */
diff --git a/include/asm-sh/mpc1211/keyboard.h b/include/asm-sh/mpc1211/keyboard.h
deleted file mode 100644 (file)
index 9020fee..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  MPC1211 specific keybord definitions
- *  Taken from the old asm-i386/keybord.h for PC/AT-style definitions
- *  created 3 Nov 1996 by Geert Uytterhoeven.
- */
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/kd.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-
-#define KEYBOARD_IRQ                   1
-#define DISABLE_KBD_DURING_INTERRUPTS  0
-
-extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-                          char raw_mode);
-extern char pckbd_unexpected_up(unsigned char keycode);
-extern void pckbd_leds(unsigned char leds);
-extern void pckbd_init_hw(void);
-extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
-extern pm_callback pm_kbd_request_override;
-
-#define kbd_setkeycode         pckbd_setkeycode
-#define kbd_getkeycode         pckbd_getkeycode
-#define kbd_translate          pckbd_translate
-#define kbd_unexpected_up      pckbd_unexpected_up
-#define kbd_leds               pckbd_leds
-#define kbd_init_hw            pckbd_init_hw
-
-/* resource allocation */
-#define kbd_request_region()
-#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
-                                             "keyboard", NULL)
-
-/* How to access the keyboard macros on this platform.  */
-#define kbd_read_input() inb(KBD_DATA_REG)
-#define kbd_read_status() inb(KBD_STATUS_REG)
-#define kbd_write_output(val) outb(val, KBD_DATA_REG)
-#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
-
-/* Some stoneage hardware needs delays after some operations.  */
-#define kbd_pause() do { } while(0)
-
-/*
- * Machine specific bits for the PS/2 driver
- */
-
-#define AUX_IRQ 12
-
-#define aux_request_irq(hand, dev_id)                                  \
-       request_irq(AUX_IRQ, hand, IRQF_SHARED, "PS2 Mouse", dev_id)
-
-#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
-
-#endif /* __KERNEL__ */
diff --git a/include/asm-sh/mpc1211/m1543c.h b/include/asm-sh/mpc1211/m1543c.h
deleted file mode 100644 (file)
index c95d132..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef __ASM_SH_M1543C_H
-#define __ASM_SH_M1543C_H
-
-/*
- * linux/include/asm-sh/m1543c.h
- * Copyright (C) 2001  Nobuhiro Sakawa
- * M1543C:PCI-ISA Bus Bridge with Super IO Chip support
- *
- * from
- *
- * linux/include/asm-sh/smc37c93x.h
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * SMSC 37C93x Super IO Chip support
- */
-
-/* Default base I/O address */
-#define FDC_PRIMARY_BASE       0x3f0
-#define IDE1_PRIMARY_BASE      0x1f0
-#define IDE1_SECONDARY_BASE    0x170
-#define PARPORT_PRIMARY_BASE   0x378
-#define COM1_PRIMARY_BASE      0x2f8
-#define COM2_PRIMARY_BASE      0x3f8
-#define COM3_PRIMARY_BASE      0x3e8
-#define RTC_PRIMARY_BASE       0x070
-#define KBC_PRIMARY_BASE       0x060
-#define AUXIO_PRIMARY_BASE     0x000   /* XXX */
-#define I8259_M_CR             0x20
-#define I8259_M_MR             0x21
-#define I8259_S_CR             0xa0
-#define I8259_S_MR             0xa1
-
-/* Logical device number */
-#define LDN_FDC                        0
-#define LDN_IDE1               1
-#define LDN_IDE2               2
-#define LDN_PARPORT            3
-#define LDN_COM1               4
-#define LDN_COM2               5
-#define LDN_COM3               11
-#define LDN_RTC                        6
-#define LDN_KBC                        7
-
-/* Configuration port and key */
-#define CONFIG_PORT            0x3f0
-#define INDEX_PORT             CONFIG_PORT
-#define DATA_PORT              0x3f1
-#define CONFIG_ENTER1          0x51
-#define CONFIG_ENTER2          0x23
-#define CONFIG_EXIT            0xbb
-
-/* Configuration index */
-#define CURRENT_LDN_INDEX      0x07
-#define POWER_CONTROL_INDEX    0x22
-#define ACTIVATE_INDEX         0x30
-#define IO_BASE_HI_INDEX       0x60
-#define IO_BASE_LO_INDEX       0x61
-#define IRQ_SELECT_INDEX       0x70
-#define PS2_IRQ_INDEX          0x72
-#define DMA_SELECT_INDEX       0x74
-
-/* UART stuff. Only for debugging.  */
-/* UART Register */
-
-#define UART_RBR       0x0     /* Receiver Buffer Register (Read Only) */
-#define UART_THR       0x0     /* Transmitter Holding Register (Write Only) */
-#define UART_IER       0x2     /* Interrupt Enable Register */
-#define UART_IIR       0x4     /* Interrupt Ident Register (Read Only) */
-#define UART_FCR       0x4     /* FIFO Control Register (Write Only) */
-#define UART_LCR       0x6     /* Line Control Register */
-#define UART_MCR       0x8     /* MODEM Control Register */
-#define UART_LSR       0xa     /* Line Status Register */
-#define UART_MSR       0xc     /* MODEM Status Register */
-#define UART_SCR       0xe     /* Scratch Register */
-#define UART_DLL       0x0     /* Divisor Latch (LS) */
-#define UART_DLM       0x2     /* Divisor Latch (MS) */
-
-#ifndef __ASSEMBLY__
-typedef struct uart_reg {
-       volatile __u16 rbr;
-       volatile __u16 ier;
-       volatile __u16 iir;
-       volatile __u16 lcr;
-       volatile __u16 mcr;
-       volatile __u16 lsr;
-       volatile __u16 msr;
-       volatile __u16 scr;
-} uart_reg;
-#endif /* ! __ASSEMBLY__ */
-
-/* Alias for Write Only Register */
-
-#define thr    rbr
-#define tcr    iir
-
-/* Alias for Divisor Latch Register */
-
-#define dll    rbr
-#define dlm    ier
-#define fcr    iir
-
-/* Interrupt Enable Register */
-
-#define IER_ERDAI      0x0100  /* Enable Received Data Available Interrupt */
-#define IER_ETHREI     0x0200  /* Enable Transmitter Holding Register Empty Interrupt */
-#define IER_ELSI       0x0400  /* Enable Receiver Line Status Interrupt */
-#define IER_EMSI       0x0800  /* Enable MODEM Status Interrupt */
-
-/* Interrupt Ident Register */
-
-#define IIR_IP         0x0100  /* "0" if Interrupt Pending */
-#define IIR_IIB0       0x0200  /* Interrupt ID Bit 0 */
-#define IIR_IIB1       0x0400  /* Interrupt ID Bit 1 */
-#define IIR_IIB2       0x0800  /* Interrupt ID Bit 2 */
-#define IIR_FIFO       0xc000  /* FIFOs enabled */
-
-/* FIFO Control Register */
-
-#define FCR_FEN                0x0100  /* FIFO enable */
-#define FCR_RFRES      0x0200  /* Receiver FIFO reset */
-#define FCR_TFRES      0x0400  /* Transmitter FIFO reset */
-#define FCR_DMA                0x0800  /* DMA mode select */
-#define FCR_RTL                0x4000  /* Receiver triger (LSB) */
-#define FCR_RTM                0x8000  /* Receiver triger (MSB) */
-
-/* Line Control Register */
-
-#define LCR_WLS0       0x0100  /* Word Length Select Bit 0 */
-#define LCR_WLS1       0x0200  /* Word Length Select Bit 1 */
-#define LCR_STB                0x0400  /* Number of Stop Bits */
-#define LCR_PEN                0x0800  /* Parity Enable */
-#define LCR_EPS                0x1000  /* Even Parity Select */
-#define LCR_SP         0x2000  /* Stick Parity */
-#define LCR_SB         0x4000  /* Set Break */
-#define LCR_DLAB       0x8000  /* Divisor Latch Access Bit */
-
-/* MODEM Control Register */
-
-#define MCR_DTR                0x0100  /* Data Terminal Ready */
-#define MCR_RTS                0x0200  /* Request to Send */
-#define MCR_OUT1       0x0400  /* Out 1 */
-#define MCR_IRQEN      0x0800  /* IRQ Enable */
-#define MCR_LOOP       0x1000  /* Loop */
-
-/* Line Status Register */
-
-#define LSR_DR         0x0100  /* Data Ready */
-#define LSR_OE         0x0200  /* Overrun Error */
-#define LSR_PE         0x0400  /* Parity Error */
-#define LSR_FE         0x0800  /* Framing Error */
-#define LSR_BI         0x1000  /* Break Interrupt */
-#define LSR_THRE       0x2000  /* Transmitter Holding Register Empty */
-#define LSR_TEMT       0x4000  /* Transmitter Empty */
-#define LSR_FIFOE      0x8000  /* Receiver FIFO error */
-
-/* MODEM Status Register */
-
-#define MSR_DCTS       0x0100  /* Delta Clear to Send */
-#define MSR_DDSR       0x0200  /* Delta Data Set Ready */
-#define MSR_TERI       0x0400  /* Trailing Edge Ring Indicator */
-#define MSR_DDCD       0x0800  /* Delta Data Carrier Detect */
-#define MSR_CTS                0x1000  /* Clear to Send */
-#define MSR_DSR                0x2000  /* Data Set Ready */
-#define MSR_RI         0x4000  /* Ring Indicator */
-#define MSR_DCD                0x8000  /* Data Carrier Detect */
-
-/* Baud Rate Divisor */
-
-#define UART_CLK       (1843200)       /* 1.8432 MHz */
-#define UART_BAUD(x)   (UART_CLK / (16 * (x)))
-
-/* RTC register definition */
-#define RTC_SECONDS             0
-#define RTC_SECONDS_ALARM       1
-#define RTC_MINUTES             2
-#define RTC_MINUTES_ALARM       3
-#define RTC_HOURS               4
-#define RTC_HOURS_ALARM         5
-#define RTC_DAY_OF_WEEK         6
-#define RTC_DAY_OF_MONTH        7
-#define RTC_MONTH               8
-#define RTC_YEAR                9
-#define RTC_FREQ_SELECT                10
-# define RTC_UIP 0x80
-# define RTC_DIV_CTL 0x70
-/* This RTC can work under 32.768KHz clock only.  */
-# define RTC_OSC_ENABLE 0x20
-# define RTC_OSC_DISABLE 0x00
-#define RTC_CONTROL            11
-# define RTC_SET 0x80
-# define RTC_PIE 0x40
-# define RTC_AIE 0x20
-# define RTC_UIE 0x10
-# define RTC_SQWE 0x08
-# define RTC_DM_BINARY 0x04
-# define RTC_24H 0x02
-# define RTC_DST_EN 0x01
-
-#endif  /* __ASM_SH_M1543C_H */
diff --git a/include/asm-sh/mpc1211/mc146818rtc.h b/include/asm-sh/mpc1211/mc146818rtc.h
deleted file mode 100644 (file)
index e245f2a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * MPC1211 uses PC/AT style RTC definitions.
- */
-#include <asm-x86/mc146818rtc_32.h>
-
-
diff --git a/include/asm-sh/mpc1211/mpc1211.h b/include/asm-sh/mpc1211/mpc1211.h
deleted file mode 100644 (file)
index fa456c3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __ASM_SH_MPC1211_H
-#define __ASM_SH_MPC1211_H
-
-/*
- * linux/include/asm-sh/mpc1211.h
- *
- * Copyright (C) 2001  Saito.K & Jeanne
- *
- * Interface MPC-1211 support
- */
-
-#define PA_PCI_IO       (0xa4000000)    /* PCI I/O space */
-#define PA_PCI_MEM      (0xb0000000)    /* PCI MEM space */
-
-#define PCIPAR          (0xa4000cf8)    /* PCI Config address */
-#define PCIPDR          (0xa4000cfc)    /* PCI Config data    */
-
-#endif  /* __ASM_SH_MPC1211_H */
diff --git a/include/asm-sh/mpc1211/pci.h b/include/asm-sh/mpc1211/pci.h
deleted file mode 100644 (file)
index d9162c5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *     Low-Level PCI Support for MPC-1211
- *
- *      (c) 2002 Saito.K & Jeanne
- *
- */
-
-#ifndef _PCI_MPC1211_H_
-#define _PCI_MPC1211_H_
-
-#include <linux/pci.h>
-
-/* set debug level 4=verbose...1=terse */
-//#define DEBUG_PCI 3
-#undef DEBUG_PCI
-
-#ifdef DEBUG_PCI
-#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
-#else
-#define PCIDBG(n, x...)
-#endif
-
-/* startup values */
-#define PCI_PROBE_BIOS    1
-#define PCI_PROBE_CONF1   2
-#define PCI_PROBE_CONF2   4
-#define PCI_NO_CHECKS     0x400
-#define PCI_ASSIGN_ROMS   0x1000
-#define PCI_BIOS_IRQ_SCAN 0x2000
-
-/* MPC-1211 Specific Values */
-#define PCIPAR            (0xa4000cf8)    /* PCI Config address */
-#define PCIPDR            (0xa4000cfc)    /* PCI Config data    */
-
-#define PA_PCI_IO         (0xa4000000)    /* PCI I/O space */
-#define PA_PCI_MEM        (0xb0000000)    /* PCI MEM space */
-
-#endif /* _PCI_MPC1211_H_ */
index a33838f23a6d879b1b443554f66c36b1d6e685a8..306f7359f7d4c345a9cb8b19b7556d79720a3969 100644 (file)
 #define IRQ_SCIF0              (HL_FPGA_IRQ_BASE + 15)
 #define IRQ_SCIF1              (HL_FPGA_IRQ_BASE + 16)
 
-unsigned char *highlander_init_irq_r7780mp(void);
-unsigned char *highlander_init_irq_r7780rp(void);
-unsigned char *highlander_init_irq_r7785rp(void);
+unsigned char *highlander_plat_irq_setup(void);
 
 #endif  /* __ASM_SH_RENESAS_R7780RP */
index 0308e05fc57be27a1fd48f3bfeaccee9a7b0a305..0a96f3af69e3122ff6ea8b8646349ed12d4f000d 100644 (file)
@@ -56,6 +56,7 @@ static inline void __flush_tlb_slot(unsigned long long slot)
        __asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot));
 }
 
+#ifdef CONFIG_MMU
 /* arch/sh64/mm/tlb.c */
 int sh64_tlb_init(void);
 unsigned long long sh64_next_free_dtlb_entry(void);
@@ -64,6 +65,13 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry);
 void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
                         unsigned long asid, unsigned long paddr);
 void sh64_teardown_tlb_slot(unsigned long long config_addr);
-
+#else
+#define sh64_tlb_init()                                        do { } while (0)
+#define sh64_next_free_dtlb_entry()                    (0)
+#define sh64_get_wired_dtlb_entry()                    (0)
+#define sh64_put_wired_dtlb_entry(entry)               do { } while (0)
+#define sh64_setup_tlb_slot(conf, virt, asid, phys)    do { } while (0)
+#define sh64_teardown_tlb_slot(addr)                   do { } while (0)
+#endif /* CONFIG_MMU */
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_SH_TLB_64_H */
index 34cdb28e8f4429c2deb7ed7e96ec9e07c50bbd98..95f0085e098a6859d746581b3b4b616439062854 100644 (file)
        .nr_balance_failed      = 0,                    \
 }
 
+#define cpu_to_node(cpu)       ((void)(cpu),0)
+#define parent_node(node)      ((void)(node),0)
+
+#define node_to_cpumask(node)  ((void)node, cpu_online_map)
+#define node_to_first_cpu(node)        ((void)(node),0)
+
+#define pcibus_to_node(bus)    ((void)(bus), -1)
+#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
+                                       CPU_MASK_ALL : \
+                                       node_to_cpumask(pcibus_to_node(bus)) \
+                               )
 #endif
 
 #include <asm-generic/topology.h>
index a6e1d4126e6756fdc0dbf78f345637bc42eb3b72..beea4e6f8dfd927c181137016e8b5f1c40e8f59f 100644 (file)
@@ -1,29 +1,12 @@
 #ifndef __ASM_SH_TYPES_H
 #define __ASM_SH_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -35,19 +18,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-
-typedef __signed__ char s8;
-typedef unsigned char u8;
-
-typedef __signed__ short s16;
-typedef unsigned short u16;
-
-typedef __signed__ int s32;
-typedef unsigned int u32;
-
-typedef __signed__ long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index f956b7b316c7a102cd25005fd1f60ebfeabd5fb5..a9b68d094844eb7a93556edf8e7c0016d380f46c 100644 (file)
@@ -274,7 +274,9 @@ struct exception_table_entry
        unsigned long insn, fixup;
 };
 
+#ifdef CONFIG_MMU
 #define ARCH_HAS_SEARCH_EXTABLE
+#endif
 
 /* Returns 0 if exception not found and fixup.unit otherwise.  */
 extern unsigned long search_exception_table(unsigned long addr);
index 17ba82ee220a791c40b13d4079ab607c11f4c2a4..7becc846544aa76813a912292de177451f954505 100644 (file)
@@ -34,9 +34,6 @@ extern unsigned int prom_rev, prom_prev;
  */
 extern int prom_root_node;
 
-/* PROM stdin and stdout */
-extern int prom_stdin, prom_stdout;
-
 /* Pointer to prom structure containing the device tree traversal
  * and usage utility functions.  Only prom-lib should use these,
  * users use the interface defined by the library only!
@@ -84,20 +81,6 @@ extern int prom_devclose(int device_handle);
 extern void prom_seek(int device_handle, unsigned int seek_hival,
                      unsigned int seek_lowval);
 
-/* Machine memory configuration routine. */
-
-/* This function returns a V0 format memory descriptor table, it has three
- * entries.  One for the total amount of physical ram on the machine, one
- * for the amount of physical ram available, and one describing the virtual
- * areas which are allocated by the prom.  So, in a sense the physical
- * available is a calculation of the total physical minus the physical mapped
- * by the prom with virtual mappings.
- *
- * These lists are returned pre-sorted, this should make your life easier
- * since the prom itself is way too lazy to do such nice things.
- */
-extern struct linux_mem_v0 *prom_meminfo(void);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
index 39ccf2da297c757e6b9e47f60d3dddec04bb4da4..1625a8c3e0d239f8b989026183a42316219a6ad0 100644 (file)
 
 /* The following structure is used to hold the physical
  * memory configuration of the machine.  This is filled in
- * probe_memory() and is later used by mem_init() to set up
- * mem_map[].  We statically allocate SPARC_PHYS_BANKS of
+ * prom_meminit() and is later used by mem_init() to set up
+ * mem_map[].  We statically allocate SPARC_PHYS_BANKS+1 of
  * these structs, this is arbitrary.  The entry after the
  * last valid one has num_bytes==0.
  */
-
 struct sparc_phys_banks {
   unsigned long base_addr;
   unsigned long num_bytes;
index 19c9780511180f2b24378bf26dfdeff9ecb535c8..213970477a2499a25723eaf8513b610db2d453d1 100644 (file)
@@ -25,6 +25,7 @@
 #define PSR_PIL     0x00000f00         /* processor interrupt level  */
 #define PSR_EF      0x00001000         /* enable floating point      */
 #define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
 #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
 #define PSR_ICC     0x00f00000         /* integer condition codes    */
 #define PSR_C       0x00100000         /* carry bit                  */
index 8201a7b29d49bdc7052793b4ccac9b75fb5b8b73..0afb867d6c1b242b36a1f446b71553773b0f5289 100644 (file)
@@ -10,6 +10,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/types.h>
+
 struct pt_regs {
        unsigned long psr;
        unsigned long pc;
@@ -39,6 +41,16 @@ struct pt_regs {
 #define UREG_FP        UREG_I6
 #define UREG_RETPC     UREG_I7
 
+static inline bool pt_regs_is_syscall(struct pt_regs *regs)
+{
+       return (regs->psr & PSR_SYSCALL);
+}
+
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
+{
+       return (regs->psr &= ~PSR_SYSCALL);
+}
+
 /* A register window */
 struct reg_window {
        unsigned long locals[8];
@@ -149,6 +161,7 @@ extern void show_regs(struct pt_regs *);
 #define SF_XXARG  0x5c
 
 /* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
 #define PTRACE_GETREGS            12
 #define PTRACE_SETREGS            13
 #define PTRACE_GETFPREGS          14
index d03a21c97abbda83d56ba4264cd9e4921d659158..94071c75701f4b1c8511cdf768c298ce988fa364 100644 (file)
@@ -199,13 +199,7 @@ typedef struct sigaltstack {
        size_t          ss_size;
 } stack_t;
 
-struct sparc_deliver_cookie {
-       int restart_syscall;
-       unsigned long orig_i0;
-};
-
-struct pt_regs;
-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* !(__KERNEL__) */
 
index 42fc6ed9815690e563fceb6ca1590df9e86f5df4..1b08ef860a6654f768de3cdadcbd25380fa8a83b 100644 (file)
@@ -2,11 +2,6 @@
 #ifndef _SPARC_TYPES_H
 #define _SPARC_TYPES_H
 
-/*
- * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space.
- */
-
 /*
  * This file is never included by application software unless
  * explicitly requested (e.g., via linux/types.h) in which case the
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-ll64.h>
 
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-
 #endif /* __ASSEMBLY__ */
 
 #ifdef __KERNEL__
@@ -39,18 +23,6 @@ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef __signed__ char s8;
-typedef unsigned char u8;
-
-typedef __signed__ short s16;
-typedef unsigned short u16;
-
-typedef __signed__ int s32;
-typedef unsigned int u32;
-
-typedef __signed__ long long s64;
-typedef unsigned long long u64;
-
 typedef u32 dma_addr_t;
 typedef u32 dma64_addr_t;
 
index 5590ce6bd0767273e2bc5e296af9fbf1d91e7864..3614ca04753fff3792fbab5e8029296f56aa7840 100644 (file)
@@ -12,6 +12,7 @@
 #define PSR_PIL     0x00000f00         /* processor interrupt level  */
 #define PSR_EF      0x00001000         /* enable floating point      */
 #define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
 #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
 #define PSR_ICC     0x00f00000         /* integer condition codes    */
 #define PSR_C       0x00100000         /* carry bit                  */
@@ -30,6 +31,7 @@ static inline unsigned int tstate_to_psr(unsigned long tstate)
                PSR_S                                   |
                ((tstate & TSTATE_ICC) >> 12)           |
                ((tstate & TSTATE_XCC) >> 20)           |
+               ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
                PSR_V8PLUS);
 }
 
index f3c45484c63635fef86342942d715ce83ea25c16..949aebaf991d601a5d01a6a4f4b4db26f463feb5 100644 (file)
@@ -62,6 +62,7 @@
 #define TSTATE_PRIV    _AC(0x0000000000000400,UL) /* Privilege.        */
 #define TSTATE_IE      _AC(0x0000000000000200,UL) /* Interrupt Enable. */
 #define TSTATE_AG      _AC(0x0000000000000100,UL) /* Alternate Globals.*/
+#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap   */
 #define TSTATE_CWP     _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */
 
 /* Floating-Point Registers State Register.
index 714b81956f32a653a4c9863edbbc2aefb16b89a8..90972a5ada59f8e3b324f430587922c7cbb2a562 100644 (file)
@@ -42,16 +42,14 @@ static inline int pt_regs_trap_type(struct pt_regs *regs)
        return regs->magic & 0x1ff;
 }
 
-static inline int pt_regs_clear_trap_type(struct pt_regs *regs)
+static inline bool pt_regs_is_syscall(struct pt_regs *regs)
 {
-       return regs->magic &= ~0x1ff;
+       return (regs->tstate & TSTATE_SYSCALL);
 }
 
-static inline bool pt_regs_is_syscall(struct pt_regs *regs)
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
 {
-       int tt = pt_regs_trap_type(regs);
-
-       return (tt == 0x110 || tt == 0x111 || tt == 0x16d);
+       return (regs->tstate &= ~TSTATE_SYSCALL);
 }
 
 struct pt_regs32 {
@@ -298,6 +296,7 @@ extern void __show_regs(struct pt_regs *);
 #define SF_XXARG  0x5c
 
 /* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
 #define PTRACE_GETREGS            12
 #define PTRACE_SETREGS            13
 #define PTRACE_GETFPREGS          14
index fa6f467389db2735daf794361b481a08b40ec942..c49f32d387071594d67eef8a3284e80fcb3b9251 100644 (file)
@@ -186,13 +186,7 @@ struct k_sigaction {
        void __user             *ka_restorer;
 };
 
-struct signal_deliver_cookie {
-       int restart_syscall;
-       unsigned long orig_i0;
-};
-
-struct pt_regs;
-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* !(__KERNEL__) */
 
index 1b55538b944fa82ce802dbdd358dde60818f7ae8..52d67d394107f5fe57d3a29f14aada25008aec27 100644 (file)
         nop;
        
 #define SYSCALL_TRAP(routine, systbl)                  \
+       rdpr    %pil, %g2;                              \
+       mov     TSTATE_SYSCALL, %g3;                    \
        sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etrap;                            \
+       ba,pt   %xcc, etrap_syscall;                    \
 109:    or     %g7, %lo(109b), %g7;                    \
        sethi   %hi(systbl), %l7;                       \
        ba,pt   %xcc, routine;                          \
-        or     %l7, %lo(systbl), %l7;                  \
-       nop; nop;
+        or     %l7, %lo(systbl), %l7;
        
 #define TRAP_UTRAP(handler,lvl)                                \
        mov     handler, %g3;                           \
index d0ee7f105838abadfb8b47504a6d0033d49347b8..5dbe04f4044a98043f6dbadd532b839cdc0bbe44 100644 (file)
@@ -9,28 +9,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-l64.h>
 
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space.
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
 #endif /* __ASSEMBLY__ */
 
 #ifdef __KERNEL__
@@ -39,18 +23,6 @@ typedef unsigned long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef __signed__ char s8;
-typedef unsigned char u8;
-
-typedef __signed__ short s16;
-typedef unsigned short u16;
-
-typedef __signed__ int s32;
-typedef unsigned int u32;
-
-typedef __signed__ long s64;
-typedef unsigned long u64;
-
 /* Dma addresses come in generic and 64-bit flavours.  */
 
 typedef u32 dma_addr_t;
index 7b73b2cd5b340be8212d45657eb44ad9cda71425..1e17f7409cabc072df18f3f516b0df0bc2a58506 100644 (file)
@@ -3,5 +3,4 @@
 
 #include "asm/arch/div64.h"
 
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
 #endif
index de389a477cdd648ad8493164228737c03ef1303f..4a2037f8204baff05ed0b86e097fcc07e465f456 100644 (file)
@@ -15,8 +15,9 @@
 #define SIGIO_WRITE_IRQ        11
 #define TELNETD_IRQ            12
 #define XTERM_IRQ              13
+#define RANDOM_IRQ             14
 
-#define LAST_IRQ XTERM_IRQ
+#define LAST_IRQ RANDOM_IRQ
 #define NR_IRQS (LAST_IRQ + 1)
 
 #endif
diff --git a/include/asm-um/keyboard.h b/include/asm-um/keyboard.h
deleted file mode 100644 (file)
index ee2e230..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_KEYBOARD_H
-#define __UM_KEYBOARD_H
-
-#include "asm/arch/keyboard.h"
-
-#endif
index 381f96b1c8259153fca3433c9eca220031fa1e63..916e1a61999f4b414b94e31db9b928c09ef69aff 100644 (file)
@@ -7,16 +7,20 @@
 #ifndef __UM_PAGE_H
 #define __UM_PAGE_H
 
-struct page;
-
-#include <linux/types.h>
-#include <asm/vm-flags.h>
+#include <linux/const.h>
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT     12
-#define PAGE_SIZE      (1UL << PAGE_SHIFT)
+#define PAGE_SIZE      (_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
+#ifndef __ASSEMBLY__
+
+struct page;
+
+#include <linux/types.h>
+#include <asm/vm-flags.h>
+
 /*
  * These are used to make use of C type-checking..
  */
@@ -120,4 +124,5 @@ extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
 #include <asm-generic/memory_model.h>
 #include <asm-generic/page.h>
 
-#endif
+#endif /* __ASSEMBLY__ */
+#endif /* __UM_PAGE_H */
index 284bda88211293b040fcee3f3b50143d3bd0b7cb..89f735ee41dd6b478dbed3cdf6e16acdd6d18082 100644 (file)
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+#include <asm-generic/int-ll64.h>
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 #endif /* !__ASSEMBLY__ */
 
 /*
@@ -43,18 +25,6 @@ __extension__ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
index b81a4d4d333787e4c9e8b69cb74fd190f09c4e69..ee4b3ead6a438d8d68c626803031072f60a19060 100644 (file)
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
 /* Technically wrong, but this avoids compilation errors on some gcc
    versions. */
-#define ADDR "=m" (*(volatile long *)addr)
-#define BIT_ADDR "=m" (((volatile int *)addr)[nr >> 5])
+#define ADDR "=m" (*(volatile long *) addr)
 #else
 #define ADDR "+m" (*(volatile long *) addr)
-#define BIT_ADDR "+m" (((volatile int *)addr)[nr >> 5])
 #endif
-#define BASE_ADDR "m" (*(volatile int *)addr)
 
 /**
  * set_bit - Atomically set a bit in memory
@@ -77,7 +74,7 @@ static inline void __set_bit(int nr, volatile void *addr)
  */
 static inline void clear_bit(int nr, volatile void *addr)
 {
-       asm volatile(LOCK_PREFIX "btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+       asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr));
 }
 
 /*
@@ -96,7 +93,7 @@ static inline void clear_bit_unlock(unsigned nr, volatile void *addr)
 
 static inline void __clear_bit(int nr, volatile void *addr)
 {
-       asm volatile("btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+       asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
 }
 
 /*
@@ -131,7 +128,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile void *addr)
  */
 static inline void __change_bit(int nr, volatile void *addr)
 {
-       asm volatile("btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+       asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
 }
 
 /**
@@ -145,7 +142,7 @@ static inline void __change_bit(int nr, volatile void *addr)
  */
 static inline void change_bit(int nr, volatile void *addr)
 {
-       asm volatile(LOCK_PREFIX "btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+       asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr));
 }
 
 /**
@@ -191,9 +188,10 @@ static inline int __test_and_set_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
-       asm volatile("bts %2,%3\n\t"
-                    "sbb %0,%0"
-                    : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+       asm("bts %2,%1\n\t"
+           "sbb %0,%0"
+           : "=r" (oldbit), ADDR
+           : "Ir" (nr));
        return oldbit;
 }
 
@@ -229,9 +227,10 @@ static inline int __test_and_clear_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
-       asm volatile("btr %2,%3\n\t"
+       asm volatile("btr %2,%1\n\t"
                     "sbb %0,%0"
-                    : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+                    : "=r" (oldbit), ADDR
+                    : "Ir" (nr));
        return oldbit;
 }
 
@@ -240,9 +239,10 @@ static inline int __test_and_change_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
-       asm volatile("btc %2,%3\n\t"
+       asm volatile("btc %2,%1\n\t"
                     "sbb %0,%0"
-                    : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+                    : "=r" (oldbit), ADDR
+                    : "Ir" (nr) : "memory");
 
        return oldbit;
 }
@@ -276,11 +276,10 @@ static inline int variable_test_bit(int nr, volatile const void *addr)
 {
        int oldbit;
 
-       asm volatile("bt %2,%3\n\t"
+       asm volatile("bt %2,%1\n\t"
                     "sbb %0,%0"
                     : "=r" (oldbit)
-                    : "m" (((volatile const int *)addr)[nr >> 5]),
-                      "Ir" (nr), BASE_ADDR);
+                    : "m" (*(unsigned long *)addr), "Ir" (nr));
 
        return oldbit;
 }
@@ -397,8 +396,6 @@ static inline int fls(int x)
 }
 #endif /* __KERNEL__ */
 
-#undef BASE_ADDR
-#undef BIT_ADDR
 #undef ADDR
 
 static inline void set_bit_string(unsigned long *bitmap,
index e8659909e5f69a93dc781402fc5cf5db9df95c75..f62f4733606bfa9388ad98dce4a0c72fec7e9b2f 100644 (file)
 
 /* extensible setup data list node */
 struct setup_data {
-       u64 next;
-       u32 type;
-       u32 len;
-       u8 data[0];
+       __u64 next;
+       __u32 type;
+       __u32 len;
+       __u8 data[0];
 };
 
 struct setup_header {
index 0dbf8bf3ef0a8d06308ea3cf8e72612c28c016c2..9a2d644c08efc0981dbc13b1700e81917fef7c63 100644 (file)
        __mod;                                                  \
 })
 
-/*
- * (long)X = ((long long)divs) / (long)div
- * (long)rem = ((long long)divs) % (long)div
- *
- * Warning, this will do an exception if X overflows.
- */
-#define div_long_long_rem(a, b, c) div_ll_X_l_rem(a, b, c)
-
-static inline long div_ll_X_l_rem(long long divs, long div, long *rem)
+static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 {
-       long dum2;
-       asm("divl %2":"=a"(dum2), "=d"(*rem)
-           : "rm"(div), "A"(divs));
-
-       return dum2;
-
+       union {
+               u64 v64;
+               u32 v32[2];
+       } d = { dividend };
+       u32 upper;
+
+       upper = d.v32[1];
+       d.v32[1] = 0;
+       if (upper >= divisor) {
+               d.v32[1] = upper / divisor;
+               upper %= divisor;
+       }
+       asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
+               "rm" (divisor), "0" (d.v32[0]), "1" (upper));
+       return d.v64;
 }
-
-extern uint64_t div64_64(uint64_t dividend, uint64_t divisor);
+#define div_u64_rem    div_u64_rem
 
 #else
 # include <asm-generic/div64.h>
index 1241e6ad1935b99c6273554eb8501f05833b28cb..4edf7514a75033d8173428e1ce1640995a87f154 100644 (file)
@@ -27,6 +27,7 @@ static inline void *dmi_alloc(unsigned len)
 
 #endif
 
+/* Use early IO mappings for DMI because it's initialized early */
 #define dmi_ioremap early_ioremap
 #define dmi_iounmap early_iounmap
 
index 7154dc4de9511692c5417973ac866f4883d2d7c3..6e6458853a36322bc2830628270f8a6656d6c9f3 100644 (file)
@@ -185,16 +185,14 @@ static inline int is_geode(void)
        return (is_geode_gx() || is_geode_lx());
 }
 
-/*
- * The VSA has virtual registers that we can query for a signature.
- */
+#ifdef CONFIG_MGEODE_LX
+extern int geode_has_vsa2(void);
+#else
 static inline int geode_has_vsa2(void)
 {
-       outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
-       outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
-
-       return (inw(VSA_VRC_DATA) == VSA_SIG);
+       return 0;
 }
+#endif
 
 /* MFGPTs */
 
index da2adb45f6e3949476ac0a4d2c1aa1cbb2024986..6b722d315936705605850bdd43141064bae9f71f 100644 (file)
@@ -175,7 +175,15 @@ static inline int save_i387(struct _fpstate __user *buf)
  */
 static inline int restore_i387(struct _fpstate __user *buf)
 {
-       set_used_math();
+       struct task_struct *tsk = current;
+       int err;
+
+       if (!used_math()) {
+               err = init_fpu(tsk);
+               if (err)
+                       return err;
+       }
+
        if (!(task_thread_info(current)->status & TS_USEDFPU)) {
                clts();
                task_thread_info(current)->status |= TS_USEDFPU;
index 6e73467a4fb13783ba21a73108e238e8e4e35fe7..049e81e797a0919e8090135c5b16fe5b99a32c5e 100644 (file)
@@ -133,11 +133,6 @@ extern void *early_ioremap(unsigned long offset, unsigned long size);
 extern void early_iounmap(void *addr, unsigned long size);
 extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
 
-/* Use early IO mappings for DMI because it's initialized early */
-#define dmi_ioremap early_ioremap
-#define dmi_iounmap early_iounmap
-#define dmi_alloc alloc_bootmem
-
 /*
  * ISA I/O bus memory addresses are 1:1 with the physical address.
  */
index 9d963cd6533c5d7541b71dac204d3debf524f685..1d8cd01fa5147221ccf6e598b8d8f0d3a100bf3e 100644 (file)
@@ -314,6 +314,9 @@ struct kvm_arch{
        struct page *apic_access_page;
 
        gpa_t wall_clock;
+
+       struct page *ept_identity_pagetable;
+       bool ept_identity_pagetable_done;
 };
 
 struct kvm_vm_stat {
@@ -422,6 +425,7 @@ struct kvm_x86_ops {
                                       struct kvm_run *run);
 
        int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
+       int (*get_tdp_level)(void);
 };
 
 extern struct kvm_x86_ops *kvm_x86_ops;
@@ -433,6 +437,9 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
 int kvm_mmu_create(struct kvm_vcpu *vcpu);
 int kvm_mmu_setup(struct kvm_vcpu *vcpu);
 void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
+void kvm_mmu_set_base_ptes(u64 base_pte);
+void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
+               u64 dirty_mask, u64 nx_mask, u64 x_mask);
 
 int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
 void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
@@ -620,7 +627,7 @@ static inline void fx_restore(struct i387_fxsave_struct *image)
        asm("fxrstor (%0)":: "r" (image));
 }
 
-static inline void fpu_init(void)
+static inline void fx_finit(void)
 {
        asm("finit");
 }
@@ -644,6 +651,7 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code)
 #define ASM_VMX_VMWRITE_RSP_RDX   ".byte 0x0f, 0x79, 0xd4"
 #define ASM_VMX_VMXOFF            ".byte 0x0f, 0x01, 0xc4"
 #define ASM_VMX_VMXON_RAX         ".byte 0xf3, 0x0f, 0xc7, 0x30"
+#define ASM_VMX_INVEPT           ".byte 0x66, 0x0f, 0x38, 0x80, 0x08"
 #define ASM_VMX_INVVPID                  ".byte 0x66, 0x0f, 0x38, 0x81, 0x08"
 
 #define MSR_IA32_TIME_STAMP_COUNTER            0x010
index 8b822b5a17861215eacfa2d7253ea99c84f310b7..88f60cc6a22737f8e45b20e36a67b27410bb5326 100644 (file)
@@ -4,7 +4,13 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_X86_PAT
 extern int pat_wc_enabled;
+extern void validate_pat_support(struct cpuinfo_x86 *c);
+#else
+static const int pat_wc_enabled = 0;
+static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
+#endif
 
 extern void pat_init(void);
 
@@ -12,5 +18,7 @@ extern int reserve_memtype(u64 start, u64 end,
                unsigned long req_type, unsigned long *ret_type);
 extern int free_memtype(u64 start, u64 end);
 
+extern void pat_disable(char *reason);
+
 #endif
 
index 577ab79c4c27b8ebaa84542806dfe4d3f217553f..d7f0403bbecb89a31c9097e79392c4c9b0c7eae5 100644 (file)
@@ -88,14 +88,7 @@ extern unsigned long pg0[];
 /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
 #define pmd_none(x)    (!(unsigned long)pmd_val((x)))
 #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT)
-
-extern int pmd_bad(pmd_t pmd);
-
-#define pmd_bad_v1(x)                                                  \
-       (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER)))
-#define        pmd_bad_v2(x)                                                   \
-       (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER |    \
-                                           _PAGE_PSE | _PAGE_NX)))
+#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
index a3bbf8766c1d62790d2f999bba1edac5dab7fa64..efe83dcbd41200fc6822a96ebea1a678fe452ef1 100644 (file)
@@ -158,14 +158,12 @@ static inline unsigned long pgd_bad(pgd_t pgd)
 
 static inline unsigned long pud_bad(pud_t pud)
 {
-       return pud_val(pud) &
-               ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+       return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
 }
 
 static inline unsigned long pmd_bad(pmd_t pmd)
 {
-       return pmd_val(pmd) &
-               ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+       return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
 }
 
 #define pte_none(x)    (!pte_val((x)))
index bc6376f1bc5a9d8029c8448b49fcba8685c9b7b8..21e89bf92f1c8cd547b697fcc37021388d8115e2 100644 (file)
  */
 
 #ifdef CONFIG_X86_32
-typedef char _slock_t;
-# define LOCK_INS_DEC "decb"
-# define LOCK_INS_XCH "xchgb"
-# define LOCK_INS_MOV "movb"
-# define LOCK_INS_CMP "cmpb"
 # define LOCK_PTR_REG "a"
 #else
-typedef int _slock_t;
-# define LOCK_INS_DEC "decl"
-# define LOCK_INS_XCH "xchgl"
-# define LOCK_INS_MOV "movl"
-# define LOCK_INS_CMP "cmpl"
 # define LOCK_PTR_REG "D"
 #endif
 
@@ -66,14 +56,14 @@ typedef int _slock_t;
 #if (NR_CPUS < 256)
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) != (tmp & 0xff));
 }
 
 static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
 }
@@ -130,14 +120,14 @@ static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
 #else
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
 }
 
 static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
 }
index 4f35a0fb4f22ac5ba6d459a45f4eb8971eb50cac..dcf3f8131d6b4b728643b84cd9d395b0ea4dd963 100644 (file)
 #ifndef _ASM_X86_TOPOLOGY_H
 #define _ASM_X86_TOPOLOGY_H
 
+#ifdef CONFIG_X86_32
+# ifdef CONFIG_X86_HT
+#  define ENABLE_TOPO_DEFINES
+# endif
+#else
+# ifdef CONFIG_SMP
+#  define ENABLE_TOPO_DEFINES
+# endif
+#endif
+
 #ifdef CONFIG_NUMA
 #include <linux/cpumask.h>
 #include <asm/mpspec.h>
@@ -130,10 +140,6 @@ extern unsigned long node_end_pfn[];
 extern unsigned long node_remap_size[];
 #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
 
-# ifdef CONFIG_X86_HT
-#  define ENABLE_TOPO_DEFINES
-# endif
-
 # define SD_CACHE_NICE_TRIES   1
 # define SD_IDLE_IDX           1
 # define SD_NEWIDLE_IDX                2
@@ -141,10 +147,6 @@ extern unsigned long node_remap_size[];
 
 #else
 
-# ifdef CONFIG_SMP
-#  define ENABLE_TOPO_DEFINES
-# endif
-
 # define SD_CACHE_NICE_TRIES   2
 # define SD_IDLE_IDX           2
 # define SD_NEWIDLE_IDX                2
index 63733f315688e03423f389352c506c35d5a53d5a..1ac80cd9acf8599a143ce5cf98913b91a668eda7 100644 (file)
@@ -1,34 +1,12 @@
 #ifndef _ASM_X86_TYPES_H
 #define _ASM_X86_TYPES_H
 
+#include <asm-generic/int-ll64.h>
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifdef __i386__
-# ifdef __GNUC__
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-# endif
-#else
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -44,18 +22,6 @@ typedef unsigned long long __u64;
 
 #ifndef __ASSEMBLY__
 
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
 typedef u64 dma64_addr_t;
 #if defined(CONFIG_X86_64) || defined(CONFIG_HIGHMEM64G)
 /* DMA addresses come in 32-bit and 64-bit flavours. */
index b27d841a8eb7f2b4e4e934ccd9a876a494ac2273..c89569a8da0cec6f2c664d073aa0010d265825ea 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef _XTENSA_TYPES_H
 #define _XTENSA_TYPES_H
 
+#include <asm-generic/int-ll64.h>
 
 #ifdef __ASSEMBLY__
 # define __XTENSA_UL(x)                (x)
 
 typedef unsigned short umode_t;
 
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__)
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#endif
-
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
 #ifdef __KERNEL__
 
-typedef __signed__ char s8;
-typedef unsigned char u8;
-
-typedef __signed__ short s16;
-typedef unsigned short u16;
-
-typedef __signed__ int s32;
-typedef unsigned int u32;
-
-typedef __signed__ long long s64;
-typedef unsigned long long u64;
-
-
 #define BITS_PER_LONG 32
 
 /* Dma addresses are 32-bits wide.  */
index 224658b8d80689560e6ebf7c7bd94c41a2ea76bf..833d208c25d64194525e8b1ff09d8ddaf261251d 100644 (file)
@@ -57,10 +57,14 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
                                        struct scatterlist *sg2)
 {
        sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
+       sg1[num - 1].page_link &= ~0x02;
 }
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
+       if (sg_is_last(sg))
+               return NULL;
+
        return (++sg)->length ? sg : (void *)sg_page(sg);
 }
 
index 78fade0a1e3528aaae16a306a47f22e91336e0e7..b7d81b2a90411bb16b5b4de8a7766c8547e1d01f 100644 (file)
@@ -346,6 +346,11 @@ unifdef-y += videodev.h
 unifdef-y += virtio_config.h
 unifdef-y += virtio_blk.h
 unifdef-y += virtio_net.h
+unifdef-y += virtio_9p.h
+unifdef-y += virtio_balloon.h
+unifdef-y += virtio_console.h
+unifdef-y += virtio_pci.h
+unifdef-y += virtio_ring.h
 unifdef-y += vt.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
index b2e1ba325b9a4c0d044ea20c6629bda8d4d27200..6129e58ca7c99407716acbf6482e2d02d09956e9 100644 (file)
@@ -8,8 +8,7 @@
 #ifndef _LINUX_ANON_INODES_H
 #define _LINUX_ANON_INODES_H
 
-int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
-                    const char *name, const struct file_operations *fops,
+int anon_inode_getfd(const char *name, const struct file_operations *fops,
                     void *priv);
 
 #endif /* _LINUX_ANON_INODES_H */
index 43b406def35f6bfadcdbf5b621995e7f920bc851..1abfe664c4446a9a64ea182ce680e6c08d1a3086 100644 (file)
@@ -110,7 +110,6 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits);
 
 extern int bitmap_scnprintf(char *buf, unsigned int len,
                        const unsigned long *src, int nbits);
-extern int bitmap_scnprintf_len(unsigned int len);
 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
                        unsigned long *dst, int nbits);
 extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
diff --git a/include/linux/calc64.h b/include/linux/calc64.h
deleted file mode 100644 (file)
index ebf4b8f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _LINUX_CALC64_H
-#define _LINUX_CALC64_H
-
-#include <linux/types.h>
-#include <asm/div64.h>
-
-/*
- * This is a generic macro which is used when the architecture
- * specific div64.h does not provide a optimized one.
- *
- * The 64bit dividend is divided by the divisor (data type long), the
- * result is returned and the remainder stored in the variable
- * referenced by remainder (data type long *). In contrast to the
- * do_div macro the dividend is kept intact.
- */
-#ifndef div_long_long_rem
-#define div_long_long_rem(dividend, divisor, remainder)        \
-       do_div_llr((dividend), divisor, remainder)
-
-static inline unsigned long do_div_llr(const long long dividend,
-                                      const long divisor, long *remainder)
-{
-       u64 result = dividend;
-
-       *(remainder) = do_div(result, divisor);
-       return (unsigned long) result;
-}
-#endif
-
-/*
- * Sign aware variation of the above. On some architectures a
- * negative dividend leads to an divide overflow exception, which
- * is avoided by the sign check.
- */
-static inline long div_long_long_rem_signed(const long long dividend,
-                                           const long divisor, long *remainder)
-{
-       long res;
-
-       if (unlikely(dividend < 0)) {
-               res = -div_long_long_rem(-dividend, divisor, remainder);
-               *remainder = -(*remainder);
-       } else
-               res = div_long_long_rem(dividend, divisor, remainder);
-
-       return res;
-}
-
-#endif
index 35094479ca557012e043ea0def0fbf9b6df11e65..55e434feec993d9656ccf6bcd31964005daa9667 100644 (file)
@@ -93,6 +93,8 @@ struct clocksource {
 #endif
 };
 
+extern struct clocksource *clock;      /* current clocksource */
+
 /*
  * Clock source flags bits::
  */
index 8fa7857e153bc7f7649ea25e088924fb0a6190f9..cf8d11cad5aef24dd99c57c3f7406d9ea4c541d6 100644 (file)
@@ -65,10 +65,11 @@ struct compat_timex {
        compat_long_t calcnt;
        compat_long_t errcnt;
        compat_long_t stbcnt;
+       compat_int_t tai;
 
        compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
        compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
-       compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
+       compat_int_t :32; compat_int_t :32; compat_int_t :32;
 };
 
 #define _COMPAT_NSIG_WORDS     (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
index dcae0c8d97e6e2d04a8db04494e899eb403e1c18..c8bd2daf95ec51e0f42ad05e6b8c13be1300ce16 100644 (file)
@@ -182,4 +182,16 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __section(S) __attribute__ ((__section__(#S)))
 #endif
 
+/*
+ * Prevent the compiler from merging or refetching accesses.  The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering.  One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.
+ */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
 #endif /* __LINUX_COMPILER_H */
index 9650806fe2ea266a6c786ec9a95d96adfe8269d3..5df3db58fcc65620fe5daf05752252c59048a21c 100644 (file)
@@ -289,13 +289,6 @@ static inline int __cpumask_scnprintf(char *buf, int len,
        return bitmap_scnprintf(buf, len, srcp->bits, nbits);
 }
 
-#define cpumask_scnprintf_len(len) \
-                       __cpumask_scnprintf_len((len))
-static inline int __cpumask_scnprintf_len(int len)
-{
-       return bitmap_scnprintf_len(len);
-}
-
 #define cpumask_parse_user(ubuf, ulen, dst) \
                        __cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS)
 static inline int __cpumask_parse_user(const char __user *buf, int len,
index 832fb0eb293368793cef2565db179a333907c09d..8c23e3dfe3ac215c721c1e54942f8260b25f3d43 100644 (file)
@@ -380,6 +380,12 @@ struct device {
 /* Get the wakeup routines, which depend on struct device */
 #include <linux/pm_wakeup.h>
 
+static inline const char *dev_name(struct device *dev)
+{
+       /* will be changed into kobject_name(&dev->kobj) in the near future */
+       return dev->bus_id;
+}
+
 #ifdef CONFIG_NUMA
 static inline int dev_to_node(struct device *dev)
 {
@@ -478,7 +484,7 @@ extern void sysdev_shutdown(void);
 extern const char *dev_driver_string(struct device *dev);
 #define dev_printk(level, dev, format, arg...) \
        printk(level "%s %s: " format , dev_driver_string(dev) , \
-              (dev)->bus_id , ## arg)
+              dev_name(dev) , ## arg)
 
 #define dev_emerg(dev, format, arg...)         \
        dev_printk(KERN_EMERG , dev , format , ## arg)
index de8387b7ceb6cd85ab872c3fe5e5f62c366af260..f5abd1306638379ecd609512cc742b8af53169e3 100644 (file)
@@ -33,6 +33,19 @@ enum fid_type {
         * 32 bit parent directory inode number.
         */
        FILEID_INO32_GEN_PARENT = 2,
+
+       /*
+        * 32 bit block number, 16 bit partition reference,
+        * 16 bit unused, 32 bit generation number.
+        */
+       FILEID_UDF_WITHOUT_PARENT = 0x51,
+
+       /*
+        * 32 bit block number, 16 bit partition reference,
+        * 16 bit unused, 32 bit generation number,
+        * 32 bit parent block number, 32 bit parent generation number
+        */
+       FILEID_UDF_WITH_PARENT = 0x52,
 };
 
 struct fid {
@@ -43,6 +56,14 @@ struct fid {
                        u32 parent_ino;
                        u32 parent_gen;
                } i32;
+               struct {
+                       u32 block;
+                       u16 partref;
+                       u16 parent_partref;
+                       u32 generation;
+                       u32 parent_block;
+                       u32 parent_generation;
+               } udf;
                __u32 raw[0];
        };
 };
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
new file mode 100644 (file)
index 0000000..a118f3c
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * descriptor table internals; you almost certainly want file.h instead.
+ */
+
+#ifndef __LINUX_FDTABLE_H
+#define __LINUX_FDTABLE_H
+
+#include <asm/atomic.h>
+#include <linux/posix_types.h>
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/types.h>
+
+/*
+ * The default fd array needs to be at least BITS_PER_LONG,
+ * as this is the granularity returned by copy_fdset().
+ */
+#define NR_OPEN_DEFAULT BITS_PER_LONG
+
+/*
+ * The embedded_fd_set is a small fd_set,
+ * suitable for most tasks (which open <= BITS_PER_LONG files)
+ */
+struct embedded_fd_set {
+       unsigned long fds_bits[1];
+};
+
+struct fdtable {
+       unsigned int max_fds;
+       struct file ** fd;      /* current fd array */
+       fd_set *close_on_exec;
+       fd_set *open_fds;
+       struct rcu_head rcu;
+       struct fdtable *next;
+};
+
+/*
+ * Open file table structure
+ */
+struct files_struct {
+  /*
+   * read mostly part
+   */
+       atomic_t count;
+       struct fdtable *fdt;
+       struct fdtable fdtab;
+  /*
+   * written part on a separate cache line in SMP
+   */
+       spinlock_t file_lock ____cacheline_aligned_in_smp;
+       int next_fd;
+       struct embedded_fd_set close_on_exec_init;
+       struct embedded_fd_set open_fds_init;
+       struct file * fd_array[NR_OPEN_DEFAULT];
+};
+
+#define files_fdtable(files) (rcu_dereference((files)->fdt))
+
+extern struct kmem_cache *filp_cachep;
+
+struct file_operations;
+struct vfsmount;
+struct dentry;
+
+extern int expand_files(struct files_struct *, int nr);
+extern void free_fdtable_rcu(struct rcu_head *rcu);
+extern void __init files_defer_init(void);
+
+static inline void free_fdtable(struct fdtable *fdt)
+{
+       call_rcu(&fdt->rcu, free_fdtable_rcu);
+}
+
+static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
+{
+       struct file * file = NULL;
+       struct fdtable *fdt = files_fdtable(files);
+
+       if (fd < fdt->max_fds)
+               file = rcu_dereference(fdt->fd[fd]);
+       return file;
+}
+
+/*
+ * Check whether the specified fd has an open file.
+ */
+#define fcheck(fd)     fcheck_files(current->files, fd)
+
+struct task_struct;
+
+struct files_struct *get_files_struct(struct task_struct *);
+void put_files_struct(struct files_struct *fs);
+void reset_files_struct(struct files_struct *);
+int unshare_files(struct files_struct **);
+
+extern struct kmem_cache *files_cachep;
+
+#endif /* __LINUX_FDTABLE_H */
index 69baf5a4f0a582cfeb061af5735e4a2d70e701e6..27c64bdc68c961baa821614bbfc6246951393acd 100644 (file)
@@ -5,59 +5,11 @@
 #ifndef __LINUX_FILE_H
 #define __LINUX_FILE_H
 
-#include <asm/atomic.h>
-#include <linux/posix_types.h>
 #include <linux/compiler.h>
-#include <linux/spinlock.h>
-#include <linux/rcupdate.h>
 #include <linux/types.h>
+#include <linux/posix_types.h>
 
-/*
- * The default fd array needs to be at least BITS_PER_LONG,
- * as this is the granularity returned by copy_fdset().
- */
-#define NR_OPEN_DEFAULT BITS_PER_LONG
-
-/*
- * The embedded_fd_set is a small fd_set,
- * suitable for most tasks (which open <= BITS_PER_LONG files)
- */
-struct embedded_fd_set {
-       unsigned long fds_bits[1];
-};
-
-struct fdtable {
-       unsigned int max_fds;
-       struct file ** fd;      /* current fd array */
-       fd_set *close_on_exec;
-       fd_set *open_fds;
-       struct rcu_head rcu;
-       struct fdtable *next;
-};
-
-/*
- * Open file table structure
- */
-struct files_struct {
-  /*
-   * read mostly part
-   */
-       atomic_t count;
-       struct fdtable *fdt;
-       struct fdtable fdtab;
-  /*
-   * written part on a separate cache line in SMP
-   */
-       spinlock_t file_lock ____cacheline_aligned_in_smp;
-       int next_fd;
-       struct embedded_fd_set close_on_exec_init;
-       struct embedded_fd_set open_fds_init;
-       struct file * fd_array[NR_OPEN_DEFAULT];
-};
-
-#define files_fdtable(files) (rcu_dereference((files)->fdt))
-
-extern struct kmem_cache *filp_cachep;
+struct file;
 
 extern void __fput(struct file *);
 extern void fput(struct file *);
@@ -85,41 +37,7 @@ extern void put_filp(struct file *);
 extern int get_unused_fd(void);
 extern int get_unused_fd_flags(int flags);
 extern void put_unused_fd(unsigned int fd);
-struct kmem_cache;
-
-extern int expand_files(struct files_struct *, int nr);
-extern void free_fdtable_rcu(struct rcu_head *rcu);
-extern void __init files_defer_init(void);
-
-static inline void free_fdtable(struct fdtable *fdt)
-{
-       call_rcu(&fdt->rcu, free_fdtable_rcu);
-}
-
-static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
-{
-       struct file * file = NULL;
-       struct fdtable *fdt = files_fdtable(files);
-
-       if (fd < fdt->max_fds)
-               file = rcu_dereference(fdt->fd[fd]);
-       return file;
-}
-
-/*
- * Check whether the specified fd has an open file.
- */
-#define fcheck(fd)     fcheck_files(current->files, fd)
 
 extern void fd_install(unsigned int fd, struct file *file);
 
-struct task_struct;
-
-struct files_struct *get_files_struct(struct task_struct *);
-void put_files_struct(struct files_struct *fs);
-void reset_files_struct(struct files_struct *);
-int unshare_files(struct files_struct **);
-
-extern struct kmem_cache *files_cachep;
-
 #endif /* __LINUX_FILE_H */
index a1ba005d08e7ef80f441d00a7f5d934582fe13e6..f413085f748e574140ca4216abbb303209cc7fb0 100644 (file)
@@ -1289,17 +1289,12 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
 extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
                unsigned long, loff_t *);
 
-/*
- * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
- * without the big kernel lock held in all filesystems.
- */
 struct super_operations {
        struct inode *(*alloc_inode)(struct super_block *sb);
        void (*destroy_inode)(struct inode *);
 
        void (*dirty_inode) (struct inode *);
        int (*write_inode) (struct inode *, int);
-       void (*put_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
        void (*put_super) (struct super_block *);
@@ -1821,7 +1816,6 @@ extern void iget_failed(struct inode *);
 extern void clear_inode(struct inode *);
 extern void destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
-extern int __remove_suid(struct dentry *, int);
 extern int should_remove_suid(struct dentry *);
 extern int remove_suid(struct dentry *);
 
index 5c86f1196c3ad132ed714d2a07eb2bfed832bc47..d48282197696fdf1644820a121ce75cd5571bd67 100644 (file)
@@ -109,6 +109,7 @@ struct fuse_file_lock {
 #define FUSE_POSIX_LOCKS       (1 << 1)
 #define FUSE_FILE_OPS          (1 << 2)
 #define FUSE_ATOMIC_O_TRUNC    (1 << 3)
+#define FUSE_BIG_WRITES                (1 << 5)
 
 /**
  * Release flags
index ecd2bf63fc849e201f4825010293ba20a736d09b..e9874e7fcdf90c04cea4c18cae9574bbd5e50e89 100644 (file)
@@ -178,17 +178,17 @@ static inline struct hd_struct *get_part(struct gendisk *gendiskp,
 
 static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)      {
        int i;
+
        for_each_possible_cpu(i)
                memset(per_cpu_ptr(gendiskp->dkstats, i), value,
-                               sizeof (struct disk_stats));
+                               sizeof(struct disk_stats));
 }              
 
 #define __part_stat_add(part, field, addnd)                            \
        (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd)
 
-#define __all_stat_add(gendiskp, field, addnd, sector)         \
+#define __all_stat_add(gendiskp, part, field, addnd, sector)   \
 ({                                                             \
-       struct hd_struct *part = get_part(gendiskp, sector);    \
        if (part)                                               \
                __part_stat_add(part, field, addnd);            \
        __disk_stat_add(gendiskp, field, addnd);                \
@@ -203,11 +203,13 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) {
        res;                                                            \
 })
 
-static inline void part_stat_set_all(struct hd_struct *part, int value)        {
+static inline void part_stat_set_all(struct hd_struct *part, int value)
+{
        int i;
+
        for_each_possible_cpu(i)
                memset(per_cpu_ptr(part->dkstats, i), value,
-                      sizeof(struct disk_stats));
+                               sizeof(struct disk_stats));
 }
                                
 #else /* !CONFIG_SMP */
@@ -223,9 +225,8 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)
 #define __part_stat_add(part, field, addnd) \
        (part->dkstats.field += addnd)
 
-#define __all_stat_add(gendiskp, field, addnd, sector)         \
+#define __all_stat_add(gendiskp, part, field, addnd, sector)   \
 ({                                                             \
-       struct hd_struct *part = get_part(gendiskp, sector);    \
        if (part)                                               \
                part->dkstats.field += addnd;                   \
        __disk_stat_add(gendiskp, field, addnd);                \
@@ -276,10 +277,10 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
 #define part_stat_sub(gendiskp, field, subnd) \
                part_stat_add(gendiskp, field, -subnd)
 
-#define all_stat_add(gendiskp, field, addnd, sector)           \
+#define all_stat_add(gendiskp, part, field, addnd, sector)     \
        do {                                                    \
                preempt_disable();                              \
-               __all_stat_add(gendiskp, field, addnd, sector); \
+               __all_stat_add(gendiskp, part, field, addnd, sector);   \
                preempt_enable();                               \
        } while (0)
 
@@ -288,15 +289,15 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
 #define all_stat_dec(gendiskp, field, sector) \
                all_stat_add(gendiskp, field, -1, sector)
 
-#define __all_stat_inc(gendiskp, field, sector) \
-               __all_stat_add(gendiskp, field, 1, sector)
-#define all_stat_inc(gendiskp, field, sector) \
-               all_stat_add(gendiskp, field, 1, sector)
+#define __all_stat_inc(gendiskp, part, field, sector) \
+               __all_stat_add(gendiskp, part, field, 1, sector)
+#define all_stat_inc(gendiskp, part, field, sector) \
+               all_stat_add(gendiskp, part, field, 1, sector)
 
-#define __all_stat_sub(gendiskp, field, subnd, sector) \
-               __all_stat_add(gendiskp, field, -subnd, sector)
-#define all_stat_sub(gendiskp, field, subnd, sector) \
-               all_stat_add(gendiskp, field, -subnd, sector)
+#define __all_stat_sub(gendiskp, part, field, subnd, sector) \
+               __all_stat_add(gendiskp, part, field, -subnd, sector)
+#define all_stat_sub(gendiskp, part, field, subnd, sector) \
+               all_stat_add(gendiskp, part, field, -subnd, sector)
 
 /* Inlines to alloc and free disk stats in struct gendisk */
 #ifdef  CONFIG_SMP
index 897f723bd222f73a9c9e72519fe4b8cd14e40f14..181006cc94a03ecd29630d80d91762589fc1c316 100644 (file)
 #define in_softirq()           (softirq_count())
 #define in_interrupt()         (irq_count())
 
+#if defined(CONFIG_PREEMPT)
+# define PREEMPT_INATOMIC_BASE kernel_locked()
+# define PREEMPT_CHECK_OFFSET 1
+#else
+# define PREEMPT_INATOMIC_BASE 0
+# define PREEMPT_CHECK_OFFSET 0
+#endif
+
 /*
  * Are we running in atomic context?  WARNING: this macro cannot
  * always detect atomic context; in particular, it cannot know about
  * used in the general case to determine whether sleeping is possible.
  * Do not use in_atomic() in driver code.
  */
-#define in_atomic()            ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
-
-#ifdef CONFIG_PREEMPT
-# define PREEMPT_CHECK_OFFSET 1
-#else
-# define PREEMPT_CHECK_OFFSET 0
-#endif
+#define in_atomic()    ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE)
 
 /*
  * Check whether we were atomic before we did preempt_disable():
- * (used by the scheduler)
+ * (used by the scheduler, *after* releasing the kernel lock)
  */
 #define in_atomic_preempt_off() \
                ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
index 31a4d653389f6d8e76405451c75f88c721328c03..6d93dce61cbbc25c8b17d2f8f8c5c9d0e864ee9f 100644 (file)
@@ -316,6 +316,15 @@ static inline int hrtimer_is_queued(struct hrtimer *timer)
                (HRTIMER_STATE_ENQUEUED | HRTIMER_STATE_PENDING);
 }
 
+/*
+ * Helper function to check, whether the timer is running the callback
+ * function
+ */
+static inline int hrtimer_callback_running(struct hrtimer *timer)
+{
+       return timer->state & HRTIMER_STATE_CALLBACK;
+}
+
 /* Forward a hrtimer so it expires after now: */
 extern u64
 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
index cb63da5c2139f04c331f44da7e681c36ec07ece1..6716ec808c5e11efde450b526a6910cd25407de2 100644 (file)
@@ -262,7 +262,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
  * client handles for the extra addresses.
  */
 extern struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type);
+i2c_new_dummy(struct i2c_adapter *adap, u16 address);
 
 extern void i2c_unregister_device(struct i2c_client *);
 
index bf6b8a61f8db22913e5b9a09fa915adb6e69c768..b24c2875aa0570524502e12c97d8e7c3b0d44fa0 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX__INIT_TASK_H
 #define _LINUX__INIT_TASK_H
 
-#include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/rcupdate.h>
 #include <linux/irqflags.h>
 #include <linux/utsname.h>
index 3a03a3604cce7e61e024c793739d227b5933176f..6c7f0ba0d5faf473b6c2ffb60d1a0c957c007059 100644 (file)
@@ -65,5 +65,6 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 void devm_iounmap(struct device *dev, void __iomem *addr);
 int check_signature(const volatile void __iomem *io_addr,
                        const unsigned char *signature, int length);
+void devm_ioremap_release(struct device *dev, void *res);
 
 #endif /* _LINUX_IO_H */
index 2a3bb1bb74336f27c27f6627153900d46d6c178a..f98a656b17e5b4b732e57e0e70e4eb5ec53bce84 100644 (file)
@@ -67,6 +67,20 @@ static inline int task_nice_ioprio(struct task_struct *task)
        return (task_nice(task) + 20) / 5;
 }
 
+/*
+ * This is for the case where the task hasn't asked for a specific IO class.
+ * Check for idle and rt task process, and return appropriate IO class.
+ */
+static inline int task_nice_ioclass(struct task_struct *task)
+{
+       if (task->policy == SCHED_IDLE)
+               return IOPRIO_CLASS_IDLE;
+       else if (task->policy == SCHED_FIFO || task->policy == SCHED_RR)
+               return IOPRIO_CLASS_RT;
+       else
+               return IOPRIO_CLASS_BE;
+}
+
 /*
  * For inheritance, return the highest of the two given priorities
  */
index 1883a85625dd6a7d0290e6add5a3ea6bd9936fd9..552e0ec269c9640b0536e2306a07236b9e0d43f8 100644 (file)
@@ -61,6 +61,7 @@ typedef       void (*irq_flow_handler_t)(unsigned int irq,
 #define IRQ_WAKEUP             0x00100000      /* IRQ triggers system wakeup */
 #define IRQ_MOVE_PENDING       0x00200000      /* need to re-target IRQ destination */
 #define IRQ_NO_BALANCING       0x00400000      /* IRQ is excluded from balancing */
+#define IRQ_SPURIOUS_DISABLED  0x00800000      /* IRQ was disabled by the spurious trap */
 
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
index 33ef710dac24481774d14d2333f73e0af34de6a5..abb6ac639e8e19740c8bbd30148db72a1028d031 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX_JIFFIES_H
 #define _LINUX_JIFFIES_H
 
-#include <linux/calc64.h>
+#include <linux/math64.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/time.h>
index 9757b1a6d9dc238798317cad70f04703adc602e4..6adcc297e35408f45990ce5263f006827a08b062 100644 (file)
@@ -261,10 +261,12 @@ struct kgdb_io {
 
 extern struct kgdb_arch                arch_kgdb_ops;
 
+extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
+
 extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
 extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
 
-extern int kgdb_hex2long(char **ptr, long *long_val);
+extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
 extern int kgdb_mem2hex(char *mem, char *buf, int count);
 extern int kgdb_hex2mem(char *buf, char *mem, int count);
 
index d1dfe872ee308f854a4b7dd2113e124c4813d1ab..0f17643e0a6e06c6942ceba10017b99c12674027 100644 (file)
@@ -1039,6 +1039,7 @@ extern void ata_eh_thaw_port(struct ata_port *ap);
 
 extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
+extern void ata_eh_analyze_ncq_error(struct ata_link *link);
 
 extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
                      ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
@@ -1381,6 +1382,18 @@ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
        return *(struct ata_port **)&host->hostdata[0];
 }
 
+static inline int ata_check_ready(u8 status)
+{
+       if (!(status & ATA_BUSY))
+               return 1;
+
+       /* 0xff indicates either no device or device not ready */
+       if (status == 0xff)
+               return -ENODEV;
+
+       return 0;
+}
+
 
 /**************************************************************************
  * PMP - drivers/ata/libata-pmp.c
diff --git a/include/linux/math64.h b/include/linux/math64.h
new file mode 100644 (file)
index 0000000..c1a5f81
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _LINUX_MATH64_H
+#define _LINUX_MATH64_H
+
+#include <linux/types.h>
+#include <asm/div64.h>
+
+#if BITS_PER_LONG == 64
+
+/**
+ * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
+ *
+ * This is commonly provided by 32bit archs to provide an optimized 64bit
+ * divide.
+ */
+static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+{
+       *remainder = dividend % divisor;
+       return dividend / divisor;
+}
+
+/**
+ * div_s64_rem - signed 64bit divide with 32bit divisor with remainder
+ */
+static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
+{
+       *remainder = dividend % divisor;
+       return dividend / divisor;
+}
+
+/**
+ * div64_u64 - unsigned 64bit divide with 64bit divisor
+ */
+static inline u64 div64_u64(u64 dividend, u64 divisor)
+{
+       return dividend / divisor;
+}
+
+#elif BITS_PER_LONG == 32
+
+#ifndef div_u64_rem
+static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+{
+       *remainder = do_div(dividend, divisor);
+       return dividend;
+}
+#endif
+
+#ifndef div_s64_rem
+extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
+#endif
+
+#ifndef div64_u64
+extern u64 div64_u64(u64 dividend, u64 divisor);
+#endif
+
+#endif /* BITS_PER_LONG */
+
+/**
+ * div_u64 - unsigned 64bit divide with 32bit divisor
+ *
+ * This is the most common 64bit divide and should be used if possible,
+ * as many 32bit archs can optimize this variant better than a full 64bit
+ * divide.
+ */
+#ifndef div_u64
+static inline u64 div_u64(u64 dividend, u32 divisor)
+{
+       u32 remainder;
+       return div_u64_rem(dividend, divisor, &remainder);
+}
+#endif
+
+/**
+ * div_s64 - signed 64bit divide with 32bit divisor
+ */
+#ifndef div_s64
+static inline s64 div_s64(s64 dividend, s32 divisor)
+{
+       s32 remainder;
+       return div_s64_rem(dividend, divisor, &remainder);
+}
+#endif
+
+#endif /* _LINUX_MATH64_H */
index eb7c16cc95596fae106848e0a66b3b04f6f6b68a..02a27ae78539cfe536106f46a8f89b50ea63985e 100644 (file)
@@ -226,8 +226,17 @@ struct mm_struct {
        rwlock_t                ioctx_list_lock;        /* aio lock */
        struct kioctx           *ioctx_list;
 #ifdef CONFIG_MM_OWNER
-       struct task_struct *owner;      /* The thread group leader that */
-                                       /* owns the mm_struct.          */
+       /*
+        * "owner" points to a task that is regarded as the canonical
+        * user/owner of this mm. All of the following must be true in
+        * order for it to be changed:
+        *
+        * current == mm->owner
+        * current->mm != mm
+        * new_owner->mm == mm
+        * new_owner->alloc_lock is held
+        */
+       struct task_struct *owner;
 #endif
 
 #ifdef CONFIG_PROC_FS
index 819c4e889bf16f0157f45ad4326afa7e83418582..3e03b1acbc94a8ba7fbbd28e394f442c4710f2f9 100644 (file)
@@ -190,7 +190,7 @@ void *__symbol_get_gpl(const char *symbol);
        extern typeof(sym) sym;                                 \
        __CRC_SYMBOL(sym, sec)                                  \
        static const char __kstrtab_##sym[]                     \
-       __attribute__((section("__ksymtab_strings")))           \
+       __attribute__((section("__ksymtab_strings"), aligned(1))) \
        = MODULE_SYMBOL_PREFIX #sym;                            \
        static const struct kernel_symbol __ksymtab_##sym       \
        __used                                                  \
@@ -229,23 +229,6 @@ enum module_state
        MODULE_STATE_GOING,
 };
 
-/* Similar stuff for section attributes. */
-struct module_sect_attr
-{
-       struct module_attribute mattr;
-       char *name;
-       unsigned long address;
-};
-
-struct module_sect_attrs
-{
-       struct attribute_group grp;
-       int nsections;
-       struct module_sect_attr attrs[0];
-};
-
-struct module_param_attrs;
-
 struct module
 {
        enum module_state state;
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h
deleted file mode 100644 (file)
index 9006feb..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-
-/* JEDEC Flash Interface.
- * This is an older type of interface for self programming flash. It is
- * commonly use in older AMD chips and is obsolete compared with CFI.
- * It is called JEDEC because the JEDEC association distributes the ID codes
- * for the chips.
- *
- * See the AMD flash databook for information on how to operate the interface.
- *
- * $Id: jedec.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $
- */
-
-#ifndef __LINUX_MTD_JEDEC_H__
-#define __LINUX_MTD_JEDEC_H__
-
-#include <linux/types.h>
-
-#define MAX_JEDEC_CHIPS 16
-
-// Listing of all supported chips and their information
-struct JEDECTable
-{
-   __u16 jedec;
-   char *name;
-   unsigned long size;
-   unsigned long sectorsize;
-   __u32 capabilities;
-};
-
-// JEDEC being 0 is the end of the chip array
-struct jedec_flash_chip
-{
-   __u16 jedec;
-   unsigned long size;
-   unsigned long sectorsize;
-
-   // *(__u8*)(base + (adder << addrshift)) = data << datashift
-   // Address size = size << addrshift
-   unsigned long base;           // Byte 0 of the flash, will be unaligned
-   unsigned int datashift;       // Useful for 32bit/16bit accesses
-   unsigned int addrshift;
-   unsigned long offset;         // linerized start. base==offset for unbanked, uninterleaved flash
-
-   __u32 capabilities;
-
-   // These markers are filled in by the flash_chip_scan function
-   unsigned long start;
-   unsigned long length;
-};
-
-struct jedec_private
-{
-   unsigned long size;         // Total size of all the devices
-
-   /* Bank handling. If sum(bank_fill) == size then this is linear flash.
-      Otherwise the mapping has holes in it. bank_fill may be used to
-      find the holes, but in the common symetric case
-      bank_fill[0] == bank_fill[*], thus addresses may be computed
-      mathmatically. bank_fill must be powers of two */
-   unsigned is_banked;
-   unsigned long bank_fill[MAX_JEDEC_CHIPS];
-
-   struct jedec_flash_chip chips[MAX_JEDEC_CHIPS];
-};
-
-#endif
index 0a13bb35f044fa249c58f54e0ceab9bbe9e01f23..245f9098e171cfe2bf5b27860f6be2e0365fa57f 100644 (file)
@@ -143,10 +143,12 @@ struct mtd_info {
        int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
 
        /* This stuff for eXecute-In-Place */
-       int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
+       /* phys is optional and may be set to NULL */
+       int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
+                       size_t *retlen, void **virt, resource_size_t *phys);
 
        /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
-       void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
+       void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
 
 
        int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
index a7f6d20ad407bf7dcbb5859ed6dc78a6a2cfc7d7..5cc070c24d88646229bfd7f1f64aa06b76ebdbac 100644 (file)
@@ -36,8 +36,9 @@ struct mypriv {
  * Function Prototypes
  */
 static int pmc551_erase(struct mtd_info *, struct erase_info *);
-static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
-static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
+static void pmc551_unpoint(struct mtd_info *, loff_t, size_t);
+static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
+               size_t *retlen, void **virt, resource_size_t *phys);
 static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 
index 2e5a9673204223451e56362bd0a59fdb4f25473e..bd2a870ec29621f54b4b53aea5dd15f8bb8c346f 100644 (file)
 
 #include <linux/i2c.h>
 
-#ifdef CONFIG_OF_I2C
-
 void of_register_i2c_devices(struct i2c_adapter *adap,
                             struct device_node *adap_node);
 
-#endif /* CONFIG_OF_I2C */
-
 #endif /* __LINUX_OF_I2C_H */
index 96acd0dae2419bd42fe102e60df664304c83cfba..509159bcd4e7cad2bba88ecc960ff3ed1bc8840e 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mod_devicetable.h>
 
 #include <linux/types.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/list.h>
 #include <linux/compiler.h>
@@ -474,7 +475,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(struct pci_bus *bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
                                      struct pci_ops *ops, void *sysdata);
-static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
+static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
                                           void *sysdata)
 {
        struct pci_bus *root_bus;
@@ -666,7 +667,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 
 void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
                  void *userdata);
-int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix);
+int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
 unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 
index e5a53daf17f14c88705c2aa7a752e515a0b23dcd..cf6dbd759395fbb4a9680e52f0dd960bbbac6605 100644 (file)
 #define PCI_DEVICE_ID_NEO_2DB9PRI       0x00C9
 #define PCI_DEVICE_ID_NEO_2RJ45         0x00CA
 #define PCI_DEVICE_ID_NEO_2RJ45PRI      0x00CB
+#define PCIE_DEVICE_ID_NEO_4_IBM        0x00F4
 
 #define PCI_VENDOR_ID_XIRCOM           0x115d
 #define PCI_DEVICE_ID_XIRCOM_RBM56G    0x0101
index 225beb136807dd4650288464c2b4f4ffb8de2e59..cb7d10f3076343f2e60e5a853411c05aefd6eb0f 100644 (file)
 #define PDA_POWER_CHARGE_AC  (1 << 0)
 #define PDA_POWER_CHARGE_USB (1 << 1)
 
+struct device;
+
 struct pda_power_pdata {
+       int (*init)(struct device *dev);
        int (*is_ac_online)(void);
        int (*is_usb_online)(void);
        void (*set_charge)(int flags);
+       void (*exit)(struct device *dev);
 
        char **supplied_to;
        size_t num_supplicants;
index 16d813b364ef41c26d5404a53c480e3b0dbef0d3..ef453828877a35aefc4bbdd1a4753734bbccd882 100644 (file)
@@ -117,6 +117,8 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset)
 extern int do_select(int n, fd_set_bits *fds, s64 *timeout);
 extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds,
                       s64 *timeout);
+extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
+                          fd_set __user *exp, s64 *timeout);
 
 #endif /* KERNEL */
 
index 52e49dce658402fc652c082ff1e6979ff6ead7e2..dcddfb2009479f42a543363d0c0873c76d4bfcee 100644 (file)
@@ -347,6 +347,9 @@ struct quota_info {
        ((type) == USRQUOTA ? (sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED) : \
                              (sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED))
 
+#define sb_any_quota_suspended(sb) (sb_has_quota_suspended(sb, USRQUOTA) | \
+                                 sb_has_quota_suspended(sb, GRPQUOTA))
+
 int register_quota_format(struct quota_format_type *fmt);
 void unregister_quota_format(struct quota_format_type *fmt);
 
index 8082d6587a0f6544a1ec6c28af922dc01a4b90ea..d42dbec0608343c9471c3fd3a8c8ae734e27e55f 100644 (file)
@@ -131,18 +131,6 @@ struct rcu_head {
  */
 #define rcu_read_unlock_bh() __rcu_read_unlock_bh()
 
-/*
- * Prevent the compiler from merging or refetching accesses.  The compiler
- * is also forbidden from reordering successive instances of ACCESS_ONCE(),
- * but only when the compiler is aware of some particular ordering.  One way
- * to make the compiler aware of ordering is to put the two invocations of
- * ACCESS_ONCE() in different C statements.
- *
- * This macro does absolutely -nothing- to prevent the CPU from reordering,
- * merging, or refetching absolutely anything at any time.
- */
-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-
 /**
  * rcu_dereference - fetch an RCU-protected pointer in an
  * RCU read-side critical section.  This pointer may later
index c1c99c9643d38f5373e779dcbe5211e9bec31537..dc0c75556c63c763da2f29e1173606b0502ae78b 100644 (file)
@@ -161,6 +161,8 @@ enum rio_phy_type {
  * @ops: configuration space functions
  * @id: Port ID, unique among all ports
  * @index: Port index, unique among all port interfaces of the same type
+ * @sys_size: RapidIO common transport system size
+ * @phy_type: RapidIO phy type
  * @name: Port name string
  * @priv: Master port private data
  */
index 03c238088aee57a26fbbcd110cf10e901e918fb9..5395a6176f4be13911a57d7174de0274947edb94 100644 (file)
@@ -158,6 +158,8 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 }
 #endif
 
+extern unsigned long long time_sync_thresh;
+
 /*
  * Task state bitmask. NOTE! These bits are also
  * encoded in fs/proc/array.c: get_task_state().
@@ -1551,6 +1553,35 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
 
 extern unsigned long long sched_clock(void);
 
+#ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+static inline void sched_clock_init(void)
+{
+}
+
+static inline u64 sched_clock_cpu(int cpu)
+{
+       return sched_clock();
+}
+
+static inline void sched_clock_tick(void)
+{
+}
+
+static inline void sched_clock_idle_sleep_event(void)
+{
+}
+
+static inline void sched_clock_idle_wakeup_event(u64 delta_ns)
+{
+}
+#else
+extern void sched_clock_init(void);
+extern u64 sched_clock_cpu(int cpu);
+extern void sched_clock_tick(void);
+extern void sched_clock_idle_sleep_event(void);
+extern void sched_clock_idle_wakeup_event(u64 delta_ns);
+#endif
+
 /*
  * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
  * clock constructed from sched_clock():
@@ -1977,6 +2008,11 @@ static inline void clear_tsk_need_resched(struct task_struct *tsk)
        clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
 }
 
+static inline int test_tsk_need_resched(struct task_struct *tsk)
+{
+       return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED));
+}
+
 static inline int signal_pending(struct task_struct *p)
 {
        return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
@@ -2001,13 +2037,13 @@ static inline int need_resched(void)
  * cond_resched_lock() will drop the spinlock before scheduling,
  * cond_resched_softirq() will enable bhs before scheduling.
  */
-#ifdef CONFIG_PREEMPT
+extern int _cond_resched(void);
+#ifdef CONFIG_PREEMPT_BKL
 static inline int cond_resched(void)
 {
        return 0;
 }
 #else
-extern int _cond_resched(void);
 static inline int cond_resched(void)
 {
        return _cond_resched();
@@ -2015,6 +2051,10 @@ static inline int cond_resched(void)
 #endif
 extern int cond_resched_lock(spinlock_t * lock);
 extern int cond_resched_softirq(void);
+static inline int cond_resched_bkl(void)
+{
+       return _cond_resched();
+}
 
 /*
  * Does a critical section need to be broken due to another
index c5d3fcad7b57c87449d7de9085daa64cd80f984f..efdc44593b522054dda0454f105fb0636b8ec0c2 100644 (file)
@@ -109,5 +109,7 @@ extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
 extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
 extern void argv_free(char **argv);
 
+extern bool sysfs_streq(const char *s1, const char *s2);
+
 #endif
 #endif /* _LINUX_STRING_H_ */
index 8ea3e71ba7fa8ff17d8de5587f482450c349ef36..fc6035d29d568a018e5c43f6575e5b860379fa96 100644 (file)
@@ -58,6 +58,8 @@
 
 #include <asm/param.h>
 
+#define NTP_API                4       /* NTP API version */
+
 /*
  * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
  * for a slightly underdamped convergence characteristic. SHIFT_KH
 #define MAXTC          10      /* maximum time constant (shift) */
 
 /*
- * The SHIFT_UPDATE define establishes the decimal point of the
- * time_offset variable which represents the current offset with
- * respect to standard time.
- *
  * SHIFT_USEC defines the scaling (shift) of the time_freq and
  * time_tolerance variables, which represent the current frequency
  * offset and maximum frequency tolerance.
  */
-#define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */
 #define SHIFT_USEC 16          /* frequency offset scale (shift) */
-#define SHIFT_NSEC 12          /* kernel frequency offset scale */
-
-#define MAXPHASE 512000L        /* max phase error (us) */
-#define MAXFREQ (512L << SHIFT_USEC)  /* max frequency error (ppm) */
-#define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */
+#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC))
+#define PPM_SCALE_INV_SHIFT 20
+#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
+                      PPM_SCALE + 1)
+
+#define MAXPHASE 500000000l    /* max phase error (ns) */
+#define MAXFREQ 500000         /* max frequency error (ns/s) */
+#define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT)
 #define MINSEC 256             /* min interval between updates (s) */
 #define MAXSEC 2048            /* max interval between updates (s) */
-#define        NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */
+#define NTP_PHASE_LIMIT ((MAXPHASE / NSEC_PER_USEC) << 5) /* beyond max. dispersion */
 
 /*
  * syscall interface - used (mainly by NTP daemon)
@@ -121,9 +121,11 @@ struct timex {
        long errcnt;            /* calibration errors (ro) */
        long stbcnt;            /* stability limit exceeded (ro) */
 
+       int tai;                /* TAI offset (ro) */
+
        int  :32; int  :32; int  :32; int  :32;
        int  :32; int  :32; int  :32; int  :32;
-       int  :32; int  :32; int  :32; int  :32;
+       int  :32; int  :32; int  :32;
 };
 
 /*
@@ -135,6 +137,9 @@ struct timex {
 #define ADJ_ESTERROR           0x0008  /* estimated time error */
 #define ADJ_STATUS             0x0010  /* clock status */
 #define ADJ_TIMECONST          0x0020  /* pll time constant */
+#define ADJ_TAI                        0x0080  /* set TAI offset */
+#define ADJ_MICRO              0x1000  /* select microsecond resolution */
+#define ADJ_NANO               0x2000  /* select nanosecond resolution */
 #define ADJ_TICK               0x4000  /* tick value */
 #define ADJ_OFFSET_SINGLESHOT  0x8001  /* old-fashioned adjtime */
 #define ADJ_OFFSET_SS_READ     0xa001  /* read-only adjtime */
@@ -146,8 +151,6 @@ struct timex {
 #define MOD_ESTERROR   ADJ_ESTERROR
 #define MOD_STATUS     ADJ_STATUS
 #define MOD_TIMECONST  ADJ_TIMECONST
-#define MOD_CLKB       ADJ_TICK
-#define MOD_CLKA       ADJ_OFFSET_SINGLESHOT /* 0x8000 in original */
 
 
 /*
@@ -169,9 +172,13 @@ struct timex {
 #define STA_PPSERROR   0x0800  /* PPS signal calibration error (ro) */
 
 #define STA_CLOCKERR   0x1000  /* clock hardware fault (ro) */
+#define STA_NANO       0x2000  /* resolution (0 = us, 1 = ns) (ro) */
+#define STA_MODE       0x4000  /* mode (0 = PLL, 1 = FLL) (ro) */
+#define STA_CLK                0x8000  /* clock source (0 = A, 1 = B) (ro) */
 
+/* read-only bits */
 #define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
-    STA_PPSERROR | STA_CLOCKERR) /* read-only bits */
+       STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
 
 /*
  * Clock states (time_state)
@@ -203,10 +210,9 @@ extern int time_status;            /* clock synchronization status bits */
 extern long time_maxerror;     /* maximum error */
 extern long time_esterror;     /* estimated error */
 
-extern long time_freq;         /* frequency offset (scaled ppm) */
-
 extern long time_adjust;       /* The amount of adjtime left */
 
+extern void ntp_init(void);
 extern void ntp_clear(void);
 
 /**
@@ -225,7 +231,7 @@ static inline int ntp_synced(void)
        __x < 0 ? -(-__x >> __s) : __x >> __s;  \
 })
 
-#define TICK_LENGTH_SHIFT      32
+#define NTP_SCALE_SHIFT                32
 
 #ifdef CONFIG_NO_HZ
 #define NTP_INTERVAL_FREQ  (2)
@@ -234,8 +240,8 @@ static inline int ntp_synced(void)
 #endif
 #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
 
-/* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */
-extern u64 current_tick_length(void);
+/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
+extern u64 tick_length;
 
 extern void second_overflow(void);
 extern void update_ntp_one_tick(void);
diff --git a/include/linux/usb/c67x00.h b/include/linux/usb/c67x00.h
new file mode 100644 (file)
index 0000000..83c6b45
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301  USA.
+ */
+
+#ifndef _LINUX_USB_C67X00_H
+#define _LINUX_USB_C67X00_H
+
+/* SIE configuration */
+#define C67X00_SIE_UNUSED      0
+#define C67X00_SIE_HOST                1
+#define C67X00_SIE_PERIPHERAL_A        2       /* peripheral on A port */
+#define C67X00_SIE_PERIPHERAL_B        3       /* peripheral on B port */
+
+#define c67x00_sie_config(config, n)  (((config)>>(4*(n)))&0x3)
+
+#define C67X00_SIE1_UNUSED             (C67X00_SIE_UNUSED              << 0)
+#define C67X00_SIE1_HOST               (C67X00_SIE_HOST                << 0)
+#define C67X00_SIE1_PERIPHERAL_A       (C67X00_SIE_PERIPHERAL_A        << 0)
+#define C67X00_SIE1_PERIPHERAL_B       (C67X00_SIE_PERIPHERAL_B        << 0)
+
+#define C67X00_SIE2_UNUSED             (C67X00_SIE_UNUSED              << 4)
+#define C67X00_SIE2_HOST               (C67X00_SIE_HOST                << 4)
+#define C67X00_SIE2_PERIPHERAL_A       (C67X00_SIE_PERIPHERAL_A        << 4)
+#define C67X00_SIE2_PERIPHERAL_B       (C67X00_SIE_PERIPHERAL_B        << 4)
+
+struct c67x00_platform_data {
+       int sie_config;                 /* SIEs config (C67X00_SIEx_*) */
+       unsigned long hpi_regstep;      /* Step between HPI registers  */
+};
+
+#endif /* _LINUX_USB_C67X00_H */
index 7e0d3084f76c8411aa5dad0b09772f840020b50a..73a2f4eb1f7ae1a6f9c23131a56f5d1d6d631d58 100644 (file)
@@ -455,7 +455,7 @@ struct usb_encryption_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
-/* USB_DT_BOS:  group of wireless capabilities */
+/* USB_DT_BOS:  group of device-level capabilities */
 struct usb_bos_descriptor {
        __u8  bLength;
        __u8  bDescriptorType;
@@ -501,6 +501,16 @@ struct usb_wireless_cap_descriptor {       /* Ultra Wide Band */
        __u8  bReserved;
 } __attribute__((packed));
 
+#define        USB_CAP_TYPE_EXT                2
+
+struct usb_ext_cap_descriptor {                /* Link Power Management */
+       __u8  bLength;
+       __u8  bDescriptorType;
+       __u8  bDevCapabilityType;
+       __u8  bmAttributes;
+#define USB_LPM_SUPPORT                        (1 << 1)        /* supports LPM */
+} __attribute__((packed));
+
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
index d8128f7102c92858bc01d71c7544882849318ae7..cf468fbdbf8e80b504ecb3ac1d798120c066ca2f 100644 (file)
@@ -114,6 +114,8 @@ struct usb_ep_ops {
        int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
 
        int (*set_halt) (struct usb_ep *ep, int value);
+       int (*set_wedge) (struct usb_ep *ep);
+
        int (*fifo_status) (struct usb_ep *ep);
        void (*fifo_flush) (struct usb_ep *ep);
 };
@@ -348,6 +350,25 @@ static inline int usb_ep_clear_halt(struct usb_ep *ep)
        return ep->ops->set_halt(ep, 0);
 }
 
+/**
+ * usb_ep_set_wedge - sets the halt feature and ignores clear requests
+ * @ep: the endpoint being wedged
+ *
+ * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT)
+ * requests. If the gadget driver clears the halt status, it will
+ * automatically unwedge the endpoint.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_ep_set_wedge(struct usb_ep *ep)
+{
+       if (ep->ops->set_wedge)
+               return ep->ops->set_wedge(ep);
+       else
+               return ep->ops->set_halt(ep, 1);
+}
+
 /**
  * usb_ep_fifo_status - returns number of bytes in fifo, or error
  * @ep: the endpoint whose fifo status is being checked.
index 4d0909e53595dcd9423c9e845bd13d0da36bfcaa..79b9837d9ca079b809405ae7d0a6ed93d5cf273c 100644 (file)
 #else
 #define MODULE_VERMAGIC_MODULE_UNLOAD ""
 #endif
+#ifdef CONFIG_MODVERSIONS
+#define MODULE_VERMAGIC_MODVERSIONS "modversions "
+#else
+#define MODULE_VERMAGIC_MODVERSIONS ""
+#endif
 #ifndef MODULE_ARCH_VERMAGIC
 #define MODULE_ARCH_VERMAGIC ""
 #endif
@@ -24,5 +29,6 @@
 #define VERMAGIC_STRING                                                \
        UTS_RELEASE " "                                                 \
        MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT                     \
-       MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC
+       MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS       \
+       MODULE_ARCH_VERMAGIC
 
index e7d10845b3c17be5c8bf26fa088a5c82c92e3af4..06005fa9e982e0f703a7eef56f4108378c566f24 100644 (file)
@@ -76,6 +76,7 @@ struct virtqueue_ops {
  * @dev: underlying device.
  * @id: the device type identification (used to match it with a driver).
  * @config: the configuration ops for this device.
+ * @features: the features supported by both driver and device.
  * @priv: private pointer for the driver's use.
  */
 struct virtio_device
@@ -84,6 +85,8 @@ struct virtio_device
        struct device dev;
        struct virtio_device_id id;
        struct virtio_config_ops *config;
+       /* Note that this is a Linux set_bit-style bitmap. */
+       unsigned long features[1];
        void *priv;
 };
 
@@ -94,6 +97,8 @@ void unregister_virtio_device(struct virtio_device *dev);
  * virtio_driver - operations for a virtio I/O driver
  * @driver: underlying device driver (populate name and owner).
  * @id_table: the ids serviced by this driver.
+ * @feature_table: an array of feature numbers supported by this device.
+ * @feature_table_size: number of entries in the feature table array.
  * @probe: the function to call when a device is found.  Returns a token for
  *    remove, or PTR_ERR().
  * @remove: the function when a device is removed.
@@ -103,6 +108,8 @@ void unregister_virtio_device(struct virtio_device *dev);
 struct virtio_driver {
        struct device_driver driver;
        const struct virtio_device_id *id_table;
+       const unsigned int *feature_table;
+       unsigned int feature_table_size;
        int (*probe)(struct virtio_device *dev);
        void (*remove)(struct virtio_device *dev);
        void (*config_changed)(struct virtio_device *dev);
index bca0b10d79470056cc6456101ef45454f813149f..d4695a3356d018f4198df0d5813070cc4b5cf5ad 100644 (file)
@@ -9,6 +9,7 @@
 #define VIRTIO_BLK_F_BARRIER   0       /* Does host support barriers? */
 #define VIRTIO_BLK_F_SIZE_MAX  1       /* Indicates maximum segment size */
 #define VIRTIO_BLK_F_SEG_MAX   2       /* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY  4       /* Legacy geometry available  */
 
 struct virtio_blk_config
 {
@@ -18,6 +19,12 @@ struct virtio_blk_config
        __le32 size_max;
        /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
        __le32 seg_max;
+       /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
+       struct virtio_blk_geometry {
+               __le16 cylinders;
+               __u8 heads;
+               __u8 sectors;
+       } geometry;
 } __attribute__((packed));
 
 /* These two define direction. */
@@ -41,13 +48,8 @@ struct virtio_blk_outhdr
        __u64 sector;
 };
 
+/* And this is the final byte of the write scatter-gather list. */
 #define VIRTIO_BLK_S_OK                0
 #define VIRTIO_BLK_S_IOERR     1
 #define VIRTIO_BLK_S_UNSUPP    2
-
-/* This is the first element of the write scatter-gather list */
-struct virtio_blk_inhdr
-{
-       unsigned char status;
-};
 #endif /* _LINUX_VIRTIO_BLK_H */
index d581b2914b342cbbe83744bc15762fb8718a81a3..50db245c81ad94f1131d88b512c100219475717b 100644 (file)
 #define VIRTIO_CONFIG_S_FAILED         0x80
 
 #ifdef __KERNEL__
-struct virtio_device;
+#include <linux/virtio.h>
 
 /**
  * virtio_config_ops - operations for configuring a virtio device
- * @feature: search for a feature in this config
- *     vdev: the virtio_device
- *     bit: the feature bit
- *     Returns true if the feature is supported.  Acknowledges the feature
- *     so the host can see it.
  * @get: read the value of a configuration field
  *     vdev: the virtio_device
  *     offset: the offset of the configuration field
  *     buf: the buffer to write the field value into.
  *     len: the length of the buffer
- *     Note that contents are conventionally little-endian.
  * @set: write the value of a configuration field
  *     vdev: the virtio_device
  *     offset: the offset of the configuration field
  *     buf: the buffer to read the field value from.
  *     len: the length of the buffer
- *     Note that contents are conventionally little-endian.
  * @get_status: read the status byte
  *     vdev: the virtio_device
  *     Returns the status byte
@@ -52,10 +45,15 @@ struct virtio_device;
  *     callback: the virqtueue callback
  *     Returns the new virtqueue or ERR_PTR() (eg. -ENOENT).
  * @del_vq: free a virtqueue found by find_vq().
+ * @get_features: get the array of feature bits for this device.
+ *     vdev: the virtio_device
+ *     Returns the first 32 feature bits (all we currently need).
+ * @set_features: confirm what device features we'll be using.
+ *     vdev: the virtio_device
+ *     feature: the first 32 feature bits
  */
 struct virtio_config_ops
 {
-       bool (*feature)(struct virtio_device *vdev, unsigned bit);
        void (*get)(struct virtio_device *vdev, unsigned offset,
                    void *buf, unsigned len);
        void (*set)(struct virtio_device *vdev, unsigned offset,
@@ -67,43 +65,52 @@ struct virtio_config_ops
                                     unsigned index,
                                     void (*callback)(struct virtqueue *));
        void (*del_vq)(struct virtqueue *vq);
+       u32 (*get_features)(struct virtio_device *vdev);
+       void (*set_features)(struct virtio_device *vdev, u32 features);
 };
 
+/* If driver didn't advertise the feature, it will never appear. */
+void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
+                                        unsigned int fbit);
+
 /**
- * virtio_config_val - look for a feature and get a single virtio config.
- * @vdev: the virtio device
+ * virtio_has_feature - helper to determine if this device has this feature.
+ * @vdev: the device
  * @fbit: the feature bit
- * @offset: the type to search for.
- * @val: a pointer to the value to fill in.
- *
- * The return value is -ENOENT if the feature doesn't exist.  Otherwise
- * the value is endian-corrected and returned in v. */
-#define virtio_config_val(vdev, fbit, offset, v) ({                    \
-       int _err;                                                       \
-       if ((vdev)->config->feature((vdev), (fbit))) {                  \
-               __virtio_config_val((vdev), (offset), (v));             \
-               _err = 0;                                               \
-       } else                                                          \
-               _err = -ENOENT;                                         \
-       _err;                                                           \
-})
+ */
+static inline bool virtio_has_feature(const struct virtio_device *vdev,
+                                     unsigned int fbit)
+{
+       /* Did you forget to fix assumptions on max features? */
+       if (__builtin_constant_p(fbit))
+               BUILD_BUG_ON(fbit >= 32);
+
+       virtio_check_driver_offered_feature(vdev, fbit);
+       return test_bit(fbit, vdev->features);
+}
 
 /**
- * __virtio_config_val - get a single virtio config without feature check.
+ * virtio_config_val - look for a feature and get a virtio config entry.
  * @vdev: the virtio device
+ * @fbit: the feature bit
  * @offset: the type to search for.
  * @val: a pointer to the value to fill in.
  *
- * The value is endian-corrected and returned in v. */
-#define __virtio_config_val(vdev, offset, v) do {                      \
-       BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2             \
-                    && sizeof(*(v)) != 4 && sizeof(*(v)) != 8);        \
-       (vdev)->config->get((vdev), (offset), (v), sizeof(*(v)));       \
-       switch (sizeof(*(v))) {                                         \
-       case 2: le16_to_cpus((__u16 *) v); break;                       \
-       case 4: le32_to_cpus((__u32 *) v); break;                       \
-       case 8: le64_to_cpus((__u64 *) v); break;                       \
-       }                                                               \
-} while(0)
+ * The return value is -ENOENT if the feature doesn't exist.  Otherwise
+ * the config value is copied into whatever is pointed to by v. */
+#define virtio_config_val(vdev, fbit, offset, v) \
+       virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(v))
+
+static inline int virtio_config_buf(struct virtio_device *vdev,
+                                   unsigned int fbit,
+                                   unsigned int offset,
+                                   void *buf, unsigned len)
+{
+       if (!virtio_has_feature(vdev, fbit))
+               return -ENOENT;
+
+       vdev->config->get(vdev, offset, buf, len);
+       return 0;
+}
 #endif /* __KERNEL__ */
 #endif /* _LINUX_VIRTIO_CONFIG_H */
index 1ea3351df609474d097b67e4f0df31131257a34f..9405aa6cdf2672d40375bfa4bfb4ae90ce86e335 100644 (file)
@@ -6,9 +6,18 @@
 #define VIRTIO_ID_NET  1
 
 /* The feature bitmap for virtio net */
-#define VIRTIO_NET_F_CSUM      0       /* Can handle pkts w/ partial csum */
+#define VIRTIO_NET_F_CSUM      0       /* Host handles pkts w/ partial csum */
+#define VIRTIO_NET_F_GUEST_CSUM        1       /* Guest handles pkts w/ partial csum */
 #define VIRTIO_NET_F_MAC       5       /* Host has given MAC address. */
-#define VIRTIO_NET_F_GSO       6       /* Can handle pkts w/ any GSO type */
+#define VIRTIO_NET_F_GSO       6       /* Host handles pkts w/ any GSO type */
+#define VIRTIO_NET_F_GUEST_TSO4        7       /* Guest can handle TSOv4 in. */
+#define VIRTIO_NET_F_GUEST_TSO6        8       /* Guest can handle TSOv6 in. */
+#define VIRTIO_NET_F_GUEST_ECN 9       /* Guest can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_GUEST_UFO 10      /* Guest can handle UFO in. */
+#define VIRTIO_NET_F_HOST_TSO4 11      /* Host can handle TSOv4 in. */
+#define VIRTIO_NET_F_HOST_TSO6 12      /* Host can handle TSOv6 in. */
+#define VIRTIO_NET_F_HOST_ECN  13      /* Host can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_HOST_UFO  14      /* Host can handle UFO in. */
 
 struct virtio_net_config
 {
index 347b6f8beb23761fa4a7c77fa65ad1dc6a81274b..878562278b674588577c88bfeb22cb7858bbd29c 100644 (file)
@@ -31,6 +31,7 @@ struct v4l2_i2c_driver_data {
        int (*resume)(struct i2c_client *client);
        int (*legacy_probe)(struct i2c_adapter *adapter);
        int legacy_class;
+       const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -124,6 +125,7 @@ static int __init v4l2_i2c_drv_init(void)
        v4l2_i2c_driver.command = v4l2_i2c_data.command;
        v4l2_i2c_driver.probe = v4l2_i2c_data.probe;
        v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
+       v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
        err = i2c_add_driver(&v4l2_i2c_driver);
        if (err)
                i2c_del_driver(&v4l2_i2c_driver_legacy);
index 7b6f06be795034d7ae64b385bfa9ef0eac4078c9..40ecef29801d3be1e5902cea4aee4a823e87f158 100644 (file)
@@ -36,6 +36,7 @@ struct v4l2_i2c_driver_data {
        int (*resume)(struct i2c_client *client);
        int (*legacy_probe)(struct i2c_adapter *adapter);
        int legacy_class;
+       const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -53,6 +54,7 @@ static int __init v4l2_i2c_drv_init(void)
        v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
        v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend;
        v4l2_i2c_driver.resume = v4l2_i2c_data.resume;
+       v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
        return i2c_add_driver(&v4l2_i2c_driver);
 }
 
index 1f74bcd603fedaee2d513758add2ebe4d827fea6..32742c4563de22131a6abce886ff2d8ff5629724 100644 (file)
 #define SCSI_MAX_SG_CHAIN_SEGMENTS     SCSI_MAX_SG_SEGMENTS
 #endif
 
-/*
- *     SCSI command lengths
- */
-
-extern const unsigned char scsi_command_size[8];
-#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
-
 /*
  * Special value for scanning to specify scanning or rescanning of all
  * possible channels, (target) ids, or luns on a given shost.
@@ -109,6 +102,7 @@ extern const unsigned char scsi_command_size[8];
 #define MODE_SENSE_10         0x5a
 #define PERSISTENT_RESERVE_IN 0x5e
 #define PERSISTENT_RESERVE_OUT 0x5f
+#define VARIABLE_LENGTH_CMD   0x7f
 #define REPORT_LUNS           0xa0
 #define MAINTENANCE_IN        0xa3
 #define MOVE_MEDIUM           0xa5
@@ -135,6 +129,38 @@ extern const unsigned char scsi_command_size[8];
 #define        ATA_16                0x85      /* 16-byte pass-thru */
 #define        ATA_12                0xa1      /* 12-byte pass-thru */
 
+/*
+ *     SCSI command lengths
+ */
+
+#define SCSI_MAX_VARLEN_CDB_SIZE 260
+
+/* defined in T10 SCSI Primary Commands-2 (SPC2) */
+struct scsi_varlen_cdb_hdr {
+       u8 opcode;        /* opcode always == VARIABLE_LENGTH_CMD */
+       u8 control;
+       u8 misc[5];
+       u8 additional_cdb_length;         /* total cdb length - 8 */
+       __be16 service_action;
+       /* service specific data follows */
+};
+
+static inline unsigned
+scsi_varlen_cdb_length(const void *hdr)
+{
+       return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8;
+}
+
+extern const unsigned char scsi_command_size_tbl[8];
+#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7]
+
+static inline unsigned
+scsi_command_size(const unsigned char *cmnd)
+{
+       return (cmnd[0] == VARIABLE_LENGTH_CMD) ?
+               scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
+}
+
 /*
  *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
  *  T10/1561-D Revision 4 Draft dated 7th November 2002.
index 8d20e60a94b7e18b25f8d1c44d393635cd892211..3e46dfae81940dd889262c0fb22a4f0730fff413 100644 (file)
@@ -7,10 +7,28 @@
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/scatterlist.h>
+#include <linux/blkdev.h>
 
 struct Scsi_Host;
 struct scsi_device;
 
+/*
+ * MAX_COMMAND_SIZE is:
+ * The longest fixed-length SCSI CDB as per the SCSI standard.
+ * fixed-length means: commands that their size can be determined
+ * by their opcode and the CDB does not carry a length specifier, (unlike
+ * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly
+ * true and the SCSI standard also defines extended commands and
+ * vendor specific commands that can be bigger than 16 bytes. The kernel
+ * will support these using the same infrastructure used for VARLEN CDB's.
+ * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml
+ * supports without specifying a cmd_len by ULD's
+ */
+#define MAX_COMMAND_SIZE 16
+#if (MAX_COMMAND_SIZE > BLK_MAX_CDB)
+# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB
+#endif
+
 struct scsi_data_buffer {
        struct sg_table table;
        unsigned length;
@@ -60,12 +78,11 @@ struct scsi_cmnd {
        int allowed;
        int timeout_per_command;
 
-       unsigned char cmd_len;
+       unsigned short cmd_len;
        enum dma_data_direction sc_data_direction;
 
        /* These elements define the operation we are about to perform */
-#define MAX_COMMAND_SIZE       16
-       unsigned char cmnd[MAX_COMMAND_SIZE];
+       unsigned char *cmnd;
 
        struct timer_list eh_timeout;   /* Used to time out the command. */
 
index d3a133b4a072bf2104a0204d29084be7b79bd186..2a9add21267d7fddfc4f443b6d5f475eba65b31e 100644 (file)
@@ -75,11 +75,11 @@ struct scsi_eh_save {
        int result;
        enum dma_data_direction data_direction;
        unsigned char cmd_len;
-       unsigned char cmnd[MAX_COMMAND_SIZE];
+       unsigned char *cmnd;
        struct scsi_data_buffer sdb;
        struct request *next_rq;
-
        /* new command support */
+       unsigned char eh_cmnd[BLK_MAX_CDB];
        struct scatterlist sense_sgl;
 };
 
index d967d6dc7a28d7de7d58eb40b4a2258c4187c2a8..1834fdfe82a7d7129880e2a0380c2e99b77adfa3 100644 (file)
@@ -573,13 +573,11 @@ struct Scsi_Host {
        /*
         * The maximum length of SCSI commands that this host can accept.
         * Probably 12 for most host adapters, but could be 16 for others.
+        * or 260 if the driver supports variable length cdbs.
         * For drivers that don't set this field, a value of 12 is
-        * assumed.  I am leaving this as a number rather than a bit
-        * because you never know what subsequent SCSI standards might do
-        * (i.e. could there be a 20 byte or a 24-byte command a few years
-        * down the road?).  
+        * assumed.
         */
-       unsigned char max_cmd_len;
+       unsigned short max_cmd_len;
 
        int this_id;
        int can_queue;
index e6ea6f7509414566c2327a841e206b7249cbaa2c..d3c8c033dff83b06d772e4dab9178f35413e17ff 100644 (file)
@@ -238,7 +238,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
 int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
-#define snd_soc_info_bool_ext          snd_ctl_boolean_mono
+#define snd_soc_info_bool_ext          snd_ctl_boolean_mono_info
 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
index 3e7b257fc05fca6fba4d6325a3da1ae95c3f9fde..6135d07f31ece506c597e06c04d220d53308fbfe 100644 (file)
@@ -316,9 +316,16 @@ config CPUSETS
 
          Say N if unsure.
 
+#
+# Architectures with an unreliable sched_clock() should select this:
+#
+config HAVE_UNSTABLE_SCHED_CLOCK
+       bool
+
 config GROUP_SCHED
        bool "Group CPU scheduler"
-       default y
+       depends on EXPERIMENTAL
+       default n
        help
          This feature lets CPU scheduler recognize task groups and control CPU
          bandwidth allocation to such task groups.
@@ -326,7 +333,7 @@ config GROUP_SCHED
 config FAIR_GROUP_SCHED
        bool "Group scheduling for SCHED_OTHER"
        depends on GROUP_SCHED
-       default y
+       default GROUP_SCHED
 
 config RT_GROUP_SCHED
        bool "Group scheduling for SCHED_RR/FIFO"
@@ -627,6 +634,14 @@ config ELF_CORE
        help
          Enable support for generating core dumps. Disabling saves about 4k.
 
+config PCSPKR_PLATFORM
+       bool "Enable PC-Speaker support" if EMBEDDED
+       depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+       default y
+       help
+          This option allows to disable the internal PC-Speaker
+          support, saving some memory.
+
 config COMPAT_BRK
        bool "Disable heap randomization"
        default y
@@ -720,7 +735,7 @@ config VM_EVENT_COUNTERS
 config SLUB_DEBUG
        default y
        bool "Enable SLUB debugging support" if EMBEDDED
-       depends on SLUB
+       depends on SLUB && SYSFS
        help
          SLUB has extensive debug support features. Disabling these can
          result in significant savings in code size. This also disables
@@ -825,6 +840,15 @@ menuconfig MODULES
 
          If unsure, say Y.
 
+config MODULE_FORCE_LOAD
+       bool "Forced module loading"
+       depends on MODULES
+       default n
+       help
+         Allow loading of modules without version information (ie. modprobe
+         --force).  Forced module loading sets the 'F' (forced) taint flag and
+         is usually a really bad idea.
+
 config MODULE_UNLOAD
        bool "Module unloading"
        depends on MODULES
index a87d4ca5c36c19706ee4d8eb2997c45f727f4ff1..f406fefa626cadc74871e36c954c9781a4dc795f 100644 (file)
@@ -602,6 +602,7 @@ asmlinkage void __init start_kernel(void)
        softirq_init();
        timekeeping_init();
        time_init();
+       sched_clock_init();
        profile_init();
        if (!irqs_disabled())
                printk("start_kernel(): bug: interrupts were enabled early\n");
@@ -701,7 +702,6 @@ static void __init do_initcalls(void)
 
        for (call = __initcall_start; call < __initcall_end; call++) {
                ktime_t t0, t1, delta;
-               char *msg = NULL;
                char msgbuf[40];
                int result;
 
@@ -723,22 +723,23 @@ static void __init do_initcalls(void)
                                (unsigned long long) delta.tv64 >> 20);
                }
 
-               if (result && result != -ENODEV && initcall_debug) {
-                       sprintf(msgbuf, "error code %d", result);
-                       msg = msgbuf;
-               }
+               msgbuf[0] = 0;
+
+               if (result && result != -ENODEV && initcall_debug)
+                       sprintf(msgbuf, "error code %d ", result);
+
                if (preempt_count() != count) {
-                       msg = "preemption imbalance";
+                       strncat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
                        preempt_count() = count;
                }
                if (irqs_disabled()) {
-                       msg = "disabled interrupts";
+                       strncat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
                        local_irq_enable();
                }
-               if (msg) {
+               if (msgbuf[0]) {
                        print_fn_descriptor_symbol(KERN_WARNING "initcall %s()",
                                        (unsigned long) *call);
-                       printk(" returned with %s\n", msg);
+                       printk(" returned with %s\n", msgbuf);
                }
        }
 
index 94fd3b08fb77036d35ecd1a337785f1847fe1613..b3b69fd5133024f9c7aaa116cab75c65772379d4 100644 (file)
@@ -673,7 +673,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
        if (IS_ERR(name = getname(u_name)))
                return PTR_ERR(name);
 
-       fd = get_unused_fd();
+       fd = get_unused_fd_flags(O_CLOEXEC);
        if (fd < 0)
                goto out_putname;
 
@@ -709,7 +709,6 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
                goto out_putfd;
        }
 
-       set_close_on_exec(fd, 1);
        fd_install(fd, filp);
        goto out_upsem;
 
index 188c43223f52a33e3b948dba43124a70cd349e30..1c9938addb9d9bc7af3acb74b0a3090acbb8d466 100644 (file)
@@ -9,7 +9,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
            rcupdate.o extable.o params.o posix-timers.o \
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
            hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
-           notifier.o ksysfs.o pm_qos_params.o
+           notifier.o ksysfs.o pm_qos_params.o sched_clock.o
 
 obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
index 4a856a3643bb3f3ba3f99f6183bd8400b3f97eb9..32c254a8ab9af07ae3ac102972063956592e0b3b 100644 (file)
@@ -955,7 +955,8 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
                        __put_user(txc.jitcnt, &utp->jitcnt) ||
                        __put_user(txc.calcnt, &utp->calcnt) ||
                        __put_user(txc.errcnt, &utp->errcnt) ||
-                       __put_user(txc.stbcnt, &utp->stbcnt))
+                       __put_user(txc.stbcnt, &utp->stbcnt) ||
+                       __put_user(txc.tai, &utp->tai))
                ret = -EFAULT;
 
        return ret;
index 8da627d33804db7c9e30936fead573cedd4407e3..86ea9e34e3260138401663be21dd22d1892c4ce3 100644 (file)
@@ -1031,11 +1031,9 @@ int current_cpuset_is_being_rebound(void)
        return task_cs(current) == cpuset_being_rebound;
 }
 
-static int update_relax_domain_level(struct cpuset *cs, char *buf)
+static int update_relax_domain_level(struct cpuset *cs, s64 val)
 {
-       int val = simple_strtol(buf, NULL, 10);
-
-       if (val < 0)
+       if ((int)val < 0)
                val = -1;
 
        if (val != cs->relax_domain_level) {
@@ -1280,9 +1278,6 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont,
        case FILE_MEMLIST:
                retval = update_nodemask(cs, buffer);
                break;
-       case FILE_SCHED_RELAX_DOMAIN_LEVEL:
-               retval = update_relax_domain_level(cs, buffer);
-               break;
        default:
                retval = -EINVAL;
                goto out2;
@@ -1348,6 +1343,30 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
        return retval;
 }
 
+static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val)
+{
+       int retval = 0;
+       struct cpuset *cs = cgroup_cs(cgrp);
+       cpuset_filetype_t type = cft->private;
+
+       cgroup_lock();
+
+       if (cgroup_is_removed(cgrp)) {
+               cgroup_unlock();
+               return -ENODEV;
+       }
+       switch (type) {
+       case FILE_SCHED_RELAX_DOMAIN_LEVEL:
+               retval = update_relax_domain_level(cs, val);
+               break;
+       default:
+               retval = -EINVAL;
+               break;
+       }
+       cgroup_unlock();
+       return retval;
+}
+
 /*
  * These ascii lists should be read in a single call, by using a user
  * buffer large enough to hold the entire map.  If read in smaller
@@ -1406,9 +1425,6 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont,
        case FILE_MEMLIST:
                s += cpuset_sprintf_memlist(s, cs);
                break;
-       case FILE_SCHED_RELAX_DOMAIN_LEVEL:
-               s += sprintf(s, "%d", cs->relax_domain_level);
-               break;
        default:
                retval = -EINVAL;
                goto out;
@@ -1449,6 +1465,18 @@ static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft)
        }
 }
 
+static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft)
+{
+       struct cpuset *cs = cgroup_cs(cont);
+       cpuset_filetype_t type = cft->private;
+       switch (type) {
+       case FILE_SCHED_RELAX_DOMAIN_LEVEL:
+               return cs->relax_domain_level;
+       default:
+               BUG();
+       }
+}
+
 
 /*
  * for the common functions, 'private' gives the type of file
@@ -1499,8 +1527,8 @@ static struct cftype files[] = {
 
        {
                .name = "sched_relax_domain_level",
-               .read_u64 = cpuset_read_u64,
-               .write_u64 = cpuset_write_u64,
+               .read_s64 = cpuset_read_s64,
+               .write_s64 = cpuset_write_s64,
                .private = FILE_SCHED_RELAX_DOMAIN_LEVEL,
        },
 
index d3ad54677f9c0257fa0a373f8ce1b4774e947722..1510f78a0ffa5a9496604b3acee679ca63d93c99 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/acct.h>
 #include <linux/tsacct_kern.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/binfmts.h>
 #include <linux/nsproxy.h>
 #include <linux/pid_namespace.h>
index 2bb675af4de30908b2dd1a22e745541e2bcbc3f5..933e60ebccae9f35001753a4426993c6aaf54fb6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mempolicy.h>
 #include <linux/sem.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/key.h>
 #include <linux/binfmts.h>
 #include <linux/mman.h>
index 98092c9817f42597c8c9a51b5ca1c4ce90509548..449def8074fea501f16371365c5721b173797164 100644 (file)
@@ -104,10 +104,6 @@ struct futex_q {
        /* Key which the futex is hashed on: */
        union futex_key key;
 
-       /* For fd, sigio sent using these: */
-       int fd;
-       struct file *filp;
-
        /* Optional priority inheritance state: */
        struct futex_pi_state *pi_state;
        struct task_struct *task;
@@ -126,9 +122,6 @@ struct futex_hash_bucket {
 
 static struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];
 
-/* Futex-fs vfsmount entry: */
-static struct vfsmount *futex_mnt;
-
 /*
  * Take mm->mmap_sem, when futex is shared
  */
@@ -610,8 +603,6 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
 static void wake_futex(struct futex_q *q)
 {
        plist_del(&q->list, &q->list.plist);
-       if (q->filp)
-               send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
        /*
         * The lock in wake_up_all() is a crucial memory barrier after the
         * plist_del() and also before assigning to q->lock_ptr.
@@ -988,14 +979,10 @@ out:
 }
 
 /* The key must be already stored in q->key. */
-static inline struct futex_hash_bucket *
-queue_lock(struct futex_q *q, int fd, struct file *filp)
+static inline struct futex_hash_bucket *queue_lock(struct futex_q *q)
 {
        struct futex_hash_bucket *hb;
 
-       q->fd = fd;
-       q->filp = filp;
-
        init_waitqueue_head(&q->waiters);
 
        get_futex_key_refs(&q->key);
@@ -1006,7 +993,7 @@ queue_lock(struct futex_q *q, int fd, struct file *filp)
        return hb;
 }
 
-static inline void __queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
+static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
 {
        int prio;
 
@@ -1041,15 +1028,6 @@ queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
  * exactly once.  They are called with the hashed spinlock held.
  */
 
-/* The key must be already stored in q->key. */
-static void queue_me(struct futex_q *q, int fd, struct file *filp)
-{
-       struct futex_hash_bucket *hb;
-
-       hb = queue_lock(q, fd, filp);
-       __queue_me(q, hb);
-}
-
 /* Return 1 if we were still queued (ie. 0 means we were woken) */
 static int unqueue_me(struct futex_q *q)
 {
@@ -1194,7 +1172,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
        if (unlikely(ret != 0))
                goto out_release_sem;
 
-       hb = queue_lock(&q, -1, NULL);
+       hb = queue_lock(&q);
 
        /*
         * Access the page AFTER the futex is queued.
@@ -1238,7 +1216,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
                goto out_unlock_release_sem;
 
        /* Only actually queue if *uaddr contained val.  */
-       __queue_me(&q, hb);
+       queue_me(&q, hb);
 
        /*
         * Now the futex is queued and we have checked the data, we
@@ -1386,7 +1364,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                goto out_release_sem;
 
  retry_unlocked:
-       hb = queue_lock(&q, -1, NULL);
+       hb = queue_lock(&q);
 
  retry_locked:
        ret = lock_taken = 0;
@@ -1499,7 +1477,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
        /*
         * Only actually queue now that the atomic ops are done:
         */
-       __queue_me(&q, hb);
+       queue_me(&q, hb);
 
        /*
         * Now the futex is queued and we have checked the data, we
@@ -1746,121 +1724,6 @@ pi_faulted:
        return ret;
 }
 
-static int futex_close(struct inode *inode, struct file *filp)
-{
-       struct futex_q *q = filp->private_data;
-
-       unqueue_me(q);
-       kfree(q);
-
-       return 0;
-}
-
-/* This is one-shot: once it's gone off you need a new fd */
-static unsigned int futex_poll(struct file *filp,
-                              struct poll_table_struct *wait)
-{
-       struct futex_q *q = filp->private_data;
-       int ret = 0;
-
-       poll_wait(filp, &q->waiters, wait);
-
-       /*
-        * plist_node_empty() is safe here without any lock.
-        * q->lock_ptr != 0 is not safe, because of ordering against wakeup.
-        */
-       if (plist_node_empty(&q->list))
-               ret = POLLIN | POLLRDNORM;
-
-       return ret;
-}
-
-static const struct file_operations futex_fops = {
-       .release        = futex_close,
-       .poll           = futex_poll,
-};
-
-/*
- * Signal allows caller to avoid the race which would occur if they
- * set the sigio stuff up afterwards.
- */
-static int futex_fd(u32 __user *uaddr, int signal)
-{
-       struct futex_q *q;
-       struct file *filp;
-       int ret, err;
-       struct rw_semaphore *fshared;
-       static unsigned long printk_interval;
-
-       if (printk_timed_ratelimit(&printk_interval, 60 * 60 * 1000)) {
-               printk(KERN_WARNING "Process `%s' used FUTEX_FD, which "
-                      "will be removed from the kernel in June 2007\n",
-                      current->comm);
-       }
-
-       ret = -EINVAL;
-       if (!valid_signal(signal))
-               goto out;
-
-       ret = get_unused_fd();
-       if (ret < 0)
-               goto out;
-       filp = get_empty_filp();
-       if (!filp) {
-               put_unused_fd(ret);
-               ret = -ENFILE;
-               goto out;
-       }
-       filp->f_op = &futex_fops;
-       filp->f_path.mnt = mntget(futex_mnt);
-       filp->f_path.dentry = dget(futex_mnt->mnt_root);
-       filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping;
-
-       if (signal) {
-               err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1);
-               if (err < 0) {
-                       goto error;
-               }
-               filp->f_owner.signum = signal;
-       }
-
-       q = kmalloc(sizeof(*q), GFP_KERNEL);
-       if (!q) {
-               err = -ENOMEM;
-               goto error;
-       }
-       q->pi_state = NULL;
-
-       fshared = &current->mm->mmap_sem;
-       down_read(fshared);
-       err = get_futex_key(uaddr, fshared, &q->key);
-
-       if (unlikely(err != 0)) {
-               up_read(fshared);
-               kfree(q);
-               goto error;
-       }
-
-       /*
-        * queue_me() must be called before releasing mmap_sem, because
-        * key->shared.inode needs to be referenced while holding it.
-        */
-       filp->private_data = q;
-
-       queue_me(q, ret, filp);
-       up_read(fshared);
-
-       /* Now we map fd to filp, so userspace can access it */
-       fd_install(ret, filp);
-out:
-       return ret;
-error:
-       put_unused_fd(ret);
-       put_filp(filp);
-       ret = err;
-       goto out;
-}
-
 /*
  * Support for robust futexes: the kernel cleans up held futexes at
  * thread exit time.
@@ -2092,10 +1955,6 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
        case FUTEX_WAKE_BITSET:
                ret = futex_wake(uaddr, fshared, val, val3);
                break;
-       case FUTEX_FD:
-               /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
-               ret = futex_fd(uaddr, val);
-               break;
        case FUTEX_REQUEUE:
                ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL);
                break;
@@ -2156,19 +2015,6 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val,
        return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
 }
 
-static int futexfs_get_sb(struct file_system_type *fs_type,
-                         int flags, const char *dev_name, void *data,
-                         struct vfsmount *mnt)
-{
-       return get_sb_pseudo(fs_type, "futex", NULL, FUTEXFS_SUPER_MAGIC, mnt);
-}
-
-static struct file_system_type futex_fs_type = {
-       .name           = "futexfs",
-       .get_sb         = futexfs_get_sb,
-       .kill_sb        = kill_anon_super,
-};
-
 static int __init futex_init(void)
 {
        u32 curval;
@@ -2193,16 +2039,6 @@ static int __init futex_init(void)
                spin_lock_init(&futex_queues[i].lock);
        }
 
-       i = register_filesystem(&futex_fs_type);
-       if (i)
-               return i;
-
-       futex_mnt = kern_mount(&futex_fs_type);
-       if (IS_ERR(futex_mnt)) {
-               unregister_filesystem(&futex_fs_type);
-               return PTR_ERR(futex_mnt);
-       }
-
        return 0;
 }
 __initcall(futex_init);
index 9af1d6a8095e40f80e64cdade6c0c3b505184466..421be5fe5cc78f5d2be0eabd3ba2367fe1b15b3e 100644 (file)
@@ -153,15 +153,6 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
                ktime_add(xtim, tomono);
 }
 
-/*
- * Helper function to check, whether the timer is running the callback
- * function
- */
-static inline int hrtimer_callback_running(struct hrtimer *timer)
-{
-       return timer->state & HRTIMER_STATE_CALLBACK;
-}
-
 /*
  * Functions and macros which are different for UP/SMP systems are kept in a
  * single place
index 46e4ad1723f0545377c342c57a988a5ff99fef9c..46d6611a33bbe4a7997637168feb543acd0f0b8e 100644 (file)
@@ -150,6 +150,26 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
+static void __enable_irq(struct irq_desc *desc, unsigned int irq)
+{
+       switch (desc->depth) {
+       case 0:
+               printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
+               WARN_ON(1);
+               break;
+       case 1: {
+               unsigned int status = desc->status & ~IRQ_DISABLED;
+
+               /* Prevent probing on this irq: */
+               desc->status = status | IRQ_NOPROBE;
+               check_irq_resend(desc, irq);
+               /* fall-through */
+       }
+       default:
+               desc->depth--;
+       }
+}
+
 /**
  *     enable_irq - enable handling of an irq
  *     @irq: Interrupt to enable
@@ -169,22 +189,7 @@ void enable_irq(unsigned int irq)
                return;
 
        spin_lock_irqsave(&desc->lock, flags);
-       switch (desc->depth) {
-       case 0:
-               printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
-               WARN_ON(1);
-               break;
-       case 1: {
-               unsigned int status = desc->status & ~IRQ_DISABLED;
-
-               /* Prevent probing on this irq: */
-               desc->status = status | IRQ_NOPROBE;
-               check_irq_resend(desc, irq);
-               /* fall-through */
-       }
-       default:
-               desc->depth--;
-       }
+       __enable_irq(desc, irq);
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 EXPORT_SYMBOL(enable_irq);
@@ -365,7 +370,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
                        compat_irq_chip_set_default_handler(desc);
 
                desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
-                                 IRQ_INPROGRESS);
+                                 IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED);
 
                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
@@ -381,6 +386,16 @@ int setup_irq(unsigned int irq, struct irqaction *new)
        /* Reset broken irq detection when installing new handler */
        desc->irq_count = 0;
        desc->irqs_unhandled = 0;
+
+       /*
+        * Check whether we disabled the irq via the spurious handler
+        * before. Reenable it and give it another chance.
+        */
+       if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) {
+               desc->status &= ~IRQ_SPURIOUS_DISABLED;
+               __enable_irq(desc, irq);
+       }
+
        spin_unlock_irqrestore(&desc->lock, flags);
 
        new->irq = irq;
index 088dabbf2d6a6cbca786ec80fe0ce6851175fef9..c66d3f10e85326ab1041a29202047734769b9b10 100644 (file)
@@ -209,8 +209,8 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
                 * Now kill the IRQ
                 */
                printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
-               desc->status |= IRQ_DISABLED;
-               desc->depth = 1;
+               desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
+               desc->depth++;
                desc->chip->disable(irq);
        }
        desc->irqs_unhandled = 0;
index cb85c79989b440a3979e3d2e6dd3bcfa198b1c3b..1c5fcacbcf336b8dc82d0b02202a3d95c32fbd13 100644 (file)
@@ -1217,7 +1217,7 @@ static int __init parse_crashkernel_mem(char                      *cmdline,
                }
 
                /* match ? */
-               if (system_ram >= start && system_ram <= end) {
+               if (system_ram >= start && system_ram < end) {
                        *crash_size = size;
                        break;
                }
index 1bd0ec1c80b284ec06870bc8bc2b2ce726e27815..39e31a036f5b0e31bf6187df2751a589d409b328 100644 (file)
@@ -61,7 +61,7 @@ struct kgdb_state {
        int                     err_code;
        int                     cpu;
        int                     pass_exception;
-       long                    threadid;
+       unsigned long           threadid;
        long                    kgdb_usethreadid;
        struct pt_regs          *linux_regs;
 };
@@ -146,7 +146,7 @@ atomic_t                    kgdb_cpu_doing_single_step = ATOMIC_INIT(-1);
  * the other CPUs might interfere with your debugging context, so
  * use this with care:
  */
-int                            kgdb_do_roundup = 1;
+static int kgdb_do_roundup = 1;
 
 static int __init opt_nokgdbroundup(char *str)
 {
@@ -438,7 +438,7 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
  * While we find nice hex chars, build a long_val.
  * Return number of chars processed.
  */
-int kgdb_hex2long(char **ptr, long *long_val)
+int kgdb_hex2long(char **ptr, unsigned long *long_val)
 {
        int hex_val;
        int num = 0;
@@ -709,7 +709,7 @@ int kgdb_isremovedbreak(unsigned long addr)
        return 0;
 }
 
-int remove_all_break(void)
+static int remove_all_break(void)
 {
        unsigned long addr;
        int error;
index e2764047ec03ed123acd3546ff4357341302cabb..8df97d3dfda8611423d7cac323cb9ef5dce5170c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mnt_namespace.h>
 #include <linux/completion.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/workqueue.h>
 #include <linux/security.h>
 #include <linux/mount.h>
index 8d6cccc6c3cf99870f76b00202a2775bd5e2a54f..f5e9491ef7ac2ed9d9473ded84c37f5018ed722c 100644 (file)
@@ -164,131 +164,140 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
        return NULL;
 }
 
-static void printk_unused_warning(const char *name)
+static bool always_ok(bool gplok, bool warn, const char *name)
 {
-       printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
-               "however this module is using it.\n", name);
-       printk(KERN_WARNING "This symbol will go away in the future.\n");
-       printk(KERN_WARNING "Please evalute if this is the right api to use, "
-               "and if it really is, submit a report the linux kernel "
-               "mailinglist together with submitting your code for "
-               "inclusion.\n");
+       return true;
 }
 
-/* Find a symbol, return value, crc and module which owns it */
-static unsigned long __find_symbol(const char *name,
-                                  struct module **owner,
-                                  const unsigned long **crc,
-                                  int gplok)
+static bool printk_unused_warning(bool gplok, bool warn, const char *name)
 {
-       struct module *mod;
-       const struct kernel_symbol *ks;
-
-       /* Core kernel first. */
-       *owner = NULL;
-       ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
-       if (ks) {
-               *crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
-               return ks->value;
-       }
-       if (gplok) {
-               ks = lookup_symbol(name, __start___ksymtab_gpl,
-                                        __stop___ksymtab_gpl);
-               if (ks) {
-                       *crc = symversion(__start___kcrctab_gpl,
-                                         (ks - __start___ksymtab_gpl));
-                       return ks->value;
-               }
+       if (warn) {
+               printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
+                      "however this module is using it.\n", name);
+               printk(KERN_WARNING
+                      "This symbol will go away in the future.\n");
+               printk(KERN_WARNING
+                      "Please evalute if this is the right api to use and if "
+                      "it really is, submit a report the linux kernel "
+                      "mailinglist together with submitting your code for "
+                      "inclusion.\n");
        }
-       ks = lookup_symbol(name, __start___ksymtab_gpl_future,
-                                __stop___ksymtab_gpl_future);
-       if (ks) {
-               if (!gplok) {
-                       printk(KERN_WARNING "Symbol %s is being used "
-                              "by a non-GPL module, which will not "
-                              "be allowed in the future\n", name);
-                       printk(KERN_WARNING "Please see the file "
-                              "Documentation/feature-removal-schedule.txt "
-                              "in the kernel source tree for more "
-                              "details.\n");
-               }
-               *crc = symversion(__start___kcrctab_gpl_future,
-                                 (ks - __start___ksymtab_gpl_future));
-               return ks->value;
+       return true;
+}
+
+static bool gpl_only_unused_warning(bool gplok, bool warn, const char *name)
+{
+       if (!gplok)
+               return false;
+       return printk_unused_warning(gplok, warn, name);
+}
+
+static bool gpl_only(bool gplok, bool warn, const char *name)
+{
+       return gplok;
+}
+
+static bool warn_if_not_gpl(bool gplok, bool warn, const char *name)
+{
+       if (!gplok && warn) {
+               printk(KERN_WARNING "Symbol %s is being used "
+                      "by a non-GPL module, which will not "
+                      "be allowed in the future\n", name);
+               printk(KERN_WARNING "Please see the file "
+                      "Documentation/feature-removal-schedule.txt "
+                      "in the kernel source tree for more details.\n");
        }
+       return true;
+}
 
-       ks = lookup_symbol(name, __start___ksymtab_unused,
-                                __stop___ksymtab_unused);
-       if (ks) {
-               printk_unused_warning(name);
-               *crc = symversion(__start___kcrctab_unused,
-                                 (ks - __start___ksymtab_unused));
-               return ks->value;
+struct symsearch {
+       const struct kernel_symbol *start, *stop;
+       const unsigned long *crcs;
+       bool (*check)(bool gplok, bool warn, const char *name);
+};
+
+/* Look through this array of symbol tables for a symbol match which
+ * passes the check function. */
+static const struct kernel_symbol *search_symarrays(const struct symsearch *arr,
+                                                   unsigned int num,
+                                                   const char *name,
+                                                   bool gplok,
+                                                   bool warn,
+                                                   const unsigned long **crc)
+{
+       unsigned int i;
+       const struct kernel_symbol *ks;
+
+       for (i = 0; i < num; i++) {
+               ks = lookup_symbol(name, arr[i].start, arr[i].stop);
+               if (!ks || !arr[i].check(gplok, warn, name))
+                       continue;
+
+               if (crc)
+                       *crc = symversion(arr[i].crcs, ks - arr[i].start);
+               return ks;
        }
+       return NULL;
+}
 
-       if (gplok)
-               ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
-                                __stop___ksymtab_unused_gpl);
+/* Find a symbol, return value, (optional) crc and (optional) module
+ * which owns it */
+static unsigned long find_symbol(const char *name,
+                                struct module **owner,
+                                const unsigned long **crc,
+                                bool gplok,
+                                bool warn)
+{
+       struct module *mod;
+       const struct kernel_symbol *ks;
+       const struct symsearch arr[] = {
+               { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
+                 always_ok },
+               { __start___ksymtab_gpl, __stop___ksymtab_gpl,
+                 __start___kcrctab_gpl, gpl_only },
+               { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,
+                 __start___kcrctab_gpl_future, warn_if_not_gpl },
+               { __start___ksymtab_unused, __stop___ksymtab_unused,
+                 __start___kcrctab_unused, printk_unused_warning },
+               { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,
+                 __start___kcrctab_unused_gpl, gpl_only_unused_warning },
+       };
+
+       /* Core kernel first. */
+       ks = search_symarrays(arr, ARRAY_SIZE(arr), name, gplok, warn, crc);
        if (ks) {
-               printk_unused_warning(name);
-               *crc = symversion(__start___kcrctab_unused_gpl,
-                                 (ks - __start___ksymtab_unused_gpl));
+               if (owner)
+                       *owner = NULL;
                return ks->value;
        }
 
        /* Now try modules. */
        list_for_each_entry(mod, &modules, list) {
-               *owner = mod;
-               ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
+               struct symsearch arr[] = {
+                       { mod->syms, mod->syms + mod->num_syms, mod->crcs,
+                         always_ok },
+                       { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
+                         mod->gpl_crcs, gpl_only },
+                       { mod->gpl_future_syms,
+                         mod->gpl_future_syms + mod->num_gpl_future_syms,
+                         mod->gpl_future_crcs, warn_if_not_gpl },
+                       { mod->unused_syms,
+                         mod->unused_syms + mod->num_unused_syms,
+                         mod->unused_crcs, printk_unused_warning },
+                       { mod->unused_gpl_syms,
+                         mod->unused_gpl_syms + mod->num_unused_gpl_syms,
+                         mod->unused_gpl_crcs, gpl_only_unused_warning },
+               };
+
+               ks = search_symarrays(arr, ARRAY_SIZE(arr),
+                                     name, gplok, warn, crc);
                if (ks) {
-                       *crc = symversion(mod->crcs, (ks - mod->syms));
-                       return ks->value;
-               }
-
-               if (gplok) {
-                       ks = lookup_symbol(name, mod->gpl_syms,
-                                          mod->gpl_syms + mod->num_gpl_syms);
-                       if (ks) {
-                               *crc = symversion(mod->gpl_crcs,
-                                                 (ks - mod->gpl_syms));
-                               return ks->value;
-                       }
-               }
-               ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
-               if (ks) {
-                       printk_unused_warning(name);
-                       *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
-                       return ks->value;
-               }
-
-               if (gplok) {
-                       ks = lookup_symbol(name, mod->unused_gpl_syms,
-                                          mod->unused_gpl_syms + mod->num_unused_gpl_syms);
-                       if (ks) {
-                               printk_unused_warning(name);
-                               *crc = symversion(mod->unused_gpl_crcs,
-                                                 (ks - mod->unused_gpl_syms));
-                               return ks->value;
-                       }
-               }
-               ks = lookup_symbol(name, mod->gpl_future_syms,
-                                  (mod->gpl_future_syms +
-                                   mod->num_gpl_future_syms));
-               if (ks) {
-                       if (!gplok) {
-                               printk(KERN_WARNING "Symbol %s is being used "
-                                      "by a non-GPL module, which will not "
-                                      "be allowed in the future\n", name);
-                               printk(KERN_WARNING "Please see the file "
-                                      "Documentation/feature-removal-schedule.txt "
-                                      "in the kernel source tree for more "
-                                      "details.\n");
-                       }
-                       *crc = symversion(mod->gpl_future_crcs,
-                                         (ks - mod->gpl_future_syms));
+                       if (owner)
+                               *owner = mod;
                        return ks->value;
                }
        }
+
        DEBUGP("Failed to find symbol %s\n", name);
        return -ENOENT;
 }
@@ -736,12 +745,13 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
        if (!forced && module_refcount(mod) != 0)
                wait_for_zero_refcount(mod);
 
+       mutex_unlock(&module_mutex);
        /* Final destruction now noone is using it. */
-       if (mod->exit != NULL) {
-               mutex_unlock(&module_mutex);
+       if (mod->exit != NULL)
                mod->exit();
-               mutex_lock(&module_mutex);
-       }
+       blocking_notifier_call_chain(&module_notify_list,
+                                    MODULE_STATE_GOING, mod);
+       mutex_lock(&module_mutex);
        /* Store the name of the last unloaded module for diagnostic purposes */
        strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
        free_module(mod);
@@ -777,10 +787,9 @@ static void print_unload_info(struct seq_file *m, struct module *mod)
 void __symbol_put(const char *symbol)
 {
        struct module *owner;
-       const unsigned long *crc;
 
        preempt_disable();
-       if (IS_ERR_VALUE(__find_symbol(symbol, &owner, &crc, 1)))
+       if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
                BUG();
        module_put(owner);
        preempt_enable();
@@ -881,6 +890,19 @@ static struct module_attribute *modinfo_attrs[] = {
 
 static const char vermagic[] = VERMAGIC_STRING;
 
+static int try_to_force_load(struct module *mod, const char *symname)
+{
+#ifdef CONFIG_MODULE_FORCE_LOAD
+       if (!(tainted & TAINT_FORCED_MODULE))
+               printk("%s: no version for \"%s\" found: kernel tainted.\n",
+                      mod->name, symname);
+       add_taint_module(mod, TAINT_FORCED_MODULE);
+       return 0;
+#else
+       return -ENOEXEC;
+#endif
+}
+
 #ifdef CONFIG_MODVERSIONS
 static int check_version(Elf_Shdr *sechdrs,
                         unsigned int versindex,
@@ -895,6 +917,10 @@ static int check_version(Elf_Shdr *sechdrs,
        if (!crc)
                return 1;
 
+       /* No versions at all?  modprobe --force does this. */
+       if (versindex == 0)
+               return try_to_force_load(mod, symname) == 0;
+
        versions = (void *) sechdrs[versindex].sh_addr;
        num_versions = sechdrs[versindex].sh_size
                / sizeof(struct modversion_info);
@@ -905,18 +931,19 @@ static int check_version(Elf_Shdr *sechdrs,
 
                if (versions[i].crc == *crc)
                        return 1;
-               printk("%s: disagrees about version of symbol %s\n",
-                      mod->name, symname);
                DEBUGP("Found checksum %lX vs module %lX\n",
                       *crc, versions[i].crc);
-               return 0;
+               goto bad_version;
        }
-       /* Not in module's version table.  OK, but that taints the kernel. */
-       if (!(tainted & TAINT_FORCED_MODULE))
-               printk("%s: no version for \"%s\" found: kernel tainted.\n",
-                      mod->name, symname);
-       add_taint_module(mod, TAINT_FORCED_MODULE);
-       return 1;
+
+       printk(KERN_WARNING "%s: no symbol version for %s\n",
+              mod->name, symname);
+       return 0;
+
+bad_version:
+       printk("%s: disagrees about version of symbol %s\n",
+              mod->name, symname);
+       return 0;
 }
 
 static inline int check_modstruct_version(Elf_Shdr *sechdrs,
@@ -924,20 +951,20 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
                                          struct module *mod)
 {
        const unsigned long *crc;
-       struct module *owner;
 
-       if (IS_ERR_VALUE(__find_symbol("struct_module",
-                                               &owner, &crc, 1)))
+       if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
                BUG();
-       return check_version(sechdrs, versindex, "struct_module", mod,
-                            crc);
+       return check_version(sechdrs, versindex, "struct_module", mod, crc);
 }
 
-/* First part is kernel version, which we ignore. */
-static inline int same_magic(const char *amagic, const char *bmagic)
+/* First part is kernel version, which we ignore if module has crcs. */
+static inline int same_magic(const char *amagic, const char *bmagic,
+                            bool has_crcs)
 {
-       amagic += strcspn(amagic, " ");
-       bmagic += strcspn(bmagic, " ");
+       if (has_crcs) {
+               amagic += strcspn(amagic, " ");
+               bmagic += strcspn(bmagic, " ");
+       }
        return strcmp(amagic, bmagic) == 0;
 }
 #else
@@ -957,7 +984,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
        return 1;
 }
 
-static inline int same_magic(const char *amagic, const char *bmagic)
+static inline int same_magic(const char *amagic, const char *bmagic,
+                            bool has_crcs)
 {
        return strcmp(amagic, bmagic) == 0;
 }
@@ -974,8 +1002,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
        unsigned long ret;
        const unsigned long *crc;
 
-       ret = __find_symbol(name, &owner, &crc,
-                       !(mod->taints & TAINT_PROPRIETARY_MODULE));
+       ret = find_symbol(name, &owner, &crc,
+                         !(mod->taints & TAINT_PROPRIETARY_MODULE), true);
        if (!IS_ERR_VALUE(ret)) {
                /* use_module can fail due to OOM,
                   or module initialization or unloading */
@@ -991,6 +1019,20 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
  * J. Corbet <corbet@lwn.net>
  */
 #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS)
+struct module_sect_attr
+{
+       struct module_attribute mattr;
+       char *name;
+       unsigned long address;
+};
+
+struct module_sect_attrs
+{
+       struct attribute_group grp;
+       unsigned int nsections;
+       struct module_sect_attr attrs[0];
+};
+
 static ssize_t module_sect_show(struct module_attribute *mattr,
                                struct module *mod, char *buf)
 {
@@ -1001,7 +1043,7 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
 {
-       int section;
+       unsigned int section;
 
        for (section = 0; section < sect_attrs->nsections; section++)
                kfree(sect_attrs->attrs[section].name);
@@ -1362,10 +1404,9 @@ void *__symbol_get(const char *symbol)
 {
        struct module *owner;
        unsigned long value;
-       const unsigned long *crc;
 
        preempt_disable();
-       value = __find_symbol(symbol, &owner, &crc, 1);
+       value = find_symbol(symbol, &owner, NULL, true, true);
        if (IS_ERR_VALUE(value))
                value = 0;
        else if (strong_try_module_get(owner))
@@ -1382,33 +1423,33 @@ EXPORT_SYMBOL_GPL(__symbol_get);
  */
 static int verify_export_symbols(struct module *mod)
 {
-       const char *name = NULL;
-       unsigned long i, ret = 0;
+       unsigned int i;
        struct module *owner;
-       const unsigned long *crc;
-
-       for (i = 0; i < mod->num_syms; i++)
-               if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name,
-                                                       &owner, &crc, 1))) {
-                       name = mod->syms[i].name;
-                       ret = -ENOEXEC;
-                       goto dup;
-               }
+       const struct kernel_symbol *s;
+       struct {
+               const struct kernel_symbol *sym;
+               unsigned int num;
+       } arr[] = {
+               { mod->syms, mod->num_syms },
+               { mod->gpl_syms, mod->num_gpl_syms },
+               { mod->gpl_future_syms, mod->num_gpl_future_syms },
+               { mod->unused_syms, mod->num_unused_syms },
+               { mod->unused_gpl_syms, mod->num_unused_gpl_syms },
+       };
 
-       for (i = 0; i < mod->num_gpl_syms; i++)
-               if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name,
-                                                       &owner, &crc, 1))) {
-                       name = mod->gpl_syms[i].name;
-                       ret = -ENOEXEC;
-                       goto dup;
+       for (i = 0; i < ARRAY_SIZE(arr); i++) {
+               for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
+                       if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
+                                                     NULL, true, false))) {
+                               printk(KERN_ERR
+                                      "%s: exports duplicate symbol %s"
+                                      " (owned by %s)\n",
+                                      mod->name, s->name, module_name(owner));
+                               return -ENOEXEC;
+                       }
                }
-
-dup:
-       if (ret)
-               printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
-                       mod->name, name, module_name(owner));
-
-       return ret;
+       }
+       return 0;
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */
@@ -1814,8 +1855,9 @@ static struct module *load_module(void __user *umod,
        unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME);
 #endif
 
-       /* Don't keep modinfo section */
+       /* Don't keep modinfo and version sections. */
        sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
+       sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #ifdef CONFIG_KALLSYMS
        /* Keep symbol and string tables for decoding later. */
        sechdrs[symindex].sh_flags |= SHF_ALLOC;
@@ -1833,10 +1875,10 @@ static struct module *load_module(void __user *umod,
        modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
-               add_taint_module(mod, TAINT_FORCED_MODULE);
-               printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
-                      mod->name);
-       } else if (!same_magic(modmagic, vermagic)) {
+               err = try_to_force_load(mod, "magic");
+               if (err)
+                       goto free_hdr;
+       } else if (!same_magic(modmagic, vermagic, versindex)) {
                printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
                       mod->name, modmagic, vermagic);
                err = -ENOEXEC;
@@ -1977,7 +2019,8 @@ static struct module *load_module(void __user *umod,
                mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
        mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr;
        if (unusedgplcrcindex)
-               mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
+               mod->unused_gpl_crcs
+                       = (void *)sechdrs[unusedgplcrcindex].sh_addr;
 
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !crcindex) ||
@@ -1985,9 +2028,10 @@ static struct module *load_module(void __user *umod,
            (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
            (mod->num_unused_syms && !unusedcrcindex) ||
            (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
-               printk(KERN_WARNING "%s: No versions for exported symbols."
-                      " Tainting kernel.\n", mod->name);
-               add_taint_module(mod, TAINT_FORCED_MODULE);
+               printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
+               err = try_to_force_load(mod, "nocrc");
+               if (err)
+                       goto cleanup;
        }
 #endif
        markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
@@ -2171,6 +2215,8 @@ sys_init_module(void __user *umod,
                mod->state = MODULE_STATE_GOING;
                synchronize_sched();
                module_put(mod);
+               blocking_notifier_call_chain(&module_notify_list,
+                                            MODULE_STATE_GOING, mod);
                mutex_lock(&module_mutex);
                free_module(mod);
                mutex_unlock(&module_mutex);
index ae5c6c147c4b37def0b8e3e89f0db9c022d0bc67..f1525ad06cb3ebbb83680b2bc0176854002217ca 100644 (file)
@@ -4,8 +4,9 @@
 
 #include <linux/sched.h>
 #include <linux/posix-timers.h>
-#include <asm/uaccess.h>
 #include <linux/errno.h>
+#include <linux/math64.h>
+#include <asm/uaccess.h>
 
 static int check_clock(const clockid_t which_clock)
 {
@@ -47,12 +48,10 @@ static void sample_to_timespec(const clockid_t which_clock,
                               union cpu_time_count cpu,
                               struct timespec *tp)
 {
-       if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
-               tp->tv_sec = div_long_long_rem(cpu.sched,
-                                              NSEC_PER_SEC, &tp->tv_nsec);
-       } else {
+       if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED)
+               *tp = ns_to_timespec(cpu.sched);
+       else
                cputime_to_timespec(cpu.cpu, tp);
-       }
 }
 
 static inline int cpu_time_before(const clockid_t which_clock,
index dcc199c43a12abcb9e62b4a70e090084d3075fa4..6c19e94fd0a5482786e432599a0fb4840a5c66cb 100644 (file)
@@ -534,7 +534,6 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
 #define arch_ptrace_attach(child)      do { } while (0)
 #endif
 
-#ifndef __ARCH_SYS_PTRACE
 asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
@@ -582,7 +581,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
        unlock_kernel();
        return ret;
 }
-#endif /* __ARCH_SYS_PTRACE */
 
 int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
 {
index 7de644cdec43590be390d3037206e5722aa46856..bc24dcdc570f5dfa222edbff1c1a2d80e23cb7e1 100644 (file)
@@ -1191,7 +1191,7 @@ static ssize_t relay_file_splice_read(struct file *in,
        ret = 0;
        spliced = 0;
 
-       while (len && !spliced) {
+       while (len) {
                ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
                if (ret < 0)
                        break;
index e2f7f5acc80778328a892961d8e26faa7c4c8841..8841a915545dfd84a8ed9c6f9e49c777963fd3c9 100644 (file)
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
 
-/*
- * Scheduler clock - returns current time in nanosec units.
- * This is default implementation.
- * Architectures and sub-architectures can override this.
- */
-unsigned long long __attribute__((weak)) sched_clock(void)
-{
-       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
-}
-
 /*
  * Convert user-nice values [ -20 ... 0 ... 19 ]
  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@ -242,6 +232,12 @@ static void destroy_rt_bandwidth(struct rt_bandwidth *rt_b)
 }
 #endif
 
+/*
+ * sched_domains_mutex serializes calls to arch_init_sched_domains,
+ * detach_destroy_domains and partition_sched_domains.
+ */
+static DEFINE_MUTEX(sched_domains_mutex);
+
 #ifdef CONFIG_GROUP_SCHED
 
 #include <linux/cgroup.h>
@@ -308,9 +304,6 @@ static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp;
  */
 static DEFINE_SPINLOCK(task_group_lock);
 
-/* doms_cur_mutex serializes access to doms_cur[] array */
-static DEFINE_MUTEX(doms_cur_mutex);
-
 #ifdef CONFIG_FAIR_GROUP_SCHED
 #ifdef CONFIG_USER_SCHED
 # define INIT_TASK_GROUP_LOAD  (2*NICE_0_LOAD)
@@ -318,7 +311,13 @@ static DEFINE_MUTEX(doms_cur_mutex);
 # define INIT_TASK_GROUP_LOAD  NICE_0_LOAD
 #endif
 
+/*
+ * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems.
+ * (The default weight is 1024 - so there's no practical
+ *  limitation from this.)
+ */
 #define MIN_SHARES     2
+#define MAX_SHARES     (ULONG_MAX - 1)
 
 static int init_task_group_load = INIT_TASK_GROUP_LOAD;
 #endif
@@ -358,21 +357,9 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 #endif
 }
 
-static inline void lock_doms_cur(void)
-{
-       mutex_lock(&doms_cur_mutex);
-}
-
-static inline void unlock_doms_cur(void)
-{
-       mutex_unlock(&doms_cur_mutex);
-}
-
 #else
 
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
-static inline void lock_doms_cur(void) { }
-static inline void unlock_doms_cur(void) { }
 
 #endif /* CONFIG_GROUP_SCHED */
 
@@ -560,13 +547,7 @@ struct rq {
        unsigned long next_balance;
        struct mm_struct *prev_mm;
 
-       u64 clock, prev_clock_raw;
-       s64 clock_max_delta;
-
-       unsigned int clock_warps, clock_overflows, clock_underflows;
-       u64 idle_clock;
-       unsigned int clock_deep_idle_events;
-       u64 tick_timestamp;
+       u64 clock;
 
        atomic_t nr_iowait;
 
@@ -631,82 +612,6 @@ static inline int cpu_of(struct rq *rq)
 #endif
 }
 
-#ifdef CONFIG_NO_HZ
-static inline bool nohz_on(int cpu)
-{
-       return tick_get_tick_sched(cpu)->nohz_mode != NOHZ_MODE_INACTIVE;
-}
-
-static inline u64 max_skipped_ticks(struct rq *rq)
-{
-       return nohz_on(cpu_of(rq)) ? jiffies - rq->last_tick_seen + 2 : 1;
-}
-
-static inline void update_last_tick_seen(struct rq *rq)
-{
-       rq->last_tick_seen = jiffies;
-}
-#else
-static inline u64 max_skipped_ticks(struct rq *rq)
-{
-       return 1;
-}
-
-static inline void update_last_tick_seen(struct rq *rq)
-{
-}
-#endif
-
-/*
- * Update the per-runqueue clock, as finegrained as the platform can give
- * us, but without assuming monotonicity, etc.:
- */
-static void __update_rq_clock(struct rq *rq)
-{
-       u64 prev_raw = rq->prev_clock_raw;
-       u64 now = sched_clock();
-       s64 delta = now - prev_raw;
-       u64 clock = rq->clock;
-
-#ifdef CONFIG_SCHED_DEBUG
-       WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
-#endif
-       /*
-        * Protect against sched_clock() occasionally going backwards:
-        */
-       if (unlikely(delta < 0)) {
-               clock++;
-               rq->clock_warps++;
-       } else {
-               /*
-                * Catch too large forward jumps too:
-                */
-               u64 max_jump = max_skipped_ticks(rq) * TICK_NSEC;
-               u64 max_time = rq->tick_timestamp + max_jump;
-
-               if (unlikely(clock + delta > max_time)) {
-                       if (clock < max_time)
-                               clock = max_time;
-                       else
-                               clock++;
-                       rq->clock_overflows++;
-               } else {
-                       if (unlikely(delta > rq->clock_max_delta))
-                               rq->clock_max_delta = delta;
-                       clock += delta;
-               }
-       }
-
-       rq->prev_clock_raw = now;
-       rq->clock = clock;
-}
-
-static void update_rq_clock(struct rq *rq)
-{
-       if (likely(smp_processor_id() == cpu_of(rq)))
-               __update_rq_clock(rq);
-}
-
 /*
  * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
  * See detach_destroy_domains: synchronize_sched for details.
@@ -722,6 +627,11 @@ static void update_rq_clock(struct rq *rq)
 #define task_rq(p)             cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)          (cpu_rq(cpu)->curr)
 
+static inline void update_rq_clock(struct rq *rq)
+{
+       rq->clock = sched_clock_cpu(cpu_of(rq));
+}
+
 /*
  * Tunables that become constants when CONFIG_SCHED_DEBUG is off:
  */
@@ -757,14 +667,14 @@ const_debug unsigned int sysctl_sched_features =
 #define SCHED_FEAT(name, enabled)      \
        #name ,
 
-__read_mostly char *sched_feat_names[] = {
+static __read_mostly char *sched_feat_names[] = {
 #include "sched_features.h"
        NULL
 };
 
 #undef SCHED_FEAT
 
-int sched_feat_open(struct inode *inode, struct file *filp)
+static int sched_feat_open(struct inode *inode, struct file *filp)
 {
        filp->private_data = inode->i_private;
        return 0;
@@ -899,7 +809,7 @@ static inline u64 global_rt_runtime(void)
        return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC;
 }
 
-static const unsigned long long time_sync_thresh = 100000;
+unsigned long long time_sync_thresh = 100000;
 
 static DEFINE_PER_CPU(unsigned long long, time_offset);
 static DEFINE_PER_CPU(unsigned long long, prev_cpu_time);
@@ -913,11 +823,14 @@ static DEFINE_PER_CPU(unsigned long long, prev_cpu_time);
 static DEFINE_SPINLOCK(time_sync_lock);
 static unsigned long long prev_global_time;
 
-static unsigned long long __sync_cpu_clock(cycles_t time, int cpu)
+static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&time_sync_lock, flags);
+       /*
+        * We want this inlined, to not get tracer function calls
+        * in this critical section:
+        */
+       spin_acquire(&time_sync_lock.dep_map, 0, 0, _THIS_IP_);
+       __raw_spin_lock(&time_sync_lock.raw_lock);
 
        if (time < prev_global_time) {
                per_cpu(time_offset, cpu) += prev_global_time - time;
@@ -926,7 +839,8 @@ static unsigned long long __sync_cpu_clock(cycles_t time, int cpu)
                prev_global_time = time;
        }
 
-       spin_unlock_irqrestore(&time_sync_lock, flags);
+       __raw_spin_unlock(&time_sync_lock.raw_lock);
+       spin_release(&time_sync_lock.dep_map, 1, _THIS_IP_);
 
        return time;
 }
@@ -934,8 +848,6 @@ static unsigned long long __sync_cpu_clock(cycles_t time, int cpu)
 static unsigned long long __cpu_clock(int cpu)
 {
        unsigned long long now;
-       unsigned long flags;
-       struct rq *rq;
 
        /*
         * Only call sched_clock() if the scheduler has already been
@@ -944,11 +856,7 @@ static unsigned long long __cpu_clock(int cpu)
        if (unlikely(!scheduler_running))
                return 0;
 
-       local_irq_save(flags);
-       rq = cpu_rq(cpu);
-       update_rq_clock(rq);
-       now = rq->clock;
-       local_irq_restore(flags);
+       now = sched_clock_cpu(cpu);
 
        return now;
 }
@@ -960,13 +868,18 @@ static unsigned long long __cpu_clock(int cpu)
 unsigned long long cpu_clock(int cpu)
 {
        unsigned long long prev_cpu_time, time, delta_time;
+       unsigned long flags;
 
+       local_irq_save(flags);
        prev_cpu_time = per_cpu(prev_cpu_time, cpu);
        time = __cpu_clock(cpu) + per_cpu(time_offset, cpu);
        delta_time = time-prev_cpu_time;
 
-       if (unlikely(delta_time > time_sync_thresh))
+       if (unlikely(delta_time > time_sync_thresh)) {
                time = __sync_cpu_clock(time, cpu);
+               per_cpu(prev_cpu_time, cpu) = time;
+       }
+       local_irq_restore(flags);
 
        return time;
 }
@@ -1117,43 +1030,6 @@ static struct rq *this_rq_lock(void)
        return rq;
 }
 
-/*
- * We are going deep-idle (irqs are disabled):
- */
-void sched_clock_idle_sleep_event(void)
-{
-       struct rq *rq = cpu_rq(smp_processor_id());
-
-       spin_lock(&rq->lock);
-       __update_rq_clock(rq);
-       spin_unlock(&rq->lock);
-       rq->clock_deep_idle_events++;
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
-
-/*
- * We just idled delta nanoseconds (called with irqs disabled):
- */
-void sched_clock_idle_wakeup_event(u64 delta_ns)
-{
-       struct rq *rq = cpu_rq(smp_processor_id());
-       u64 now = sched_clock();
-
-       rq->idle_clock += delta_ns;
-       /*
-        * Override the previous timestamp and ignore all
-        * sched_clock() deltas that occured while we idled,
-        * and use the PM-provided delta_ns to advance the
-        * rq clock:
-        */
-       spin_lock(&rq->lock);
-       rq->prev_clock_raw = now;
-       rq->clock += delta_ns;
-       spin_unlock(&rq->lock);
-       touch_softlockup_watchdog();
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
-
 static void __resched_task(struct task_struct *p, int tif_bit);
 
 static inline void resched_task(struct task_struct *p)
@@ -1189,6 +1065,7 @@ static inline void resched_rq(struct rq *rq)
 enum {
        HRTICK_SET,             /* re-programm hrtick_timer */
        HRTICK_RESET,           /* not a new slice */
+       HRTICK_BLOCK,           /* stop hrtick operations */
 };
 
 /*
@@ -1200,6 +1077,8 @@ static inline int hrtick_enabled(struct rq *rq)
 {
        if (!sched_feat(HRTICK))
                return 0;
+       if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags)))
+               return 0;
        return hrtimer_is_hres_active(&rq->hrtick_timer);
 }
 
@@ -1275,14 +1154,70 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
        WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
 
        spin_lock(&rq->lock);
-       __update_rq_clock(rq);
+       update_rq_clock(rq);
        rq->curr->sched_class->task_tick(rq, rq->curr, 1);
        spin_unlock(&rq->lock);
 
        return HRTIMER_NORESTART;
 }
 
-static inline void init_rq_hrtick(struct rq *rq)
+static void hotplug_hrtick_disable(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rq->lock, flags);
+       rq->hrtick_flags = 0;
+       __set_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+       spin_unlock_irqrestore(&rq->lock, flags);
+
+       hrtick_clear(rq);
+}
+
+static void hotplug_hrtick_enable(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rq->lock, flags);
+       __clear_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+       spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static int
+hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+       int cpu = (int)(long)hcpu;
+
+       switch (action) {
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
+       case CPU_DOWN_PREPARE:
+       case CPU_DOWN_PREPARE_FROZEN:
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               hotplug_hrtick_disable(cpu);
+               return NOTIFY_OK;
+
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+       case CPU_DOWN_FAILED:
+       case CPU_DOWN_FAILED_FROZEN:
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               hotplug_hrtick_enable(cpu);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static void init_hrtick(void)
+{
+       hotcpu_notifier(hotplug_hrtick, 0);
+}
+
+static void init_rq_hrtick(struct rq *rq)
 {
        rq->hrtick_flags = 0;
        hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -1319,6 +1254,10 @@ static inline void init_rq_hrtick(struct rq *rq)
 void hrtick_resched(void)
 {
 }
+
+static inline void init_hrtick(void)
+{
+}
 #endif
 
 /*
@@ -1438,8 +1377,8 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight,
 {
        u64 tmp;
 
-       if (unlikely(!lw->inv_weight))
-               lw->inv_weight = (WMULT_CONST-lw->weight/2) / (lw->weight+1);
+       if (!lw->inv_weight)
+               lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1);
 
        tmp = (u64)delta_exec * weight;
        /*
@@ -1748,6 +1687,8 @@ __update_group_shares_cpu(struct task_group *tg, struct sched_domain *sd,
 
        if (shares < MIN_SHARES)
                shares = MIN_SHARES;
+       else if (shares > MAX_SHARES)
+               shares = MAX_SHARES;
 
        __set_se_shares(tg->se[tcpu], shares);
 }
@@ -4339,8 +4280,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
        struct rq *rq = this_rq();
        cputime64_t tmp;
 
-       if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0))
-               return account_guest_time(p, cputime);
+       if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
+               account_guest_time(p, cputime);
+               return;
+       }
 
        p->stime = cputime_add(p->stime, cputime);
 
@@ -4404,19 +4347,11 @@ void scheduler_tick(void)
        int cpu = smp_processor_id();
        struct rq *rq = cpu_rq(cpu);
        struct task_struct *curr = rq->curr;
-       u64 next_tick = rq->tick_timestamp + TICK_NSEC;
+
+       sched_clock_tick();
 
        spin_lock(&rq->lock);
-       __update_rq_clock(rq);
-       /*
-        * Let rq->clock advance by at least TICK_NSEC:
-        */
-       if (unlikely(rq->clock < next_tick)) {
-               rq->clock = next_tick;
-               rq->clock_underflows++;
-       }
-       rq->tick_timestamp = rq->clock;
-       update_last_tick_seen(rq);
+       update_rq_clock(rq);
        update_cpu_load(rq);
        curr->sched_class->task_tick(rq, curr, 0);
        spin_unlock(&rq->lock);
@@ -4570,7 +4505,7 @@ need_resched_nonpreemptible:
         * Do the rq-clock update outside the rq lock:
         */
        local_irq_disable();
-       __update_rq_clock(rq);
+       update_rq_clock(rq);
        spin_lock(&rq->lock);
        clear_tsk_need_resched(prev);
 
@@ -4595,9 +4530,9 @@ need_resched_nonpreemptible:
        prev->sched_class->put_prev_task(rq, prev);
        next = pick_next_task(rq, prev);
 
-       sched_info_switch(prev, next);
-
        if (likely(prev != next)) {
+               sched_info_switch(prev, next);
+
                rq->nr_switches++;
                rq->curr = next;
                ++*switch_count;
@@ -4632,8 +4567,6 @@ EXPORT_SYMBOL(schedule);
 asmlinkage void __sched preempt_schedule(void)
 {
        struct thread_info *ti = current_thread_info();
-       struct task_struct *task = current;
-       int saved_lock_depth;
 
        /*
         * If there is a non-zero preempt_count or interrupts are disabled,
@@ -4644,16 +4577,7 @@ asmlinkage void __sched preempt_schedule(void)
 
        do {
                add_preempt_count(PREEMPT_ACTIVE);
-
-               /*
-                * We keep the big kernel semaphore locked, but we
-                * clear ->lock_depth so that schedule() doesnt
-                * auto-release the semaphore:
-                */
-               saved_lock_depth = task->lock_depth;
-               task->lock_depth = -1;
                schedule();
-               task->lock_depth = saved_lock_depth;
                sub_preempt_count(PREEMPT_ACTIVE);
 
                /*
@@ -4674,26 +4598,15 @@ EXPORT_SYMBOL(preempt_schedule);
 asmlinkage void __sched preempt_schedule_irq(void)
 {
        struct thread_info *ti = current_thread_info();
-       struct task_struct *task = current;
-       int saved_lock_depth;
 
        /* Catch callers which need to be fixed */
        BUG_ON(ti->preempt_count || !irqs_disabled());
 
        do {
                add_preempt_count(PREEMPT_ACTIVE);
-
-               /*
-                * We keep the big kernel semaphore locked, but we
-                * clear ->lock_depth so that schedule() doesnt
-                * auto-release the semaphore:
-                */
-               saved_lock_depth = task->lock_depth;
-               task->lock_depth = -1;
                local_irq_enable();
                schedule();
                local_irq_disable();
-               task->lock_depth = saved_lock_depth;
                sub_preempt_count(PREEMPT_ACTIVE);
 
                /*
@@ -5612,7 +5525,6 @@ static void __cond_resched(void)
        } while (need_resched());
 }
 
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
 int __sched _cond_resched(void)
 {
        if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
@@ -5623,7 +5535,6 @@ int __sched _cond_resched(void)
        return 0;
 }
 EXPORT_SYMBOL(_cond_resched);
-#endif
 
 /*
  * cond_resched_lock() - if a reschedule is pending, drop the given lock,
@@ -5918,8 +5829,11 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
        spin_unlock_irqrestore(&rq->lock, flags);
 
        /* Set the preempt count _outside_ the spinlocks! */
+#if defined(CONFIG_PREEMPT)
+       task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
+#else
        task_thread_info(idle)->preempt_count = 0;
-
+#endif
        /*
         * The idle tasks have their own, simple scheduling class:
         */
@@ -7755,7 +7669,7 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
 {
        int i, j;
 
-       lock_doms_cur();
+       mutex_lock(&sched_domains_mutex);
 
        /* always unregister in case we don't destroy any domains */
        unregister_sched_domain_sysctl();
@@ -7804,7 +7718,7 @@ match2:
 
        register_sched_domain_sysctl();
 
-       unlock_doms_cur();
+       mutex_unlock(&sched_domains_mutex);
 }
 
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -7813,8 +7727,10 @@ int arch_reinit_sched_domains(void)
        int err;
 
        get_online_cpus();
+       mutex_lock(&sched_domains_mutex);
        detach_destroy_domains(&cpu_online_map);
        err = arch_init_sched_domains(&cpu_online_map);
+       mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
 
        return err;
@@ -7932,13 +7848,16 @@ void __init sched_init_smp(void)
        BUG_ON(sched_group_nodes_bycpu == NULL);
 #endif
        get_online_cpus();
+       mutex_lock(&sched_domains_mutex);
        arch_init_sched_domains(&cpu_online_map);
        cpus_andnot(non_isolated_cpus, cpu_possible_map, cpu_isolated_map);
        if (cpus_empty(non_isolated_cpus))
                cpu_set(smp_processor_id(), non_isolated_cpus);
+       mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
        /* XXX: Theoretical race here - CPU may be hotplugged now */
        hotcpu_notifier(update_sched_domains, 0);
+       init_hrtick();
 
        /* Move init over to a non-isolated CPU */
        if (set_cpus_allowed_ptr(current, &non_isolated_cpus) < 0)
@@ -8025,7 +7944,7 @@ static void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
 
        se->my_q = cfs_rq;
        se->load.weight = tg->shares;
-       se->load.inv_weight = div64_64(1ULL<<32, se->load.weight);
+       se->load.inv_weight = 0;
        se->parent = parent;
 }
 #endif
@@ -8149,8 +8068,6 @@ void __init sched_init(void)
                spin_lock_init(&rq->lock);
                lockdep_set_class(&rq->lock, &rq->rq_lock_key);
                rq->nr_running = 0;
-               rq->clock = 1;
-               update_last_tick_seen(rq);
                init_cfs_rq(&rq->cfs, rq);
                init_rt_rq(&rq->rt, rq);
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -8294,6 +8211,7 @@ EXPORT_SYMBOL(__might_sleep);
 static void normalize_task(struct rq *rq, struct task_struct *p)
 {
        int on_rq;
+
        update_rq_clock(rq);
        on_rq = p->se.on_rq;
        if (on_rq)
@@ -8325,7 +8243,6 @@ void normalize_rt_tasks(void)
                p->se.sleep_start               = 0;
                p->se.block_start               = 0;
 #endif
-               task_rq(p)->clock               = 0;
 
                if (!rt_task(p)) {
                        /*
@@ -8692,7 +8609,7 @@ static void __set_se_shares(struct sched_entity *se, unsigned long shares)
                dequeue_entity(cfs_rq, se, 0);
 
        se->load.weight = shares;
-       se->load.inv_weight = div64_64((1ULL<<32), shares);
+       se->load.inv_weight = 0;
 
        if (on_rq)
                enqueue_entity(cfs_rq, se, 0);
@@ -8722,13 +8639,10 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
        if (!tg->se[0])
                return -EINVAL;
 
-       /*
-        * A weight of 0 or 1 can cause arithmetics problems.
-        * (The default weight is 1024 - so there's no practical
-        *  limitation from this.)
-        */
        if (shares < MIN_SHARES)
                shares = MIN_SHARES;
+       else if (shares > MAX_SHARES)
+               shares = MAX_SHARES;
 
        mutex_lock(&shares_mutex);
        if (tg->shares == shares)
@@ -8753,7 +8667,7 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
                 * force a rebalance
                 */
                cfs_rq_set_shares(tg->cfs_rq[i], 0);
-               set_se_shares(tg->se[i], shares/nr_cpu_ids);
+               set_se_shares(tg->se[i], shares);
        }
 
        /*
@@ -8787,7 +8701,7 @@ static unsigned long to_ratio(u64 period, u64 runtime)
        if (runtime == RUNTIME_INF)
                return 1ULL << 16;
 
-       return div64_64(runtime << 16, period);
+       return div64_u64(runtime << 16, period);
 }
 
 #ifdef CONFIG_CGROUP_SCHED
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
new file mode 100644 (file)
index 0000000..9c597e3
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * sched_clock for unstable cpu clocks
+ *
+ *  Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ * Based on code by:
+ *   Ingo Molnar <mingo@redhat.com>
+ *   Guillaume Chazarain <guichaz@gmail.com>
+ *
+ * Create a semi stable clock from a mixture of other events, including:
+ *  - gtod
+ *  - jiffies
+ *  - sched_clock()
+ *  - explicit idle events
+ *
+ * We use gtod as base and the unstable clock deltas. The deltas are filtered,
+ * making it monotonic and keeping it within an expected window.  This window
+ * is set up using jiffies.
+ *
+ * Furthermore, explicit sleep and wakeup hooks allow us to account for time
+ * that is otherwise invisible (TSC gets stopped).
+ *
+ * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat
+ * consistent between cpus (never more than 1 jiffies difference).
+ */
+#include <linux/sched.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+
+
+#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+
+struct sched_clock_data {
+       /*
+        * Raw spinlock - this is a special case: this might be called
+        * from within instrumentation code so we dont want to do any
+        * instrumentation ourselves.
+        */
+       raw_spinlock_t          lock;
+
+       unsigned long           prev_jiffies;
+       u64                     prev_raw;
+       u64                     tick_raw;
+       u64                     tick_gtod;
+       u64                     clock;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct sched_clock_data, sched_clock_data);
+
+static inline struct sched_clock_data *this_scd(void)
+{
+       return &__get_cpu_var(sched_clock_data);
+}
+
+static inline struct sched_clock_data *cpu_sdc(int cpu)
+{
+       return &per_cpu(sched_clock_data, cpu);
+}
+
+void sched_clock_init(void)
+{
+       u64 ktime_now = ktime_to_ns(ktime_get());
+       u64 now = 0;
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               struct sched_clock_data *scd = cpu_sdc(cpu);
+
+               scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+               scd->prev_jiffies = jiffies;
+               scd->prev_raw = now;
+               scd->tick_raw = now;
+               scd->tick_gtod = ktime_now;
+               scd->clock = ktime_now;
+       }
+}
+
+/*
+ * update the percpu scd from the raw @now value
+ *
+ *  - filter out backward motion
+ *  - use jiffies to generate a min,max window to clip the raw values
+ */
+static void __update_sched_clock(struct sched_clock_data *scd, u64 now)
+{
+       unsigned long now_jiffies = jiffies;
+       long delta_jiffies = now_jiffies - scd->prev_jiffies;
+       u64 clock = scd->clock;
+       u64 min_clock, max_clock;
+       s64 delta = now - scd->prev_raw;
+
+       WARN_ON_ONCE(!irqs_disabled());
+       min_clock = scd->tick_gtod + delta_jiffies * TICK_NSEC;
+
+       if (unlikely(delta < 0)) {
+               clock++;
+               goto out;
+       }
+
+       max_clock = min_clock + TICK_NSEC;
+
+       if (unlikely(clock + delta > max_clock)) {
+               if (clock < max_clock)
+                       clock = max_clock;
+               else
+                       clock++;
+       } else {
+               clock += delta;
+       }
+
+ out:
+       if (unlikely(clock < min_clock))
+               clock = min_clock;
+
+       scd->prev_raw = now;
+       scd->prev_jiffies = now_jiffies;
+       scd->clock = clock;
+}
+
+static void lock_double_clock(struct sched_clock_data *data1,
+                               struct sched_clock_data *data2)
+{
+       if (data1 < data2) {
+               __raw_spin_lock(&data1->lock);
+               __raw_spin_lock(&data2->lock);
+       } else {
+               __raw_spin_lock(&data2->lock);
+               __raw_spin_lock(&data1->lock);
+       }
+}
+
+u64 sched_clock_cpu(int cpu)
+{
+       struct sched_clock_data *scd = cpu_sdc(cpu);
+       u64 now, clock;
+
+       WARN_ON_ONCE(!irqs_disabled());
+       now = sched_clock();
+
+       if (cpu != raw_smp_processor_id()) {
+               /*
+                * in order to update a remote cpu's clock based on our
+                * unstable raw time rebase it against:
+                *   tick_raw           (offset between raw counters)
+                *   tick_gotd          (tick offset between cpus)
+                */
+               struct sched_clock_data *my_scd = this_scd();
+
+               lock_double_clock(scd, my_scd);
+
+               now -= my_scd->tick_raw;
+               now += scd->tick_raw;
+
+               now -= my_scd->tick_gtod;
+               now += scd->tick_gtod;
+
+               __raw_spin_unlock(&my_scd->lock);
+       } else {
+               __raw_spin_lock(&scd->lock);
+       }
+
+       __update_sched_clock(scd, now);
+       clock = scd->clock;
+
+       __raw_spin_unlock(&scd->lock);
+
+       return clock;
+}
+
+void sched_clock_tick(void)
+{
+       struct sched_clock_data *scd = this_scd();
+       u64 now, now_gtod;
+
+       WARN_ON_ONCE(!irqs_disabled());
+
+       now = sched_clock();
+       now_gtod = ktime_to_ns(ktime_get());
+
+       __raw_spin_lock(&scd->lock);
+       __update_sched_clock(scd, now);
+       /*
+        * update tick_gtod after __update_sched_clock() because that will
+        * already observe 1 new jiffy; adding a new tick_gtod to that would
+        * increase the clock 2 jiffies.
+        */
+       scd->tick_raw = now;
+       scd->tick_gtod = now_gtod;
+       __raw_spin_unlock(&scd->lock);
+}
+
+/*
+ * We are going deep-idle (irqs are disabled):
+ */
+void sched_clock_idle_sleep_event(void)
+{
+       sched_clock_cpu(smp_processor_id());
+}
+EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
+
+/*
+ * We just idled delta nanoseconds (called with irqs disabled):
+ */
+void sched_clock_idle_wakeup_event(u64 delta_ns)
+{
+       struct sched_clock_data *scd = this_scd();
+       u64 now = sched_clock();
+
+       /*
+        * Override the previous timestamp and ignore all
+        * sched_clock() deltas that occured while we idled,
+        * and use the PM-provided delta_ns to advance the
+        * rq clock:
+        */
+       __raw_spin_lock(&scd->lock);
+       scd->prev_raw = now;
+       scd->clock += delta_ns;
+       __raw_spin_unlock(&scd->lock);
+
+       touch_softlockup_watchdog();
+}
+EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
+
+#endif
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ * This is default implementation.
+ * Architectures and sub-architectures can override this.
+ */
+unsigned long long __attribute__((weak)) sched_clock(void)
+{
+       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
+}
index 8a9498e7c8311e582f35709c7ffc3019fda2f601..5f06118fbc318fd5994bd0d515c7a6a4209cd3d0 100644 (file)
@@ -204,13 +204,6 @@ static void print_cpu(struct seq_file *m, int cpu)
        PN(next_balance);
        P(curr->pid);
        PN(clock);
-       PN(idle_clock);
-       PN(prev_clock_raw);
-       P(clock_warps);
-       P(clock_overflows);
-       P(clock_underflows);
-       P(clock_deep_idle_events);
-       PN(clock_max_delta);
        P(cpu_load[0]);
        P(cpu_load[1]);
        P(cpu_load[2]);
@@ -357,8 +350,8 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
 
                avg_per_cpu = p->se.sum_exec_runtime;
                if (p->se.nr_migrations) {
-                       avg_per_cpu = div64_64(avg_per_cpu,
-                                              p->se.nr_migrations);
+                       avg_per_cpu = div64_u64(avg_per_cpu,
+                                               p->se.nr_migrations);
                } else {
                        avg_per_cpu = -1LL;
                }
index 89fa32b4edf27d500c3d6c644596ffc4afb881f5..e24ecd39c4b8aec9786d0ab3df0a01ad6dcba08d 100644 (file)
@@ -662,10 +662,15 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
        if (!initial) {
                /* sleeps upto a single latency don't count. */
                if (sched_feat(NEW_FAIR_SLEEPERS)) {
+                       unsigned long thresh = sysctl_sched_latency;
+
+                       /*
+                        * convert the sleeper threshold into virtual time
+                        */
                        if (sched_feat(NORMALIZED_SLEEPER))
-                               vruntime -= calc_delta_weight(sysctl_sched_latency, se);
-                       else
-                               vruntime -= sysctl_sched_latency;
+                               thresh = calc_delta_fair(thresh, se);
+
+                       vruntime -= thresh;
                }
 
                /* ensure we never gain time by being placed backwards. */
@@ -682,6 +687,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
         * Update run-time statistics of the 'current'.
         */
        update_curr(cfs_rq);
+       account_entity_enqueue(cfs_rq, se);
 
        if (wakeup) {
                place_entity(cfs_rq, se, 0);
@@ -692,7 +698,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
        check_spread(cfs_rq, se);
        if (se != cfs_rq->curr)
                __enqueue_entity(cfs_rq, se);
-       account_entity_enqueue(cfs_rq, se);
 }
 
 static void update_avg(u64 *avg, u64 sample)
@@ -841,8 +846,10 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
         * queued ticks are scheduled to match the slice, so don't bother
         * validating it and just reschedule.
         */
-       if (queued)
-               return resched_task(rq_of(cfs_rq)->curr);
+       if (queued) {
+               resched_task(rq_of(cfs_rq)->curr);
+               return;
+       }
        /*
         * don't let the period tick interfere with the hrtick preemption
         */
@@ -957,7 +964,7 @@ static void yield_task_fair(struct rq *rq)
                return;
 
        if (likely(!sysctl_sched_compat_yield) && curr->policy != SCHED_BATCH) {
-               __update_rq_clock(rq);
+               update_rq_clock(rq);
                /*
                 * Update run-time statistics of the 'current'.
                 */
@@ -1007,7 +1014,7 @@ static int wake_idle(int cpu, struct task_struct *p)
         * sibling runqueue info. This will avoid the checks and cache miss
         * penalities associated with that.
         */
-       if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
+       if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1)
                return cpu;
 
        for_each_domain(cpu, sd) {
@@ -1611,30 +1618,6 @@ static const struct sched_class fair_sched_class = {
 };
 
 #ifdef CONFIG_SCHED_DEBUG
-static void
-print_cfs_rq_tasks(struct seq_file *m, struct cfs_rq *cfs_rq, int depth)
-{
-       struct sched_entity *se;
-
-       if (!cfs_rq)
-               return;
-
-       list_for_each_entry_rcu(se, &cfs_rq->tasks, group_node) {
-               int i;
-
-               for (i = depth; i; i--)
-                       seq_puts(m, "  ");
-
-               seq_printf(m, "%lu %s %lu\n",
-                               se->load.weight,
-                               entity_is_task(se) ? "T" : "G",
-                               calc_delta_weight(SCHED_LOAD_SCALE, se)
-                               );
-               if (!entity_is_task(se))
-                       print_cfs_rq_tasks(m, group_cfs_rq(se), depth + 1);
-       }
-}
-
 static void print_cfs_stats(struct seq_file *m, int cpu)
 {
        struct cfs_rq *cfs_rq;
@@ -1642,9 +1625,6 @@ static void print_cfs_stats(struct seq_file *m, int cpu)
        rcu_read_lock();
        for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq)
                print_cfs_rq(m, cpu, cfs_rq);
-
-       seq_printf(m, "\nWeight tree:\n");
-       print_cfs_rq_tasks(m, &cpu_rq(cpu)->cfs, 1);
        rcu_read_unlock();
 }
 #endif
index 2bcafa375633896af9c0bcea45fbdf389d9b11fd..3a4f92dbbe6609b786da0add62f2306e991b791f 100644 (file)
@@ -99,7 +99,7 @@ static void prio_changed_idle(struct rq *rq, struct task_struct *p,
 /*
  * Simple, special scheduling class for the per-CPU idle tasks:
  */
-const struct sched_class idle_sched_class = {
+static const struct sched_class idle_sched_class = {
        /* .next is NULL */
        /* no enqueue/yield_task for idle tasks */
 
index c2730a5a4f056c04526cb56008b772fe26712072..060e87b0cb1c7e3ab7c12084da2061322e4a3f5a 100644 (file)
@@ -1098,11 +1098,14 @@ static void post_schedule_rt(struct rq *rq)
        }
 }
 
-
+/*
+ * If we are not running and we are not going to reschedule soon, we should
+ * try to push tasks away now
+ */
 static void task_wake_up_rt(struct rq *rq, struct task_struct *p)
 {
        if (!task_running(rq, p) &&
-           (p->prio >= rq->rt.highest_prio) &&
+           !test_tsk_need_resched(rq->curr) &&
            rq->rt.overloaded)
                push_rt_tasks(rq);
 }
@@ -1309,7 +1312,7 @@ static void set_curr_task_rt(struct rq *rq)
        p->se.exec_start = rq->clock;
 }
 
-const struct sched_class rt_sched_class = {
+static const struct sched_class rt_sched_class = {
        .next                   = &fair_sched_class,
        .enqueue_task           = enqueue_task_rt,
        .dequeue_task           = dequeue_task_rt,
index 3c44956ee7e2312d30f28bc68a5b9825a7da657a..36e0617400470f398700376c7fa3359d768e7e58 100644 (file)
@@ -589,16 +589,20 @@ static void takeover_tasklets(unsigned int cpu)
        local_irq_disable();
 
        /* Find end, append list for that CPU. */
-       *__get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).head;
-       __get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).tail;
-       per_cpu(tasklet_vec, cpu).head = NULL;
-       per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head;
+       if (&per_cpu(tasklet_vec, cpu).head != per_cpu(tasklet_vec, cpu).tail) {
+               *(__get_cpu_var(tasklet_vec).tail) = per_cpu(tasklet_vec, cpu).head;
+               __get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).tail;
+               per_cpu(tasklet_vec, cpu).head = NULL;
+               per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head;
+       }
        raise_softirq_irqoff(TASKLET_SOFTIRQ);
 
-       *__get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).head;
-       __get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).tail;
-       per_cpu(tasklet_hi_vec, cpu).head = NULL;
-       per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head;
+       if (&per_cpu(tasklet_hi_vec, cpu).head != per_cpu(tasklet_hi_vec, cpu).tail) {
+               *__get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).head;
+               __get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).tail;
+               per_cpu(tasklet_hi_vec, cpu).head = NULL;
+               per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head;
+       }
        raise_softirq_irqoff(HI_SOFTIRQ);
 
        local_irq_enable();
index 86729042e4cd067b1168fe8ed5cc2da01576cf03..6a08660b4fac30f97ea573b9cd017941401046ff 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/security.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/math64.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -245,7 +246,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j)
        return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
 #else
 # if BITS_PER_LONG == 32
-       return ((u64)HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
+       return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
 # else
        return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
 # endif
@@ -261,7 +262,7 @@ unsigned int inline jiffies_to_usecs(const unsigned long j)
        return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
 #else
 # if BITS_PER_LONG == 32
-       return ((u64)HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
+       return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
 # else
        return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
 # endif
@@ -391,13 +392,17 @@ EXPORT_SYMBOL(set_normalized_timespec);
 struct timespec ns_to_timespec(const s64 nsec)
 {
        struct timespec ts;
+       s32 rem;
 
        if (!nsec)
                return (struct timespec) {0, 0};
 
-       ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec);
-       if (unlikely(nsec < 0))
-               set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec);
+       ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
+       if (unlikely(rem < 0)) {
+               ts.tv_sec--;
+               rem += NSEC_PER_SEC;
+       }
+       ts.tv_nsec = rem;
 
        return ts;
 }
@@ -471,7 +476,7 @@ unsigned long msecs_to_jiffies(const unsigned int m)
        if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
                return MAX_JIFFY_OFFSET;
 
-       return ((u64)MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+       return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
                >> MSEC_TO_HZ_SHR32;
 #endif
 }
@@ -486,7 +491,7 @@ unsigned long usecs_to_jiffies(const unsigned int u)
 #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
        return u * (HZ / USEC_PER_SEC);
 #else
-       return ((u64)USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
+       return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
                >> USEC_TO_HZ_SHR32;
 #endif
 }
@@ -527,8 +532,10 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
         * Convert jiffies to nanoseconds and separate with
         * one divide.
         */
-       u64 nsec = (u64)jiffies * TICK_NSEC;
-       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec);
+       u32 rem;
+       value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
+                                   NSEC_PER_SEC, &rem);
+       value->tv_nsec = rem;
 }
 EXPORT_SYMBOL(jiffies_to_timespec);
 
@@ -566,12 +573,11 @@ void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
         * Convert jiffies to nanoseconds and separate with
         * one divide.
         */
-       u64 nsec = (u64)jiffies * TICK_NSEC;
-       long tv_usec;
+       u32 rem;
 
-       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec);
-       tv_usec /= NSEC_PER_USEC;
-       value->tv_usec = tv_usec;
+       value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
+                                   NSEC_PER_SEC, &rem);
+       value->tv_usec = rem / NSEC_PER_USEC;
 }
 EXPORT_SYMBOL(jiffies_to_timeval);
 
@@ -587,9 +593,7 @@ clock_t jiffies_to_clock_t(long x)
        return x / (HZ / USER_HZ);
 # endif
 #else
-       u64 tmp = (u64)x * TICK_NSEC;
-       do_div(tmp, (NSEC_PER_SEC / USER_HZ));
-       return (long)tmp;
+       return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ);
 #endif
 }
 EXPORT_SYMBOL(jiffies_to_clock_t);
@@ -601,16 +605,12 @@ unsigned long clock_t_to_jiffies(unsigned long x)
                return ~0UL;
        return x * (HZ / USER_HZ);
 #else
-       u64 jif;
-
        /* Don't worry about loss of precision here .. */
        if (x >= ~0UL / HZ * USER_HZ)
                return ~0UL;
 
        /* .. but do try to contain it here */
-       jif = x * (u64) HZ;
-       do_div(jif, USER_HZ);
-       return jif;
+       return div_u64((u64)x * HZ, USER_HZ);
 #endif
 }
 EXPORT_SYMBOL(clock_t_to_jiffies);
@@ -619,10 +619,9 @@ u64 jiffies_64_to_clock_t(u64 x)
 {
 #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
 # if HZ < USER_HZ
-       x *= USER_HZ;
-       do_div(x, HZ);
+       x = div_u64(x * USER_HZ, HZ);
 # elif HZ > USER_HZ
-       do_div(x, HZ / USER_HZ);
+       x = div_u64(x, HZ / USER_HZ);
 # else
        /* Nothing to do */
 # endif
@@ -632,8 +631,7 @@ u64 jiffies_64_to_clock_t(u64 x)
         * but even this doesn't overflow in hundreds of years
         * in 64 bits, so..
         */
-       x *= TICK_NSEC;
-       do_div(x, (NSEC_PER_SEC / USER_HZ));
+       x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ));
 #endif
        return x;
 }
@@ -642,21 +640,17 @@ EXPORT_SYMBOL(jiffies_64_to_clock_t);
 u64 nsec_to_clock_t(u64 x)
 {
 #if (NSEC_PER_SEC % USER_HZ) == 0
-       do_div(x, (NSEC_PER_SEC / USER_HZ));
+       return div_u64(x, NSEC_PER_SEC / USER_HZ);
 #elif (USER_HZ % 512) == 0
-       x *= USER_HZ/512;
-       do_div(x, (NSEC_PER_SEC / 512));
+       return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512);
 #else
        /*
          * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024,
          * overflow after 64.99 years.
          * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
          */
-       x *= 9;
-       do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2)) /
-                                 USER_HZ));
+       return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ);
 #endif
-       return x;
 }
 
 #if (BITS_PER_LONG < 64)
index 73961f35fdc84ba1ba28251bb4115f52b094d908..dadde5361f32df668877aaa8d5a2e56abb5bb9ff 100644 (file)
@@ -471,10 +471,10 @@ sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
 /*
  * Sysfs setup bits:
  */
-static SYSDEV_ATTR(current_clocksource, 0600, sysfs_show_current_clocksources,
+static SYSDEV_ATTR(current_clocksource, 0644, sysfs_show_current_clocksources,
                   sysfs_override_clocksource);
 
-static SYSDEV_ATTR(available_clocksource, 0600,
+static SYSDEV_ATTR(available_clocksource, 0444,
                   sysfs_show_available_clocksources, NULL);
 
 static struct sysdev_class clocksource_sysclass = {
index 5fd9b946977038cbdc192dc5a11146696ad53947..5125ddd8196ba3cffb2fd683c2fd3abdac0a695b 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/jiffies.h>
 #include <linux/hrtimer.h>
 #include <linux/capability.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
+#include <linux/clocksource.h>
 #include <asm/timex.h>
 
 /*
  */
 unsigned long tick_usec = TICK_USEC;           /* USER_HZ period (usec) */
 unsigned long tick_nsec;                       /* ACTHZ period (nsec) */
-static u64 tick_length, tick_length_base;
+u64 tick_length;
+static u64 tick_length_base;
+
+static struct hrtimer leap_timer;
 
 #define MAX_TICKADJ            500             /* microsecs */
 #define MAX_TICKADJ_SCALED     (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \
-                                 TICK_LENGTH_SHIFT) / NTP_INTERVAL_FREQ)
+                                 NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
 
 /*
  * phase-lock loop variables
@@ -35,11 +39,12 @@ static u64 tick_length, tick_length_base;
 /* TIME_ERROR prevents overwriting the CMOS clock */
 static int time_state = TIME_OK;       /* clock synchronization status */
 int time_status = STA_UNSYNC;          /* clock status bits            */
-static s64 time_offset;                /* time adjustment (ns)         */
+static long time_tai;                  /* TAI offset (s)               */
+static s64 time_offset;                        /* time adjustment (ns)         */
 static long time_constant = 2;         /* pll time constant            */
 long time_maxerror = NTP_PHASE_LIMIT;  /* maximum error (us)           */
 long time_esterror = NTP_PHASE_LIMIT;  /* estimated error (us)         */
-long time_freq;                                /* frequency offset (scaled ppm)*/
+static s64 time_freq;                  /* frequency offset (scaled ns/s)*/
 static long time_reftime;              /* time at last adjustment (s)  */
 long time_adjust;
 static long ntp_tick_adj;
@@ -47,16 +52,56 @@ static long ntp_tick_adj;
 static void ntp_update_frequency(void)
 {
        u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ)
-                               << TICK_LENGTH_SHIFT;
-       second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT;
-       second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
+                               << NTP_SCALE_SHIFT;
+       second_length += (s64)ntp_tick_adj << NTP_SCALE_SHIFT;
+       second_length += time_freq;
 
        tick_length_base = second_length;
 
-       do_div(second_length, HZ);
-       tick_nsec = second_length >> TICK_LENGTH_SHIFT;
+       tick_nsec = div_u64(second_length, HZ) >> NTP_SCALE_SHIFT;
+       tick_length_base = div_u64(tick_length_base, NTP_INTERVAL_FREQ);
+}
+
+static void ntp_update_offset(long offset)
+{
+       long mtemp;
+       s64 freq_adj;
+
+       if (!(time_status & STA_PLL))
+               return;
 
-       do_div(tick_length_base, NTP_INTERVAL_FREQ);
+       if (!(time_status & STA_NANO))
+               offset *= NSEC_PER_USEC;
+
+       /*
+        * Scale the phase adjustment and
+        * clamp to the operating range.
+        */
+       offset = min(offset, MAXPHASE);
+       offset = max(offset, -MAXPHASE);
+
+       /*
+        * Select how the frequency is to be controlled
+        * and in which mode (PLL or FLL).
+        */
+       if (time_status & STA_FREQHOLD || time_reftime == 0)
+               time_reftime = xtime.tv_sec;
+       mtemp = xtime.tv_sec - time_reftime;
+       time_reftime = xtime.tv_sec;
+
+       freq_adj = (s64)offset * mtemp;
+       freq_adj <<= NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant);
+       time_status &= ~STA_MODE;
+       if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
+               freq_adj += div_s64((s64)offset << (NTP_SCALE_SHIFT - SHIFT_FLL),
+                                   mtemp);
+               time_status |= STA_MODE;
+       }
+       freq_adj += time_freq;
+       freq_adj = min(freq_adj, MAXFREQ_SCALED);
+       time_freq = max(freq_adj, -MAXFREQ_SCALED);
+
+       time_offset = div_s64((s64)offset << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ);
 }
 
 /**
@@ -78,62 +123,70 @@ void ntp_clear(void)
 }
 
 /*
- * this routine handles the overflow of the microsecond field
- *
- * The tricky bits of code to handle the accurate clock support
- * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
- * They were originally developed for SUN and DEC kernels.
- * All the kudos should go to Dave for this stuff.
+ * Leap second processing. If in leap-insert state at the end of the
+ * day, the system clock is set back one second; if in leap-delete
+ * state, the system clock is set ahead one second.
  */
-void second_overflow(void)
+static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
 {
-       long time_adj;
+       enum hrtimer_restart res = HRTIMER_NORESTART;
 
-       /* Bump the maxerror field */
-       time_maxerror += MAXFREQ >> SHIFT_USEC;
-       if (time_maxerror > NTP_PHASE_LIMIT) {
-               time_maxerror = NTP_PHASE_LIMIT;
-               time_status |= STA_UNSYNC;
-       }
+       write_seqlock_irq(&xtime_lock);
 
-       /*
-        * Leap second processing. If in leap-insert state at the end of the
-        * day, the system clock is set back one second; if in leap-delete
-        * state, the system clock is set ahead one second. The microtime()
-        * routine or external clock driver will insure that reported time is
-        * always monotonic. The ugly divides should be replaced.
-        */
        switch (time_state) {
        case TIME_OK:
-               if (time_status & STA_INS)
-                       time_state = TIME_INS;
-               else if (time_status & STA_DEL)
-                       time_state = TIME_DEL;
                break;
        case TIME_INS:
-               if (xtime.tv_sec % 86400 == 0) {
-                       xtime.tv_sec--;
-                       wall_to_monotonic.tv_sec++;
-                       time_state = TIME_OOP;
-                       printk(KERN_NOTICE "Clock: inserting leap second "
-                                       "23:59:60 UTC\n");
-               }
+               xtime.tv_sec--;
+               wall_to_monotonic.tv_sec++;
+               time_state = TIME_OOP;
+               printk(KERN_NOTICE "Clock: "
+                      "inserting leap second 23:59:60 UTC\n");
+               leap_timer.expires = ktime_add_ns(leap_timer.expires,
+                                                 NSEC_PER_SEC);
+               res = HRTIMER_RESTART;
                break;
        case TIME_DEL:
-               if ((xtime.tv_sec + 1) % 86400 == 0) {
-                       xtime.tv_sec++;
-                       wall_to_monotonic.tv_sec--;
-                       time_state = TIME_WAIT;
-                       printk(KERN_NOTICE "Clock: deleting leap second "
-                                       "23:59:59 UTC\n");
-               }
+               xtime.tv_sec++;
+               time_tai--;
+               wall_to_monotonic.tv_sec--;
+               time_state = TIME_WAIT;
+               printk(KERN_NOTICE "Clock: "
+                      "deleting leap second 23:59:59 UTC\n");
                break;
        case TIME_OOP:
+               time_tai++;
                time_state = TIME_WAIT;
-               break;
+               /* fall through */
        case TIME_WAIT:
                if (!(time_status & (STA_INS | STA_DEL)))
-               time_state = TIME_OK;
+                       time_state = TIME_OK;
+               break;
+       }
+       update_vsyscall(&xtime, clock);
+
+       write_sequnlock_irq(&xtime_lock);
+
+       return res;
+}
+
+/*
+ * this routine handles the overflow of the microsecond field
+ *
+ * The tricky bits of code to handle the accurate clock support
+ * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
+ * They were originally developed for SUN and DEC kernels.
+ * All the kudos should go to Dave for this stuff.
+ */
+void second_overflow(void)
+{
+       s64 time_adj;
+
+       /* Bump the maxerror field */
+       time_maxerror += MAXFREQ / NSEC_PER_USEC;
+       if (time_maxerror > NTP_PHASE_LIMIT) {
+               time_maxerror = NTP_PHASE_LIMIT;
+               time_status |= STA_UNSYNC;
        }
 
        /*
@@ -143,7 +196,7 @@ void second_overflow(void)
        tick_length = tick_length_base;
        time_adj = shift_right(time_offset, SHIFT_PLL + time_constant);
        time_offset -= time_adj;
-       tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE);
+       tick_length += time_adj;
 
        if (unlikely(time_adjust)) {
                if (time_adjust > MAX_TICKADJ) {
@@ -154,25 +207,12 @@ void second_overflow(void)
                        tick_length -= MAX_TICKADJ_SCALED;
                } else {
                        tick_length += (s64)(time_adjust * NSEC_PER_USEC /
-                                       NTP_INTERVAL_FREQ) << TICK_LENGTH_SHIFT;
+                                       NTP_INTERVAL_FREQ) << NTP_SCALE_SHIFT;
                        time_adjust = 0;
                }
        }
 }
 
-/*
- * Return how long ticks are at the moment, that is, how much time
- * update_wall_time_one_tick will add to xtime next time we call it
- * (assuming no calls to do_adjtimex in the meantime).
- * The return value is in fixed-point nanoseconds shifted by the
- * specified number of bits to the right of the binary point.
- * This function has no side-effects.
- */
-u64 current_tick_length(void)
-{
-       return tick_length;
-}
-
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
 
 /* Disable the cmos update - used by virtualization and embedded */
@@ -236,8 +276,8 @@ static inline void notify_cmos_timer(void) { }
  */
 int do_adjtimex(struct timex *txc)
 {
-       long mtemp, save_adjust, rem;
-       s64 freq_adj, temp64;
+       struct timespec ts;
+       long save_adjust, sec;
        int result;
 
        /* In order to modify anything, you gotta be super-user! */
@@ -247,147 +287,132 @@ int do_adjtimex(struct timex *txc)
        /* Now we validate the data before disabling interrupts */
 
        if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) {
-         /* singleshot must not be used with any other mode bits */
-               if (txc->modes != ADJ_OFFSET_SINGLESHOT &&
-                                       txc->modes != ADJ_OFFSET_SS_READ)
+               /* singleshot must not be used with any other mode bits */
+               if (txc->modes & ~ADJ_OFFSET_SS_READ)
                        return -EINVAL;
        }
 
-       if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
-         /* adjustment Offset limited to +- .512 seconds */
-               if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
-                       return -EINVAL;
-
        /* if the quartz is off by more than 10% something is VERY wrong ! */
        if (txc->modes & ADJ_TICK)
                if (txc->tick <  900000/USER_HZ ||
                    txc->tick > 1100000/USER_HZ)
                        return -EINVAL;
 
+       if (time_state != TIME_OK && txc->modes & ADJ_STATUS)
+               hrtimer_cancel(&leap_timer);
+       getnstimeofday(&ts);
+
        write_seqlock_irq(&xtime_lock);
-       result = time_state;    /* mostly `TIME_OK' */
 
        /* Save for later - semantics of adjtime is to return old value */
        save_adjust = time_adjust;
 
-#if 0  /* STA_CLOCKERR is never set yet */
-       time_status &= ~STA_CLOCKERR;           /* reset STA_CLOCKERR */
-#endif
        /* If there are input parameters, then process them */
-       if (txc->modes)
-       {
-           if (txc->modes & ADJ_STATUS)        /* only set allowed bits */
-               time_status =  (txc->status & ~STA_RONLY) |
-                             (time_status & STA_RONLY);
-
-           if (txc->modes & ADJ_FREQUENCY) {   /* p. 22 */
-               if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
-                   result = -EINVAL;
-                   goto leave;
-               }
-               time_freq = ((s64)txc->freq * NSEC_PER_USEC)
-                               >> (SHIFT_USEC - SHIFT_NSEC);
-           }
-
-           if (txc->modes & ADJ_MAXERROR) {
-               if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
-                   result = -EINVAL;
-                   goto leave;
+       if (txc->modes) {
+               if (txc->modes & ADJ_STATUS) {
+                       if ((time_status & STA_PLL) &&
+                           !(txc->status & STA_PLL)) {
+                               time_state = TIME_OK;
+                               time_status = STA_UNSYNC;
+                       }
+                       /* only set allowed bits */
+                       time_status &= STA_RONLY;
+                       time_status |= txc->status & ~STA_RONLY;
+
+                       switch (time_state) {
+                       case TIME_OK:
+                       start_timer:
+                               sec = ts.tv_sec;
+                               if (time_status & STA_INS) {
+                                       time_state = TIME_INS;
+                                       sec += 86400 - sec % 86400;
+                                       hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS);
+                               } else if (time_status & STA_DEL) {
+                                       time_state = TIME_DEL;
+                                       sec += 86400 - (sec + 1) % 86400;
+                                       hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS);
+                               }
+                               break;
+                       case TIME_INS:
+                       case TIME_DEL:
+                               time_state = TIME_OK;
+                               goto start_timer;
+                               break;
+                       case TIME_WAIT:
+                               if (!(time_status & (STA_INS | STA_DEL)))
+                                       time_state = TIME_OK;
+                               break;
+                       case TIME_OOP:
+                               hrtimer_restart(&leap_timer);
+                               break;
+                       }
                }
-               time_maxerror = txc->maxerror;
-           }
 
-           if (txc->modes & ADJ_ESTERROR) {
-               if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
-                   result = -EINVAL;
-                   goto leave;
+               if (txc->modes & ADJ_NANO)
+                       time_status |= STA_NANO;
+               if (txc->modes & ADJ_MICRO)
+                       time_status &= ~STA_NANO;
+
+               if (txc->modes & ADJ_FREQUENCY) {
+                       time_freq = (s64)txc->freq * PPM_SCALE;
+                       time_freq = min(time_freq, MAXFREQ_SCALED);
+                       time_freq = max(time_freq, -MAXFREQ_SCALED);
                }
-               time_esterror = txc->esterror;
-           }
 
-           if (txc->modes & ADJ_TIMECONST) {   /* p. 24 */
-               if (txc->constant < 0) {        /* NTP v4 uses values > 6 */
-                   result = -EINVAL;
-                   goto leave;
+               if (txc->modes & ADJ_MAXERROR)
+                       time_maxerror = txc->maxerror;
+               if (txc->modes & ADJ_ESTERROR)
+                       time_esterror = txc->esterror;
+
+               if (txc->modes & ADJ_TIMECONST) {
+                       time_constant = txc->constant;
+                       if (!(time_status & STA_NANO))
+                               time_constant += 4;
+                       time_constant = min(time_constant, (long)MAXTC);
+                       time_constant = max(time_constant, 0l);
                }
-               time_constant = min(txc->constant + 4, (long)MAXTC);
-           }
 
-           if (txc->modes & ADJ_OFFSET) {      /* values checked earlier */
-               if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
-                   /* adjtime() is independent from ntp_adjtime() */
-                   time_adjust = txc->offset;
+               if (txc->modes & ADJ_TAI && txc->constant > 0)
+                       time_tai = txc->constant;
+
+               if (txc->modes & ADJ_OFFSET) {
+                       if (txc->modes == ADJ_OFFSET_SINGLESHOT)
+                               /* adjtime() is independent from ntp_adjtime() */
+                               time_adjust = txc->offset;
+                       else
+                               ntp_update_offset(txc->offset);
                }
-               else if (time_status & STA_PLL) {
-                   time_offset = txc->offset * NSEC_PER_USEC;
-
-                   /*
-                    * Scale the phase adjustment and
-                    * clamp to the operating range.
-                    */
-                   time_offset = min(time_offset, (s64)MAXPHASE * NSEC_PER_USEC);
-                   time_offset = max(time_offset, (s64)-MAXPHASE * NSEC_PER_USEC);
-
-                   /*
-                    * Select whether the frequency is to be controlled
-                    * and in which mode (PLL or FLL). Clamp to the operating
-                    * range. Ugly multiply/divide should be replaced someday.
-                    */
-
-                   if (time_status & STA_FREQHOLD || time_reftime == 0)
-                       time_reftime = xtime.tv_sec;
-                   mtemp = xtime.tv_sec - time_reftime;
-                   time_reftime = xtime.tv_sec;
-
-                   freq_adj = time_offset * mtemp;
-                   freq_adj = shift_right(freq_adj, time_constant * 2 +
-                                          (SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
-                   if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
-                       u64 utemp64;
-                       temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL);
-                       if (time_offset < 0) {
-                           utemp64 = -temp64;
-                           do_div(utemp64, mtemp);
-                           freq_adj -= utemp64;
-                       } else {
-                           utemp64 = temp64;
-                           do_div(utemp64, mtemp);
-                           freq_adj += utemp64;
-                       }
-                   }
-                   freq_adj += time_freq;
-                   freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
-                   time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
-                   time_offset = div_long_long_rem_signed(time_offset,
-                                                          NTP_INTERVAL_FREQ,
-                                                          &rem);
-                   time_offset <<= SHIFT_UPDATE;
-               } /* STA_PLL */
-           } /* txc->modes & ADJ_OFFSET */
-           if (txc->modes & ADJ_TICK)
-               tick_usec = txc->tick;
-
-           if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
-                   ntp_update_frequency();
-       } /* txc->modes */
-leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
+               if (txc->modes & ADJ_TICK)
+                       tick_usec = txc->tick;
+
+               if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
+                       ntp_update_frequency();
+       }
+
+       result = time_state;    /* mostly `TIME_OK' */
+       if (time_status & (STA_UNSYNC|STA_CLOCKERR))
                result = TIME_ERROR;
 
        if ((txc->modes == ADJ_OFFSET_SINGLESHOT) ||
-                       (txc->modes == ADJ_OFFSET_SS_READ))
+           (txc->modes == ADJ_OFFSET_SS_READ))
                txc->offset = save_adjust;
-       else
-               txc->offset = ((long)shift_right(time_offset, SHIFT_UPDATE)) *
-                               NTP_INTERVAL_FREQ / 1000;
-       txc->freq          = (time_freq / NSEC_PER_USEC) <<
-                               (SHIFT_USEC - SHIFT_NSEC);
+       else {
+               txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
+                                         NTP_SCALE_SHIFT);
+               if (!(time_status & STA_NANO))
+                       txc->offset /= NSEC_PER_USEC;
+       }
+       txc->freq          = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) *
+                                        (s64)PPM_SCALE_INV,
+                                        NTP_SCALE_SHIFT);
        txc->maxerror      = time_maxerror;
        txc->esterror      = time_esterror;
        txc->status        = time_status;
        txc->constant      = time_constant;
        txc->precision     = 1;
-       txc->tolerance     = MAXFREQ;
+       txc->tolerance     = MAXFREQ_SCALED / PPM_SCALE;
        txc->tick          = tick_usec;
+       txc->tai           = time_tai;
 
        /* PPS is not implemented, so these are zero */
        txc->ppsfreq       = 0;
@@ -399,9 +424,15 @@ leave:     if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
        txc->errcnt        = 0;
        txc->stbcnt        = 0;
        write_sequnlock_irq(&xtime_lock);
-       do_gettimeofday(&txc->time);
+
+       txc->time.tv_sec = ts.tv_sec;
+       txc->time.tv_usec = ts.tv_nsec;
+       if (!(time_status & STA_NANO))
+               txc->time.tv_usec /= NSEC_PER_USEC;
+
        notify_cmos_timer();
-       return(result);
+
+       return result;
 }
 
 static int __init ntp_tick_adj_setup(char *str)
@@ -411,3 +442,10 @@ static int __init ntp_tick_adj_setup(char *str)
 }
 
 __setup("ntp_tick_adj=", ntp_tick_adj_setup);
+
+void __init ntp_init(void)
+{
+       ntp_clear();
+       hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+       leap_timer.function = ntp_leap_second;
+}
index 2d6087c7cf9820fb4a16c43fdd75ed9f33d16bca..e91c29f961c900d7739c0dc2f27b81c480cdb55c 100644 (file)
@@ -53,7 +53,7 @@ void update_xtime_cache(u64 nsec)
        timespec_add_ns(&xtime_cache, nsec);
 }
 
-static struct clocksource *clock; /* pointer to current clocksource */
+struct clocksource *clock;
 
 
 #ifdef CONFIG_GENERIC_TIME
@@ -246,7 +246,7 @@ void __init timekeeping_init(void)
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
-       ntp_clear();
+       ntp_init();
 
        clock = clocksource_get_next();
        clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
@@ -371,7 +371,7 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
         * here.  This is tuned so that an error of about 1 msec is adjusted
         * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
         */
-       error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
+       error2 = clock->error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
        error2 = abs(error2);
        for (look_ahead = 0; error2 > 0; look_ahead++)
                error2 >>= 2;
@@ -380,8 +380,7 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
         * Now calculate the error in (1 << look_ahead) ticks, but first
         * remove the single look ahead already included in the error.
         */
-       tick_error = current_tick_length() >>
-               (TICK_LENGTH_SHIFT - clock->shift + 1);
+       tick_error = tick_length >> (NTP_SCALE_SHIFT - clock->shift + 1);
        tick_error -= clock->xtime_interval >> 1;
        error = ((error - tick_error) >> look_ahead) + tick_error;
 
@@ -412,7 +411,7 @@ static void clocksource_adjust(s64 offset)
        s64 error, interval = clock->cycle_interval;
        int adj;
 
-       error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
+       error = clock->error >> (NTP_SCALE_SHIFT - clock->shift - 1);
        if (error > interval) {
                error >>= 2;
                if (likely(error <= interval))
@@ -434,7 +433,7 @@ static void clocksource_adjust(s64 offset)
        clock->xtime_interval += interval;
        clock->xtime_nsec -= offset;
        clock->error -= (interval - offset) <<
-                       (TICK_LENGTH_SHIFT - clock->shift);
+                       (NTP_SCALE_SHIFT - clock->shift);
 }
 
 /**
@@ -473,8 +472,8 @@ void update_wall_time(void)
                }
 
                /* accumulate error between NTP and clock interval */
-               clock->error += current_tick_length();
-               clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
+               clock->error += tick_length;
+               clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
        }
 
        /* correct the clock when NTP error is too big */
index 41468035473ccbb943495466159173058862d6f0..eb51d76e058a401477776e279fba95c95a315a4a 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 # -----------------------------------------------------------------------
 #
-#   Copyright 2007 rPath, Inc. - All Rights Reserved
+#   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
 #
 #   This file is part of the Linux kernel, and is made available under
 #   the terms of the GNU General Public License version 2 or (at your
 %canned_values = (
        24 => [
                '0xa6aaaaab','0x2aaaaaa',26,
-               '0xa6aaaaaaaaaaaaab','0x2aaaaaaaaaaaaaa',58,
                125,3,
                '0xc49ba5e4','0x1fbe76c8b4',37,
-               '0xc49ba5e353f7ceda','0x1fbe76c8b439581062',69,
                3,125,
                '0xa2c2aaab','0xaaaa',16,
-               '0xa2c2aaaaaaaaaaab','0xaaaaaaaaaaaa',48,
                125000,3,
                '0xc9539b89','0x7fffbce4217d',47,
-               '0xc9539b8887229e91','0x7fffbce4217d2849cb25',79,
                3,125000,
        ], 32 => [
                '0xfa000000','0x6000000',27,
-               '0xfa00000000000000','0x600000000000000',59,
                125,4,
                '0x83126e98','0xfdf3b645a',36,
-               '0x83126e978d4fdf3c','0xfdf3b645a1cac0831',68,
                4,125,
                '0xf4240000','0x0',17,
-               '0xf424000000000000','0x0',49,
                31250,1,
                '0x8637bd06','0x3fff79c842fa',46,
-               '0x8637bd05af6c69b6','0x3fff79c842fa5093964a',78,
                1,31250,
        ], 48 => [
                '0xa6aaaaab','0x6aaaaaa',27,
-               '0xa6aaaaaaaaaaaaab','0x6aaaaaaaaaaaaaa',59,
                125,6,
                '0xc49ba5e4','0xfdf3b645a',36,
-               '0xc49ba5e353f7ceda','0xfdf3b645a1cac0831',68,
                6,125,
                '0xa2c2aaab','0x15555',17,
-               '0xa2c2aaaaaaaaaaab','0x1555555555555',49,
                62500,3,
                '0xc9539b89','0x3fffbce4217d',46,
-               '0xc9539b8887229e91','0x3fffbce4217d2849cb25',78,
                3,62500,
        ], 64 => [
                '0xfa000000','0xe000000',28,
-               '0xfa00000000000000','0xe00000000000000',60,
                125,8,
                '0x83126e98','0x7ef9db22d',35,
-               '0x83126e978d4fdf3c','0x7ef9db22d0e560418',67,
                8,125,
                '0xf4240000','0x0',18,
-               '0xf424000000000000','0x0',50,
                15625,1,
                '0x8637bd06','0x1fff79c842fa',45,
-               '0x8637bd05af6c69b6','0x1fff79c842fa5093964a',77,
                1,15625,
        ], 100 => [
                '0xa0000000','0x0',28,
-               '0xa000000000000000','0x0',60,
                10,1,
                '0xcccccccd','0x733333333',35,
-               '0xcccccccccccccccd','0x73333333333333333',67,
                1,10,
                '0x9c400000','0x0',18,
-               '0x9c40000000000000','0x0',50,
                10000,1,
                '0xd1b71759','0x1fff2e48e8a7',45,
-               '0xd1b71758e219652c','0x1fff2e48e8a71de69ad4',77,
                1,10000,
        ], 122 => [
                '0x8325c53f','0xfbcda3a',28,
-               '0x8325c53ef368eb05','0xfbcda3ac10c9714',60,
                500,61,
                '0xf9db22d1','0x7fbe76c8b',35,
-               '0xf9db22d0e560418a','0x7fbe76c8b43958106',67,
                61,500,
                '0x8012e2a0','0x3ef36',18,
-               '0x8012e29f79b47583','0x3ef368eb04325',50,
                500000,61,
                '0xffda4053','0x1ffffbce4217',45,
-               '0xffda4052d666a983','0x1ffffbce4217d2849cb2',77,
                61,500000,
        ], 128 => [
                '0xfa000000','0x1e000000',29,
-               '0xfa00000000000000','0x1e00000000000000',61,
                125,16,
                '0x83126e98','0x3f7ced916',34,
-               '0x83126e978d4fdf3c','0x3f7ced916872b020c',66,
                16,125,
                '0xf4240000','0x40000',19,
-               '0xf424000000000000','0x4000000000000',51,
                15625,2,
                '0x8637bd06','0xfffbce4217d',44,
-               '0x8637bd05af6c69b6','0xfffbce4217d2849cb25',76,
                2,15625,
        ], 200 => [
                '0xa0000000','0x0',29,
-               '0xa000000000000000','0x0',61,
                5,1,
                '0xcccccccd','0x333333333',34,
-               '0xcccccccccccccccd','0x33333333333333333',66,
                1,5,
                '0x9c400000','0x0',19,
-               '0x9c40000000000000','0x0',51,
                5000,1,
                '0xd1b71759','0xfff2e48e8a7',44,
-               '0xd1b71758e219652c','0xfff2e48e8a71de69ad4',76,
                1,5000,
        ], 250 => [
                '0x80000000','0x0',29,
-               '0x8000000000000000','0x0',61,
                4,1,
                '0x80000000','0x180000000',33,
-               '0x8000000000000000','0x18000000000000000',65,
                1,4,
                '0xfa000000','0x0',20,
-               '0xfa00000000000000','0x0',52,
                4000,1,
                '0x83126e98','0x7ff7ced9168',43,
-               '0x83126e978d4fdf3c','0x7ff7ced916872b020c4',75,
                1,4000,
        ], 256 => [
                '0xfa000000','0x3e000000',30,
-               '0xfa00000000000000','0x3e00000000000000',62,
                125,32,
                '0x83126e98','0x1fbe76c8b',33,
-               '0x83126e978d4fdf3c','0x1fbe76c8b43958106',65,
                32,125,
                '0xf4240000','0xc0000',20,
-               '0xf424000000000000','0xc000000000000',52,
                15625,4,
                '0x8637bd06','0x7ffde7210be',43,
-               '0x8637bd05af6c69b6','0x7ffde7210be9424e592',75,
                4,15625,
        ], 300 => [
                '0xd5555556','0x2aaaaaaa',30,
-               '0xd555555555555556','0x2aaaaaaaaaaaaaaa',62,
                10,3,
                '0x9999999a','0x1cccccccc',33,
-               '0x999999999999999a','0x1cccccccccccccccc',65,
                3,10,
                '0xd0555556','0xaaaaa',20,
-               '0xd055555555555556','0xaaaaaaaaaaaaa',52,
                10000,3,
                '0x9d495183','0x7ffcb923a29',43,
-               '0x9d495182a9930be1','0x7ffcb923a29c779a6b5',75,
                3,10000,
        ], 512 => [
                '0xfa000000','0x7e000000',31,
-               '0xfa00000000000000','0x7e00000000000000',63,
                125,64,
                '0x83126e98','0xfdf3b645',32,
-               '0x83126e978d4fdf3c','0xfdf3b645a1cac083',64,
                64,125,
                '0xf4240000','0x1c0000',21,
-               '0xf424000000000000','0x1c000000000000',53,
                15625,8,
                '0x8637bd06','0x3ffef39085f',42,
-               '0x8637bd05af6c69b6','0x3ffef39085f4a1272c9',74,
                8,15625,
        ], 1000 => [
                '0x80000000','0x0',31,
-               '0x8000000000000000','0x0',63,
                1,1,
                '0x80000000','0x0',31,
-               '0x8000000000000000','0x0',63,
                1,1,
                '0xfa000000','0x0',22,
-               '0xfa00000000000000','0x0',54,
                1000,1,
                '0x83126e98','0x1ff7ced9168',41,
-               '0x83126e978d4fdf3c','0x1ff7ced916872b020c4',73,
                1,1000,
        ], 1024 => [
                '0xfa000000','0xfe000000',32,
-               '0xfa00000000000000','0xfe00000000000000',64,
                125,128,
                '0x83126e98','0x7ef9db22',31,
-               '0x83126e978d4fdf3c','0x7ef9db22d0e56041',63,
                128,125,
                '0xf4240000','0x3c0000',22,
-               '0xf424000000000000','0x3c000000000000',54,
                15625,16,
                '0x8637bd06','0x1fff79c842f',41,
-               '0x8637bd05af6c69b6','0x1fff79c842fa5093964',73,
                16,15625,
        ], 1200 => [
                '0xd5555556','0xd5555555',32,
-               '0xd555555555555556','0xd555555555555555',64,
                5,6,
                '0x9999999a','0x66666666',31,
-               '0x999999999999999a','0x6666666666666666',63,
                6,5,
                '0xd0555556','0x2aaaaa',22,
-               '0xd055555555555556','0x2aaaaaaaaaaaaa',54,
                2500,3,
                '0x9d495183','0x1ffcb923a29',41,
-               '0x9d495182a9930be1','0x1ffcb923a29c779a6b5',73,
                3,2500,
        ]
 );
@@ -264,6 +204,15 @@ sub fmuls($$$) {
        return 0;
 }
 
+# Generate a hex value if the result fits in 64 bits;
+# otherwise skip.
+sub bignum_hex($) {
+       my($x) = @_;
+       my $s = $x->as_hex();
+
+       return (length($s) > 18) ? undef : $s;
+}
+
 # Provides mul, adj, and shr factors for a specific
 # (bit, time, hz) combination
 sub muladj($$$) {
@@ -271,7 +220,7 @@ sub muladj($$$) {
        my $s = fmuls($b, $t, $hz);
        my $m = fmul($s, $t, $hz);
        my $a = fadj($s, $t, $hz);
-       return ($m->as_hex(), $a->as_hex(), $s);
+       return (bignum_hex($m), bignum_hex($a), $s);
 }
 
 # Provides numerator, denominator values
@@ -288,12 +237,10 @@ sub conversions($$) {
 
        # HZ_TO_xx
        push(@val, muladj(32, $t, $hz));
-       push(@val, muladj(64, $t, $hz));
        push(@val, numden($t, $hz));
 
        # xx_TO_HZ
        push(@val, muladj(32, $hz, $t));
-       push(@val, muladj(64, $hz, $t));
        push(@val, numden($hz, $t));
 
        return @val;
@@ -318,6 +265,19 @@ sub compute_values($) {
        return @val;
 }
 
+sub outputval($$)
+{
+       my($name, $val) = @_;
+       my $csuf;
+
+       if (defined($val)) {
+           if ($name !~ /SHR/) {
+               $val = "U64_C($val)";
+           }
+           printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
+       }
+}
+
 sub output($@)
 {
        my($hz, @val) = @_;
@@ -331,6 +291,7 @@ sub output($@)
        print "\n";
 
        print "#include <linux/param.h>\n";
+       print "#include <linux/types.h>\n";
 
        print "\n";
        print "#if HZ != $hz\n";
@@ -340,15 +301,13 @@ sub output($@)
 
        foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
                      'HZ_TO_USEC','USEC_TO_HZ') {
-               foreach $bit (32, 64) {
+               foreach $bit (32) {
                        foreach $suf ('MUL', 'ADJ', 'SHR') {
-                               printf "#define %-23s %s\n",
-                                       "${pfx}_$suf$bit", shift(@val);
+                               outputval("${pfx}_$suf$bit", shift(@val));
                        }
                }
                foreach $suf ('NUM', 'DEN') {
-                       printf "#define %-23s %s\n",
-                               "${pfx}_$suf", shift(@val);
+                       outputval("${pfx}_$suf", shift(@val));
                }
        }
 
@@ -356,6 +315,23 @@ sub output($@)
        print "#endif /* KERNEL_TIMECONST_H */\n";
 }
 
+# Pretty-print Perl values
+sub perlvals(@) {
+       my $v;
+       my @l = ();
+
+       foreach $v (@_) {
+               if (!defined($v)) {
+                       push(@l, 'undef');
+               } elsif ($v =~ /^0x/) {
+                       push(@l, "\'".$v."\'");
+               } else {
+                       push(@l, $v.'');
+               }
+       }
+       return join(',', @l);
+}
+
 ($hz) = @ARGV;
 
 # Use this to generate the %canned_values structure
@@ -373,15 +349,15 @@ if ($hz eq '--can') {
                print "$pf$hz => [\n";
                while (scalar(@values)) {
                        my $bit;
-                       foreach $bit (32, 64) {
+                       foreach $bit (32) {
                                my $m = shift(@values);
                                my $a = shift(@values);
                                my $s = shift(@values);
-                               print "\t\t\'",$m,"\',\'",$a,"\',",$s,",\n";
+                               print "\t\t", perlvals($m,$a,$s), ",\n";
                        }
                        my $n = shift(@values);
                        my $d = shift(@values);
-                       print "\t\t",$n,',',$d,",\n";
+                       print "\t\t", perlvals($n,$d), ",\n";
                }
                print "\t]";
                $pf = ', ';
index 721093a22561100bd626a9e16981c768ead6c40f..29fc39f1029cec92528b0cb66380028670b9eee1 100644 (file)
@@ -195,7 +195,6 @@ static void delayed_work_timer_fn(unsigned long __data)
 int queue_delayed_work(struct workqueue_struct *wq,
                        struct delayed_work *dwork, unsigned long delay)
 {
-       timer_stats_timer_set_start_info(&dwork->timer);
        if (delay == 0)
                return queue_work(wq, &dwork->work);
 
@@ -219,11 +218,12 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
        struct timer_list *timer = &dwork->timer;
        struct work_struct *work = &dwork->work;
 
-       timer_stats_timer_set_start_info(&dwork->timer);
        if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) {
                BUG_ON(timer_pending(timer));
                BUG_ON(!list_empty(&work->entry));
 
+               timer_stats_timer_set_start_info(&dwork->timer);
+
                /* This stores cwq for the moment, for the timer_fn */
                set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id()));
                timer->expires = jiffies + delay;
@@ -564,7 +564,6 @@ EXPORT_SYMBOL(schedule_work);
 int schedule_delayed_work(struct delayed_work *dwork,
                                        unsigned long delay)
 {
-       timer_stats_timer_set_start_info(&dwork->timer);
        return queue_delayed_work(keventd_wq, dwork, delay);
 }
 EXPORT_SYMBOL(schedule_delayed_work);
@@ -581,7 +580,6 @@ EXPORT_SYMBOL(schedule_delayed_work);
 int schedule_delayed_work_on(int cpu,
                        struct delayed_work *dwork, unsigned long delay)
 {
-       timer_stats_timer_set_start_info(&dwork->timer);
        return queue_delayed_work_on(cpu, keventd_wq, dwork, delay);
 }
 EXPORT_SYMBOL(schedule_delayed_work_on);
index f2e01ac5ab0905e5af78202bf8bccc475d6d59f6..a5d4b1dac2a574ed09870e2ce25b2e300f07a1d5 100644 (file)
@@ -1,4 +1,10 @@
 
+config HAVE_ARCH_KGDB_SHADOW_INFO
+       bool
+
+config HAVE_ARCH_KGDB
+       bool
+
 menuconfig KGDB
        bool "KGDB: kernel debugging with remote gdb"
        select FRAME_POINTER
@@ -10,15 +16,10 @@ menuconfig KGDB
          at http://kgdb.sourceforge.net as well as in DocBook form
          in Documentation/DocBook/.  If unsure, say N.
 
-config HAVE_ARCH_KGDB_SHADOW_INFO
-       bool
-
-config HAVE_ARCH_KGDB
-       bool
+if KGDB
 
 config KGDB_SERIAL_CONSOLE
        tristate "KGDB: use kgdb over the serial console"
-       depends on KGDB
        select CONSOLE_POLL
        select MAGIC_SYSRQ
        default y
@@ -28,7 +29,6 @@ config KGDB_SERIAL_CONSOLE
 
 config KGDB_TESTS
        bool "KGDB: internal test suite"
-       depends on KGDB
        default n
        help
          This is a kgdb I/O module specifically designed to test
@@ -56,3 +56,5 @@ config KGDB_TESTS_BOOT_STRING
          boot.  See the drivers/misc/kgdbts.c for detailed
          information about other strings you could use beyond the
          default of V1F100.
+
+endif # KGDB
index c4cb48f77f0c6ab157ba41ec0411644a44a39ca9..482df94ea21eb3e9ab7b2ef4efe88643147c3d80 100644 (file)
@@ -315,22 +315,6 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
 }
 EXPORT_SYMBOL(bitmap_scnprintf);
 
-/**
- * bitmap_scnprintf_len - return buffer length needed to convert
- * bitmap to an ASCII hex string.
- * @len: number of bits to be converted
- */
-int bitmap_scnprintf_len(unsigned int len)
-{
-       /* we need 9 chars per word for 32 bit words (8 hexdigits + sep/null) */
-       int bitslen = ALIGN(len, CHUNKSZ);
-       int wordlen = CHUNKSZ / 4;
-       int buflen = (bitslen / wordlen) * (wordlen + 1) * sizeof(char);
-
-       return buflen;
-}
-EXPORT_SYMBOL(bitmap_scnprintf_len);
-
 /**
  * __bitmap_parse - convert an ASCII hex string into a bitmap.
  * @buf: pointer to buffer containing string.
index 26c87c49d776cf8365e9ff7ba2a7319e481f716f..72c8909006da156a41c4a70a1de2562198b45103 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 
-static void devm_ioremap_release(struct device *dev, void *res)
+void devm_ioremap_release(struct device *dev, void *res)
 {
        iounmap(*(void __iomem **)res);
 }
index b71cf93c529adaa3364afa4a1b997c54cc9ef363..bb5bd0c0f030a9cf44c57ef07b50fac3e7170ce8 100644 (file)
@@ -16,9 +16,8 @@
  * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S.
  */
 
-#include <linux/types.h>
 #include <linux/module.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
 
 /* Not needed on 64bit architectures */
 #if BITS_PER_LONG == 32
@@ -58,10 +57,31 @@ uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
 
 EXPORT_SYMBOL(__div64_32);
 
+#ifndef div_s64_rem
+s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
+{
+       u64 quotient;
+
+       if (dividend < 0) {
+               quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
+               *remainder = -*remainder;
+               if (divisor > 0)
+                       quotient = -quotient;
+       } else {
+               quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
+               if (divisor < 0)
+                       quotient = -quotient;
+       }
+       return quotient;
+}
+EXPORT_SYMBOL(div_s64_rem);
+#endif
+
 /* 64bit divisor, dividend and result. dynamic precision */
-uint64_t div64_64(uint64_t dividend, uint64_t divisor)
+#ifndef div64_u64
+u64 div64_u64(u64 dividend, u64 divisor)
 {
-       uint32_t high, d;
+       u32 high, d;
 
        high = divisor >> 32;
        if (high) {
@@ -72,10 +92,9 @@ uint64_t div64_64(uint64_t dividend, uint64_t divisor)
        } else
                d = divisor;
 
-       do_div(dividend, d);
-
-       return dividend;
+       return div_u64(dividend, d);
 }
-EXPORT_SYMBOL(div64_64);
+EXPORT_SYMBOL(div64_u64);
+#endif
 
 #endif /* BITS_PER_LONG == 32 */
index 8368c81fcb7d21cd3d85c8c0880f918b9c1911f5..7a02e173f02773c2bc5fc3bfa763e269ef1b9f7a 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -385,8 +385,8 @@ void idr_remove(struct idr *idp, int id)
        while (idp->id_free_cnt >= IDR_FREE_MAX) {
                p = alloc_layer(idp);
                kmem_cache_free(idr_layer_cache, p);
-               return;
        }
+       return;
 }
 EXPORT_SYMBOL(idr_remove);
 
index cd3e82530b03b7099d9ee6f777623a0140a43a0c..01a3c22c1b5a9c951dc33a0c37179306f36e18e4 100644 (file)
 #include <linux/semaphore.h>
 
 /*
- * The 'big kernel semaphore'
+ * The 'big kernel lock'
  *
- * This mutex is taken and released recursively by lock_kernel()
+ * This spinlock is taken and released recursively by lock_kernel()
  * and unlock_kernel().  It is transparently dropped and reacquired
  * over schedule().  It is used to protect legacy code that hasn't
  * been migrated to a proper locking design yet.
  *
- * Note: code locked by this semaphore will only be serialized against
- * other code using the same locking facility. The code guarantees that
- * the task remains on the same CPU.
- *
  * Don't use in new code.
  */
-static DECLARE_MUTEX(kernel_sem);
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag);
+
 
 /*
- * Re-acquire the kernel semaphore.
+ * Acquire/release the underlying lock from the scheduler.
  *
- * This function is called with preemption off.
+ * This is called with preemption disabled, and should
+ * return an error value if it cannot get the lock and
+ * TIF_NEED_RESCHED gets set.
  *
- * We are executing in schedule() so the code must be extremely careful
- * about recursion, both due to the down() and due to the enabling of
- * preemption. schedule() will re-check the preemption flag after
- * reacquiring the semaphore.
+ * If it successfully gets the lock, it should increment
+ * the preemption count like any spinlock does.
+ *
+ * (This works on UP too - _raw_spin_trylock will never
+ * return false in that case)
  */
 int __lockfunc __reacquire_kernel_lock(void)
 {
-       struct task_struct *task = current;
-       int saved_lock_depth = task->lock_depth;
-
-       BUG_ON(saved_lock_depth < 0);
-
-       task->lock_depth = -1;
-       preempt_enable_no_resched();
-
-       down(&kernel_sem);
-
+       while (!_raw_spin_trylock(&kernel_flag)) {
+               if (test_thread_flag(TIF_NEED_RESCHED))
+                       return -EAGAIN;
+               cpu_relax();
+       }
        preempt_disable();
-       task->lock_depth = saved_lock_depth;
-
        return 0;
 }
 
 void __lockfunc __release_kernel_lock(void)
 {
-       up(&kernel_sem);
+       _raw_spin_unlock(&kernel_flag);
+       preempt_enable_no_resched();
 }
 
 /*
- * Getting the big kernel semaphore.
+ * These are the BKL spinlocks - we try to be polite about preemption.
+ * If SMP is not on (ie UP preemption), this all goes away because the
+ * _raw_spin_trylock() will always succeed.
  */
-void __lockfunc lock_kernel(void)
+#ifdef CONFIG_PREEMPT
+static inline void __lock_kernel(void)
 {
-       struct task_struct *task = current;
-       int depth = task->lock_depth + 1;
+       preempt_disable();
+       if (unlikely(!_raw_spin_trylock(&kernel_flag))) {
+               /*
+                * If preemption was disabled even before this
+                * was called, there's nothing we can be polite
+                * about - just spin.
+                */
+               if (preempt_count() > 1) {
+                       _raw_spin_lock(&kernel_flag);
+                       return;
+               }
 
-       if (likely(!depth))
                /*
-                * No recursion worries - we set up lock_depth _after_
+                * Otherwise, let's wait for the kernel lock
+                * with preemption enabled..
                 */
-               down(&kernel_sem);
+               do {
+                       preempt_enable();
+                       while (spin_is_locked(&kernel_flag))
+                               cpu_relax();
+                       preempt_disable();
+               } while (!_raw_spin_trylock(&kernel_flag));
+       }
+}
 
-       task->lock_depth = depth;
+#else
+
+/*
+ * Non-preemption case - just get the spinlock
+ */
+static inline void __lock_kernel(void)
+{
+       _raw_spin_lock(&kernel_flag);
 }
+#endif
 
-void __lockfunc unlock_kernel(void)
+static inline void __unlock_kernel(void)
 {
-       struct task_struct *task = current;
+       /*
+        * the BKL is not covered by lockdep, so we open-code the
+        * unlocking sequence (and thus avoid the dep-chain ops):
+        */
+       _raw_spin_unlock(&kernel_flag);
+       preempt_enable();
+}
 
-       BUG_ON(task->lock_depth < 0);
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously, so we only need to
+ * worry about other CPU's.
+ */
+void __lockfunc lock_kernel(void)
+{
+       int depth = current->lock_depth+1;
+       if (likely(!depth))
+               __lock_kernel();
+       current->lock_depth = depth;
+}
 
-       if (likely(--task->lock_depth < 0))
-               up(&kernel_sem);
+void __lockfunc unlock_kernel(void)
+{
+       BUG_ON(current->lock_depth < 0);
+       if (likely(--current->lock_depth < 0))
+               __unlock_kernel();
 }
 
 EXPORT_SYMBOL(lock_kernel);
index 5efafed3d6b65df9e56f968e32fb012f4cd13c65..b19b87af65a3553a0650d679cabfac9fecd4eb3b 100644 (file)
@@ -493,6 +493,33 @@ char *strsep(char **s, const char *ct)
 EXPORT_SYMBOL(strsep);
 #endif
 
+/**
+ * sysfs_streq - return true if strings are equal, modulo trailing newline
+ * @s1: one string
+ * @s2: another string
+ *
+ * This routine returns true iff two strings are equal, treating both
+ * NUL and newline-then-NUL as equivalent string terminations.  It's
+ * geared for use with sysfs input strings, which generally terminate
+ * with newlines but are compared against values without newlines.
+ */
+bool sysfs_streq(const char *s1, const char *s2)
+{
+       while (*s1 && *s1 == *s2) {
+               s1++;
+               s2++;
+       }
+
+       if (*s1 == *s2)
+               return true;
+       if (!*s1 && *s2 == '\n' && !s2[1])
+               return true;
+       if (*s1 == '\n' && !s1[1] && !*s2)
+               return true;
+       return false;
+}
+EXPORT_SYMBOL(sysfs_streq);
+
 #ifndef __HAVE_ARCH_MEMSET
 /**
  * memset - Fill a region of memory with the given value
index 239d36163bbe53fbb2115595e82ed9aef3180b02..2dead9adf8b76806e66ac1b0169510773be58e14 100644 (file)
@@ -1655,7 +1655,7 @@ int should_remove_suid(struct dentry *dentry)
 }
 EXPORT_SYMBOL(should_remove_suid);
 
-int __remove_suid(struct dentry *dentry, int kill)
+static int __remove_suid(struct dentry *dentry, int kill)
 {
        struct iattr newattrs;
 
index 33add96cd5fbf98c2f804fb2511aeec3f5a2594d..e46451e1d9b793563b08d8ef015927b484b0be1d 100644 (file)
@@ -48,6 +48,8 @@ enum mem_cgroup_stat_index {
         */
        MEM_CGROUP_STAT_CACHE,     /* # of pages charged as cache */
        MEM_CGROUP_STAT_RSS,       /* # of pages charged as rss */
+       MEM_CGROUP_STAT_PGPGIN_COUNT,   /* # of pages paged in */
+       MEM_CGROUP_STAT_PGPGOUT_COUNT,  /* # of pages paged out */
 
        MEM_CGROUP_STAT_NSTATS,
 };
@@ -199,6 +201,13 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags,
                __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val);
        else
                __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val);
+
+       if (charge)
+               __mem_cgroup_stat_add_safe(stat,
+                               MEM_CGROUP_STAT_PGPGIN_COUNT, 1);
+       else
+               __mem_cgroup_stat_add_safe(stat,
+                               MEM_CGROUP_STAT_PGPGOUT_COUNT, 1);
 }
 
 static struct mem_cgroup_per_zone *
@@ -884,6 +893,8 @@ static const struct mem_cgroup_stat_desc {
 } mem_cgroup_stat_desc[] = {
        [MEM_CGROUP_STAT_CACHE] = { "cache", PAGE_SIZE, },
        [MEM_CGROUP_STAT_RSS] = { "rss", PAGE_SIZE, },
+       [MEM_CGROUP_STAT_PGPGIN_COUNT] = {"pgpgin", 1, },
+       [MEM_CGROUP_STAT_PGPGOUT_COUNT] = {"pgpgout", 1, },
 };
 
 static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft,
index bbab1e37055e22df235af61ddd201fe4b9832283..fb5608a120edc77cffac3050ce7e5ebbcff94b8f 100644 (file)
@@ -311,6 +311,21 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
        if (!new)
                return -ENOMEM;
 
+       /*
+        * Ensure all pte setup (eg. pte page lock and page clearing) are
+        * visible before the pte is made visible to other CPUs by being
+        * put into page tables.
+        *
+        * The other side of the story is the pointer chasing in the page
+        * table walking code (when walking the page table without locking;
+        * ie. most of the time). Fortunately, these data accesses consist
+        * of a chain of data-dependent loads, meaning most CPUs (alpha
+        * being the notable exception) will already guarantee loads are
+        * seen in-order. See the alpha page table accessors for the
+        * smp_read_barrier_depends() barriers in page table walking code.
+        */
+       smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */
+
        spin_lock(&mm->page_table_lock);
        if (!pmd_present(*pmd)) {       /* Has another populated it ? */
                mm->nr_ptes++;
@@ -329,6 +344,8 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
        if (!new)
                return -ENOMEM;
 
+       smp_wmb(); /* See comment in __pte_alloc */
+
        spin_lock(&init_mm.page_table_lock);
        if (!pmd_present(*pmd)) {       /* Has another populated it ? */
                pmd_populate_kernel(&init_mm, pmd, new);
@@ -969,7 +986,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                goto no_page_table;
        
        pmd = pmd_offset(pud, address);
-       if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+       if (pmd_none(*pmd))
                goto no_page_table;
 
        if (pmd_huge(*pmd)) {
@@ -978,6 +995,9 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                goto out;
        }
 
+       if (unlikely(pmd_bad(*pmd)))
+               goto no_page_table;
+
        ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
        if (!ptep)
                goto out;
@@ -2616,6 +2636,8 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
        if (!new)
                return -ENOMEM;
 
+       smp_wmb(); /* See comment in __pte_alloc */
+
        spin_lock(&mm->page_table_lock);
        if (pgd_present(*pgd))          /* Another has populated it */
                pud_free(mm, new);
@@ -2637,6 +2659,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
        if (!new)
                return -ENOMEM;
 
+       smp_wmb(); /* See comment in __pte_alloc */
+
        spin_lock(&mm->page_table_lock);
 #ifndef __ARCH_HAS_4LEVEL_HACK
        if (pud_present(*pud))          /* Another has populated it */
index 1c96cfc9e0400cf0e6b3c4cf41cdccc03bff17c0..9d834aa4b9795264d87eef283c2492a99d67597b 100644 (file)
@@ -207,7 +207,6 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
 
        spin_lock_irqsave(&pdflush_lock, flags);
        if (list_empty(&pdflush_list)) {
-               spin_unlock_irqrestore(&pdflush_lock, flags);
                ret = -1;
        } else {
                struct pdflush_work *pdf;
@@ -219,8 +218,9 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
                pdf->fn = fn;
                pdf->arg0 = arg0;
                wake_up_process(pdf->who);
-               spin_unlock_irqrestore(&pdflush_lock, flags);
        }
+       spin_unlock_irqrestore(&pdflush_lock, flags);
+
        return ret;
 }
 
index 70db2897c1ea626ea3b6f576fda91fa6c3c48cd9..a505a828ef411e08f149a413fb37f32da7c47e21 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -22,6 +22,7 @@
 #include <linux/debugobjects.h>
 #include <linux/kallsyms.h>
 #include <linux/memory.h>
+#include <linux/math64.h>
 
 /*
  * Lock order:
@@ -216,7 +217,7 @@ struct track {
 
 enum track_item { TRACK_ALLOC, TRACK_FREE };
 
-#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)
+#ifdef CONFIG_SLUB_DEBUG
 static int sysfs_slab_add(struct kmem_cache *);
 static int sysfs_slab_alias(struct kmem_cache *, const char *);
 static void sysfs_slab_remove(struct kmem_cache *);
@@ -813,7 +814,8 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
        return search == NULL;
 }
 
-static void trace(struct kmem_cache *s, struct page *page, void *object, int alloc)
+static void trace(struct kmem_cache *s, struct page *page, void *object,
+                                                               int alloc)
 {
        if (s->flags & SLAB_TRACE) {
                printk(KERN_INFO "TRACE %s %s 0x%p inuse=%d fp=0x%p\n",
@@ -1266,8 +1268,7 @@ static void add_partial(struct kmem_cache_node *n,
        spin_unlock(&n->list_lock);
 }
 
-static void remove_partial(struct kmem_cache *s,
-                                               struct page *page)
+static void remove_partial(struct kmem_cache *s, struct page *page)
 {
        struct kmem_cache_node *n = get_node(s, page_to_nid(page));
 
@@ -1282,7 +1283,8 @@ static void remove_partial(struct kmem_cache *s,
  *
  * Must hold list_lock.
  */
-static inline int lock_and_freeze_slab(struct kmem_cache_node *n, struct page *page)
+static inline int lock_and_freeze_slab(struct kmem_cache_node *n,
+                                                       struct page *page)
 {
        if (slab_trylock(page)) {
                list_del(&page->lru);
@@ -1419,8 +1421,8 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
                         * so that the others get filled first. That way the
                         * size of the partial list stays small.
                         *
-                        * kmem_cache_shrink can reclaim any empty slabs from the
-                        * partial list.
+                        * kmem_cache_shrink can reclaim any empty slabs from
+                        * the partial list.
                         */
                        add_partial(n, page, 1);
                        slab_unlock(page);
@@ -2908,7 +2910,7 @@ static int slab_mem_going_online_callback(void *arg)
                return 0;
 
        /*
-        * We are bringing a node online. No memory is availabe yet. We must
+        * We are bringing a node online. No memory is available yet. We must
         * allocate a kmem_cache_node structure in order to bring the node
         * online.
         */
@@ -3245,7 +3247,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
        return slab_alloc(s, gfpflags, node, caller);
 }
 
-#if (defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)) || defined(CONFIG_SLABINFO)
+#ifdef CONFIG_SLUB_DEBUG
 static unsigned long count_partial(struct kmem_cache_node *n,
                                        int (*get_count)(struct page *))
 {
@@ -3274,9 +3276,7 @@ static int count_free(struct page *page)
 {
        return page->objects - page->inuse;
 }
-#endif
 
-#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)
 static int validate_slab(struct kmem_cache *s, struct page *page,
                                                unsigned long *map)
 {
@@ -3621,12 +3621,10 @@ static int list_locations(struct kmem_cache *s, char *buf,
                        len += sprintf(buf + len, "<not-available>");
 
                if (l->sum_time != l->min_time) {
-                       unsigned long remainder;
-
                        len += sprintf(buf + len, " age=%ld/%ld/%ld",
-                       l->min_time,
-                       div_long_long_rem(l->sum_time, l->count, &remainder),
-                       l->max_time);
+                               l->min_time,
+                               (long)div_u64(l->sum_time, l->count),
+                               l->max_time);
                } else
                        len += sprintf(buf + len, " age=%ld",
                                l->min_time);
@@ -3764,7 +3762,7 @@ static int any_slab_objects(struct kmem_cache *s)
                if (!n)
                        continue;
 
-               if (atomic_read(&n->total_objects))
+               if (atomic_long_read(&n->total_objects))
                        return 1;
        }
        return 0;
@@ -3813,7 +3811,12 @@ SLAB_ATTR_RO(objs_per_slab);
 static ssize_t order_store(struct kmem_cache *s,
                                const char *buf, size_t length)
 {
-       int order = simple_strtoul(buf, NULL, 10);
+       unsigned long order;
+       int err;
+
+       err = strict_strtoul(buf, 10, &order);
+       if (err)
+               return err;
 
        if (order > slub_max_order || order < slub_min_order)
                return -EINVAL;
@@ -4066,10 +4069,16 @@ static ssize_t remote_node_defrag_ratio_show(struct kmem_cache *s, char *buf)
 static ssize_t remote_node_defrag_ratio_store(struct kmem_cache *s,
                                const char *buf, size_t length)
 {
-       int n = simple_strtoul(buf, NULL, 10);
+       unsigned long ratio;
+       int err;
+
+       err = strict_strtoul(buf, 10, &ratio);
+       if (err)
+               return err;
+
+       if (ratio < 100)
+               s->remote_node_defrag_ratio = ratio * 10;
 
-       if (n < 100)
-               s->remote_node_defrag_ratio = n * 10;
        return length;
 }
 SLAB_ATTR(remote_node_defrag_ratio);
@@ -4426,8 +4435,8 @@ __initcall(slab_sysfs_init);
  */
 #ifdef CONFIG_SLABINFO
 
-ssize_t slabinfo_write(struct file *file, const char __user * buffer,
-                       size_t count, loff_t *ppos)
+ssize_t slabinfo_write(struct file *file, const char __user *buffer,
+                      size_t count, loff_t *ppos)
 {
        return -EINVAL;
 }
index 2a39cf128aba2a7a583501a6686d9214070eb7bd..6e45b0f3d1256e0bdc3a3caffa74597cf96a5138 100644 (file)
@@ -547,6 +547,7 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
  *     @gfp_mask:      flags for the page level allocator
  *     @prot:          protection mask for the allocated pages
  *     @node:          node to use for allocation or -1
+ *     @caller:        caller's return address
  *
  *     Allocate enough pages to cover @size from the page level
  *     allocator with @gfp_mask flags.  Map them into contiguous
index 1a32130b958c418ec8a018aa676c73bb3d7cde32..db9eabb2c5b3a992a04ac2396bf791b72bbdcf94 100644 (file)
@@ -41,7 +41,9 @@ static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask)
 */
 void all_vm_events(unsigned long *ret)
 {
+       get_online_cpus();
        sum_vm_events(ret, &cpu_online_map);
+       put_online_cpus();
 }
 EXPORT_SYMBOL_GPL(all_vm_events);
 
index 74fd2d33aff43f3b73c00c52626a2f044c9c138b..d9a3a9d13bedbb5b11cc1850aa604adccf47ad1c 100644 (file)
@@ -412,12 +412,6 @@ static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
        bcm_send_to_user(op, &head, data, 1);
 }
 
-/* TODO: move to linux/hrtimer.h */
-static inline int hrtimer_callback_running(struct hrtimer *timer)
-{
-        return timer->state & HRTIMER_STATE_CALLBACK;
-}
-
 /*
  * bcm_rx_update_and_send - process a detected relevant receive content change
  *                          1. update the last received data
index eb5b9854c8c7330791ada69b8c9e8695f7a73f3d..4a1221e5e8ee2ec8b7d1a5157aa063f6a3f8011e 100644 (file)
@@ -15,8 +15,8 @@
 
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/math64.h>
 #include <net/tcp.h>
-#include <asm/div64.h>
 
 #define BICTCP_BETA_SCALE    1024      /* Scale factor beta calculation
                                         * max_cwnd = snd_cwnd * beta
@@ -128,7 +128,7 @@ static u32 cubic_root(u64 a)
         * x    = ( 2 * x  +  a / x  ) / 3
         *  k+1          k         k
         */
-       x = (2 * x + (u32)div64_64(a, (u64)x * (u64)(x - 1)));
+       x = (2 * x + (u32)div64_u64(a, (u64)x * (u64)(x - 1)));
        x = ((x * 341) >> 10);
        return x;
 }
index b15e7e2fa14328612cdf4de25150cc62604e8a58..d7e8983cd37f6303921edf25bc201eca7e99c4a2 100644 (file)
@@ -4,12 +4,11 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
+#include <linux/math64.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connbytes.h>
 #include <net/netfilter/nf_conntrack.h>
 
-#include <asm/div64.h>
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
@@ -82,7 +81,7 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
                        break;
                }
                if (pkts != 0)
-                       what = div64_64(bytes, pkts);
+                       what = div64_u64(bytes, pkts);
                break;
        }
 
index d74c2d269539a03a4267dcc93d195ca20e68d522..01c7e311b904597e826b1da925a03c888aa090f7 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/sched.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
index 4bc68f20a73c4ab8ac9364133ee57e5cd5655375..96521cb087ec388587d4737c375c42862f4b5a24 100644 (file)
@@ -11,9 +11,9 @@
 #ifndef KBUILD_NO_NLS
 # include <libintl.h>
 #else
-# define gettext(Msgid) ((const char *) (Msgid))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+static inline const char *gettext(const char *txt) { return txt; }
+static inline void textdomain(const char *domainname) {}
+static inline void bindtextdomain(const char *name, const char *dir) {}
 #endif
 
 #ifdef __cplusplus
index 62e1e02126e61d5cde4945c9d7f922153ea6f90e..5552154cbedb723411708a2723f1a4f07a30890f 100644 (file)
@@ -36,8 +36,10 @@ trap "rm -f $tmp" 0 1 2 3 15
 
 # Check if we can link to ncurses
 check() {
-       echo -e " #include CURSES_LOC \n main() {}" |
-           $cc -xc - -o $tmp 2> /dev/null
+        $cc -xc - -o $tmp 2>/dev/null <<'EOF'
+#include CURSES_LOC
+main() {}
+EOF
        if [ $? != 0 ]; then
            echo " *** Unable to find the ncurses libraries or the"       1>&2
            echo " *** required header files."                            1>&2
index 734cf4f3131e69b36c26ee23ee36dfe0a59496ff..6841e95c0989bcd2007b46ad4178e8ad28dd1bbf 100644 (file)
@@ -773,7 +773,7 @@ static void conf_string(struct menu *menu)
 
        while (1) {
                int res;
-               char *heading;
+               const char *heading;
 
                switch (sym_get_type(menu->sym)) {
                case S_INT:
@@ -925,3 +925,4 @@ int main(int ac, char **av)
 
        return 0;
 }
+
index e04c4218cb5200d415a8933e84478e68b9cceee6..cea4a790e1e97170459576b8b68c94daf3e95cc9 100644 (file)
@@ -51,6 +51,15 @@ do {                                                            \
                 sprintf(str + strlen(str), "*");                \
 } while(0)
 
+/* Always end in a wildcard, for future extension */
+static inline void add_wildcard(char *str)
+{
+       int len = strlen(str);
+
+       if (str[len - 1] != '*')
+               strcat(str + len, "*");
+}
+
 unsigned int cross_build = 0;
 /**
  * Check that sizeof(device_id type) are consistent with size of section
@@ -133,9 +142,7 @@ static void do_usb_entry(struct usb_device_id *id,
            id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
            id->bInterfaceProtocol);
 
-       /* Always end in a wildcard, for future extension */
-       if (alias[strlen(alias)-1] != '*')
-               strcat(alias, "*");
+       add_wildcard(alias);
        buf_printf(&mod->dev_table_buf,
                   "MODULE_ALIAS(\"%s\");\n", alias);
 }
@@ -219,6 +226,7 @@ static int do_ieee1394_entry(const char *filename,
        ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
            id->version);
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -261,6 +269,7 @@ static int do_pci_entry(const char *filename,
        ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
        ADD(alias, "sc", subclass_mask == 0xFF, subclass);
        ADD(alias, "i", interface_mask == 0xFF, interface);
+       add_wildcard(alias);
        return 1;
 }
 
@@ -283,6 +292,7 @@ static int do_ccw_entry(const char *filename,
            id->dev_type);
        ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL,
            id->dev_model);
+       add_wildcard(alias);
        return 1;
 }
 
@@ -290,7 +300,7 @@ static int do_ccw_entry(const char *filename,
 static int do_ap_entry(const char *filename,
                       struct ap_device_id *id, char *alias)
 {
-       sprintf(alias, "ap:t%02X", id->dev_type);
+       sprintf(alias, "ap:t%02X*", id->dev_type);
        return 1;
 }
 
@@ -309,6 +319,7 @@ static int do_serio_entry(const char *filename,
        ADD(alias, "id", id->id != SERIO_ANY, id->id);
        ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -316,7 +327,7 @@ static int do_serio_entry(const char *filename,
 static int do_acpi_entry(const char *filename,
                        struct acpi_device_id *id, char *alias)
 {
-       sprintf(alias, "acpi*:%s:", id->id);
+       sprintf(alias, "acpi*:%s:*", id->id);
        return 1;
 }
 
@@ -324,7 +335,7 @@ static int do_acpi_entry(const char *filename,
 static int do_pnp_entry(const char *filename,
                        struct pnp_device_id *id, char *alias)
 {
-       sprintf(alias, "pnp:d%s", id->id);
+       sprintf(alias, "pnp:d%s*", id->id);
        return 1;
 }
 
@@ -409,6 +420,7 @@ static int do_pcmcia_entry(const char *filename,
        ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]);
        ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]);
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -432,6 +444,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali
         if (isspace (*tmp))
             *tmp = '_';
 
+    add_wildcard(alias);
     return 1;
 }
 
@@ -448,6 +461,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
                if (isspace (*tmp))
                        *tmp = '_';
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -511,6 +525,8 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
 {
        if (eisa->sig[0])
                sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", eisa->sig);
+       else
+               strcat(alias, "*");
        return 1;
 }
 
@@ -529,6 +545,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
        ADD(alias, "rev", id->hversion_rev != PA_HVERSION_REV_ANY_ID, id->hversion_rev);
        ADD(alias, "sv", id->sversion != PA_SVERSION_ANY_ID, id->sversion);
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -544,6 +561,7 @@ static int do_sdio_entry(const char *filename,
        ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
        ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
        ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
+       add_wildcard(alias);
        return 1;
 }
 
@@ -559,6 +577,7 @@ static int do_ssb_entry(const char *filename,
        ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor);
        ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid);
        ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision);
+       add_wildcard(alias);
        return 1;
 }
 
@@ -573,6 +592,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
        ADD(alias, "d", 1, id->device);
        ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
 
+       add_wildcard(alias);
        return 1;
 }
 
@@ -612,9 +632,6 @@ static void do_table(void *symval, unsigned long size,
 
        for (i = 0; i < size; i += id_size) {
                if (do_entry(mod->name, symval+i, alias)) {
-                       /* Always end in a wildcard, for future extension */
-                       if (alias[strlen(alias)-1] != '*')
-                               strcat(alias, "*");
                        buf_printf(&mod->dev_table_buf,
                                   "MODULE_ALIAS(\"%s\");\n", alias);
                }
index 1b50a6ebc55fca85edaa9b7ef6256f31cc07ad4d..1c864c0efe2b90592d0e86a49e7347ff8ad02829 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/ext2_fs.h>
index a78a8d045175bb65b4dc576612e289b36957b898..379bcb074463ead02f154777023bb0c9a02bd8c8 100644 (file)
@@ -5,8 +5,8 @@ menu "Generic devices"
 
 
 config SND_PCSP
-       tristate "Internal PC speaker support"
-       depends on X86_PC && HIGH_RES_TIMERS
+       tristate "PC-Speaker support"
+       depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS
        depends on INPUT
        depends on SND
        select SND_PCM
index 59203511e77d936b8f2bceb78d762fc761c3b602..54a1f9036c665bdee89de479d8cd785711709cc0 100644 (file)
@@ -194,6 +194,7 @@ static void pcsp_stop_beep(struct snd_pcsp *chip)
        spin_unlock_irq(&chip->substream_lock);
 }
 
+#ifdef CONFIG_PM
 static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct snd_pcsp *chip = platform_get_drvdata(dev);
@@ -201,6 +202,9 @@ static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
        snd_pcm_suspend_all(chip->pcm);
        return 0;
 }
+#else
+#define pcsp_suspend NULL
+#endif /* CONFIG_PM */
 
 static void pcsp_shutdown(struct platform_device *dev)
 {
index dfe670f12e67d71117904db746c2a2b8e87af10d..eb9bc365530dde4107f1cf4f9de102bd66dac59b 100644 (file)
@@ -67,7 +67,7 @@ static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id
                return 1;
        
        mem = ioremap(base, 128);
-       if(mem == 0UL)
+       if (!mem)
                return 1;
        map = readw(mem + 0x18);        /* Read the SMI enables */
        iounmap(mem);
index 581debf37dcb711d9f996a52f5b36cb05fdad5cd..7e47421095726afd72650cffe20e2306aebfa252 100644 (file)
@@ -515,19 +515,16 @@ config SND_FM801
 config SND_FM801_TEA575X_BOOL
        bool "ForteMedia FM801 + TEA5757 tuner"
        depends on SND_FM801
+       depends on VIDEO_V4L1=y || VIDEO_V4L1=SND_FM801
        help
          Say Y here to include support for soundcards based on the ForteMedia
          FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
          Forte SF256-PCS-02) into the snd-fm801 driver.
 
-         This will enable support for the old V4L1 API.
-
 config SND_FM801_TEA575X
        tristate
        depends on SND_FM801_TEA575X_BOOL
        default SND_FM801
-       select VIDEO_V4L1
-       select VIDEO_DEV
 
 config SND_HDA_INTEL
        tristate "Intel HD Audio"
index 39198e505b12aabacd6842389647da8dff2c7c68..2da89810ca10fbab1e440aa4a0ae282e61799c42 100644 (file)
@@ -3446,6 +3446,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
 int patch_vt1617a(struct snd_ac97 * ac97)
 {
        int err = 0;
+       int val;
 
        /* we choose to not fail out at this point, but we tell the
           caller when we return */
@@ -3456,7 +3457,13 @@ int patch_vt1617a(struct snd_ac97 * ac97)
        /* bring analog power consumption to normal by turning off the
         * headphone amplifier, like WinXP driver for EPIA SP
         */
-       snd_ac97_write_cache(ac97, 0x5c, 0x20);
+       /* We need to check the bit before writing it.
+        * On some (many?) hardwares, setting bit actually clears it!
+        */
+       val = snd_ac97_read(ac97, 0x5c);
+       if (!(val & 0x20))
+               snd_ac97_write_cache(ac97, 0x5c, 0x20);
+
        ac97->ext_id |= AC97_EI_SPDIF;  /* force the detection of spdif */
        ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
        ac97->build_ops = &patch_vt1616_ops;
index d9783a4263e0bee2a8ae47e01eb7e063e7dea51b..6d4df45e81e033372354d1275a1681bea4e46b73 100644 (file)
@@ -11902,7 +11902,10 @@ static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
                                              hda_nid_t nid,
                                              int pin_type, int dac_idx)
 {
-       alc_set_pin_output(codec, nid, pin_type);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           pin_type);
+       snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           AMP_OUT_UNMUTE);
 }
 
 static void alc861_auto_init_multi_out(struct hda_codec *codec)
index b3a15d616873f42df941a87b941c239e635f1b4a..393f7fd2b1be2eaa4755b9c6b642e5fe42f3a74e 100644 (file)
@@ -4289,6 +4289,8 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
        { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
        { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
        { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
+       { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
+       { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
        /* The following does not take into account .id=0x83847661 when subsys =
         * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
         * currently not fully supported.
index 67c88e322fb1259b5ab265cc385bb0e3a6e31f10..ccac6bd2889c0f56589f2234aa899aeb42b42ff0 100644 (file)
@@ -103,7 +103,8 @@ static void at91_pcm_dma_irq(u32 ssc_sr,
                if (prtd->period_ptr >= prtd->dma_buffer_end) {
                        prtd->period_ptr = prtd->dma_buffer;
                }
-               at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
+               at91_ssc_write(params->ssc_base + params->pdc->xnpr,
+                              prtd->period_ptr);
                at91_ssc_write(params->ssc_base + params->pdc->xncr,
                                prtd->period_size / params->pdc_xfer_size);
        }
@@ -191,10 +192,12 @@ static int at91_pcm_trigger(struct snd_pcm_substream *substream,
                at91_ssc_write(params->ssc_base + AT91_SSC_IER,
                        params->mask->ssc_endx | params->mask->ssc_endbuf);
 
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
+               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
+                       params->mask->pdc_enable);
 
-               DBG("sr=%lx imr=%lx\n", at91_ssc_read(params->ssc_base + AT91_SSC_SR),
-                                       at91_ssc_read(params->ssc_base + AT91_SSC_IER));
+               DBG("sr=%lx imr=%lx\n",
+                   at91_ssc_read(params->ssc_base + AT91_SSC_SR),
+                   at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
index f642d2dd4ec310119deabca184dea7cad7a4c481..bc35d00a38f86b89778bd86953a165d4075dfef2 100644 (file)
@@ -590,7 +590,7 @@ static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
                        printk(KERN_WARNING "at91-ssc: request_irq failure\n");
 
                        DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-                       at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
+                       at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
                        return ret;
                }
 
index 630684f4a0bc5ec1c91741902d9b8d7d3bcc1fa9..09b1661b8a3a3930720947d91cf9a582b642cb0f 100644 (file)
@@ -539,8 +539,8 @@ static const char *intercon[][3] = {
        {"HPRCOM", NULL, "Right HP Com"},
 
        /* Mono Output */
-       {"MONOLOUT", NULL, "Mono Out"},
-       {"MONOLOUT", NULL, "Mono Out"},
+       {"MONO_LOUT", NULL, "Mono Out"},
+       {"MONO_LOUT", NULL, "Mono Out"},
 
        /* Left Input */
        {"Left Line1L Mux", "single-ended", "LINE1L"},
index b2a11b0d2e4c3b9cb6eb17c1dee1ec1743aec48a..f588545698f3687f75941977b8e597791c964e9e 100644 (file)
@@ -416,7 +416,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
                         * to put data into its FIFO.  Without it, ALSA starts
                         * to complain about overruns.
                         */
-                       msleep(1);
+                       mdelay(1);
                }
                break;
 
index 83b1eb4e40f3f6046e6987de1bc4086264c56034..6533563a6011d01ccb71084c136f79d7a1b808d6 100644 (file)
@@ -188,8 +188,8 @@ static const char *audio_map[][3] = {
 static const char *spk_function[] = {"Off", "On"};
 static const char *jack_function[] = {"Off", "Headphone"};
 static const struct soc_enum n810_enum[] = {
-       SOC_ENUM_SINGLE_EXT(2, spk_function),
-       SOC_ENUM_SINGLE_EXT(3, jack_function),
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
 };
 
 static const struct snd_kcontrol_new aic33_n810_controls[] = {
index 4ebcd6a8bf2867d1963ba29deab52b98d2987e38..1ed6afd454591ac9c5cab7b82b13b4105681826e 100644 (file)
@@ -224,6 +224,7 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai,
                iismod |= S3C2410_IISMOD_SLAVE;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
+               iismod &= ~S3C2410_IISMOD_SLAVE;
                break;
        default:
                return -EINVAL;
@@ -234,6 +235,7 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai,
                iismod |= S3C2410_IISMOD_MSB;
                break;
        case SND_SOC_DAIFMT_I2S:
+               iismod &= ~S3C2410_IISMOD_MSB;
                break;
        default:
                return -EINVAL;
index 6c70a81c730cdbf8aea253a4240cd7007c7cfd68..7806ae614617ca13f2c8c3325cf2daa800820f35 100644 (file)
@@ -171,7 +171,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
                ret = s3c2410_dma_request(prtd->params->channel,
                                          prtd->params->client, NULL);
 
-               if (ret) {
+               if (ret < 0) {
                        DBG(KERN_ERR "failed to get dma channel\n");
                        return ret;
                }
index 478369bb38c34118701f08966c0cf2b96f2beab4..b343818dbb964ae3137b7e90c08284ffa03e92c6 100644 (file)
@@ -341,8 +341,12 @@ snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
        case MIDI_CTL_SOFT_PEDAL:
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
                /* FIXME: this is an emulation */
-               snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
+               if (chan->control[type] >= 64)
+                       snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
                                     EMUX_FX_FLAG_ADD);
+               else
+                       snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
+                                    EMUX_FX_FLAG_OFF);
 #endif
                break;
 
index c82cf15730a1e85c751483f75944e8905c0baa10..f7ba099049eaeab16caf69d6bed1afc280a4a712 100644 (file)
@@ -522,6 +522,7 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
                return bad_hva();
        return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE);
 }
+EXPORT_SYMBOL_GPL(gfn_to_hva);
 
 /*
  * Requires current->mm->mmap_sem to be held
@@ -834,16 +835,9 @@ static const struct file_operations kvm_vcpu_fops = {
  */
 static int create_vcpu_fd(struct kvm_vcpu *vcpu)
 {
-       int fd, r;
-       struct inode *inode;
-       struct file *file;
-
-       r = anon_inode_getfd(&fd, &inode, &file,
-                            "kvm-vcpu", &kvm_vcpu_fops, vcpu);
-       if (r) {
+       int fd = anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu);
+       if (fd < 0)
                kvm_put_kvm(vcpu->kvm);
-               return r;
-       }
        return fd;
 }
 
@@ -1168,19 +1162,15 @@ static const struct file_operations kvm_vm_fops = {
 
 static int kvm_dev_ioctl_create_vm(void)
 {
-       int fd, r;
-       struct inode *inode;
-       struct file *file;
+       int fd;
        struct kvm *kvm;
 
        kvm = kvm_create_vm();
        if (IS_ERR(kvm))
                return PTR_ERR(kvm);
-       r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
-       if (r) {
+       fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm);
+       if (fd < 0)
                kvm_put_kvm(kvm);
-               return r;
-       }
 
        return fd;
 }