Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 2 Nov 2009 17:46:06 +0000 (09:46 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 2 Nov 2009 17:46:06 +0000 (09:46 -0800)
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf tools: Remove -Wcast-align
  perf tools: Fix compatibility with libelf 0.8 and autodetect
  perf events: Don't generate events for the idle task when exclude_idle is set
  perf events: Fix swevent hrtimer sampling by keeping track of remaining time when enabling/disabling swevent hrtimers

636 files changed:
Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc [moved from Documentation/ABI/testing/sysfs-class-usb_host with 88% similarity]
Documentation/ABI/testing/sysfs-devices-cache_disable [deleted file]
Documentation/ABI/testing/sysfs-devices-system-cpu [new file with mode: 0644]
Documentation/cputopology.txt
Documentation/debugging-via-ohci1394.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/ext3.txt
Documentation/flexible-arrays.txt
Documentation/hwmon/sysfs-interface
Documentation/lguest/lguest.c
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/trace/ftrace.txt
Documentation/vm/hwpoison.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/arm/configs/n8x0_defconfig
arch/arm/configs/omap3_beagle_defconfig
arch/arm/configs/u300_defconfig
arch/arm/include/asm/bitops.h
arch/arm/include/asm/elf.h
arch/arm/include/asm/tlbflush.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-header.S
arch/arm/kernel/process.c
arch/arm/kernel/traps.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-bcmring/core.c
arch/arm/mach-bcmring/include/mach/system.h
arch/arm/mach-ep93xx/Kconfig
arch/arm/mach-ep93xx/Makefile.boot
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-ep93xx/include/mach/gpio.h
arch/arm/mach-ep93xx/include/mach/memory.h
arch/arm/mach-ep93xx/include/mach/platform.h
arch/arm/mach-ep93xx/micro9.c
arch/arm/mach-mx2/clock_imx27.c
arch/arm/mach-mx2/pcm038.c
arch/arm/mach-mx2/pcm970-baseboard.c
arch/arm/mach-mx25/devices.c
arch/arm/mach-mx25/mx25pdk.c
arch/arm/mach-mx3/clock-imx35.c
arch/arm/mach-mx3/clock.c
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/devices.h
arch/arm/mach-mx3/mm.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/board-zoom2.c
arch/arm/mach-omap2/clock24xx.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/cpufreq-pxa2xx.c
arch/arm/mach-pxa/csb726.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-sa1100/Makefile
arch/arm/mm/Kconfig
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/fault-armv.c
arch/arm/mm/fault.c
arch/arm/mm/highmem.c
arch/arm/mm/init.c
arch/arm/oprofile/op_model_v6.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/include/mach/keypad.h
arch/arm/plat-omap/iommu.c
arch/arm/plat-omap/mcbsp.c
arch/frv/kernel/signal.c
arch/m68k/Kconfig
arch/powerpc/boot/dts/cm5200.dts
arch/powerpc/boot/dts/digsy_mtc.dts
arch/powerpc/boot/dts/lite5200.dts
arch/powerpc/boot/dts/lite5200b.dts
arch/powerpc/boot/dts/media5200.dts
arch/powerpc/boot/dts/motionpro.dts
arch/powerpc/boot/dts/mpc5121ads.dts
arch/powerpc/boot/dts/mucmc52.dts [new file with mode: 0644]
arch/powerpc/boot/dts/pcm030.dts
arch/powerpc/boot/dts/pcm032.dts
arch/powerpc/boot/dts/tqm5200.dts
arch/powerpc/boot/dts/uc101.dts [new file with mode: 0644]
arch/powerpc/configs/52xx/cm5200_defconfig
arch/powerpc/configs/52xx/lite5200b_defconfig
arch/powerpc/configs/52xx/motionpro_defconfig
arch/powerpc/configs/52xx/pcm030_defconfig
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/mpc5200_defconfig
arch/powerpc/configs/ppc64e_defconfig [new file with mode: 0644]
arch/powerpc/include/asm/firmware.h
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/perf_event.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vdso32/vdso32.lds.S
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/mm/slb_low.S
arch/powerpc/platforms/52xx/mpc5200_simple.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/iseries/Makefile
arch/powerpc/platforms/iseries/dt.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/xmon/xmon.c
arch/s390/hypfs/hypfs_diag.c
arch/s390/include/asm/cputime.h
arch/s390/kernel/ipl.c
arch/s390/kernel/processor.c
arch/s390/kernel/smp.c
arch/s390/kernel/swsusp_asm64.S
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/boards/mach-landisk/gio.c
arch/sh/boards/mach-rsk/devices-rsk7203.c
arch/sh/boards/mach-rsk/setup.c
arch/sh/boot/Makefile
arch/sh/kernel/dwarf.c
arch/sh/kernel/entry-common.S
arch/sh/kernel/ftrace.c
arch/sh/kernel/irq.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/signal_32.c
arch/sh/kernel/smp.c
arch/sh/kernel/traps_32.c
arch/sh/mm/Kconfig
arch/sh/mm/cache-sh4.c
arch/sh/mm/cache.c
arch/sparc/kernel/ldc.c
arch/sparc/kernel/perf_event.c
arch/sparc/mm/init_64.c
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/Makefile
arch/x86/boot/setup.ld
arch/x86/crypto/aesni-intel_glue.c
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/topology.h
arch/x86/include/asm/uv/uv_hub.h
arch/x86/kernel/acpi/realmode/wakeup.lds.S
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/crash_dump_32.c
arch/x86/kernel/efi.c
arch/x86/kernel/irq.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/smp.c
arch/x86/kernel/time.c
arch/x86/kernel/tlb_uv.c
arch/x86/kernel/trampoline.c
arch/x86/kernel/trampoline_64.S
arch/x86/kernel/vmi_32.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/kvm/i8254.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/xen/enlighten.c
block/blk-core.c
block/blk-merge.c
block/blk-settings.c
block/blk-tag.c
block/cfq-iosched.c
block/elevator.c
block/genhd.c
crypto/async_tx/async_pq.c
crypto/async_tx/async_raid6_recov.c
crypto/async_tx/async_xor.c
drivers/acpi/Kconfig
drivers/acpi/ac.c
drivers/acpi/button.c
drivers/acpi/pci_root.c
drivers/acpi/video.c
drivers/acpi/video_detect.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_via.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/base/bus.c
drivers/base/driver.c
drivers/base/platform.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/block/virtio_blk.c
drivers/char/Kconfig
drivers/char/genrtc.c
drivers/char/hw_random/virtio-rng.c
drivers/char/rtc.c
drivers/char/sonypi.c
drivers/char/tty_buffer.c
drivers/char/virtio_console.c
drivers/char/vt_ioctl.c
drivers/cpuidle/cpuidle.c
drivers/crypto/padlock-sha.c
drivers/edac/amd64_edac.c
drivers/edac/i5000_edac.c
drivers/edac/i5400_edac.c
drivers/edac/mpc85xx_edac.c
drivers/firewire/sbp2.c
drivers/gpio/twl4030-gpio.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/hid/hid-core.c
drivers/hid/hid-twinhan.c
drivers/hid/hidraw.c
drivers/hwmon/dme1737.c
drivers/hwmon/fschmd.c
drivers/hwmon/hp_accel.c
drivers/hwmon/it87.c
drivers/ide/atiixp.c
drivers/ide/cmd64x.c
drivers/input/input.c
drivers/input/keyboard/atkbd.c
drivers/input/misc/hp_sdc_rtc.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/synaptics.c
drivers/input/serio/i8042-x86ia64io.h
drivers/isdn/i4l/isdn_net.h
drivers/macintosh/via-pmu.c
drivers/md/Makefile
drivers/md/bitmap.c
drivers/md/dm-exception-store.c
drivers/md/dm-exception-store.h
drivers/md/dm-log-userspace-base.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-snap.c
drivers/md/dm.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid5.h
drivers/md/raid6altivec.uc
drivers/md/raid6int.uc
drivers/md/raid6test/Makefile
drivers/md/unroll.awk [new file with mode: 0644]
drivers/md/unroll.pl [deleted file]
drivers/mfd/twl4030-core.c
drivers/mfd/wm831x-irq.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/pxamci.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/scan.h
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/acenic.c
drivers/net/au1000_eth.c
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_main.c
drivers/net/bnx2.h
drivers/net/bonding/bond_main.c
drivers/net/can/sja1000/sja1000_of_platform.c
drivers/net/cnic.c
drivers/net/davinci_emac.c
drivers/net/dm9000.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/phy.c
drivers/net/ethoc.c
drivers/net/fec.c
drivers/net/fec_mpc52xx.c
drivers/net/fec_mpc52xx_phy.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/mii-bitbang.c
drivers/net/fs_enet/mii-fec.c
drivers/net/fsl_pq_mdio.c
drivers/net/gianfar.c
drivers/net/ibm_newemac/core.c
drivers/net/ibm_newemac/emac.h
drivers/net/ifb.c
drivers/net/igb/igb_ethtool.c
drivers/net/igbvf/ethtool.c
drivers/net/irda/sa1100_ir.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixp2000/enp2611.c
drivers/net/ixp2000/ixpdev.c
drivers/net/ks8851.c
drivers/net/ks8851.h
drivers/net/mlx4/main.c
drivers/net/myri10ge/myri10ge.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/niu.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/phy/mdio-gpio.c
drivers/net/pppoe.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r8169.c
drivers/net/sfc/rx.c
drivers/net/sh_eth.c
drivers/net/stmmac/Kconfig [new file with mode: 0644]
drivers/net/stmmac/Makefile [new file with mode: 0644]
drivers/net/stmmac/common.h [new file with mode: 0644]
drivers/net/stmmac/descs.h [new file with mode: 0644]
drivers/net/stmmac/gmac.c [new file with mode: 0644]
drivers/net/stmmac/gmac.h [new file with mode: 0644]
drivers/net/stmmac/mac100.c [new file with mode: 0644]
drivers/net/stmmac/mac100.h [new file with mode: 0644]
drivers/net/stmmac/stmmac.h [new file with mode: 0644]
drivers/net/stmmac/stmmac_ethtool.c [new file with mode: 0644]
drivers/net/stmmac/stmmac_main.c [new file with mode: 0644]
drivers/net/stmmac/stmmac_mdio.c [new file with mode: 0644]
drivers/net/stmmac/stmmac_timer.c [new file with mode: 0644]
drivers/net/stmmac/stmmac_timer.h [new file with mode: 0644]
drivers/net/usb/dm9601.c
drivers/net/usb/pegasus.c
drivers/net/usb/pegasus.h
drivers/net/usb/rndis_host.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/Makefile [new file with mode: 0644]
drivers/net/vmxnet3/upt1_defs.h [new file with mode: 0644]
drivers/net/vmxnet3/vmxnet3_defs.h [new file with mode: 0644]
drivers/net/vmxnet3/vmxnet3_drv.c [new file with mode: 0644]
drivers/net/vmxnet3/vmxnet3_ethtool.c [new file with mode: 0644]
drivers/net/vmxnet3/vmxnet3_int.h [new file with mode: 0644]
drivers/net/wan/c101.c
drivers/net/wan/hdlc_cisco.c
drivers/net/wan/n2.c
drivers/net/wan/pci200syn.c
drivers/net/wireless/adm8211.h
drivers/net/wireless/airo.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/leds.c
drivers/net/wireless/b43/leds.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/znet.c
drivers/of/of_mdio.c
drivers/oprofile/event_buffer.c
drivers/pci/dmar.c
drivers/pci/hotplug/cpqphp.h
drivers/pci/intel-iommu.c
drivers/pci/pci.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/quirks.c
drivers/pci/setup-res.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/socket_sysfs.c
drivers/pcmcia/tcic.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/fujitsu-laptop.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_eckd.c
drivers/s390/char/sclp_async.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tape_block.c
drivers/s390/cio/device.c
drivers/s390/net/smsgiucv.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_ext.h
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_sysfs.c
drivers/scsi/dpt_i2o.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/serial/8250_pci.c
drivers/serial/atmel_serial.c
drivers/serial/mpc52xx_uart.c
drivers/serial/serial_core.c
drivers/spi/amba-pl022.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/Kconfig
drivers/staging/b3dfg/b3dfg.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/et131x/et1310_address_map.h
drivers/staging/et131x/et1310_rx.c
drivers/staging/hv/ChannelMgmt.h
drivers/staging/hv/NetVsc.c
drivers/staging/hv/TODO
drivers/staging/hv/osd.c
drivers/staging/hv/osd.h
drivers/staging/hv/vmbus_drv.c
drivers/staging/iio/industrialio-core.c
drivers/staging/otus/Kconfig
drivers/staging/panel/panel.c
drivers/staging/poch/poch.c
drivers/staging/rt2860/Kconfig
drivers/staging/rt2860/common/cmm_data_2860.c
drivers/staging/rt2860/common/cmm_info.c
drivers/staging/rt2860/rt_linux.c
drivers/staging/rt2870/Kconfig
drivers/staging/rt3090/Kconfig
drivers/staging/rt3090/common/cmm_info.c
drivers/staging/rt3090/rt_linux.c
drivers/staging/rtl8187se/Kconfig
drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192e/Kconfig
drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192su/Kconfig
drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
drivers/staging/sep/sep_driver.c
drivers/staging/stlc45xx/Kconfig [deleted file]
drivers/staging/stlc45xx/Makefile [deleted file]
drivers/staging/stlc45xx/stlc45xx.c [deleted file]
drivers/staging/stlc45xx/stlc45xx.h [deleted file]
drivers/staging/stlc45xx/stlc45xx_lmac.h [deleted file]
drivers/staging/vme/bridges/vme_ca91cx42.c
drivers/staging/vme/bridges/vme_tsi148.c
drivers/staging/vt6656/main_usb.c
drivers/staging/winbond/Kconfig
drivers/staging/wlan-ng/Kconfig
drivers/usb/gadget/Kconfig
drivers/usb/gadget/ether.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/whci/asl.c
drivers/usb/host/whci/pzl.c
drivers/usb/musb/Kconfig
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
drivers/usb/storage/transport.c
drivers/usb/wusbcore/security.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_pci.c
drivers/virtio/virtio_ring.c
drivers/watchdog/riowd.c
fs/Kconfig
fs/block_dev.c
fs/btrfs/acl.c
fs/btrfs/btrfs_inode.h
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/tree-log.c
fs/btrfs/tree-log.h
fs/btrfs/xattr.c
fs/cifs/connect.c
fs/dlm/lowcomms.c
fs/ext3/super.c
fs/hfs/btree.c
fs/hfsplus/wrapper.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
fs/notify/dnotify/dnotify.c
fs/notify/inode_mark.c
fs/notify/notification.c
fs/partitions/check.c
fs/pipe.c
fs/proc/meminfo.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/xfs/linux-2.6/xfs_quotaops.c
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/xfs_ialloc.c
include/linux/Kbuild
include/linux/blkdev.h
include/linux/cpufreq.h
include/linux/device.h
include/linux/genhd.h
include/linux/kernel.h
include/linux/moduleparam.h
include/linux/netdevice.h
include/linux/pci_ids.h
include/linux/prctl.h
include/linux/rcutree.h
include/linux/string.h
include/linux/topology.h
include/linux/trace_seq.h
include/linux/virtio_9p.h
include/linux/virtio_balloon.h
include/linux/virtio_blk.h
include/linux/virtio_console.h
include/linux/virtio_net.h
include/linux/virtio_rng.h
include/linux/workqueue.h
include/net/inet_timewait_sock.h
include/net/mac80211.h
include/net/sock.h
init/Kconfig
kernel/cgroup.c
kernel/exit.c
kernel/futex.c
kernel/lockdep.c
kernel/params.c
kernel/power/suspend_test.c
kernel/rcutree.c
kernel/rcutree.h
kernel/rcutree_plugin.h
kernel/sched.c
kernel/sched_fair.c
kernel/sys.c
kernel/sysctl_check.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_output.c
kernel/workqueue.c
lib/Kconfig.debug
mm/Kconfig
mm/backing-dev.c
mm/memory-failure.c
mm/memory.c
mm/mempolicy.c
mm/nommu.c
mm/page-writeback.c
mm/page_alloc.c
mm/percpu.c
mm/swapfile.c
mm/vmscan.c
net/9p/trans_virtio.c
net/bluetooth/hci_sysfs.c
net/bluetooth/l2cap.c
net/core/pktgen.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_sockglue.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_minisocks.c
net/ipv4/udp.c
net/ipv6/ipv6_sockglue.c
net/mac80211/ibss.c
net/mac80211/mesh_hwmp.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/mac80211/util.c
net/packet/af_packet.c
net/sched/act_pedit.c
net/sched/cls_api.c
net/unix/af_unix.c
net/wireless/core.h
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/sme.c
scripts/Kbuild.include
scripts/Makefile.lib
scripts/checkkconfigsymbols.sh
scripts/checkpatch.pl
scripts/get_maintainer.pl
scripts/headers_install.pl
scripts/mkcompile_h
scripts/package/Makefile
scripts/package/mkspec
security/keys/keyctl.c
sound/arm/aaci.c
sound/pci/bt87x.c
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/ice1712/amp.c
sound/pci/ice1712/ice1724.c
sound/ppc/Kconfig
virt/kvm/kvm_main.c

@@ -1,4 +1,4 @@
-What:           /sys/class/usb_host/usb_hostN/wusb_chid
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_chid
 Date:           July 2008
 KernelVersion:  2.6.27
 Contact:        David Vrabel <david.vrabel@csr.com>
@@ -9,7 +9,7 @@ Description:
 
                 Set an all zero CHID to stop the host controller.
 
-What:           /sys/class/usb_host/usb_hostN/wusb_trust_timeout
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_trust_timeout
 Date:           July 2008
 KernelVersion:  2.6.27
 Contact:        David Vrabel <david.vrabel@csr.com>
diff --git a/Documentation/ABI/testing/sysfs-devices-cache_disable b/Documentation/ABI/testing/sysfs-devices-cache_disable
deleted file mode 100644 (file)
index 175bb4f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-What:      /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
-Date:      August 2008
-KernelVersion: 2.6.27
-Contact:       mark.langsdorf@amd.com
-Description:   These files exist in every cpu's cache index directories.
-               There are currently 2 cache_disable_# files in each
-               directory.  Reading from these files on a supported
-               processor will return that cache disable index value
-               for that processor and node.  Writing to one of these
-               files will cause the specificed cache index to be disabled.
-
-               Currently, only AMD Family 10h Processors support cache index
-               disable, and only for their L3 caches.  See the BIOS and
-               Kernel Developer's Guide at
-               http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
-               for formatting information and other details on the
-               cache index disable.
-Users:    joachim.deguara@amd.com
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
new file mode 100644 (file)
index 0000000..a703b9e
--- /dev/null
@@ -0,0 +1,156 @@
+What:          /sys/devices/system/cpu/
+Date:          pre-git history
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:
+               A collection of both global and individual CPU attributes
+
+               Individual CPU attributes are contained in subdirectories
+               named by the kernel's logical CPU number, e.g.:
+
+               /sys/devices/system/cpu/cpu#/
+
+What:          /sys/devices/system/cpu/sched_mc_power_savings
+               /sys/devices/system/cpu/sched_smt_power_savings
+Date:          June 2006
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:   Discover and adjust the kernel's multi-core scheduler support.
+
+               Possible values are:
+
+               0 - No power saving load balance (default value)
+               1 - Fill one thread/core/package first for long running threads
+               2 - Also bias task wakeups to semi-idle cpu package for power
+                   savings
+
+               sched_mc_power_savings is dependent upon SCHED_MC, which is
+               itself architecture dependent.
+
+               sched_smt_power_savings is dependent upon SCHED_SMT, which
+               is itself architecture dependent.
+
+               The two files are independent of each other. It is possible
+               that one file may be present without the other.
+
+               Introduced by git commit 5c45bf27.
+
+
+What:          /sys/devices/system/cpu/kernel_max
+               /sys/devices/system/cpu/offline
+               /sys/devices/system/cpu/online
+               /sys/devices/system/cpu/possible
+               /sys/devices/system/cpu/present
+Date:          December 2008
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:   CPU topology files that describe kernel limits related to
+               hotplug. Briefly:
+
+               kernel_max: the maximum cpu index allowed by the kernel
+               configuration.
+
+               offline: cpus that are not online because they have been
+               HOTPLUGGED off or exceed the limit of cpus allowed by the
+               kernel configuration (kernel_max above).
+
+               online: cpus that are online and being scheduled.
+
+               possible: cpus that have been allocated resources and can be
+               brought online if they are present.
+
+               present: cpus that have been identified as being present in
+               the system.
+
+               See Documentation/cputopology.txt for more information.
+
+
+
+What:          /sys/devices/system/cpu/cpu#/node
+Date:          October 2009
+Contact:       Linux memory management mailing list <linux-mm@kvack.org>
+Description:   Discover NUMA node a CPU belongs to
+
+               When CONFIG_NUMA is enabled, a symbolic link that points
+               to the corresponding NUMA node directory.
+
+               For example, the following symlink is created for cpu42
+               in NUMA node 2:
+
+               /sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
+
+
+What:          /sys/devices/system/cpu/cpu#/topology/core_id
+               /sys/devices/system/cpu/cpu#/topology/core_siblings
+               /sys/devices/system/cpu/cpu#/topology/core_siblings_list
+               /sys/devices/system/cpu/cpu#/topology/physical_package_id
+               /sys/devices/system/cpu/cpu#/topology/thread_siblings
+               /sys/devices/system/cpu/cpu#/topology/thread_siblings_list
+Date:          December 2008
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:   CPU topology files that describe a logical CPU's relationship
+               to other cores and threads in the same physical package.
+
+               One cpu# directory is created per logical CPU in the system,
+               e.g. /sys/devices/system/cpu/cpu42/.
+
+               Briefly, the files above are:
+
+               core_id: the CPU core ID of cpu#. Typically it is the
+               hardware platform's identifier (rather than the kernel's).
+               The actual value is architecture and platform dependent.
+
+               core_siblings: internal kernel map of cpu#'s hardware threads
+               within the same physical_package_id.
+
+               core_siblings_list: human-readable list of the logical CPU
+               numbers within the same physical_package_id as cpu#.
+
+               physical_package_id: physical package id of cpu#. Typically
+               corresponds to a physical socket number, but the actual value
+               is architecture and platform dependent.
+
+               thread_siblings: internel kernel map of cpu#'s hardware
+               threads within the same core as cpu#
+
+               thread_siblings_list: human-readable list of cpu#'s hardware
+               threads within the same core as cpu#
+
+               See Documentation/cputopology.txt for more information.
+
+
+What:          /sys/devices/system/cpu/cpuidle/current_driver
+               /sys/devices/system/cpu/cpuidle/current_governer_ro
+Date:          September 2007
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:   Discover cpuidle policy and mechanism
+
+               Various CPUs today support multiple idle levels that are
+               differentiated by varying exit latencies and power
+               consumption during idle.
+
+               Idle policy (governor) is differentiated from idle mechanism
+               (driver)
+
+               current_driver: displays current idle mechanism
+
+               current_governor_ro: displays current idle policy
+
+               See files in Documentation/cpuidle/ for more information.
+
+
+What:      /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
+Date:      August 2008
+KernelVersion: 2.6.27
+Contact:       mark.langsdorf@amd.com
+Description:   These files exist in every cpu's cache index directories.
+               There are currently 2 cache_disable_# files in each
+               directory.  Reading from these files on a supported
+               processor will return that cache disable index value
+               for that processor and node.  Writing to one of these
+               files will cause the specificed cache index to be disabled.
+
+               Currently, only AMD Family 10h Processors support cache index
+               disable, and only for their L3 caches.  See the BIOS and
+               Kernel Developer's Guide at
+               http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
+               for formatting information and other details on the
+               cache index disable.
+Users:    joachim.deguara@amd.com
index b41f3e5..f1c5c4b 100644 (file)
@@ -1,15 +1,28 @@
 
-Export cpu topology info via sysfs. Items (attributes) are similar
+Export CPU topology info via sysfs. Items (attributes) are similar
 to /proc/cpuinfo.
 
 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id:
-represent the physical package id of  cpu X;
+
+       physical package id of cpuX. Typically corresponds to a physical
+       socket number, but the actual value is architecture and platform
+       dependent.
+
 2) /sys/devices/system/cpu/cpuX/topology/core_id:
-represent the cpu core id to cpu X;
+
+       the CPU core ID of cpuX. Typically it is the hardware platform's
+       identifier (rather than the kernel's).  The actual value is
+       architecture and platform dependent.
+
 3) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
-represent the thread siblings to cpu X in the same core;
+
+       internel kernel map of cpuX's hardware threads within the same
+       core as cpuX
+
 4) /sys/devices/system/cpu/cpuX/topology/core_siblings:
-represent the thread siblings to cpu X in the same physical package;
+
+       internal kernel map of cpuX's hardware threads within the same
+       physical_package_id.
 
 To implement it in an architecture-neutral way, a new source file,
 drivers/base/topology.c, is to export the 4 attributes.
@@ -32,32 +45,32 @@ not defined by include/asm-XXX/topology.h:
 3) thread_siblings: just the given CPU
 4) core_siblings: just the given CPU
 
-Additionally, cpu topology information is provided under
+Additionally, CPU topology information is provided under
 /sys/devices/system/cpu and includes these files.  The internal
 source for the output is in brackets ("[]").
 
-    kernel_max: the maximum cpu index allowed by the kernel configuration.
+    kernel_max: the maximum CPU index allowed by the kernel configuration.
                [NR_CPUS-1]
 
-    offline:   cpus that are not online because they have been
+    offline:   CPUs that are not online because they have been
                HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit
-               of cpus allowed by the kernel configuration (kernel_max
+               of CPUs allowed by the kernel configuration (kernel_max
                above). [~cpu_online_mask + cpus >= NR_CPUS]
 
-    online:    cpus that are online and being scheduled [cpu_online_mask]
+    online:    CPUs that are online and being scheduled [cpu_online_mask]
 
-    possible:  cpus that have been allocated resources and can be
+    possible:  CPUs that have been allocated resources and can be
                brought online if they are present. [cpu_possible_mask]
 
-    present:   cpus that have been identified as being present in the
+    present:   CPUs that have been identified as being present in the
                system. [cpu_present_mask]
 
 The format for the above output is compatible with cpulist_parse()
 [see <linux/cpumask.h>].  Some examples follow.
 
-In this example, there are 64 cpus in the system but cpus 32-63 exceed
+In this example, there are 64 CPUs in the system but cpus 32-63 exceed
 the kernel max which is limited to 0..31 by the NR_CPUS config option
-being 32.  Note also that cpus 2 and 4-31 are not online but could be
+being 32.  Note also that CPUs 2 and 4-31 are not online but could be
 brought online as they are both present and possible.
 
      kernel_max: 31
@@ -67,8 +80,8 @@ brought online as they are both present and possible.
         present: 0-31
 
 In this example, the NR_CPUS config option is 128, but the kernel was
-started with possible_cpus=144.  There are 4 cpus in the system and cpu2
-was manually taken offline (and is the only cpu that can be brought
+started with possible_cpus=144.  There are 4 CPUs in the system and cpu2
+was manually taken offline (and is the only CPU that can be brought
 online.)
 
      kernel_max: 127
@@ -78,4 +91,4 @@ online.)
         present: 0-3
 
 See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter
-as well as more information on the various cpumask's.
+as well as more information on the various cpumasks.
index 59a91e5..611f5a5 100644 (file)
@@ -64,14 +64,14 @@ be used to view the printk buffer of a remote machine, even with live update.
 
 Bernhard Kaindl enhanced firescope to support accessing 64-bit machines
 from 32-bit firescope and vice versa:
-- ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2
+- http://halobates.de/firewire/firescope-0.2.2.tar.bz2
 
 and he implemented fast system dump (alpha version - read README.txt):
-- ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2
+- http://halobates.de/firewire/firedump-0.1.tar.bz2
 
 There is also a gdb proxy for firewire which allows to use gdb to access
 data which can be referenced from symbols found by gdb in vmlinux:
-- ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2
+- http://halobates.de/firewire/fireproxy-0.33.tar.bz2
 
 The latest version of this gdb proxy (fireproxy-0.34) can communicate (not
 yet stable) with kgdb over an memory-based communication module (kgdbom).
@@ -178,7 +178,7 @@ Step-by-step instructions for using firescope with early OHCI initialization:
 
 Notes
 -----
-Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs
+Documentation and specifications: http://halobates.de/firewire/
 
 FireWire is a trademark of Apple Inc. - for more information please refer to:
 http://en.wikipedia.org/wiki/FireWire
index 89a47b5..bc693ff 100644 (file)
@@ -418,6 +418,14 @@ When:      2.6.33
 Why:   Should be implemented in userspace, policy daemon.
 Who:   Johannes Berg <johannes@sipsolutions.net>
 
+---------------------------
+
+What:  CONFIG_INOTIFY
+When:  2.6.33
+Why:   last user (audit) will be converted to the newer more generic
+       and more easily maintained fsnotify subsystem
+Who:   Eric Paris <eparis@redhat.com>
+
 ----------------------------
 
 What:  lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
@@ -451,3 +459,33 @@ Why:       OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR
        will also allow making ALSA OSS emulation independent of
        sound_core.  The dependency will be broken then too.
 Who:   Tejun Heo <tj@kernel.org>
+
+----------------------------
+
+What:  Support for VMware's guest paravirtuliazation technique [VMI] will be
+       dropped.
+When:  2.6.37 or earlier.
+Why:   With the recent innovations in CPU hardware acceleration technologies
+       from Intel and AMD, VMware ran a few experiments to compare these
+       techniques to guest paravirtualization technique on VMware's platform.
+       These hardware assisted virtualization techniques have outperformed the
+       performance benefits provided by VMI in most of the workloads. VMware
+       expects that these hardware features will be ubiquitous in a couple of
+       years, as a result, VMware has started a phased retirement of this
+       feature from the hypervisor. We will be removing this feature from the
+       Kernel too. Right now we are targeting 2.6.37 but can retire earlier if
+       technical reasons (read opportunity to remove major chunk of pvops)
+       arise.
+
+       Please note that VMI has always been an optimization and non-VMI kernels
+       still work fine on VMware's platform.
+       Latest versions of VMware's product which support VMI are,
+       Workstation 7.0 and VSphere 4.0 on ESX side, future maintainence
+       releases for these products will continue supporting VMI.
+
+       For more details about VMI retirement take a look at this,
+       http://blogs.vmware.com/guestosguide/2009/09/vmi-retirement.html
+
+Who:   Alok N Kataria <akataria@vmware.com>
+
+----------------------------
index 570f9bd..05d5cf1 100644 (file)
@@ -123,10 +123,18 @@ resuid=n          The user ID which may use the reserved blocks.
 
 sb=n                   Use alternate superblock at this location.
 
-quota
-noquota
-grpquota
-usrquota
+quota                  These options are ignored by the filesystem. They
+noquota                        are used only by quota tools to recognize volumes
+grpquota               where quota should be turned on. See documentation
+usrquota               in the quota-tools package for more details
+                       (http://sourceforge.net/projects/linuxquota).
+
+jqfmt=<quota type>     These options tell filesystem details about quota
+usrjquota=<file>       so that quota information can be properly updated
+grpjquota=<file>       during journal replay. They replace the above
+                       quota options. See documentation in the quota-tools
+                       package for more details
+                       (http://sourceforge.net/projects/linuxquota).
 
 bh             (*)     ext3 associates buffer heads to data pages to
 nobh                   (a) cache disk block mapping information
index 84eb268..cb8a3a0 100644 (file)
@@ -1,5 +1,5 @@
 Using flexible arrays in the kernel
-Last updated for 2.6.31
+Last updated for 2.6.32
 Jonathan Corbet <corbet@lwn.net>
 
 Large contiguous memory allocations can be unreliable in the Linux kernel.
@@ -40,6 +40,13 @@ argument is passed directly to the internal memory allocation calls.  With
 the current code, using flags to ask for high memory is likely to lead to
 notably unpleasant side effects.
 
+It is also possible to define flexible arrays at compile time with:
+
+    DEFINE_FLEX_ARRAY(name, element_size, total);
+
+This macro will result in a definition of an array with the given name; the
+element size and total will be checked for validity at compile time.
+
 Storing data into a flexible array is accomplished with a call to:
 
     int flex_array_put(struct flex_array *array, unsigned int element_nr,
@@ -76,16 +83,30 @@ particular element has never been allocated.
 Note that it is possible to get back a valid pointer for an element which
 has never been stored in the array.  Memory for array elements is allocated
 one page at a time; a single allocation could provide memory for several
-adjacent elements.  The flexible array code does not know if a specific
-element has been written; it only knows if the associated memory is
-present.  So a flex_array_get() call on an element which was never stored
-in the array has the potential to return a pointer to random data.  If the
-caller does not have a separate way to know which elements were actually
-stored, it might be wise, at least, to add GFP_ZERO to the flags argument
-to ensure that all elements are zeroed.
-
-There is no way to remove a single element from the array.  It is possible,
-though, to remove all elements with a call to:
+adjacent elements.  Flexible array elements are normally initialized to the
+value FLEX_ARRAY_FREE (defined as 0x6c in <linux/poison.h>), so errors
+involving that number probably result from use of unstored array entries.
+Note that, if array elements are allocated with __GFP_ZERO, they will be
+initialized to zero and this poisoning will not happen.
+
+Individual elements in the array can be cleared with:
+
+    int flex_array_clear(struct flex_array *array, unsigned int element_nr);
+
+This function will set the given element to FLEX_ARRAY_FREE and return
+zero.  If storage for the indicated element is not allocated for the array,
+flex_array_clear() will return -EINVAL instead.  Note that clearing an
+element does not release the storage associated with it; to reduce the
+allocated size of an array, call:
+
+    int flex_array_shrink(struct flex_array *array);
+
+The return value will be the number of pages of memory actually freed.
+This function works by scanning the array for pages containing nothing but
+FLEX_ARRAY_FREE bytes, so (1) it can be expensive, and (2) it will not work
+if the array's pages are allocated with __GFP_ZERO.
+
+It is possible to remove all elements of an array with a call to:
 
     void flex_array_free_parts(struct flex_array *array);
 
index dcbd502..82def88 100644 (file)
@@ -353,10 +353,20 @@ power[1-*]_average                Average power use
                                Unit: microWatt
                                RO
 
-power[1-*]_average_interval    Power use averaging interval
+power[1-*]_average_interval    Power use averaging interval.  A poll
+                               notification is sent to this file if the
+                               hardware changes the averaging interval.
                                Unit: milliseconds
                                RW
 
+power[1-*]_average_interval_max        Maximum power use averaging interval
+                               Unit: milliseconds
+                               RO
+
+power[1-*]_average_interval_min        Minimum power use averaging interval
+                               Unit: milliseconds
+                               RO
+
 power[1-*]_average_highest     Historical average maximum power use
                                Unit: microWatt
                                RO
@@ -365,6 +375,18 @@ power[1-*]_average_lowest  Historical average minimum power use
                                Unit: microWatt
                                RO
 
+power[1-*]_average_max         A poll notification is sent to
+                               power[1-*]_average when power use
+                               rises above this value.
+                               Unit: microWatt
+                               RW
+
+power[1-*]_average_min         A poll notification is sent to
+                               power[1-*]_average when power use
+                               sinks below this value.
+                               Unit: microWatt
+                               RW
+
 power[1-*]_input               Instantaneous power use
                                Unit: microWatt
                                RO
@@ -381,6 +403,39 @@ power[1-*]_reset_history   Reset input_highest, input_lowest,
                                average_highest and average_lowest.
                                WO
 
+power[1-*]_accuracy            Accuracy of the power meter.
+                               Unit: Percent
+                               RO
+
+power[1-*]_alarm               1 if the system is drawing more power than the
+                               cap allows; 0 otherwise.  A poll notification is
+                               sent to this file when the power use exceeds the
+                               cap.  This file only appears if the cap is known
+                               to be enforced by hardware.
+                               RO
+
+power[1-*]_cap                 If power use rises above this limit, the
+                               system should take action to reduce power use.
+                               A poll notification is sent to this file if the
+                               cap is changed by the hardware.  The *_cap
+                               files only appear if the cap is known to be
+                               enforced by hardware.
+                               Unit: microWatt
+                               RW
+
+power[1-*]_cap_hyst            Margin of hysteresis built around capping and
+                               notification.
+                               Unit: microWatt
+                               RW
+
+power[1-*]_cap_max             Maximum cap that can be set.
+                               Unit: microWatt
+                               RO
+
+power[1-*]_cap_min             Minimum cap that can be set.
+                               Unit: microWatt
+                               RO
+
 **********
 * Energy *
 **********
index ba9373f..098de5b 100644 (file)
@@ -42,7 +42,6 @@
 #include <signal.h>
 #include "linux/lguest_launcher.h"
 #include "linux/virtio_config.h"
-#include <linux/virtio_ids.h>
 #include "linux/virtio_net.h"
 #include "linux/virtio_blk.h"
 #include "linux/virtio_console.h"
index 75fddb4..4c7f9ae 100644 (file)
@@ -359,6 +359,7 @@ STAC9227/9228/9229/927x
   5stack-no-fp D965 5stack without front panel
   dell-3stack  Dell Dimension E520
   dell-bios    Fixes with Dell BIOS setup
+  volknob      Fixes with volume-knob widget 0x24
   auto         BIOS setup (default)
 
 STAC92HD71B*
index 957b22f..8179692 100644 (file)
@@ -1231,6 +1231,7 @@ something like this simple program:
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <string.h>
 
 #define _STR(x) #x
 #define STR(x) _STR(x)
@@ -1265,6 +1266,7 @@ const char *find_debugfs(void)
                return NULL;
        }
 
+       strcat(debugfs, "/tracing/");
        debugfs_found = 1;
 
        return debugfs;
diff --git a/Documentation/vm/hwpoison.txt b/Documentation/vm/hwpoison.txt
new file mode 100644 (file)
index 0000000..3ffadf8
--- /dev/null
@@ -0,0 +1,136 @@
+What is hwpoison?
+
+Upcoming Intel CPUs have support for recovering from some memory errors
+(``MCA recovery''). This requires the OS to declare a page "poisoned",
+kill the processes associated with it and avoid using it in the future.
+
+This patchkit implements the necessary infrastructure in the VM.
+
+To quote the overview comment:
+
+ * High level machine check handler. Handles pages reported by the
+ * hardware as being corrupted usually due to a 2bit ECC memory or cache
+ * failure.
+ *
+ * This focusses on pages detected as corrupted in the background.
+ * When the current CPU tries to consume corruption the currently
+ * running process can just be killed directly instead. This implies
+ * that if the error cannot be handled for some reason it's safe to
+ * just ignore it because no corruption has been consumed yet. Instead
+ * when that happens another machine check will happen.
+ *
+ * Handles page cache pages in various states. The tricky part
+ * here is that we can access any page asynchronous to other VM
+ * users, because memory failures could happen anytime and anywhere,
+ * possibly violating some of their assumptions. This is why this code
+ * has to be extremely careful. Generally it tries to use normal locking
+ * rules, as in get the standard locks, even if that means the
+ * error handling takes potentially a long time.
+ *
+ * Some of the operations here are somewhat inefficient and have non
+ * linear algorithmic complexity, because the data structures have not
+ * been optimized for this case. This is in particular the case
+ * for the mapping from a vma to a process. Since this case is expected
+ * to be rare we hope we can get away with this.
+
+The code consists of a the high level handler in mm/memory-failure.c,
+a new page poison bit and various checks in the VM to handle poisoned
+pages.
+
+The main target right now is KVM guests, but it works for all kinds
+of applications. KVM support requires a recent qemu-kvm release.
+
+For the KVM use there was need for a new signal type so that
+KVM can inject the machine check into the guest with the proper
+address. This in theory allows other applications to handle
+memory failures too. The expection is that near all applications
+won't do that, but some very specialized ones might.
+
+---
+
+There are two (actually three) modi memory failure recovery can be in:
+
+vm.memory_failure_recovery sysctl set to zero:
+       All memory failures cause a panic. Do not attempt recovery.
+       (on x86 this can be also affected by the tolerant level of the
+       MCE subsystem)
+
+early kill
+       (can be controlled globally and per process)
+       Send SIGBUS to the application as soon as the error is detected
+       This allows applications who can process memory errors in a gentle
+       way (e.g. drop affected object)
+       This is the mode used by KVM qemu.
+
+late kill
+       Send SIGBUS when the application runs into the corrupted page.
+       This is best for memory error unaware applications and default
+       Note some pages are always handled as late kill.
+
+---
+
+User control:
+
+vm.memory_failure_recovery
+       See sysctl.txt
+
+vm.memory_failure_early_kill
+       Enable early kill mode globally
+
+PR_MCE_KILL
+       Set early/late kill mode/revert to system default
+       arg1: PR_MCE_KILL_CLEAR: Revert to system default
+       arg1: PR_MCE_KILL_SET: arg2 defines thread specific mode
+               PR_MCE_KILL_EARLY: Early kill
+               PR_MCE_KILL_LATE:  Late kill
+               PR_MCE_KILL_DEFAULT: Use system global default
+PR_MCE_KILL_GET
+       return current mode
+
+
+---
+
+Testing:
+
+madvise(MADV_POISON, ....)
+       (as root)
+       Poison a page in the process for testing
+
+
+hwpoison-inject module through debugfs
+       /sys/debug/hwpoison/corrupt-pfn
+
+Inject hwpoison fault at PFN echoed into this file
+
+
+Architecture specific MCE injector
+
+x86 has mce-inject, mce-test
+
+Some portable hwpoison test programs in mce-test, see blow.
+
+---
+
+References:
+
+http://halobates.de/mce-lc09-2.pdf
+       Overview presentation from LinuxCon 09
+
+git://git.kernel.org/pub/scm/utils/cpu/mce/mce-test.git
+       Test suite (hwpoison specific portable tests in tsrc)
+
+git://git.kernel.org/pub/scm/utils/cpu/mce/mce-inject.git
+       x86 specific injector
+
+
+---
+
+Limitations:
+
+- Not all page types are supported and never will. Most kernel internal
+objects cannot be recovered, only LRU pages for now.
+- Right now hugepage support is missing.
+
+---
+Andi Kleen, Oct 2009
+
index cf69091..a1a2ace 100644 (file)
@@ -65,43 +65,51 @@ trivial patch so apply some common sense.
 
 8.     Happy hacking.
 
-               -----------------------------------
-
-Maintainers List (try to look for most precise areas first)
+Descriptions of section entries:
+
+       P: Person (obsolete)
+       M: Mail patches to: FullName <address@domain>
+       L: Mailing list that is relevant to this area
+       W: Web-page with status/info
+       T: SCM tree type and location.  Type is one of: git, hg, quilt, stgit.
+       S: Status, one of the following:
+          Supported:   Someone is actually paid to look after this.
+          Maintained:  Someone actually looks after it.
+          Odd Fixes:   It has a maintainer but they don't have time to do
+                       much other than throw the odd patch in. See below..
+          Orphan:      No current maintainer [but maybe you could take the
+                       role as you write your new code].
+          Obsolete:    Old code. Something tagged obsolete generally means
+                       it has been replaced by a better system and you
+                       should be using that.
+       F: Files and directories with wildcard patterns.
+          A trailing slash includes all files and subdirectory files.
+          F:   drivers/net/    all files in and below drivers/net
+          F:   drivers/net/*   all files in drivers/net, but not below
+          F:   */net/*         all files in "any top level directory"/net
+          One pattern per line.  Multiple F: lines acceptable.
+       X: Files and directories that are NOT maintained, same rules as F:
+          Files exclusions are tested before file matches.
+          Can be useful for excluding a specific subdirectory, for instance:
+          F:   net/
+          X:   net/ipv6/
+          matches all files in and below net excluding net/ipv6/
+       K: Keyword perl extended regex pattern to match content in a
+          patch or file.  For instance:
+          K: of_get_profile
+             matches patches or files that contain "of_get_profile"
+          K: \b(printk|pr_(info|err))\b
+             matches patches or files that contain one or more of the words
+             printk, pr_info or pr_err
+          One regex pattern per line.  Multiple K: lines acceptable.
 
 Note: For the hard of thinking, this list is meant to remain in alphabetical
 order. If you could add yourselves to it in alphabetical order that would be
 so much easier [Ed]
 
-P: Person (obsolete)
-M: Mail patches to: FullName <address@domain>
-L: Mailing list that is relevant to this area
-W: Web-page with status/info
-T: SCM tree type and location.  Type is one of: git, hg, quilt, stgit.
-S: Status, one of the following:
-
-       Supported:      Someone is actually paid to look after this.
-       Maintained:     Someone actually looks after it.
-       Odd Fixes:      It has a maintainer but they don't have time to do
-                       much other than throw the odd patch in. See below..
-       Orphan:         No current maintainer [but maybe you could take the
-                       role as you write your new code].
-       Obsolete:       Old code. Something tagged obsolete generally means
-                       it has been replaced by a better system and you
-                       should be using that.
+Maintainers List (try to look for most precise areas first)
 
-F: Files and directories with wildcard patterns.
-   A trailing slash includes all files and subdirectory files.
-       F:      drivers/net/    all files in and below drivers/net
-       F:      drivers/net/*   all files in drivers/net, but not below
-       F:      */net/*         all files in "any top level directory"/net
-   One pattern per line.  Multiple F: lines acceptable.
-X: Files and directories that are NOT maintained, same rules as F:
-   Files exclusions are tested before file matches.
-   Can be useful for excluding a specific subdirectory, for instance:
-       F:      net/
-       X:      net/ipv6/
-   matches all files in and below net excluding net/ipv6/
+               -----------------------------------
 
 3C505 NETWORK DRIVER
 M:     Philip Blundell <philb@gnu.org>
@@ -577,6 +585,11 @@ M: Mike Rapoport <mike@compulab.co.il>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/CONTEC MICRO9 MACHINE SUPPORT
+M:     Hubert Feurstein <hubert.feurstein@contec.at>
+S:     Maintained
+F:     arch/arm/mach-ep93xx/micro9.c
+
 ARM/CORGI MACHINE SUPPORT
 M:     Richard Purdie <rpurdie@rpsys.net>
 S:     Maintained
@@ -987,7 +1000,7 @@ F: drivers/net/atlx/
 
 ATM
 M:     Chas Williams <chas@cmf.nrl.navy.mil>
-L:     linux-atm-general@lists.sourceforge.net (subscribers-only)
+L:     linux-atm-general@lists.sourceforge.net (moderated for non-subscribers)
 L:     netdev@vger.kernel.org
 W:     http://linux-atm.sourceforge.net
 S:     Maintained
@@ -1475,6 +1488,7 @@ F:        mm/*cgroup*
 
 CORETEMP HARDWARE MONITORING DRIVER
 M:     Rudolf Marek <r.marek@assembler.cz>
+M:     Huaxu Wan <huaxu.wan@intel.com>
 L:     lm-sensors@lm-sensors.org
 S:     Maintained
 F:     Documentation/hwmon/coretemp
@@ -2146,7 +2160,7 @@ S:        Supported
 F:     arch/powerpc/sysdev/qe_lib/
 F:     arch/powerpc/include/asm/*qe.h
 
-FREESCALE USB PERIPHERIAL DRIVERS
+FREESCALE USB PERIPHERAL DRIVERS
 M:     Li Yang <leoli@freescale.com>
 L:     linux-usb@vger.kernel.org
 L:     linuxppc-dev@ozlabs.org
@@ -2197,18 +2211,6 @@ F:       Documentation/filesystems/caching/
 F:     fs/fscache/
 F:     include/linux/fscache*.h
 
-TRACING
-M:     Steven Rostedt <rostedt@goodmis.org>
-M:     Frederic Weisbecker <fweisbec@gmail.com>
-M:     Ingo Molnar <mingo@redhat.com>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
-S:     Maintained
-F:     Documentation/trace/ftrace.txt
-F:     arch/*/*/*/ftrace.h
-F:     arch/*/kernel/ftrace.c
-F:     include/*/ftrace.h include/trace/ include/linux/trace*.h
-F:     kernel/trace/
-
 FUJITSU FR-V (FRV) PORT
 M:     David Howells <dhowells@redhat.com>
 S:     Maintained
@@ -2267,9 +2269,8 @@ S:        Maintained
 F:     include/asm-generic
 
 GENERIC UIO DRIVER FOR PCI DEVICES
-M:     Michael S. Tsirkin <mst@redhat.com>
+M:     "Michael S. Tsirkin" <mst@redhat.com>
 L:     kvm@vger.kernel.org
-L:     linux-kernel@vger.kernel.org
 S:     Supported
 F:     drivers/uio/uio_pci_generic.c
 
@@ -2610,6 +2611,7 @@ L:        linux1394-devel@lists.sourceforge.net
 W:     http://www.linux1394.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
 S:     Maintained
+F:     Documentation/debugging-via-ohci1394.txt
 F:     drivers/ieee1394/
 
 IEEE 1394 RAW I/O DRIVER
@@ -2998,8 +3000,8 @@ F:        scripts/Makefile.*
 
 KERNEL JANITORS
 L:     kernel-janitors@vger.kernel.org
-W:     http://www.kerneljanitors.org/
-S:     Maintained
+W:     http://janitor.kernelnewbies.org/
+S:     Odd Fixes
 
 KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
 M:     "J. Bruce Fields" <bfields@fieldses.org>
@@ -3661,6 +3663,7 @@ NETWORKING [GENERAL]
 M:     "David S. Miller" <davem@davemloft.net>
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net
+W:     http://patchwork.ozlabs.org/project/netdev/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
 S:     Maintained
 F:     net/
@@ -3778,7 +3781,7 @@ F:        drivers/video/riva/
 F:     drivers/video/nvidia/
 
 OMAP SUPPORT
-M:     "Tony Lindgren <tony@atomide.com>" <tony@atomide.com>
+M:     Tony Lindgren <tony@atomide.com>
 L:     linux-omap@vger.kernel.org
 W:     http://www.muru.com/linux/omap/
 W:     http://linux.omap.com/
@@ -3883,6 +3886,15 @@ S:       Maintained
 F:     Documentation/i2c/busses/i2c-ocores
 F:     drivers/i2c/busses/i2c-ocores.c
 
+OPEN FIRMWARE AND FLATTENED DEVICE TREE
+M:     Grant Likely <grant.likely@secretlab.ca>
+L:     devicetree-discuss@lists.ozlabs.org
+W:     http://fdt.secretlab.ca
+S:     Maintained
+F:     drivers/of
+F:     include/linux/of*.h
+K:     of_get_property
+
 OPROFILE
 M:     Robert Richter <robert.richter@amd.com>
 L:     oprofile-list@lists.sf.net
@@ -4318,7 +4330,7 @@ F:        drivers/video/aty/aty128fb.c
 RALINK RT2X00 WIRELESS LAN DRIVER
 P:     rt2x00 project
 L:     linux-wireless@vger.kernel.org
-L:     users@rt2x00.serialmonkey.com
+L:     users@rt2x00.serialmonkey.com (moderated for non-subscribers)
 W:     http://rt2x00.serialmonkey.com/
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git
@@ -4527,12 +4539,11 @@ F:      kernel/sched*
 F:     include/linux/sched.h
 
 SCORE ARCHITECTURE
-P:     Chen Liqin
-M:     liqin.chen@sunplusct.com
-P:     Lennox Wu
-M:     lennox.wu@gmail.com
+M:     Chen Liqin <liqin.chen@sunplusct.com>
+M:     Lennox Wu <lennox.wu@gmail.com>
 W:     http://www.sunplusct.com
 S:     Supported
+F:     arch/score/
 
 SCSI CDROM DRIVER
 M:     Jens Axboe <axboe@kernel.dk>
@@ -4605,20 +4616,20 @@ S:      Maintained
 F:     drivers/mmc/host/sdricoh_cs.c
 
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
-S:     Orphan
-L:     linux-mmc@vger.kernel.org
-F:     drivers/mmc/host/sdhci.*
+S:     Orphan
+L:     linux-mmc@vger.kernel.org
+F:     drivers/mmc/host/sdhci.*
 
 SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
 M:     Anton Vorontsov <avorontsov@ru.mvista.com>
 L:     linuxppc-dev@ozlabs.org
-L:     linux-mmc@vger.kernel.org
+L:     linux-mmc@vger.kernel.org
 S:     Maintained
-F:     drivers/mmc/host/sdhci-of.*
+F:     drivers/mmc/host/sdhci-of.*
 
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
 M:     Ben Dooks <ben-linux@fluff.org>
-L:     linux-mmc@vger.kernel.org
+L:     linux-mmc@vger.kernel.org
 S:     Maintained
 F:     drivers/mmc/host/sdhci-s3c.c
 
@@ -4721,8 +4732,7 @@ F:        drivers/usb/gadget/lh7a40*
 F:     drivers/usb/host/ohci-lh7a40*
 
 SIMPLE FIRMWARE INTERFACE (SFI)
-P:     Len Brown
-M:     lenb@kernel.org
+M:     Len Brown <lenb@kernel.org>
 L:     sfi-devel@simplefirmware.org
 W:     http://simplefirmware.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6.git
@@ -5170,6 +5180,20 @@ L:       tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/char/tpm/
 
+TRACING
+M:     Steven Rostedt <rostedt@goodmis.org>
+M:     Frederic Weisbecker <fweisbec@gmail.com>
+M:     Ingo Molnar <mingo@redhat.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
+S:     Maintained
+F:     Documentation/trace/ftrace.txt
+F:     arch/*/*/*/ftrace.h
+F:     arch/*/kernel/ftrace.c
+F:     include/*/ftrace.h
+F:     include/linux/trace*.h
+F:     include/trace/
+F:     kernel/trace/
+
 TRIVIAL PATCHES
 M:     Jiri Kosina <trivial@kernel.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
@@ -5658,6 +5682,13 @@ S:       Maintained
 F:     drivers/vlynq/vlynq.c
 F:     include/linux/vlynq.h
 
+VMWARE VMXNET3 ETHERNET DRIVER
+M:     Shreyas Bhatewara <sbhatewara@vmware.com>
+M:     VMware, Inc. <pv-drivers@vmware.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     drivers/net/vmxnet3/
+
 VOLTAGE AND CURRENT REGULATOR FRAMEWORK
 M:     Liam Girdwood <lrg@slimlogic.co.uk>
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
@@ -5729,8 +5760,7 @@ S:        Maintained
 F:     drivers/scsi/wd7000.c
 
 WINBOND CIR DRIVER
-P:     David Härdeman
-M:     david@hardeman.nu
+M:     David Härdeman <david@hardeman.nu>
 S:     Maintained
 F:     drivers/input/misc/winbond-cir.c
 
@@ -5787,9 +5817,7 @@ F:        drivers/input/touchscreen/*wm97*
 F:     include/linux/wm97xx.h
 
 WOLFSON MICROELECTRONICS PMIC DRIVERS
-P:     Mark Brown
-M:     broonie@opensource.wolfsonmicro.com
-L:     linux-kernel@vger.kernel.org
+M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
 W:     http://opensource.wolfsonmicro.com/node/8
 S:     Supported
index 927d7a3..9425d1d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 32
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
@@ -179,46 +179,9 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 # Alternatively CROSS_COMPILE can be set in the environment.
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-#
-# To force ARCH and CROSS_COMPILE settings include kernel.* files
-# in the kernel tree - do not patch this file.
 export KBUILD_BUILDHOST := $(SUBARCH)
-
-# Kbuild save the ARCH and CROSS_COMPILE setting in kernel.* files.
-# Restore these settings and check that user did not specify
-# conflicting values.
-
-saved_arch  := $(shell cat include/generated/kernel.arch  2> /dev/null)
-saved_cross := $(shell cat include/generated/kernel.cross 2> /dev/null)
-
-ifneq ($(CROSS_COMPILE),)
-        ifneq ($(saved_cross),)
-                ifneq ($(CROSS_COMPILE),$(saved_cross))
-                        $(error CROSS_COMPILE changed from \
-                                "$(saved_cross)" to \
-                                 to "$(CROSS_COMPILE)". \
-                                 Use "make mrproper" to fix it up)
-                endif
-        endif
-else
-    CROSS_COMPILE := $(saved_cross)
-endif
-
-ifneq ($(ARCH),)
-        ifneq ($(saved_arch),)
-                ifneq ($(saved_arch),$(ARCH))
-                        $(error ARCH changed from \
-                                "$(saved_arch)" to "$(ARCH)". \
-                                 Use "make mrproper" to fix it up)
-                endif
-        endif
-else
-        ifneq ($(saved_arch),)
-                ARCH := $(saved_arch)
-        else
-                ARCH := $(SUBARCH)
-        endif
-endif
+ARCH           ?= $(SUBARCH)
+CROSS_COMPILE  ?=
 
 # Architecture as present in compile.h
 UTS_MACHINE    := $(ARCH)
@@ -483,11 +446,6 @@ ifeq ($(config-targets),1)
 include $(srctree)/arch/$(SRCARCH)/Makefile
 export KBUILD_DEFCONFIG KBUILD_KCONFIG
 
-# save ARCH & CROSS_COMPILE settings
-$(shell mkdir -p include/generated &&                            \
-        echo $(ARCH)          > include/generated/kernel.arch && \
-        echo $(CROSS_COMPILE) > include/generated/kernel.cross)
-
 config: scripts_basic outputmakefile FORCE
        $(Q)mkdir -p include/linux include/config
        $(Q)$(MAKE) $(build)=scripts/kconfig $@
index 8da75de..264f52b 100644 (file)
@@ -304,7 +304,7 @@ CONFIG_ALIGNMENT_TRAP=y
 CONFIG_ZBOOT_ROM_TEXT=0x10C08000
 CONFIG_ZBOOT_ROM_BSS=0x10200000
 # CONFIG_ZBOOT_ROM is not set
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS0,115200n8"
+CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200n8"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
index 357d402..b3c8cce 100644 (file)
@@ -969,7 +969,6 @@ CONFIG_USB_ETH_RNDIS=y
 #
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_ISP1301_OMAP is not set
 CONFIG_TWL4030_USB=y
 # CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
index 7d61ae6..953ba02 100644 (file)
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Thu Jul 16 23:36:10 2009
+# Linux kernel version: 2.6.32-rc5
+# Sat Oct 17 23:32:24 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_TCM=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -44,11 +44,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -80,17 +81,15 @@ CONFIG_SHMEM=y
 # CONFIG_AIO is not set
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_SLUB_DEBUG=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -133,6 +132,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
@@ -147,6 +147,7 @@ CONFIG_DEFAULT_IOSCHED="deadline"
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -169,11 +170,13 @@ CONFIG_DEFAULT_IOSCHED="deadline"
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 CONFIG_ARCH_U300=y
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
 
 #
 # ST-Ericsson AB U300/U330/U335/U365 Platform
@@ -195,6 +198,7 @@ CONFIG_MACH_U300_BS335=y
 CONFIG_MACH_U300_DUAL_RAM=y
 CONFIG_U300_DEBUG=y
 # CONFIG_MACH_U300_SEMI_IS_SHARED is not set
+CONFIG_MACH_U300_SPIDUMMY=y
 
 #
 # All the settings below must match the bootloader's settings
@@ -207,7 +211,7 @@ CONFIG_CPU_32=y
 CONFIG_CPU_ARM926T=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WBI=y
@@ -222,6 +226,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_ARM_VIC=y
 CONFIG_ARM_VIC_NR=2
 CONFIG_COMMON_CLKDEV=y
@@ -245,6 +250,8 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -265,6 +272,7 @@ CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
 # CONFIG_UACCESS_WITH_MEMCPY is not set
@@ -313,6 +321,7 @@ CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
 # CONFIG_SUSPEND is not set
 # CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -351,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -391,6 +401,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
@@ -402,9 +413,9 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
@@ -453,6 +464,7 @@ CONFIG_MTD_CFI_I2=y
 #
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -520,6 +532,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_MD is not set
 # CONFIG_NETDEVICES is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -540,12 +553,16 @@ CONFIG_INPUT_EVDEV=y
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_GPIO is not set
 # CONFIG_KEYBOARD_MATRIX is not set
 # CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
@@ -597,6 +614,7 @@ CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -629,9 +647,6 @@ CONFIG_I2C_STU300=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -653,16 +668,21 @@ CONFIG_SPI_PL022=y
 #
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 # CONFIG_PDA_POWER is not set
 # CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
 # CONFIG_BATTERY_BQ27x00 is not set
 # CONFIG_BATTERY_MAX17040 is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -690,10 +710,24 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
 CONFIG_AB3100_CORE=y
+CONFIG_AB3100_OTP=y
 # CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+CONFIG_REGULATOR_AB3100=y
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -792,9 +826,10 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 CONFIG_MMC_ARMMMCI=y
 # CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
@@ -820,10 +855,10 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=y
 #
 # iptables trigger is under Netfilter config (LED target)
 #
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_HCTOSYS is not set
 # CONFIG_RTC_DEBUG is not set
 
 #
@@ -863,6 +898,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -878,27 +914,25 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T59 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_AB3100=y
 
 #
 # on-CPU RTC drivers
 #
 # CONFIG_RTC_DRV_PL030 is not set
 # CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_COH901331=y
 CONFIG_DMADEVICES=y
 
 #
 # DMA Devices
 #
 # CONFIG_AUXDISPLAY is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -913,6 +947,7 @@ CONFIG_REGULATOR=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
@@ -975,7 +1010,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -1033,6 +1067,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1066,11 +1101,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1121,6 +1158,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC32 is not set
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
index 63a481f..338ff19 100644 (file)
@@ -84,7 +84,7 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
        *p = res | mask;
        raw_local_irq_restore(flags);
 
-       return res & mask;
+       return (res & mask) != 0;
 }
 
 static inline int
@@ -101,7 +101,7 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
        *p = res & ~mask;
        raw_local_irq_restore(flags);
 
-       return res & mask;
+       return (res & mask) != 0;
 }
 
 static inline int
@@ -118,7 +118,7 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
        *p = res ^ mask;
        raw_local_irq_restore(flags);
 
-       return res & mask;
+       return (res & mask) != 0;
 }
 
 #include <asm-generic/bitops/non-atomic.h>
index c3b911e..6aac3f5 100644 (file)
@@ -98,6 +98,9 @@ extern int elf_check_arch(const struct elf32_hdr *);
 extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
 #define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
 
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE      4096
 
index a45ab5d..c2f1605 100644 (file)
@@ -350,7 +350,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
        if (tlb_flag(TLB_WB))
                dsb();
 
-       if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
+       if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
                if (tlb_flag(TLB_V3_FULL))
                        asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_U_FULL))
@@ -360,6 +360,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
                if (tlb_flag(TLB_V4_I_FULL))
                        asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
        }
+       put_cpu();
 
        if (tlb_flag(TLB_V6_U_ASID))
                asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
index 322410b..0022b4d 100644 (file)
@@ -608,33 +608,33 @@ call_fpe:
  THUMB(        add     pc, r8                  )
        nop
 
-       W(mov)  pc, lr                          @ CP#0
+       movw_pc lr                              @ CP#0
        W(b)    do_fpe                          @ CP#1 (FPE)
        W(b)    do_fpe                          @ CP#2 (FPE)
-       W(mov)  pc, lr                          @ CP#3
+       movw_pc lr                              @ CP#3
 #ifdef CONFIG_CRUNCH
        b       crunch_task_enable              @ CP#4 (MaverickCrunch)
        b       crunch_task_enable              @ CP#5 (MaverickCrunch)
        b       crunch_task_enable              @ CP#6 (MaverickCrunch)
 #else
-       W(mov)  pc, lr                          @ CP#4
-       W(mov)  pc, lr                          @ CP#5
-       W(mov)  pc, lr                          @ CP#6
+       movw_pc lr                              @ CP#4
+       movw_pc lr                              @ CP#5
+       movw_pc lr                              @ CP#6
 #endif
-       W(mov)  pc, lr                          @ CP#7
-       W(mov)  pc, lr                          @ CP#8
-       W(mov)  pc, lr                          @ CP#9
+       movw_pc lr                              @ CP#7
+       movw_pc lr                              @ CP#8
+       movw_pc lr                              @ CP#9
 #ifdef CONFIG_VFP
        W(b)    do_vfp                          @ CP#10 (VFP)
        W(b)    do_vfp                          @ CP#11 (VFP)
 #else
-       W(mov)  pc, lr                          @ CP#10 (VFP)
-       W(mov)  pc, lr                          @ CP#11 (VFP)
+       movw_pc lr                              @ CP#10 (VFP)
+       movw_pc lr                              @ CP#11 (VFP)
 #endif
-       W(mov)  pc, lr                          @ CP#12
-       W(mov)  pc, lr                          @ CP#13
-       W(mov)  pc, lr                          @ CP#14 (Debug)
-       W(mov)  pc, lr                          @ CP#15 (Control)
+       movw_pc lr                              @ CP#12
+       movw_pc lr                              @ CP#13
+       movw_pc lr                              @ CP#14 (Debug)
+       movw_pc lr                              @ CP#15 (Control)
 
 #ifdef CONFIG_NEON
        .align  6
index ac34c0d..7e9ed1e 100644 (file)
        mov     \rd, sp, lsr #13
        mov     \rd, \rd, lsl #13
        .endm
+
+       @
+       @ 32-bit wide "mov pc, reg"
+       @
+       .macro  movw_pc, reg
+       mov     pc, \reg
+       .endm
 #else  /* CONFIG_THUMB2_KERNEL */
        .macro  svc_exit, rpsr
        clrex                                   @ clear the exclusive monitor
        lsr     \rd, \rd, #13
        mov     \rd, \rd, lsl #13
        .endm
+
+       @
+       @ 32-bit wide "mov pc, reg"
+       @
+       .macro  movw_pc, reg
+       mov     pc, \reg
+       nop
+       .endm
 #endif /* !CONFIG_THUMB2_KERNEL */
 
 /*
index 790fbee..0d96d01 100644 (file)
@@ -327,6 +327,15 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
        return 0;
 }
 
+/*
+ * Fill in the task's elfregs structure for a core dump.
+ */
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
+{
+       elf_core_copy_regs(elfregs, task_pt_regs(t));
+       return 1;
+}
+
 /*
  * fill in the fpe structure for a core dump...
  */
index 467b69e..f838f36 100644 (file)
@@ -45,21 +45,21 @@ static int __init user_debug_setup(char *str)
 __setup("user_debug=", user_debug_setup);
 #endif
 
-static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
+static void dump_mem(const char *, const char *, unsigned long, unsigned long);
 
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
 #ifdef CONFIG_KALLSYMS
-       printk("[<%08lx>] ", where);
-       print_symbol("(%s) ", where);
-       printk("from [<%08lx>] ", from);
-       print_symbol("(%s)\n", from);
+       char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
+       sprint_symbol(sym1, where);
+       sprint_symbol(sym2, from);
+       printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
 #else
        printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
 #endif
 
        if (in_exception_text(where))
-               dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
+               dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
 }
 
 #ifndef CONFIG_ARM_UNWIND
@@ -81,9 +81,10 @@ static int verify_stack(unsigned long sp)
 /*
  * Dump out the contents of some memory nicely...
  */
-static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+                    unsigned long top)
 {
-       unsigned long p = bottom & ~31;
+       unsigned long first;
        mm_segment_t fs;
        int i;
 
@@ -95,33 +96,37 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
        fs = get_fs();
        set_fs(KERNEL_DS);
 
-       printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+       printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
 
-       for (p = bottom & ~31; p < top;) {
-               printk("%04lx: ", p & 0xffff);
+       for (first = bottom & ~31; first < top; first += 32) {
+               unsigned long p;
+               char str[sizeof(" 12345678") * 8 + 1];
 
-               for (i = 0; i < 8; i++, p += 4) {
-                       unsigned int val;
+               memset(str, ' ', sizeof(str));
+               str[sizeof(str) - 1] = '\0';
 
-                       if (p < bottom || p >= top)
-                               printk("         ");
-                       else {
-                               __get_user(val, (unsigned long *)p);
-                               printk("%08x ", val);
+               for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
+                       if (p >= bottom && p < top) {
+                               unsigned long val;
+                               if (__get_user(val, (unsigned long *)p) == 0)
+                                       sprintf(str + i * 9, " %08lx", val);
+                               else
+                                       sprintf(str + i * 9, " ????????");
                        }
                }
-               printk ("\n");
+               printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
        }
 
        set_fs(fs);
 }
 
-static void dump_instr(struct pt_regs *regs)
+static void dump_instr(const char *lvl, struct pt_regs *regs)
 {
        unsigned long addr = instruction_pointer(regs);
        const int thumb = thumb_mode(regs);
        const int width = thumb ? 4 : 8;
        mm_segment_t fs;
+       char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
        int i;
 
        /*
@@ -132,7 +137,6 @@ static void dump_instr(struct pt_regs *regs)
        fs = get_fs();
        set_fs(KERNEL_DS);
 
-       printk("Code: ");
        for (i = -4; i < 1; i++) {
                unsigned int val, bad;
 
@@ -142,13 +146,14 @@ static void dump_instr(struct pt_regs *regs)
                        bad = __get_user(val, &((u32 *)addr)[i]);
 
                if (!bad)
-                       printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
+                       p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
+                                       width, val);
                else {
-                       printk("bad PC value.");
+                       p += sprintf(p, "bad PC value");
                        break;
                }
        }
-       printk("\n");
+       printk("%sCode: %s\n", lvl, str);
 
        set_fs(fs);
 }
@@ -224,18 +229,19 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
        struct task_struct *tsk = thread->task;
        static int die_counter;
 
-       printk("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
+       printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
               str, err, ++die_counter);
+       sysfs_printk_last_file();
        print_modules();
        __show_regs(regs);
-       printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-               tsk->comm, task_pid_nr(tsk), thread + 1);
+       printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
+               TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
 
        if (!user_mode(regs) || in_interrupt()) {
-               dump_mem("Stack: ", regs->ARM_sp,
+               dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
                         THREAD_SIZE + (unsigned long)task_stack_page(tsk));
                dump_backtrace(regs, tsk);
-               dump_instr(regs);
+               dump_instr(KERN_EMERG, regs);
        }
 }
 
@@ -250,13 +256,14 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
 
        oops_enter();
 
-       console_verbose();
        spin_lock_irq(&die_lock);
+       console_verbose();
        bust_spinlocks(1);
        __die(str, err, thread, regs);
        bust_spinlocks(0);
        add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
+       oops_exit();
 
        if (in_interrupt())
                panic("Fatal exception in interrupt");
@@ -264,7 +271,6 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
        if (panic_on_oops)
                panic("Fatal exception");
 
-       oops_exit();
        do_exit(SIGSEGV);
 }
 
@@ -349,7 +355,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
        if (user_debug & UDBG_UNDEFINED) {
                printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
                        current->comm, task_pid_nr(current), pc);
-               dump_instr(regs);
+               dump_instr(KERN_INFO, regs);
        }
 #endif
 
@@ -400,7 +406,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
        if (user_debug & UDBG_SYSCALL) {
                printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
                        task_pid_nr(current), current->comm, n);
-               dump_instr(regs);
+               dump_instr(KERN_ERR, regs);
        }
 #endif
 
@@ -579,7 +585,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
        if (user_debug & UDBG_SYSCALL) {
                printk("[%d] %s: arm syscall %d\n",
                       task_pid_nr(current), current->comm, no);
-               dump_instr(regs);
+               dump_instr("", regs);
                if (user_mode(regs)) {
                        __show_regs(regs);
                        c_backtrace(regs->ARM_fp, processor_mode(regs));
@@ -656,7 +662,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
        if (user_debug & UDBG_BADABORT) {
                printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
                        task_pid_nr(current), current->comm, code, instr);
-               dump_instr(regs);
+               dump_instr(KERN_ERR, regs);
                show_pte(current->mm, addr);
        }
 #endif
index d581cff..332b784 100644 (file)
@@ -838,7 +838,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9g45_wdt_device = {
        .name           = "at91_wdt",
        .id             = -1,
index 4b4f692..e590bbe 100644 (file)
@@ -271,12 +271,12 @@ static struct irqaction bcmring_timer_irq = {
        .handler = bcmring_timer_interrupt,
 };
 
-static cycle_t bcmring_get_cycles_timer1(void)
+static cycle_t bcmring_get_cycles_timer1(struct clocksource *cs)
 {
        return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
 }
 
-static cycle_t bcmring_get_cycles_timer3(void)
+static cycle_t bcmring_get_cycles_timer3(struct clocksource *cs)
 {
        return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
 }
index cdbf93c..38b3706 100644 (file)
@@ -29,7 +29,7 @@ static inline void arch_idle(void)
        cpu_do_idle();
 }
 
-static inline void arch_reset(char mode, char *cmd)
+static inline void arch_reset(char mode, const char *cmd)
 {
        printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
 
index d7291c6..9167c3d 100644 (file)
@@ -17,13 +17,31 @@ config EP93XX_SDCE3_SYNC_PHYS_OFFSET
        bool "0x00000000 - SDCE3/SyncBoot"
        help
          Select this option if you want support for EP93xx boards with the
-         first SDRAM bank at 0x00000000
+         first SDRAM bank at 0x00000000.
 
 config EP93XX_SDCE0_PHYS_OFFSET
        bool "0xc0000000 - SDCEO"
        help
          Select this option if you want support for EP93xx boards with the
-         first SDRAM bank at 0xc0000000
+         first SDRAM bank at 0xc0000000.
+
+config EP93XX_SDCE1_PHYS_OFFSET
+       bool "0xd0000000 - SDCE1"
+       help
+         Select this option if you want support for EP93xx boards with the
+         first SDRAM bank at 0xd0000000.
+
+config EP93XX_SDCE2_PHYS_OFFSET
+       bool "0xe0000000 - SDCE2"
+       help
+         Select this option if you want support for EP93xx boards with the
+         first SDRAM bank at 0xe0000000.
+
+config EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+       bool "0xf0000000 - SDCE3/AsyncBoot"
+       help
+         Select this option if you want support for EP93xx boards with the
+         first SDRAM bank at 0xf0000000.
 
 endchoice
 
@@ -112,28 +130,36 @@ config MACH_MICRO9
        bool
 
 config MACH_MICRO9H
-       bool "Support Contec Hypercontrol Micro9-H"
+       bool "Support Contec Micro9-High"
        depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
        select MACH_MICRO9
        help
          Say 'Y' here if you want your kernel to support the
-         Contec Hypercontrol Micro9-H board.
+         Contec Micro9-High board.
 
 config MACH_MICRO9M
-       bool "Support Contec Hypercontrol Micro9-M"
-       depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+       bool "Support Contec Micro9-Mid"
+       depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
        select MACH_MICRO9
        help
          Say 'Y' here if you want your kernel to support the
-         Contec Hypercontrol Micro9-M board.
+         Contec Micro9-Mid board.
 
 config MACH_MICRO9L
-       bool "Support Contec Hypercontrol Micro9-L"
+       bool "Support Contec Micro9-Lite"
        depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
        select MACH_MICRO9
        help
          Say 'Y' here if you want your kernel to support the
-         Contec Hypercontrol Micro9-L board.
+         Contec Micro9-Lite board.
+
+config MACH_MICRO9S
+       bool "Support Contec Micro9-Slim"
+       depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+       select MACH_MICRO9
+       help
+         Say 'Y' here if you want your kernel to support the
+         Contec Micro9-Slim board.
 
 config MACH_TS72XX
        bool "Support Technologic Systems TS-72xx SBC"
index 27a085a..0ad33f1 100644 (file)
@@ -3,3 +3,12 @@ params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)    := 0x00000100
 
    zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)         := 0xc0008000
 params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)         := 0xc0000100
+
+   zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)         := 0xd0008000
+params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)         := 0xd0000100
+
+   zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)         := 0xe0008000
+params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)         := 0xe0000100
+
+   zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)   := 0xf0008000
+params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)   := 0xf0000100
index dda19cd..1d0f9d8 100644 (file)
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
 
 #include <asm/clkdev.h>
 #include <asm/div64.h>
-#include <mach/hardware.h>
 
 
 struct clk {
+       struct clk      *parent;
        unsigned long   rate;
        int             users;
        int             sw_locked;
@@ -39,40 +42,60 @@ static unsigned long get_uart_rate(struct clk *clk);
 static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
 static int set_div_rate(struct clk *clk, unsigned long rate);
 
+
+static struct clk clk_xtali = {
+       .rate           = EP93XX_EXT_CLK_RATE,
+};
 static struct clk clk_uart1 = {
+       .parent         = &clk_xtali,
        .sw_locked      = 1,
        .enable_reg     = EP93XX_SYSCON_DEVCFG,
        .enable_mask    = EP93XX_SYSCON_DEVCFG_U1EN,
        .get_rate       = get_uart_rate,
 };
 static struct clk clk_uart2 = {
+       .parent         = &clk_xtali,
        .sw_locked      = 1,
        .enable_reg     = EP93XX_SYSCON_DEVCFG,
        .enable_mask    = EP93XX_SYSCON_DEVCFG_U2EN,
        .get_rate       = get_uart_rate,
 };
 static struct clk clk_uart3 = {
+       .parent         = &clk_xtali,
        .sw_locked      = 1,
        .enable_reg     = EP93XX_SYSCON_DEVCFG,
        .enable_mask    = EP93XX_SYSCON_DEVCFG_U3EN,
        .get_rate       = get_uart_rate,
 };
-static struct clk clk_pll1;
-static struct clk clk_f;
-static struct clk clk_h;
-static struct clk clk_p;
-static struct clk clk_pll2;
+static struct clk clk_pll1 = {
+       .parent         = &clk_xtali,
+};
+static struct clk clk_f = {
+       .parent         = &clk_pll1,
+};
+static struct clk clk_h = {
+       .parent         = &clk_pll1,
+};
+static struct clk clk_p = {
+       .parent         = &clk_pll1,
+};
+static struct clk clk_pll2 = {
+       .parent         = &clk_xtali,
+};
 static struct clk clk_usb_host = {
+       .parent         = &clk_pll2,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_USH_EN,
 };
 static struct clk clk_keypad = {
+       .parent         = &clk_xtali,
        .sw_locked      = 1,
        .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
        .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
        .set_rate       = set_keytchclk_rate,
 };
 static struct clk clk_pwm = {
+       .parent         = &clk_xtali,
        .rate           = EP93XX_EXT_CLK_RATE,
 };
 
@@ -85,50 +108,62 @@ static struct clk clk_video = {
 
 /* DMA Clocks */
 static struct clk clk_m2p0 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
 };
 static struct clk clk_m2p1 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
 };
 static struct clk clk_m2p2 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
 };
 static struct clk clk_m2p3 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
 };
 static struct clk clk_m2p4 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
 };
 static struct clk clk_m2p5 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
 };
 static struct clk clk_m2p6 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
 };
 static struct clk clk_m2p7 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
 };
 static struct clk clk_m2p8 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
 };
 static struct clk clk_m2p9 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
 };
 static struct clk clk_m2m0 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
 };
 static struct clk clk_m2m1 = {
+       .parent         = &clk_h,
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
        .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
 };
@@ -137,6 +172,7 @@ static struct clk clk_m2m1 = {
        { .dev_id = dev, .con_id = con, .clk = ck }
 
 static struct clk_lookup clocks[] = {
+       INIT_CK(NULL,                   "xtali",        &clk_xtali),
        INIT_CK("apb:uart1",            NULL,           &clk_uart1),
        INIT_CK("apb:uart2",            NULL,           &clk_uart2),
        INIT_CK("apb:uart3",            NULL,           &clk_uart3),
@@ -163,48 +199,84 @@ static struct clk_lookup clocks[] = {
        INIT_CK(NULL,                   "m2m1",         &clk_m2m1),
 };
 
+static DEFINE_SPINLOCK(clk_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+       if (!clk->users++) {
+               if (clk->parent)
+                       __clk_enable(clk->parent);
+
+               if (clk->enable_reg) {
+                       u32 v;
+
+                       v = __raw_readl(clk->enable_reg);
+                       v |= clk->enable_mask;
+                       if (clk->sw_locked)
+                               ep93xx_syscon_swlocked_write(v, clk->enable_reg);
+                       else
+                               __raw_writel(v, clk->enable_reg);
+               }
+       }
+}
 
 int clk_enable(struct clk *clk)
 {
-       if (!clk->users++ && clk->enable_reg) {
-               u32 value;
+       unsigned long flags;
 
-               value = __raw_readl(clk->enable_reg);
-               value |= clk->enable_mask;
-               if (clk->sw_locked)
-                       ep93xx_syscon_swlocked_write(value, clk->enable_reg);
-               else
-                       __raw_writel(value, clk->enable_reg);
-       }
+       if (!clk)
+               return -EINVAL;
+
+       spin_lock_irqsave(&clk_lock, flags);
+       __clk_enable(clk);
+       spin_unlock_irqrestore(&clk_lock, flags);
 
        return 0;
 }
 EXPORT_SYMBOL(clk_enable);
 
-void clk_disable(struct clk *clk)
+static void __clk_disable(struct clk *clk)
 {
-       if (!--clk->users && clk->enable_reg) {
-               u32 value;
+       if (!--clk->users) {
+               if (clk->enable_reg) {
+                       u32 v;
+
+                       v = __raw_readl(clk->enable_reg);
+                       v &= ~clk->enable_mask;
+                       if (clk->sw_locked)
+                               ep93xx_syscon_swlocked_write(v, clk->enable_reg);
+                       else
+                               __raw_writel(v, clk->enable_reg);
+               }
 
-               value = __raw_readl(clk->enable_reg);
-               value &= ~clk->enable_mask;
-               if (clk->sw_locked)
-                       ep93xx_syscon_swlocked_write(value, clk->enable_reg);
-               else
-                       __raw_writel(value, clk->enable_reg);
+               if (clk->parent)
+                       __clk_disable(clk->parent);
        }
 }
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (!clk)
+               return;
+
+       spin_lock_irqsave(&clk_lock, flags);
+       __clk_disable(clk);
+       spin_unlock_irqrestore(&clk_lock, flags);
+}
 EXPORT_SYMBOL(clk_disable);
 
 static unsigned long get_uart_rate(struct clk *clk)
 {
+       unsigned long rate = clk_get_rate(clk->parent);
        u32 value;
 
        value = __raw_readl(EP93XX_SYSCON_PWRCNT);
        if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
-               return EP93XX_EXT_CLK_RATE;
+               return rate;
        else
-               return EP93XX_EXT_CLK_RATE / 2;
+               return rate / 2;
 }
 
 unsigned long clk_get_rate(struct clk *clk)
@@ -244,16 +316,16 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
-                                 int *pdiv, int *div)
+static int calc_clk_div(struct clk *clk, unsigned long rate,
+                       int *psel, int *esel, int *pdiv, int *div)
 {
-       unsigned long max_rate, best_rate = 0,
-               actual_rate = 0, mclk_rate = 0, rate_err = -1;
+       struct clk *mclk;
+       unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
        int i, found = 0, __div = 0, __pdiv = 0;
 
        /* Don't exceed the maximum rate */
        max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
-                      (unsigned long)EP93XX_EXT_CLK_RATE / 4);
+                      clk_xtali.rate / 4);
        rate = min(rate, max_rate);
 
        /*
@@ -267,11 +339,12 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
         */
        for (i = 0; i < 3; i++) {
                if (i == 0)
-                       mclk_rate = EP93XX_EXT_CLK_RATE * 2;
+                       mclk = &clk_xtali;
                else if (i == 1)
-                       mclk_rate = clk_pll1.rate * 2;
-               else if (i == 2)
-                       mclk_rate = clk_pll2.rate * 2;
+                       mclk = &clk_pll1;
+               else
+                       mclk = &clk_pll2;
+               mclk_rate = mclk->rate * 2;
 
                /* Try each predivider value */
                for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
@@ -286,7 +359,8 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
                                *div = __div;
                                *psel = (i == 2);
                                *esel = (i != 0);
-                               best_rate = actual_rate;
+                               clk->parent = mclk;
+                               clk->rate = actual_rate;
                                rate_err = abs(actual_rate - rate);
                                found = 1;
                        }
@@ -294,21 +368,19 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
        }
 
        if (!found)
-               return 0;
+               return -EINVAL;
 
-       return best_rate;
+       return 0;
 }
 
 static int set_div_rate(struct clk *clk, unsigned long rate)
 {
-       unsigned long actual_rate;
-       int psel = 0, esel = 0, pdiv = 0, div = 0;
+       int err, psel = 0, esel = 0, pdiv = 0, div = 0;
        u32 val;
 
-       actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
-       if (actual_rate == 0)
-               return -EINVAL;
-       clk->rate = actual_rate;
+       err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
+       if (err)
+               return err;
 
        /* Clear the esel, psel, pdiv and div bits */
        val = __raw_readl(clk->enable_reg);
@@ -344,7 +416,7 @@ static unsigned long calc_pll_rate(u32 config_word)
        unsigned long long rate;
        int i;
 
-       rate = EP93XX_EXT_CLK_RATE;
+       rate = clk_xtali.rate;
        rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
        rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
        do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
@@ -377,7 +449,7 @@ static int __init ep93xx_clock_init(void)
 
        value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
        if (!(value & 0x00800000)) {                    /* PLL1 bypassed?  */
-               clk_pll1.rate = EP93XX_EXT_CLK_RATE;
+               clk_pll1.rate = clk_xtali.rate;
        } else {
                clk_pll1.rate = calc_pll_rate(value);
        }
@@ -388,7 +460,7 @@ static int __init ep93xx_clock_init(void)
 
        value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
        if (!(value & 0x00080000)) {                    /* PLL2 bypassed?  */
-               clk_pll2.rate = EP93XX_EXT_CLK_RATE;
+               clk_pll2.rate = clk_xtali.rate;
        } else if (value & 0x00040000) {                /* PLL2 enabled?  */
                clk_pll2.rate = calc_pll_rate(value);
        } else {
index f7ebed9..b4357c3 100644 (file)
@@ -206,7 +206,6 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
        for (i = 0; i < 8; i++) {
                if (status & (1 << i)) {
                        int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
-                       desc = irq_desc + gpio_irq;
                        generic_handle_irq(gpio_irq);
                }
        }
@@ -550,13 +549,11 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
        platform_device_register(&ep93xx_eth_device);
 }
 
-static struct i2c_gpio_platform_data ep93xx_i2c_data = {
-       .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
-       .sda_is_open_drain      = 0,
-       .scl_pin                = EP93XX_GPIO_LINE_EECLK,
-       .scl_is_open_drain      = 0,
-       .udelay                 = 2,
-};
+
+/*************************************************************************
+ * EP93xx i2c peripheral handling
+ *************************************************************************/
+static struct i2c_gpio_platform_data ep93xx_i2c_data;
 
 static struct platform_device ep93xx_i2c_device = {
        .name                   = "i2c-gpio",
@@ -564,8 +561,25 @@ static struct platform_device ep93xx_i2c_device = {
        .dev.platform_data      = &ep93xx_i2c_data,
 };
 
-void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
+void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
+                               struct i2c_board_info *devices, int num)
 {
+       /*
+        * Set the EEPROM interface pin drive type control.
+        * Defines the driver type for the EECLK and EEDAT pins as either
+        * open drain, which will require an external pull-up, or a normal
+        * CMOS driver.
+        */
+       if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
+               pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
+       if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
+               pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
+
+       __raw_writel((data->sda_is_open_drain << 1) |
+                    (data->scl_is_open_drain << 0),
+                    EP93XX_GPIO_EEDRIVE);
+
+       ep93xx_i2c_data = *data;
        i2c_register_board_info(0, devices, num);
        platform_device_register(&ep93xx_i2c_device);
 }
index 73145ae..a4a7be3 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/i2c.h>
 #include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
 
 #include <mach/hardware.h>
 
@@ -76,13 +78,26 @@ static struct ep93xx_eth_data edb93xx_eth_data = {
        .phy_id         = 1,
 };
 
-static struct i2c_board_info __initdata edb93xxa_i2c_data[] = {
+
+/*************************************************************************
+ * EDB93xx i2c peripheral handling
+ *************************************************************************/
+static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = {
+       .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
+       .sda_is_open_drain      = 0,
+       .scl_pin                = EP93XX_GPIO_LINE_EECLK,
+       .scl_is_open_drain      = 0,
+       .udelay                 = 0,    /* default to 100 kHz */
+       .timeout                = 0,    /* default to 100 ms */
+};
+
+static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
        {
                I2C_BOARD_INFO("isl1208", 0x6f),
        },
 };
 
-static struct i2c_board_info __initdata edb93xx_i2c_data[] = {
+static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
        {
                I2C_BOARD_INFO("ds1337", 0x68),
        },
@@ -92,12 +107,14 @@ static void __init edb93xx_register_i2c(void)
 {
        if (machine_is_edb9302a() || machine_is_edb9307a() ||
            machine_is_edb9315a()) {
-               ep93xx_register_i2c(edb93xxa_i2c_data,
-                               ARRAY_SIZE(edb93xxa_i2c_data));
+               ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
+                                   edb93xxa_i2c_board_info,
+                                   ARRAY_SIZE(edb93xxa_i2c_board_info));
        } else if (machine_is_edb9307() || machine_is_edb9312() ||
                   machine_is_edb9315()) {
-               ep93xx_register_i2c(edb93xx_i2c_data,
-                               ARRAY_SIZE(edb93xx_i2c_data));
+               ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
+                                   edb93xx_i2c_board_info,
+                                   ARRAY_SIZE(edb93xx_i2c_board_info));
        }
 }
 
index 0fbf87b..b1f937e 100644 (file)
 #define EP93XX_AHB_VIRT_BASE           0xfef00000
 #define EP93XX_AHB_SIZE                        0x00100000
 
+#define EP93XX_AHB_PHYS(x)             (EP93XX_AHB_PHYS_BASE + (x))
 #define EP93XX_AHB_IOMEM(x)            IOMEM(EP93XX_AHB_VIRT_BASE + (x))
 
 #define EP93XX_APB_PHYS_BASE           0x80800000
 #define EP93XX_APB_VIRT_BASE           0xfed00000
 #define EP93XX_APB_SIZE                        0x00200000
 
+#define EP93XX_APB_PHYS(x)             (EP93XX_APB_PHYS_BASE + (x))
 #define EP93XX_APB_IOMEM(x)            IOMEM(EP93XX_APB_VIRT_BASE + (x))
 
 
 /* AHB peripherals */
 #define EP93XX_DMA_BASE                        EP93XX_AHB_IOMEM(0x00000000)
 
-#define EP93XX_ETHERNET_PHYS_BASE      (EP93XX_AHB_PHYS_BASE + 0x00010000)
+#define EP93XX_ETHERNET_PHYS_BASE      EP93XX_AHB_PHYS(0x00010000)
 #define EP93XX_ETHERNET_BASE           EP93XX_AHB_IOMEM(0x00010000)
 
-#define EP93XX_USB_PHYS_BASE           (EP93XX_AHB_PHYS_BASE + 0x00020000)
+#define EP93XX_USB_PHYS_BASE           EP93XX_AHB_PHYS(0x00020000)
 #define EP93XX_USB_BASE                        EP93XX_AHB_IOMEM(0x00020000)
 
-#define EP93XX_RASTER_PHYS_BASE                (EP93XX_AHB_PHYS_BASE + 0x00030000)
+#define EP93XX_RASTER_PHYS_BASE                EP93XX_AHB_PHYS(0x00030000)
 #define EP93XX_RASTER_BASE             EP93XX_AHB_IOMEM(0x00030000)
 
 #define EP93XX_GRAPHICS_ACCEL_BASE     EP93XX_AHB_IOMEM(0x00040000)
 
 #define EP93XX_GPIO_BASE               EP93XX_APB_IOMEM(0x00040000)
 #define EP93XX_GPIO_REG(x)             (EP93XX_GPIO_BASE + (x))
-#define EP93XX_GPIO_F_INT_TYPE1                EP93XX_GPIO_REG(0x4c)
-#define EP93XX_GPIO_F_INT_TYPE2                EP93XX_GPIO_REG(0x50)
-#define EP93XX_GPIO_F_INT_ACK          EP93XX_GPIO_REG(0x54)
-#define EP93XX_GPIO_F_INT_ENABLE       EP93XX_GPIO_REG(0x58)
 #define EP93XX_GPIO_F_INT_STATUS       EP93XX_GPIO_REG(0x5c)
-#define EP93XX_GPIO_A_INT_TYPE1                EP93XX_GPIO_REG(0x90)
-#define EP93XX_GPIO_A_INT_TYPE2                EP93XX_GPIO_REG(0x94)
-#define EP93XX_GPIO_A_INT_ACK          EP93XX_GPIO_REG(0x98)
-#define EP93XX_GPIO_A_INT_ENABLE       EP93XX_GPIO_REG(0x9c)
 #define EP93XX_GPIO_A_INT_STATUS       EP93XX_GPIO_REG(0xa0)
-#define EP93XX_GPIO_B_INT_TYPE1                EP93XX_GPIO_REG(0xac)
-#define EP93XX_GPIO_B_INT_TYPE2                EP93XX_GPIO_REG(0xb0)
-#define EP93XX_GPIO_B_INT_ACK          EP93XX_GPIO_REG(0xb4)
-#define EP93XX_GPIO_B_INT_ENABLE       EP93XX_GPIO_REG(0xb8)
 #define EP93XX_GPIO_B_INT_STATUS       EP93XX_GPIO_REG(0xbc)
+#define EP93XX_GPIO_EEDRIVE            EP93XX_GPIO_REG(0xc8)
 
 #define EP93XX_AAC_BASE                        EP93XX_APB_IOMEM(0x00080000)
 
 
 #define EP93XX_IRDA_BASE               EP93XX_APB_IOMEM(0x000b0000)
 
-#define EP93XX_UART1_PHYS_BASE         (EP93XX_APB_PHYS_BASE + 0x000c0000)
+#define EP93XX_UART1_PHYS_BASE         EP93XX_APB_PHYS(0x000c0000)
 #define EP93XX_UART1_BASE              EP93XX_APB_IOMEM(0x000c0000)
 
-#define EP93XX_UART2_PHYS_BASE         (EP93XX_APB_PHYS_BASE + 0x000d0000)
+#define EP93XX_UART2_PHYS_BASE         EP93XX_APB_PHYS(0x000d0000)
 #define EP93XX_UART2_BASE              EP93XX_APB_IOMEM(0x000d0000)
 
-#define EP93XX_UART3_PHYS_BASE         (EP93XX_APB_PHYS_BASE + 0x000e0000)
+#define EP93XX_UART3_PHYS_BASE         EP93XX_APB_PHYS(0x000e0000)
 #define EP93XX_UART3_BASE              EP93XX_APB_IOMEM(0x000e0000)
 
 #define EP93XX_KEY_MATRIX_BASE         EP93XX_APB_IOMEM(0x000f0000)
 #define EP93XX_ADC_BASE                        EP93XX_APB_IOMEM(0x00100000)
 #define EP93XX_TOUCHSCREEN_BASE                EP93XX_APB_IOMEM(0x00100000)
 
-#define EP93XX_PWM_PHYS_BASE           (EP93XX_APB_PHYS_BASE + 0x00110000)
+#define EP93XX_PWM_PHYS_BASE           EP93XX_APB_PHYS(0x00110000)
 #define EP93XX_PWM_BASE                        EP93XX_APB_IOMEM(0x00110000)
 
-#define EP93XX_RTC_PHYS_BASE           (EP93XX_APB_PHYS_BASE + 0x00120000)
+#define EP93XX_RTC_PHYS_BASE           EP93XX_APB_PHYS(0x00120000)
 #define EP93XX_RTC_BASE                        EP93XX_APB_IOMEM(0x00120000)
 
 #define EP93XX_SYSCON_BASE             EP93XX_APB_IOMEM(0x00130000)
 #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        (1<<16)
 #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
 #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV        (1<<0)
+#define EP93XX_SYSCON_SYSCFG           EP93XX_SYSCON_REG(0x9c)
+#define EP93XX_SYSCON_SYSCFG_REV_MASK  (0xf0000000)
+#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
+#define EP93XX_SYSCON_SYSCFG_SBOOT     (1<<8)
+#define EP93XX_SYSCON_SYSCFG_LCSN7     (1<<7)
+#define EP93XX_SYSCON_SYSCFG_LCSN6     (1<<6)
+#define EP93XX_SYSCON_SYSCFG_LASDO     (1<<5)
+#define EP93XX_SYSCON_SYSCFG_LEEDA     (1<<4)
+#define EP93XX_SYSCON_SYSCFG_LEECLK    (1<<3)
+#define EP93XX_SYSCON_SYSCFG_LCSN2     (1<<1)
+#define EP93XX_SYSCON_SYSCFG_LCSN1     (1<<0)
 #define EP93XX_SYSCON_SWLOCK           EP93XX_SYSCON_REG(0xc0)
 
 #define EP93XX_WATCHDOG_BASE           EP93XX_APB_IOMEM(0x00140000)
index 0a1498a..c991b14 100644 (file)
@@ -114,17 +114,9 @@ extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
  *          B0..B7  (7..15) to irq 72..79, and
  *          F0..F7 (16..24) to irq 80..87.
  */
-static inline int gpio_to_irq(unsigned gpio)
-{
-       if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ)
-               return 64 + gpio;
-
-       return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-       return irq - gpio_to_irq(0);
-}
+#define gpio_to_irq(gpio)      \
+       (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
+
+#define irq_to_gpio(irq)       ((irq) - gpio_to_irq(0))
 
 #endif
index 925b12e..554064e 100644 (file)
@@ -9,6 +9,12 @@
 #define PHYS_OFFSET            UL(0x00000000)
 #elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)
 #define PHYS_OFFSET            UL(0xc0000000)
+#elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)
+#define PHYS_OFFSET            UL(0xd0000000)
+#elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)
+#define PHYS_OFFSET            UL(0xe0000000)
+#elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)
+#define PHYS_OFFSET            UL(0xf0000000)
 #else
 #error "Kconfig bug: No EP93xx PHYS_OFFSET set"
 #endif
index 01a0f08..469fd96 100644 (file)
@@ -4,6 +4,7 @@
 
 #ifndef __ASSEMBLY__
 
+struct i2c_gpio_platform_data;
 struct i2c_board_info;
 struct platform_device;
 struct ep93xxfb_mach_info;
@@ -16,7 +17,6 @@ struct ep93xx_eth_data
 
 void ep93xx_map_io(void);
 void ep93xx_init_irq(void);
-void ep93xx_init_time(unsigned long);
 
 /* EP93xx System Controller software locked register write */
 void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
@@ -33,7 +33,8 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
 }
 
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
-void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
+void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
+                        struct i2c_board_info *devices, int num);
 void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
 void ep93xx_register_pwm(int pwm0, int pwm1);
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
index 0a313e8..d83b804 100644 (file)
@@ -2,7 +2,9 @@
  *  linux/arch/arm/mach-ep93xx/micro9.c
  *
  * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
- *                   Manfred Gruber <manfred.gruber@contec.at>
+ *                    Manfred Gruber <m.gruber@tirol.com>
+ * Copyright (C) 2009 Contec Steuerungstechnik & Automation GmbH
+ *                    Hubert Feurstein <hubert.feurstein@contec.at>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include <asm/mach/arch.h>
 
 
-static struct ep93xx_eth_data micro9_eth_data = {
-       .phy_id         = 0x1f,
-};
-
-static void __init micro9_init(void)
-{
-       ep93xx_register_eth(&micro9_eth_data, 1);
-}
-
-/*
- * Micro9-H
- */
-#ifdef CONFIG_MACH_MICRO9H
-static struct physmap_flash_data micro9h_flash_data = {
-       .width          = 4,
-};
-
-static struct resource micro9h_flash_resource = {
+/*************************************************************************
+ * Micro9 NOR Flash
+ *
+ * Micro9-High has up to 64MB of 32-bit flash on CS1
+ * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
+ * Micro9-Lite uses a seperate MTD map driver for flash support
+ * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
+ *************************************************************************/
+static struct physmap_flash_data micro9_flash_data;
+
+static struct resource micro9_flash_resource = {
        .start          = EP93XX_CS1_PHYS_BASE,
        .end            = EP93XX_CS1_PHYS_BASE + SZ_64M - 1,
        .flags          = IORESOURCE_MEM,
 };
 
-static struct platform_device micro9h_flash = {
+static struct platform_device micro9_flash = {
        .name           = "physmap-flash",
        .id             = 0,
        .dev            = {
-               .platform_data  = &micro9h_flash_data,
+               .platform_data  = &micro9_flash_data,
        },
        .num_resources  = 1,
-       .resource       = &micro9h_flash_resource,
+       .resource       = &micro9_flash_resource,
 };
 
-static void __init micro9h_init(void)
+static void __init __micro9_register_flash(unsigned int width)
+{
+       micro9_flash_data.width = width;
+
+       platform_device_register(&micro9_flash);
+}
+
+static unsigned int __init micro9_detect_bootwidth(void)
+{
+       u32 v;
+
+       /* Detect the bus width of the external flash memory */
+       v = __raw_readl(EP93XX_SYSCON_SYSCFG);
+       if (v & EP93XX_SYSCON_SYSCFG_LCSN7)
+               return 4; /* 32-bit */
+       else
+               return 2; /* 16-bit */
+}
+
+static void __init micro9_register_flash(void)
 {
-       platform_device_register(&micro9h_flash);
+       if (machine_is_micro9())
+               __micro9_register_flash(4);
+       else if (machine_is_micro9m() || machine_is_micro9s())
+               __micro9_register_flash(micro9_detect_bootwidth());
 }
 
-static void __init micro9h_init_machine(void)
+
+/*************************************************************************
+ * Micro9 Ethernet
+ *************************************************************************/
+static struct ep93xx_eth_data micro9_eth_data = {
+       .phy_id         = 0x1f,
+};
+
+
+static void __init micro9_init_machine(void)
 {
        ep93xx_init_devices();
-       micro9_init();
-       micro9h_init();
+       ep93xx_register_eth(&micro9_eth_data, 1);
+       micro9_register_flash();
 }
 
-MACHINE_START(MICRO9, "Contec Hypercontrol Micro9-H")
-       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+
+#ifdef CONFIG_MACH_MICRO9H
+MACHINE_START(MICRO9, "Contec Micro9-High")
+       /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
        .phys_io        = EP93XX_APB_PHYS_BASE,
        .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
        .boot_params    = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
        .map_io         = ep93xx_map_io,
        .init_irq       = ep93xx_init_irq,
        .timer          = &ep93xx_timer,
-       .init_machine   = micro9h_init_machine,
+       .init_machine   = micro9_init_machine,
 MACHINE_END
 #endif
 
-/*
- * Micro9-M
- */
 #ifdef CONFIG_MACH_MICRO9M
-static void __init micro9m_init_machine(void)
-{
-       ep93xx_init_devices();
-       micro9_init();
-}
-
-MACHINE_START(MICRO9M, "Contec Hypercontrol Micro9-M")
-       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+MACHINE_START(MICRO9M, "Contec Micro9-Mid")
+       /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
        .phys_io        = EP93XX_APB_PHYS_BASE,
        .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
-       .boot_params    = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+       .boot_params    = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
        .map_io         = ep93xx_map_io,
        .init_irq       = ep93xx_init_irq,
        .timer          = &ep93xx_timer,
-       .init_machine   = micro9m_init_machine,
+       .init_machine   = micro9_init_machine,
 MACHINE_END
 #endif
 
-/*
- * Micro9-L
- */
 #ifdef CONFIG_MACH_MICRO9L
-static void __init micro9l_init_machine(void)
-{
-       ep93xx_init_devices();
-       micro9_init();
-}
-
-MACHINE_START(MICRO9L, "Contec Hypercontrol Micro9-L")
-       /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
+MACHINE_START(MICRO9L, "Contec Micro9-Lite")
+       /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
        .phys_io        = EP93XX_APB_PHYS_BASE,
        .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
        .boot_params    = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
        .map_io         = ep93xx_map_io,
        .init_irq       = ep93xx_init_irq,
        .timer          = &ep93xx_timer,
-       .init_machine   = micro9l_init_machine,
+       .init_machine   = micro9_init_machine,
 MACHINE_END
 #endif
 
+#ifdef CONFIG_MACH_MICRO9S
+MACHINE_START(MICRO9S, "Contec Micro9-Slim")
+       /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = micro9_init_machine,
+MACHINE_END
+#endif
index 4089951..ff5e332 100644 (file)
@@ -638,9 +638,9 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
        _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
        _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
-       _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
-       _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
-       _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
+       _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+       _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+       _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
        _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
        _REGISTER_CLOCK(NULL, "csi", csi_clk)
        _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
@@ -665,7 +665,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
        _REGISTER_CLOCK(NULL, "ata", ata_clk)
        _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
-       _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+       _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
        _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
        _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
index ee65dda..906d59b 100644 (file)
 #include <linux/mtd/plat-ram.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -35,6 +39,7 @@
 #include <mach/iomux.h>
 #include <mach/imx-uart.h>
 #include <mach/mxc_nand.h>
+#include <mach/spi.h>
 
 #include "devices.h"
 
@@ -78,8 +83,6 @@ static int pcm038_pins[] = {
        PC6_PF_I2C2_SCL,
        /* SPI1 */
        PD25_PF_CSPI1_RDY,
-       PD27_PF_CSPI1_SS1,
-       PD28_PF_CSPI1_SS0,
        PD29_PF_CSPI1_SCLK,
        PD30_PF_CSPI1_MISO,
        PD31_PF_CSPI1_MOSI,
@@ -196,6 +199,86 @@ static struct i2c_board_info pcm038_i2c_devices[] = {
        }
 };
 
+static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
+
+static struct spi_imx_master pcm038_spi_0_data = {
+       .chipselect = pcm038_spi_cs,
+       .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
+};
+
+static struct regulator_consumer_supply sdhc1_consumers[] = {
+       {
+               .dev    = &mxc_sdhc_device1.dev,
+               .supply = "sdhc_vcc",
+       },
+};
+
+static struct regulator_init_data sdhc1_data = {
+       .constraints = {
+               .min_uV = 3000000,
+               .max_uV = 3400000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                       REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+               .valid_modes_mask = REGULATOR_MODE_NORMAL |
+                       REGULATOR_MODE_FAST,
+               .always_on = 0,
+               .boot_on = 0,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
+       .consumer_supplies = sdhc1_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+       {
+               .dev    = NULL,
+               .supply = "imx_cam_vcc",
+       },
+};
+
+static struct regulator_init_data cam_data = {
+       .constraints = {
+               .min_uV = 3000000,
+               .max_uV = 3400000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                       REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+               .valid_modes_mask = REGULATOR_MODE_NORMAL |
+                       REGULATOR_MODE_FAST,
+               .always_on = 0,
+               .boot_on = 0,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+       .consumer_supplies = cam_consumers,
+};
+
+struct mc13783_regulator_init_data pcm038_regulators[] = {
+       {
+               .id = MC13783_REGU_VCAM,
+               .init_data = &cam_data,
+       }, {
+               .id = MC13783_REGU_VMMC1,
+               .init_data = &sdhc1_data,
+       },
+};
+
+static struct mc13783_platform_data pcm038_pmic = {
+       .regulators = pcm038_regulators,
+       .num_regulators = ARRAY_SIZE(pcm038_regulators),
+       .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
+                MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+       {
+               .modalias = "mc13783",
+               .irq = IRQ_GPIOB(23),
+               .max_speed_hz = 300000,
+               .bus_num = 0,
+               .chip_select = 0,
+               .platform_data = &pcm038_pmic,
+               .mode = SPI_CS_HIGH,
+       }
+};
+
 static void __init pcm038_init(void)
 {
        mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
@@ -219,6 +302,15 @@ static void __init pcm038_init(void)
        /* PE18 for user-LED D40 */
        mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
 
+       mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+
+       /* MC13783 IRQ */
+       mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
+
+       mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
+       spi_register_board_info(pcm038_spi_board_info,
+                               ARRAY_SIZE(pcm038_spi_board_info));
+
        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
 #ifdef CONFIG_MACH_PCM970_BASEBOARD
index c261f59..3cb7f45 100644 (file)
@@ -39,7 +39,6 @@ static int pcm970_pins[] = {
        PB7_PF_SD2_D3,
        PB8_PF_SD2_CMD,
        PB9_PF_SD2_CLK,
-       GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN, /* card detect */
        /* display */
        PA5_PF_LSCLK,
        PA6_PF_LD0,
@@ -228,6 +227,7 @@ void __init pcm970_baseboard_init(void)
                        "PCM970");
 
        mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+       mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
        mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
        platform_device_register(&pcm970_sja1000);
 }
index eb12de1..63511de 100644 (file)
@@ -1,4 +1,23 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ *
+ * 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/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/gpio.h>
 #include <mach/mx25.h>
 #include <mach/irqs.h>
index 92aa4fd..d23ae57 100644 (file)
@@ -1,3 +1,21 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ *
+ * 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/types.h>
 #include <linux/init.h>
 #include <linux/clk.h>
@@ -23,19 +41,12 @@ static struct imxuart_platform_data uart_pdata = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
 
-static struct mxc_nand_platform_data nand_board_info = {
-       .width = 1,
-       .hw_ecc = 1,
-};
-
 static void __init mx25pdk_init(void)
 {
        mxc_register_device(&mxc_uart_device0, &uart_pdata);
        mxc_register_device(&mxc_usbh2, NULL);
-       mxc_register_device(&mxc_nand_device, &nand_board_info);
 }
 
-
 static void __init mx25pdk_timer_init(void)
 {
        mx25_clocks_init(26000000);
index fe5c421..c595260 100644 (file)
@@ -443,7 +443,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
        _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
        _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
-       _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
+       _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
        _REGISTER_CLOCK(NULL, "max", max_clk)
        _REGISTER_CLOCK(NULL, "admux", admux_clk)
        _REGISTER_CLOCK(NULL, "csi", csi_clk)
index 06bd618..b2a3bcf 100644 (file)
@@ -530,7 +530,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
        _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
        _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
-       _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+       _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
        _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
        _REGISTER_CLOCK(NULL, "epit", epit1_clk)
        _REGISTER_CLOCK(NULL, "epit", epit2_clk)
index 8a577f3..e6abe18 100644 (file)
@@ -459,7 +459,7 @@ struct platform_device mxc_usbh2 = {
  * SPI master controller
  * 3 channels
  */
-static struct resource imx_spi_0_resources[] = {
+static struct resource mxc_spi_0_resources[] = {
        {
               .start = CSPI1_BASE_ADDR,
               .end = CSPI1_BASE_ADDR + SZ_4K - 1,
@@ -471,7 +471,7 @@ static struct resource imx_spi_0_resources[] = {
        },
 };
 
-static struct resource imx_spi_1_resources[] = {
+static struct resource mxc_spi_1_resources[] = {
        {
                .start = CSPI2_BASE_ADDR,
                .end = CSPI2_BASE_ADDR + SZ_4K - 1,
@@ -483,7 +483,7 @@ static struct resource imx_spi_1_resources[] = {
        },
 };
 
-static struct resource imx_spi_2_resources[] = {
+static struct resource mxc_spi_2_resources[] = {
        {
                .start = CSPI3_BASE_ADDR,
                .end = CSPI3_BASE_ADDR + SZ_4K - 1,
@@ -495,25 +495,25 @@ static struct resource imx_spi_2_resources[] = {
        },
 };
 
-struct platform_device imx_spi_device0 = {
+struct platform_device mxc_spi_device0 = {
        .name = "spi_imx",
        .id = 0,
-       .num_resources = ARRAY_SIZE(imx_spi_0_resources),
-       .resource = imx_spi_0_resources,
+       .num_resources = ARRAY_SIZE(mxc_spi_0_resources),
+       .resource = mxc_spi_0_resources,
 };
 
-struct platform_device imx_spi_device1 = {
+struct platform_device mxc_spi_device1 = {
        .name = "spi_imx",
        .id = 1,
-       .num_resources = ARRAY_SIZE(imx_spi_1_resources),
-       .resource = imx_spi_1_resources,
+       .num_resources = ARRAY_SIZE(mxc_spi_1_resources),
+       .resource = mxc_spi_1_resources,
 };
 
-struct platform_device imx_spi_device2 = {
+struct platform_device mxc_spi_device2 = {
        .name = "spi_imx",
        .id = 2,
-       .num_resources = ARRAY_SIZE(imx_spi_2_resources),
-       .resource = imx_spi_2_resources,
+       .num_resources = ARRAY_SIZE(mxc_spi_2_resources),
+       .resource = mxc_spi_2_resources,
 };
 
 #ifdef CONFIG_ARCH_MX35
index 79f2be4..ab87419 100644 (file)
@@ -20,7 +20,7 @@ extern struct platform_device mxc_otg_host;
 extern struct platform_device mxc_usbh1;
 extern struct platform_device mxc_usbh2;
 extern struct platform_device mxc_rnga_device;
-extern struct platform_device imx_spi_device0;
-extern struct platform_device imx_spi_device1;
-extern struct platform_device imx_spi_device2;
+extern struct platform_device mxc_spi_device0;
+extern struct platform_device mxc_spi_device1;
+extern struct platform_device mxc_spi_device2;
 
index ad5a112..bedf5b8 100644 (file)
@@ -81,6 +81,7 @@ void __init mx31_map_io(void)
        iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
 
+#ifdef CONFIG_ARCH_MX35
 void __init mx35_map_io(void)
 {
        mxc_set_cpu_type(MXC_CPU_MX35);
@@ -89,6 +90,7 @@ void __init mx35_map_io(void)
 
        iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
+#endif
 
 void __init mx31_init_irq(void)
 {
index 42920f9..8ad5cc3 100644 (file)
@@ -219,6 +219,10 @@ static struct platform_device *ams_delta_devices[] __initdata = {
 
 static void __init ams_delta_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+
        iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
 
        omap_board_config = ams_delta_config;
@@ -231,6 +235,8 @@ static void __init ams_delta_init(void)
 
        omap_usb_init(&ams_delta_usb_config);
        platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
+
+       omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
 }
 
 static struct plat_serial8250_port ams_delta_modem_ports[] = {
index fb47239..6c8a41f 100644 (file)
@@ -64,6 +64,14 @@ static void __init omap_generic_init(void)
 {
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap15xx()) {
+               /* mux pins for uarts */
+               omap_cfg_reg(UART1_TX);
+               omap_cfg_reg(UART1_RTS);
+               omap_cfg_reg(UART2_TX);
+               omap_cfg_reg(UART2_RTS);
+               omap_cfg_reg(UART3_TX);
+               omap_cfg_reg(UART3_RX);
+
                omap_usb_init(&generic1510_usb_config);
        }
 #endif
index cc2abbb..cd6c395 100644 (file)
@@ -376,6 +376,26 @@ static void __init innovator_init(void)
 {
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap1510()) {
+               unsigned char reg;
+
+               /* mux pins for uarts */
+               omap_cfg_reg(UART1_TX);
+               omap_cfg_reg(UART1_RTS);
+               omap_cfg_reg(UART2_TX);
+               omap_cfg_reg(UART2_RTS);
+               omap_cfg_reg(UART3_TX);
+               omap_cfg_reg(UART3_RX);
+
+               reg = fpga_read(OMAP1510_FPGA_POWER);
+               reg |= OMAP1510_FPGA_PCR_COM1_EN;
+               fpga_write(reg, OMAP1510_FPGA_POWER);
+               udelay(10);
+
+               reg = fpga_read(OMAP1510_FPGA_POWER);
+               reg |= OMAP1510_FPGA_PCR_COM2_EN;
+               fpga_write(reg, OMAP1510_FPGA_POWER);
+               udelay(10);
+
                platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
                spi_register_board_info(innovator1510_boardinfo,
                                ARRAY_SIZE(innovator1510_boardinfo));
index 90dd043..4de2584 100644 (file)
@@ -342,6 +342,14 @@ static void __init palmte_misc_gpio_setup(void)
 
 static void __init omap_palmte_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+       omap_cfg_reg(UART2_TX);
+       omap_cfg_reg(UART2_RTS);
+       omap_cfg_reg(UART3_TX);
+       omap_cfg_reg(UART3_RX);
+
        omap_board_config = palmte_config;
        omap_board_config_size = ARRAY_SIZE(palmte_config);
 
index 8256139..d972cf9 100644 (file)
@@ -289,6 +289,14 @@ static void __init omap_mpu_wdt_mode(int mode) {
 
 static void __init omap_palmtt_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+       omap_cfg_reg(UART2_TX);
+       omap_cfg_reg(UART2_RTS);
+       omap_cfg_reg(UART3_TX);
+       omap_cfg_reg(UART3_RX);
+
        omap_mpu_wdt_mode(0);
 
        omap_board_config = palmtt_config;
index 81b6bde..986bd4d 100644 (file)
@@ -307,6 +307,14 @@ palmz71_gpio_setup(int early)
 static void __init
 omap_palmz71_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+       omap_cfg_reg(UART2_TX);
+       omap_cfg_reg(UART2_RTS);
+       omap_cfg_reg(UART3_TX);
+       omap_cfg_reg(UART3_RX);
+
        palmz71_gpio_setup(1);
        omap_mpu_wdt_mode(0);
 
index 02c85ca..056ae64 100644 (file)
@@ -377,6 +377,14 @@ static struct omap_board_config_kernel sx1_config[] __initdata = {
 
 static void __init omap_sx1_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+       omap_cfg_reg(UART2_TX);
+       omap_cfg_reg(UART2_RTS);
+       omap_cfg_reg(UART3_TX);
+       omap_cfg_reg(UART3_RX);
+
        platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
 
        omap_board_config = sx1_config;
index c06e7a5..07b0752 100644 (file)
@@ -152,6 +152,14 @@ static void __init voiceblue_init_irq(void)
 
 static void __init voiceblue_init(void)
 {
+       /* mux pins for uarts */
+       omap_cfg_reg(UART1_TX);
+       omap_cfg_reg(UART1_RTS);
+       omap_cfg_reg(UART2_TX);
+       omap_cfg_reg(UART2_RTS);
+       omap_cfg_reg(UART3_TX);
+       omap_cfg_reg(UART3_RX);
+
        /* Watchdog */
        gpio_request(0, "Watchdog");
        /* smc91x reset */
index d496e50..d23979b 100644 (file)
@@ -131,8 +131,6 @@ void __init omap_serial_init(void)
        }
 
        for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
-               unsigned char reg;
-
                switch (i) {
                case 0:
                        uart1_ck = clk_get(NULL, "uart1_ck");
@@ -143,16 +141,6 @@ void __init omap_serial_init(void)
                                if (cpu_is_omap15xx())
                                        clk_set_rate(uart1_ck, 12000000);
                        }
-                       if (cpu_is_omap15xx()) {
-                               omap_cfg_reg(UART1_TX);
-                               omap_cfg_reg(UART1_RTS);
-                               if (machine_is_omap_innovator()) {
-                                       reg = fpga_read(OMAP1510_FPGA_POWER);
-                                       reg |= OMAP1510_FPGA_PCR_COM1_EN;
-                                       fpga_write(reg, OMAP1510_FPGA_POWER);
-                                       udelay(10);
-                               }
-                       }
                        break;
                case 1:
                        uart2_ck = clk_get(NULL, "uart2_ck");
@@ -165,16 +153,6 @@ void __init omap_serial_init(void)
                                else
                                        clk_set_rate(uart2_ck, 48000000);
                        }
-                       if (cpu_is_omap15xx()) {
-                               omap_cfg_reg(UART2_TX);
-                               omap_cfg_reg(UART2_RTS);
-                               if (machine_is_omap_innovator()) {
-                                       reg = fpga_read(OMAP1510_FPGA_POWER);
-                                       reg |= OMAP1510_FPGA_PCR_COM2_EN;
-                                       fpga_write(reg, OMAP1510_FPGA_POWER);
-                                       udelay(10);
-                               }
-                       }
                        break;
                case 2:
                        uart3_ck = clk_get(NULL, "uart3_ck");
@@ -185,10 +163,6 @@ void __init omap_serial_init(void)
                                if (cpu_is_omap15xx())
                                        clk_set_rate(uart3_ck, 12000000);
                        }
-                       if (cpu_is_omap15xx()) {
-                               omap_cfg_reg(UART3_TX);
-                               omap_cfg_reg(UART3_RX);
-                       }
                        break;
                }
                omap_serial_reset(&serial_platform_data[i]);
index 75b1c7e..aad194f 100644 (file)
@@ -73,9 +73,21 @@ config MACH_OMAP_3430SDP
        bool "OMAP 3430 SDP board"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
 
+config MACH_NOKIA_N800
+       bool
+
+config MACH_NOKIA_N810
+       bool
+
+config MACH_NOKIA_N810_WIMAX
+       bool
+
 config MACH_NOKIA_N8X0
        bool "Nokia N800/N810"
        depends on ARCH_OMAP2420
+       select MACH_NOKIA_N800
+       select MACH_NOKIA_N810
+       select MACH_NOKIA_N810_WIMAX
 
 config MACH_NOKIA_RX51
        bool "Nokia RX-51 board"
index efaf053..0acb556 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
@@ -38,7 +39,6 @@
 #include <mach/gpmc.h>
 
 #include <mach/control.h>
-#include <mach/keypad.h>
 #include <mach/gpmc-smc91x.h>
 
 #include "sdram-qimonda-hyb18m512160af-6.h"
index eb37c40..609a5a4 100644 (file)
@@ -58,6 +58,8 @@ static void __init gic_init_irq(void)
 
 static void __init omap_4430sdp_init_irq(void)
 {
+       omap_board_config = sdp4430_config;
+       omap_board_config_size = ARRAY_SIZE(sdp4430_config);
        omap2_init_common_hw(NULL, NULL);
 #ifdef CONFIG_OMAP_32K_TIMER
        omap2_gp_clockevent_set_gptimer(1);
@@ -70,8 +72,6 @@ static void __init omap_4430sdp_init_irq(void)
 static void __init omap_4430sdp_init(void)
 {
        platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
-       omap_board_config = sdp4430_config;
-       omap_board_config_size = ARRAY_SIZE(sdp4430_config);
        omap_serial_init();
 }
 
index d110a7f..d57ec2f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/gpio_keys.h>
 #include <linux/workqueue.h>
 #include <linux/err.h>
@@ -41,7 +42,6 @@
 #include <asm/delay.h>
 #include <mach/control.h>
 #include <mach/usb.h>
-#include <mach/keypad.h>
 
 #include "mmc-twl4030.h"
 
index e4ec0c5..4c4d7f8 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/leds.h>
 
 #include <linux/spi/spi.h>
@@ -37,7 +38,6 @@
 #include <mach/usb.h>
 #include <mach/common.h>
 #include <mach/mcspi.h>
-#include <mach/keypad.h>
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
index 7f6bf87..5326e0d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/i2c/twl4030.h>
 #include <linux/leds.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/gpio_keys.h>
 
 #include <asm/mach-types.h>
@@ -39,7 +40,6 @@
 #include <mach/hardware.h>
 #include <mach/mcspi.h>
 #include <mach/usb.h>
-#include <mach/keypad.h>
 #include <mach/mux.h>
 
 #include "sdram-micron-mt46h32m32lf-6.h"
index c1af532..e34d96a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c.h>
 #include <linux/i2c/twl4030.h>
@@ -27,7 +28,6 @@
 #include <mach/common.h>
 #include <mach/dma.h>
 #include <mach/gpmc.h>
-#include <mach/keypad.h>
 #include <mach/onenand.h>
 #include <mach/gpmc-smc91x.h>
 
@@ -444,7 +444,7 @@ static int __init rx51_i2c_init(void)
                rx51_twldata.vaux3 = &rx51_vaux3_cam;
                rx51_twldata.vmmc2 = &rx51_vmmc2;
        }
-       omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
+       omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1,
                        ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
        omap_register_i2c_bus(2, 100, NULL, 0);
        omap_register_i2c_bus(3, 400, NULL, 0);
index f9196c3..78869a9 100644 (file)
@@ -26,7 +26,6 @@
 #include <mach/mux.h>
 #include <mach/board.h>
 #include <mach/common.h>
-#include <mach/keypad.h>
 #include <mach/dma.h>
 #include <mach/gpmc.h>
 #include <mach/usb.h>
index b7b3220..ea00486 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 #include <linux/gpio.h>
 #include <linux/i2c/twl4030.h>
 #include <linux/regulator/machine.h>
@@ -22,9 +23,9 @@
 
 #include <mach/common.h>
 #include <mach/usb.h>
-#include <mach/keypad.h>
 
 #include "mmc-twl4030.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
 
 /* Zoom2 has Qwerty keyboard*/
 static int board_keymap[] = {
@@ -213,7 +214,8 @@ static void __init omap_zoom2_init_irq(void)
 {
        omap_board_config = zoom2_config;
        omap_board_config_size = ARRAY_SIZE(zoom2_config);
-       omap2_init_common_hw(NULL, NULL);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+                                mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
index bc5d3ac..e2dbedd 100644 (file)
@@ -769,6 +769,7 @@ int __init omap2_clk_init(void)
                if (c->cpu & cpu_mask) {
                        clkdev_add(&c->lk);
                        clk_register(c->lk.clk);
+                       omap2_init_clk_clkdm(c->lk.clk);
                }
 
        /* Check the MPU rate set by bootloader */
index 4ef7b4f..58aff84 100644 (file)
@@ -137,6 +137,36 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
        }
 }
 
+/*
+ * _omap2_clkdm_set_hwsup - set the hwsup idle transition bit
+ * @clkdm: struct clockdomain *
+ * @enable: int 0 to disable, 1 to enable
+ *
+ * Internal helper for actually switching the bit that controls hwsup
+ * idle transitions for clkdm.
+ */
+static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
+{
+       u32 v;
+
+       if (cpu_is_omap24xx()) {
+               if (enable)
+                       v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
+               else
+                       v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
+       } else if (cpu_is_omap34xx()) {
+               if (enable)
+                       v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
+               else
+                       v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
+       } else {
+               BUG();
+       }
+
+       cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+                           v << __ffs(clkdm->clktrctrl_mask),
+                           clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+}
 
 static struct clockdomain *_clkdm_lookup(const char *name)
 {
@@ -456,8 +486,6 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
  */
 void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
 {
-       u32 v;
-
        if (!clkdm)
                return;
 
@@ -473,18 +501,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
        if (atomic_read(&clkdm->usecount) > 0)
                _clkdm_add_autodeps(clkdm);
 
-       if (cpu_is_omap24xx())
-               v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
-       else if (cpu_is_omap34xx())
-               v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
-       else
-               BUG();
-
-
-       cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
-                           v << __ffs(clkdm->clktrctrl_mask),
-                           clkdm->pwrdm.ptr->prcm_offs,
-                           CM_CLKSTCTRL);
+       _omap2_clkdm_set_hwsup(clkdm, 1);
 
        pwrdm_clkdm_state_switch(clkdm);
 }
@@ -500,8 +517,6 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
  */
 void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
 {
-       u32 v;
-
        if (!clkdm)
                return;
 
@@ -514,16 +529,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
        pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
                 clkdm->name);
 
-       if (cpu_is_omap24xx())
-               v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
-       else if (cpu_is_omap34xx())
-               v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
-       else
-               BUG();
-
-       cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
-                           v << __ffs(clkdm->clktrctrl_mask),
-                           clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
+       _omap2_clkdm_set_hwsup(clkdm, 0);
 
        if (atomic_read(&clkdm->usecount) > 0)
                _clkdm_del_autodeps(clkdm);
@@ -569,10 +575,14 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
        v = omap2_clkdm_clktrctrl_read(clkdm);
 
        if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
-           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+               /* Disable HW transitions when we are changing deps */
+               _omap2_clkdm_set_hwsup(clkdm, 0);
                _clkdm_add_autodeps(clkdm);
-       else
+               _omap2_clkdm_set_hwsup(clkdm, 1);
+       } else {
                omap2_clkdm_wakeup(clkdm);
+       }
 
        pwrdm_wait_transition(clkdm->pwrdm.ptr);
        pwrdm_clkdm_state_switch(clkdm);
@@ -623,10 +633,14 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
        v = omap2_clkdm_clktrctrl_read(clkdm);
 
        if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
-           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+           (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
+               /* Disable HW transitions when we are changing deps */
+               _omap2_clkdm_set_hwsup(clkdm, 0);
                _clkdm_del_autodeps(clkdm);
-       else
+               _omap2_clkdm_set_hwsup(clkdm, 1);
+       } else {
                omap2_clkdm_sleep(clkdm);
+       }
 
        pwrdm_clkdm_state_switch(clkdm);
 
index e3a3bad..56be87d 100644 (file)
@@ -302,7 +302,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
        pwrdm_init(powerdomains_omap);
        clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
        omap2_clk_init();
+#endif
        omap_serial_early_init();
+#ifndef CONFIG_ARCH_OMAP4
        omap_hwmod_late_init();
        omap_pm_if_init();
        omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
index 378c2f6..8946319 100644 (file)
@@ -639,14 +639,15 @@ static void __init prcm_setup_regs(void)
        prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
                          OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
-       /* Enable GPIO wakeups in PER */
+       /* Enable wakeups in PER */
        prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
                          OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
-                         OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
+                         OMAP3430_EN_GPIO6 | OMAP3430_EN_UART3,
+                         OMAP3430_PER_MOD, PM_WKEN);
        /* and allow them to wake up MPU */
        prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
                          OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
-                         OMAP3430_GRPSEL_GPIO6,
+                         OMAP3430_GRPSEL_GPIO6 | OMAP3430_EN_UART3,
                          OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 
        /* Don't attach IVA interrupts */
index ae21868..54dfeb5 100644 (file)
@@ -109,16 +109,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
                .regshift       = 2,
                .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
-#ifdef CONFIG_ARCH_OMAP4
-               .membase        = OMAP2_IO_ADDRESS(OMAP_UART4_BASE),
-               .mapbase        = OMAP_UART4_BASE,
-               .irq            = 70,
-               .flags          = UPF_BOOT_AUTOCONF,
-               .iotype         = UPIO_MEM,
-               .regshift       = 2,
-               .uartclk        = OMAP24XX_BASE_BAUD * 16,
-       }, {
-#endif
                .flags          = 0
        }
 };
index aac2cda..102916f 100644 (file)
 
 #define CM_X300_ETH_PHYS       0x08000010
 
-#define GPIO82_MMC2_IRQ                (82)
-#define GPIO85_MMC2_WP         (85)
+#define GPIO82_MMC_IRQ         (82)
+#define GPIO85_MMC_WP          (85)
 
-#define        CM_X300_MMC2_IRQ        IRQ_GPIO(GPIO82_MMC2_IRQ)
+#define        CM_X300_MMC_IRQ         IRQ_GPIO(GPIO82_MMC_IRQ)
 
 #define GPIO95_RTC_CS          (95)
 #define GPIO96_RTC_WR          (96)
@@ -292,37 +292,37 @@ static inline void cm_x300_init_nand(void) {}
 #endif
 
 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
-/* The first MMC slot of CM-X300 is hardwired to Libertas card and has
+static struct pxamci_platform_data cm_x300_mci_platform_data = {
+       .detect_delay           = 20,
+       .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
+       .gpio_card_detect       = GPIO82_MMC_IRQ,
+       .gpio_card_ro           = GPIO85_MMC_WP,
+       .gpio_power             = -1,
+};
+
+/* The second MMC slot of CM-X300 is hardwired to Libertas card and has
    no detection/ro pins */
-static int cm_x300_mci_init(struct device *dev,
-                           irq_handler_t cm_x300_detect_int,
-                           void *data)
+static int cm_x300_mci2_init(struct device *dev,
+                            irq_handler_t cm_x300_detect_int,
+       void *data)
 {
        return 0;
 }
 
-static void cm_x300_mci_exit(struct device *dev, void *data)
+static void cm_x300_mci2_exit(struct device *dev, void *data)
 {
 }
 
-static struct pxamci_platform_data cm_x300_mci_platform_data = {
+static struct pxamci_platform_data cm_x300_mci2_platform_data = {
        .detect_delay           = 20,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .init                   = cm_x300_mci_init,
-       .exit                   = cm_x300_mci_exit,
+       .init                   = cm_x300_mci2_init,
+       .exit                   = cm_x300_mci2_exit,
        .gpio_card_detect       = -1,
        .gpio_card_ro           = -1,
        .gpio_power             = -1,
 };
 
-static struct pxamci_platform_data cm_x300_mci2_platform_data = {
-       .detect_delay           = 20,
-       .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .gpio_card_detect       = GPIO82_MMC2_IRQ,
-       .gpio_card_ro           = GPIO85_MMC2_WP,
-       .gpio_power             = -1,
-};
-
 static void __init cm_x300_init_mmc(void)
 {
        pxa_set_mci_info(&cm_x300_mci_platform_data);
index 3a8ee22..983cc8c 100644 (file)
@@ -155,7 +155,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
 
 static pxa_freqs_t pxa27x_freqs[] = {
        {104000, 104000, PXA27x_CCCR(1,  8, 2), 0, CCLKCFG2(1, 0, 1),  900000, 1705000 },
-       {156000, 104000, PXA27x_CCCR(1,  8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 },
+       {156000, 104000, PXA27x_CCCR(1,  8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
        {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
        {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
        {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
index 79141f8..965480e 100644 (file)
@@ -238,7 +238,7 @@ static struct resource csb726_lan_resources[] = {
 };
 
 struct smsc911x_platform_config csb726_lan_config = {
-       .irq_type       = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
        .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
        .flags          = SMSC911X_USE_32BIT,
        .phy_interface  = PHY_INTERFACE_MODE_MII,
index ee8d603..82ff573 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gpio_keys.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/mtd/physmap.h>
@@ -375,6 +376,43 @@ static struct platform_device spitzkbd_device = {
 };
 
 
+static struct gpio_keys_button spitz_gpio_keys[] = {
+       {
+               .type   = EV_PWR,
+               .code   = KEY_SUSPEND,
+               .gpio   = SPITZ_GPIO_ON_KEY,
+               .desc   = "On/Off",
+               .wakeup = 1,
+       },
+       /* Two buttons detecting the lid state */
+       {
+               .type   = EV_SW,
+               .code   = 0,
+               .gpio   = SPITZ_GPIO_SWA,
+               .desc   = "Display Down",
+       },
+       {
+               .type   = EV_SW,
+               .code   = 1,
+               .gpio   = SPITZ_GPIO_SWB,
+               .desc   = "Lid Closed",
+       },
+};
+
+static struct gpio_keys_platform_data spitz_gpio_keys_platform_data = {
+       .buttons        = spitz_gpio_keys,
+       .nbuttons       = ARRAY_SIZE(spitz_gpio_keys),
+};
+
+static struct platform_device spitz_gpio_keys_device = {
+       .name   = "gpio-keys",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &spitz_gpio_keys_platform_data,
+       },
+};
+
+
 /*
  * Spitz LEDs
  */
@@ -689,6 +727,7 @@ static struct platform_device sharpsl_rom_device = {
 static struct platform_device *devices[] __initdata = {
        &spitzscoop_device,
        &spitzkbd_device,
+       &spitz_gpio_keys_device,
        &spitzled_device,
        &sharpsl_nand_device,
        &sharpsl_rom_device,
index 8a5546e..bb7b819 100644 (file)
@@ -25,6 +25,7 @@ led-$(CONFIG_SA1100_CERF)             += leds-cerf.o
 
 obj-$(CONFIG_SA1100_COLLIE)            += collie.o
 
+obj-$(CONFIG_SA1100_H3100)             += h3600.o
 obj-$(CONFIG_SA1100_H3600)             += h3600.o
 
 obj-$(CONFIG_SA1100_HACKKIT)           += hackkit.o
index e993140..9264d81 100644 (file)
@@ -122,10 +122,7 @@ config CPU_ARM920T
        select CPU_TLB_V4WBI if MMU
        help
          The ARM920T is licensed to be produced by numerous vendors,
-         and is used in the Maverick EP9312 and the Samsung S3C2410.
-
-         More information on the Maverick EP9312 at
-         <http://linuxdevices.com/products/PD2382866068.html>.
+         and is used in the Cirrus EP93xx and the Samsung S3C2410.
 
          Say Y if you want support for the ARM920T processor.
          Otherwise, say N.
index 8f5c13f..295e25d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 #include "proc-macros.S"
 
@@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v6_coherent_user_range)
-
+ UNWIND(.fnstart               )
 #ifdef HARVARD_CACHE
        bic     r0, r0, #CACHE_LINE_SIZE - 1
-1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D line
+1:
+ USER( mcr     p15, 0, r0, c7, c10, 1  )       @ clean D line
        add     r0, r0, #CACHE_LINE_SIZE
+2:
        cmp     r0, r1
        blo     1b
 #endif
@@ -142,6 +145,19 @@ ENTRY(v6_coherent_user_range)
 #endif
        mov     pc, lr
 
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+       mov     r0, r0, lsr #12
+       mov     r0, r0, lsl #12
+       add     r0, r0, #4096
+       b       2b
+ UNWIND(.fnend         )
+ENDPROC(v6_coherent_user_range)
+ENDPROC(v6_coherent_kern_range)
+
 /*
  *     v6_flush_kern_dcache_page(kaddr)
  *
index bda0ec3..e1bd975 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 #include "proc-macros.S"
 
@@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v7_coherent_user_range)
+ UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
-1:     mcr     p15, 0, r0, c7, c11, 1          @ clean D line to the point of unification
+1:
+ USER( mcr     p15, 0, r0, c7, c11, 1  )       @ clean D line to the point of unification
        dsb
      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I line
USER( mcr     p15, 0, r0, c7, c5, 1   )       @ invalidate I line
        add     r0, r0, r2
+2:
        cmp     r0, r1
        blo     1b
        mov     r0, #0
@@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range)
        dsb
        isb
        mov     pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+       mov     r0, r0, lsr #12
+       mov     r0, r0, lsl #12
+       add     r0, r0, #4096
+       b       2b
+ UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
 
index bc0099d..d0d17b6 100644 (file)
@@ -153,14 +153,11 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 
        page = pfn_to_page(pfn);
        mapping = page_mapping(page);
-       if (mapping) {
 #ifndef CONFIG_SMP
-               int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
-
-               if (dirty)
-                       __flush_dcache_page(mapping, page);
+       if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+               __flush_dcache_page(mapping, page);
 #endif
-
+       if (mapping) {
                if (cache_is_vivt())
                        make_coherent(mapping, vma, addr, pfn);
                else if (vma->vm_flags & VM_EXEC)
index ae0e25f..10e0680 100644 (file)
@@ -292,6 +292,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
                 * down_read()
                 */
                might_sleep();
+#ifdef CONFIG_DEBUG_VM
+               if (!user_mode(regs) &&
+                   !search_exception_tables(regs->ARM_pc))
+                       goto no_context;
+#endif
        }
 
        fault = __do_page_fault(mm, addr, fsr, tsk);
index 73cae57..30f82fb 100644 (file)
@@ -46,6 +46,8 @@ void *kmap_atomic(struct page *page, enum km_type type)
        if (!PageHighMem(page))
                return page_address(page);
 
+       debug_kmap_atomic(type);
+
        kmap = kmap_high_get(page);
        if (kmap)
                return kmap;
index 877c492..40940d7 100644 (file)
@@ -483,7 +483,7 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
        /*
         * Convert start_pfn/end_pfn to a struct page pointer.
         */
-       start_pg = pfn_to_page(start_pfn);
+       start_pg = pfn_to_page(start_pfn - 1) + 1;
        end_pg = pfn_to_page(end_pfn);
 
        /*
index fe58138..f7d2ec5 100644 (file)
@@ -33,6 +33,9 @@ static int irqs[] = {
 #ifdef CONFIG_ARCH_OMAP2
        3,
 #endif
+#ifdef CONFIG_ARCH_BCMRING
+       IRQ_PMUIRQ, /* for BCMRING, ARM PMU interrupt is 43 */
+#endif
 };
 
 static void armv6_pmu_stop(void)
index fd3154a..b53125f 100644 (file)
@@ -829,10 +829,10 @@ EXPORT_SYMBOL(omap_free_dma);
  *
  * @param arb_rate
  * @param max_fifo_depth
- * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM
- *                                                 DMA_THREAD_RESERVE_ONET
- *                                                 DMA_THREAD_RESERVE_TWOT
- *                                                 DMA_THREAD_RESERVE_THREET
+ * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM
+ *                                                DMA_THREAD_RESERVE_ONET
+ *                                                DMA_THREAD_RESERVE_TWOT
+ *                                                DMA_THREAD_RESERVE_THREET
  */
 void
 omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
@@ -844,11 +844,14 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
                return;
        }
 
+       if (max_fifo_depth == 0)
+               max_fifo_depth = 1;
        if (arb_rate == 0)
                arb_rate = 1;
 
-       reg = (arb_rate & 0xff) << 16;
-       reg |= (0xff & max_fifo_depth);
+       reg = 0xff & max_fifo_depth;
+       reg |= (0x3 & tparams) << 12;
+       reg |= (arb_rate & 0xff) << 16;
 
        dma_write(reg, GCR);
 }
@@ -975,6 +978,14 @@ void omap_stop_dma(int lch)
 {
        u32 l;
 
+       /* Disable all interrupts on the channel */
+       if (cpu_class_is_omap1())
+               dma_write(0, CICR(lch));
+
+       l = dma_read(CCR(lch));
+       l &= ~OMAP_DMA_CCR_EN;
+       dma_write(l, CCR(lch));
+
        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
                int next_lch, cur_lch = lch;
                char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
@@ -992,18 +1003,8 @@ void omap_stop_dma(int lch)
                        next_lch = dma_chan[cur_lch].next_lch;
                        cur_lch = next_lch;
                } while (next_lch != -1);
-
-               return;
        }
 
-       /* Disable all interrupts on the channel */
-       if (cpu_class_is_omap1())
-               dma_write(0, CICR(lch));
-
-       l = dma_read(CCR(lch));
-       l &= ~OMAP_DMA_CCR_EN;
-       dma_write(l, CCR(lch));
-
        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 EXPORT_SYMBOL(omap_stop_dma);
index d91b9be..3ae52cc 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef ASMARM_ARCH_KEYPAD_H
 #define ASMARM_ARCH_KEYPAD_H
 
-#include <linux/input/matrix_keypad.h>
+#warning: Please update the board to use matrix_keypad.h instead
 
 struct omap_kp_platform_data {
        int rows;
@@ -37,6 +37,9 @@ struct omap_kp_platform_data {
 
 #define KEY_PERSISTENT         0x00800000
 #define KEYNUM_MASK            0x00EFFFFF
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+#define PERSISTENT_KEY(col, row) (((col) << 28) | ((row) << 24) | \
+                                               KEY_PERSISTENT)
 
 #endif
 
index 4b60127..94584f1 100644 (file)
@@ -664,7 +664,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da)
                nent = 1; /* for the next L1 entry */
        } else {
                bytes = IOPGD_SIZE;
-               if (*iopgd & IOPGD_SUPER) {
+               if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
                        nent *= 16;
                        /* rewind to the 1st entry */
                        iopgd = (u32 *)((u32)iopgd & IOSUPER_MASK);
index 88ac976..e664b91 100644 (file)
@@ -595,7 +595,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
        rx &= 1;
        if (cpu_is_omap2430() || cpu_is_omap34xx()) {
                w = OMAP_MCBSP_READ(io_base, RCCR);
-               w |= (tx ? RDISABLE : 0);
+               w |= (rx ? RDISABLE : 0);
                OMAP_MCBSP_WRITE(io_base, RCCR, w);
        }
        w = OMAP_MCBSP_READ(io_base, SPCR1);
index 6b0a2b6..0974c0e 100644 (file)
@@ -527,7 +527,7 @@ static void do_signal(void)
 
 no_signal:
        /* Did we come from a system call? */
-       if (__frame->syscallno >= 0) {
+       if (__frame->syscallno != -1) {
                /* Restart the system call - no handlers present */
                switch (__frame->gr8) {
                case -ERESTARTNOHAND:
index 29dd848..ecdc19a 100644 (file)
@@ -561,7 +561,7 @@ config HPAPCI
 
 config MVME147_SCC
        bool "SCC support for MVME147 serial ports"
-       depends on MVME147
+       depends on MVME147 && BROKEN
        help
          This is the driver for the serial ports on the Motorola MVME147
          boards.  Everyone using one of these boards should say Y here.
@@ -576,14 +576,14 @@ config SERIAL167
 
 config MVME162_SCC
        bool "SCC support for MVME162 serial ports"
-       depends on MVME16x
+       depends on MVME16x && BROKEN
        help
          This is the driver for the serial ports on the Motorola MVME162 and
          172 boards.  Everyone using one of these boards should say Y here.
 
 config BVME6000_SCC
        bool "SCC support for BVME6000 serial ports"
-       depends on BVME6000
+       depends on BVME6000 && BROKEN
        help
          This is the driver for the serial ports on the BVME4000 and BVME6000
          boards from BVM Ltd.  Everyone using one of these boards should say
index cee8080..dd38608 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                };
 
                sram@8000 {
index 4c36186..8e9be6b 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
 
                        rtc@50 {
                                compatible = "at,24c08";
index de30b3f..82ff2b1 100644 (file)
                        compatible = "fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
                };
 
                i2c@3d40 {
                        compatible = "fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                };
                sram@8000 {
                        compatible = "fsl,mpc5200-sram";
index d13cb11..e45a63b 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
                };
 
                i2c@3d40 {
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                };
 
                sram@8000 {
index e297d8b..0c3902b 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
                };
 
                i2c@3d40 {
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                };
 
                sram@8000 {
index 7be8ca0..6ca4fc1 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
 
                        rtc@68 {
                                compatible = "dallas,ds1339";
index c2b8dbf..c353dac 100644 (file)
                        reg = <0x1700 0x20>;
                        interrupts = <9 0x8>;
                        interrupt-parent = < &ipic >;
-                       fsl5200-clocking;
                };
 
                i2c@1720 {
                        reg = <0x1720 0x20>;
                        interrupts = <10 0x8>;
                        interrupt-parent = < &ipic >;
-                       fsl5200-clocking;
                };
 
                i2c@1740 {
                        reg = <0x1740 0x20>;
                        interrupts = <11 0x8>;
                        interrupt-parent = < &ipic >;
-                       fsl5200-clocking;
                };
 
                i2ccontrol@1760 {
diff --git a/arch/powerpc/boot/dts/mucmc52.dts b/arch/powerpc/boot/dts/mucmc52.dts
new file mode 100644 (file)
index 0000000..b72a758
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Manroland mucmc52 board Device Tree Source
+ *
+ * Copyright (C) 2009 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ * Copyright 2006-2007 Secret Lab Technologies Ltd.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "manroland,mucmc52";
+       compatible = "manroland,mucmc52";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&mpc5200_pic>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,5200@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <0x4000>;        // L1, 16K
+                       i-cache-size = <0x4000>;        // L1, 16K
+                       timebase-frequency = <0>;       // from bootloader
+                       bus-frequency = <0>;            // from bootloader
+                       clock-frequency = <0>;          // from bootloader
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x04000000>;  // 64MB
+       };
+
+       soc5200@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc5200b-immr";
+               ranges = <0 0xf0000000 0x0000c000>;
+               reg = <0xf0000000 0x00000100>;
+               bus-frequency = <0>;            // from bootloader
+               system-frequency = <0>;         // from bootloader
+
+               cdm@200 {
+                       compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+                       reg = <0x200 0x38>;
+               };
+
+               mpc5200_pic: interrupt-controller@500 {
+                       // 5200 interrupts are encoded into two levels;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+                       reg = <0x500 0x80>;
+               };
+
+               gpt0: timer@600 {       // GPT 0 in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x600 0x10>;
+                       interrupts = <1 9 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt1: timer@610 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x610 0x10>;
+                       interrupts = <1 10 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt2: timer@620 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x620 0x10>;
+                       interrupts = <1 11 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt3: timer@630 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x630 0x10>;
+                       interrupts = <1 12 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpio_simple: gpio@b00 {
+                       compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+                       reg = <0xb00 0x40>;
+                       interrupts = <1 7 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpio_wkup: gpio@c00 {
+                       compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+                       reg = <0xc00 0x40>;
+                       interrupts = <1 8 0 0 3 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               dma-controller@1200 {
+                       compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+                       reg = <0x1200 0x80>;
+                       interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+                                     3 4 0  3 5 0  3 6 0  3 7 0
+                                     3 8 0  3 9 0  3 10 0  3 11 0
+                                     3 12 0  3 13 0  3 14 0  3 15 0>;
+               };
+
+               xlb@1f00 {
+                       compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+                       reg = <0x1f00 0x100>;
+               };
+
+               serial@2000 { /* PSC1 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2000 0x100>;
+                       interrupts = <2 1 0>;
+               };
+
+               serial@2200 { /* PSC2 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2200 0x100>;
+                       interrupts = <2 2 0>;
+               };
+
+               serial@2c00 { /* PSC6 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2c00 0x100>;
+                       interrupts = <2 4 0>;
+               };
+
+               ethernet@3000 {
+                       compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+                       reg = <0x3000 0x400>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <2 5 0>;
+                       phy-handle = <&phy0>;
+               };
+
+               mdio@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+                       reg = <0x3000 0x400>;   // fec range, since we need to setup fec interrupts
+                       interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
+
+                       phy0: ethernet-phy@0 {
+                               compatible = "intel,lxt971";
+                               reg = <0>;
+                       };
+               };
+
+               ata@3a00 {
+                       compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+                       reg = <0x3a00 0x100>;
+                       interrupts = <2 7 0>;
+               };
+
+               i2c@3d40 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d40 0x40>;
+                       interrupts = <2 16 0>;
+                       hwmon@2c {
+                               compatible = "ad,adm9240";
+                               reg = <0x2c>;
+                       };
+                       rtc@51 {
+                               compatible = "nxp,pcf8563";
+                               reg = <0x51>;
+                       };
+               };
+
+               sram@8000 {
+                       compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+                       reg = <0x8000 0x4000>;
+               };
+       };
+
+       pci@f0000d00 {
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               device_type = "pci";
+               compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+               reg = <0xf0000d00 0x100>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <
+                               /* IDSEL 0x10 */
+                               0x8000 0 0 1 &mpc5200_pic 0 3 3
+                               0x8000 0 0 2 &mpc5200_pic 0 3 3
+                               0x8000 0 0 3 &mpc5200_pic 0 2 3
+                               0x8000 0 0 4 &mpc5200_pic 0 1 3
+                               >;
+               clock-frequency = <0>; // From boot loader
+               interrupts = <2 8 0 2 9 0 2 10 0>;
+               bus-range = <0 0>;
+               ranges = <0x42000000 0 0x60000000 0x60000000 0 0x10000000
+                         0x02000000 0 0x90000000 0x90000000 0 0x10000000
+                         0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+       };
+
+       localbus {
+               compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+               #address-cells = <2>;
+               #size-cells = <1>;
+
+               ranges = <0 0 0xff800000 0x00800000
+                         1 0 0x80000000 0x00800000
+                         3 0 0x80000000 0x00800000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x00800000>;
+                       bank-width = <4>;
+                       device-width = <2>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+                       partition@0 {
+                               label = "DTS";
+                               reg = <0x0 0x00100000>;
+                       };
+                       partition@100000 {
+                               label = "Kernel";
+                               reg = <0x100000 0x00200000>;
+                       };
+                       partition@300000 {
+                               label = "RootFS";
+                               reg = <0x00300000 0x00200000>;
+                       };
+                       partition@500000 {
+                               label = "user";
+                               reg = <0x00500000 0x00200000>;
+                       };
+                       partition@700000 {
+                               label = "U-Boot";
+                               reg = <0x00700000 0x00040000>;
+                       };
+                       partition@740000 {
+                               label = "Env";
+                               reg = <0x00740000 0x00020000>;
+                       };
+                       partition@760000 {
+                               label = "red. Env";
+                               reg = <0x00760000 0x00020000>;
+                       };
+                       partition@780000 {
+                               label = "reserve";
+                               reg = <0x00780000 0x00080000>;
+                       };
+               };
+
+               simple100: gpio-controller-100@3,600100 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600100 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple104: gpio-controller-104@3,600104 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600104 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple200: gpio-controller-200@3,600200 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600200 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple201: gpio-controller-201@3,600201 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600201 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple202: gpio-controller-202@3,600202 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600202 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple203: gpio-controller-203@3,600203 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600203 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple204: gpio-controller-204@3,600204 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600204 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple206: gpio-controller-206@3,600206 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600206 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple207: gpio-controller-207@3,600207 {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x00600207 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+               simple20f: gpio-controller-20f@3,60020f {
+                       compatible = "manroland,mucmc52-aux-gpio";
+                       reg = <3 0x0060020f 0x1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+       };
+};
index 30bfdc0..8a4ec30 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
                };
 
                i2c@3d40 {
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                        rtc@51 {
                                compatible = "nxp,pcf8563";
                                reg = <0x51>;
index 0300426..85d857a 100644 (file)
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d00 0x40>;
                        interrupts = <2 15 0>;
-                       fsl5200-clocking;
                };
 
                i2c@3d40 {
                        compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
                        rtc@51 {
                                compatible = "nxp,pcf8563";
                                reg = <0x51>;
index c9590b5..1db07f6 100644 (file)
                        compatible = "fsl,mpc5200-i2c","fsl-i2c";
                        reg = <0x3d40 0x40>;
                        interrupts = <2 16 0>;
-                       fsl5200-clocking;
 
                         rtc@68 {
                                compatible = "dallas,ds1307";
diff --git a/arch/powerpc/boot/dts/uc101.dts b/arch/powerpc/boot/dts/uc101.dts
new file mode 100644 (file)
index 0000000..019264c
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Manroland uc101 board Device Tree Source
+ *
+ * Copyright (C) 2009 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ * Copyright 2006-2007 Secret Lab Technologies Ltd.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "manroland,uc101";
+       compatible = "manroland,uc101";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&mpc5200_pic>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,5200@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <0x4000>;        // L1, 16K
+                       i-cache-size = <0x4000>;        // L1, 16K
+                       timebase-frequency = <0>;       // from bootloader
+                       bus-frequency = <0>;            // from bootloader
+                       clock-frequency = <0>;          // from bootloader
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x04000000>;  // 64MB
+       };
+
+       soc5200@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc5200b-immr";
+               ranges = <0 0xf0000000 0x0000c000>;
+               reg = <0xf0000000 0x00000100>;
+               bus-frequency = <0>;            // from bootloader
+               system-frequency = <0>;         // from bootloader
+
+               cdm@200 {
+                       compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+                       reg = <0x200 0x38>;
+               };
+
+               mpc5200_pic: interrupt-controller@500 {
+                       // 5200 interrupts are encoded into two levels;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+                       reg = <0x500 0x80>;
+               };
+
+               gpt0: timer@600 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x600 0x10>;
+                       interrupts = <1 9 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt1: timer@610 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x610 0x10>;
+                       interrupts = <1 10 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt2: timer@620 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x620 0x10>;
+                       interrupts = <1 11 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt3: timer@630 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x630 0x10>;
+                       interrupts = <1 12 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt4: timer@640 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x640 0x10>;
+                       interrupts = <1 13 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt5: timer@650 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x650 0x10>;
+                       interrupts = <1 14 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt6: timer@660 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x660 0x10>;
+                       interrupts = <1 15 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpt7: timer@670 {       // General Purpose Timer in GPIO mode
+                       compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+                       reg = <0x670 0x10>;
+                       interrupts = <1 16 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpio_simple: gpio@b00 {
+                       compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+                       reg = <0xb00 0x40>;
+                       interrupts = <1 7 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpio_wkup: gpio@c00 {
+                       compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+                       reg = <0xc00 0x40>;
+                       interrupts = <1 8 0 0 3 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               dma-controller@1200 {
+                       compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+                       reg = <0x1200 0x80>;
+                       interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+                                     3 4 0  3 5 0  3 6 0  3 7 0
+                                     3 8 0  3 9 0  3 10 0  3 11 0
+                                     3 12 0  3 13 0  3 14 0  3 15 0>;
+               };
+
+               xlb@1f00 {
+                       compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+                       reg = <0x1f00 0x100>;
+               };
+
+               serial@2000 { /* PSC1 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2000 0x100>;
+                       interrupts = <2 1 0>;
+               };
+
+               serial@2200 { /* PSC2 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2200 0x100>;
+                       interrupts = <2 2 0>;
+               };
+
+               serial@2c00 {           /* PSC6 in UART mode */
+                       compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+                       reg = <0x2c00 0x100>;
+                       interrupts = <2 4 0>;
+               };
+
+               ethernet@3000 {
+                       compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+                       reg = <0x3000 0x400>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <2 5 0>;
+                       phy-handle = <&phy0>;
+               };
+
+               mdio@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+                       reg = <0x3000 0x400>;   // fec range, since we need to setup fec interrupts
+                       interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
+
+                       phy0: ethernet-phy@0 {
+                               compatible = "intel,lxt971";
+                               reg = <0>;
+                       };
+               };
+
+               ata@3a00 {
+                       compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+                       reg = <0x3a00 0x100>;
+                       interrupts = <2 7 0>;
+               };
+
+               i2c@3d40 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d40 0x40>;
+                       interrupts = <2 16 0>;
+                       fsl,preserve-clocking;
+                       clock-frequency = <400000>;
+
+                       hwmon@2c {
+                               compatible = "ad,adm9240";
+                               reg = <0x2c>;
+                       };
+                       rtc@51 {
+                               compatible = "nxp,pcf8563";
+                               reg = <0x51>;
+                       };
+               };
+
+               sram@8000 {
+                       compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+                       reg = <0x8000 0x4000>;
+               };
+       };
+
+       localbus {
+               compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+               #address-cells = <2>;
+               #size-cells = <1>;
+
+               ranges = <0 0 0xff800000 0x00800000
+                         1 0 0x80000000 0x00800000
+                         3 0 0x80000000 0x00800000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x00800000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       partition@0 {
+                               label = "DTS";
+                               reg = <0x0 0x00100000>;
+                       };
+                       partition@100000 {
+                               label = "Kernel";
+                               reg = <0x100000 0x00200000>;
+                       };
+                       partition@300000 {
+                               label = "RootFS";
+                               reg = <0x00300000 0x00200000>;
+                       };
+                       partition@500000 {
+                               label = "user";
+                               reg = <0x00500000 0x00200000>;
+                       };
+                       partition@700000 {
+                               label = "U-Boot";
+                               reg = <0x00700000 0x00040000>;
+                       };
+                       partition@740000 {
+                               label = "Env";
+                               reg = <0x00740000 0x00010000>;
+                       };
+                       partition@750000 {
+                               label = "red. Env";
+                               reg = <0x00750000 0x00010000>;
+                       };
+                       partition@760000 {
+                               label = "reserve";
+                               reg = <0x00760000 0x000a0000>;
+                       };
+               };
+
+       };
+};
index 3838b77..0396ce7 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:47:44 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:22 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,13 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -140,7 +158,7 @@ CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -219,11 +237,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -239,9 +259,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -252,6 +273,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -328,6 +350,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -342,6 +365,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -367,6 +391,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -457,6 +482,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -495,10 +521,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -519,7 +541,6 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -558,14 +579,14 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -636,6 +657,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -646,6 +668,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -666,23 +689,23 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -713,25 +736,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -775,11 +785,12 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
@@ -866,6 +877,10 @@ CONFIG_USB_STORAGE=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -885,10 +900,13 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -959,12 +977,12 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1064,6 +1082,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1073,6 +1092,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1090,10 +1110,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1105,11 +1129,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1118,23 +1143,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1159,7 +1186,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1200,11 +1226,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
index 29b0f34..f5c07fd 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:04 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:24 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,12 +56,14 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -78,11 +84,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -106,7 +113,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -119,6 +125,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -127,14 +140,19 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -147,7 +165,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -228,11 +246,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -248,9 +268,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -264,6 +285,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -348,6 +370,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -362,6 +385,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -387,6 +411,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -397,6 +422,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_MTD is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -431,7 +457,9 @@ CONFIG_MISC_DEVICES=y
 #
 # CONFIG_EEPROM_AT24 is not set
 # CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -454,10 +482,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -475,6 +499,8 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -483,6 +509,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
@@ -502,7 +529,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -514,11 +540,14 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
@@ -540,6 +569,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -568,6 +598,7 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
@@ -586,14 +617,17 @@ CONFIG_PATA_MPC52xx=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -640,9 +674,12 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -661,6 +698,8 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -686,10 +725,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -759,6 +795,7 @@ CONFIG_GEN_RTC=y
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -787,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -812,23 +850,23 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -847,30 +885,18 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -913,6 +939,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -932,10 +962,13 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -992,12 +1025,12 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1041,6 +1074,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1050,6 +1084,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1067,10 +1102,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1082,11 +1121,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1095,23 +1135,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1136,7 +1178,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1178,11 +1219,13 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
index 07b6b26..4f77a1b 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:22 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:22 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,13 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -140,7 +158,7 @@ CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -220,11 +238,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -240,9 +260,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -253,6 +274,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -329,6 +351,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -343,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -368,6 +392,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -458,6 +483,7 @@ CONFIG_MTD_ROM=y
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -483,6 +509,7 @@ CONFIG_MISC_DEVICES=y
 #
 # CONFIG_EEPROM_AT24 is not set
 CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -506,10 +533,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -532,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
@@ -540,7 +564,6 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -579,14 +602,14 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -647,6 +670,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -657,6 +681,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -676,22 +701,28 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -738,6 +769,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -747,9 +780,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -775,25 +806,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -817,7 +835,7 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_BD2802 is not set
 
@@ -866,6 +884,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -893,6 +912,10 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -912,10 +935,13 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -986,12 +1012,12 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1091,6 +1117,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1100,6 +1127,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1117,10 +1145,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1132,11 +1164,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1145,23 +1178,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1186,7 +1221,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1227,11 +1261,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
index afb1a3d..f9168c1 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:42 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:25 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,13 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -79,11 +85,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -105,7 +112,6 @@ CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -125,7 +138,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -133,7 +145,13 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -146,7 +164,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -227,11 +245,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -247,9 +267,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -336,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -350,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -375,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -382,9 +406,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_OF_PARTS is not set
@@ -467,6 +491,7 @@ CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 # CONFIG_BLK_DEV is not set
 # CONFIG_MISC_DEVICES is not set
@@ -492,10 +517,6 @@ CONFIG_BLK_DEV_SD=m
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -515,6 +536,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
@@ -536,6 +558,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -564,6 +587,7 @@ CONFIG_PATA_MPC52xx=m
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
@@ -582,14 +606,17 @@ CONFIG_PATA_MPC52xx=m
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -636,16 +663,16 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -722,6 +749,7 @@ CONFIG_HW_RANDOM=y
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -750,6 +778,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -776,23 +805,23 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -811,30 +840,18 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -871,15 +888,17 @@ CONFIG_USB_DEVICEFS=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_HCD_PPC_SOC is not set
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 # CONFIG_USB_OHCI_HCD_PCI is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -995,6 +1014,7 @@ CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1022,6 +1042,10 @@ CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1041,12 +1065,16 @@ CONFIG_FS_MBCACHE=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -1114,7 +1142,6 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1201,6 +1228,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1210,6 +1238,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1223,23 +1252,12 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BOOTX_TEXT is not set
index 8585c7c..75c835c 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Sat Apr 18 00:48:57 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:23 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -52,11 +56,13 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -77,11 +83,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -105,7 +112,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -118,6 +124,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -125,14 +138,19 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -145,7 +163,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -225,11 +243,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -245,9 +265,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -258,6 +279,7 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -334,6 +356,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -348,6 +371,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -373,6 +397,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -382,9 +407,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_OF_PARTS is not set
@@ -464,6 +489,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -502,10 +528,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -529,6 +551,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
@@ -538,7 +561,6 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -577,14 +599,14 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -654,6 +676,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -664,6 +687,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -685,22 +709,28 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
@@ -747,6 +777,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -756,9 +788,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -789,25 +819,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -851,11 +868,12 @@ CONFIG_USB_MON=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
@@ -969,6 +987,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -996,6 +1015,10 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1015,10 +1038,13 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1089,12 +1115,12 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1194,6 +1220,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1203,6 +1230,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1220,10 +1248,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1235,11 +1267,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1248,23 +1281,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1289,7 +1324,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1331,11 +1365,13 @@ CONFIG_CRYPTO_PCBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
index aaa4416..523d5fe 100644 (file)
@@ -1,25 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Mon Apr 20 11:06:25 2009
+# Linux kernel version: 2.6.32-rc4
+# Thu Oct 15 10:33:21 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-CONFIG_6xx=y
+CONFIG_PPC_BOOK3S_32=y
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
 CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
@@ -30,15 +32,17 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
@@ -53,12 +57,14 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 CONFIG_DEFAULT_UIMAGE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -79,11 +85,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -103,7 +110,6 @@ CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -116,6 +122,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -124,14 +137,19 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -144,7 +162,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -205,7 +223,7 @@ CONFIG_RTAS_PROC=y
 CONFIG_PPC_BESTCOMM=y
 CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
-# CONFIG_SIMPLE_GPIO is not set
+CONFIG_SIMPLE_GPIO=y
 
 #
 # Kernel options
@@ -229,11 +247,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_MAX_ACTIVE_REGIONS=32
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -249,9 +269,10 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -265,6 +286,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -349,6 +371,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -363,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -388,6 +412,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -397,9 +422,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
@@ -458,6 +483,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_DATAFLASH is not set
 # CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -493,6 +519,7 @@ CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -529,7 +556,9 @@ CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 # CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -552,10 +581,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -572,6 +597,8 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -580,6 +607,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
@@ -599,7 +627,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -611,11 +638,14 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
@@ -637,6 +667,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -665,6 +696,7 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
@@ -684,14 +716,17 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -739,16 +774,17 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_ATL2 is not set
+# CONFIG_XILINX_EMACLITE is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 
@@ -854,6 +890,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=y
@@ -883,6 +920,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
@@ -910,10 +948,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -935,6 +969,11 @@ CONFIG_SPI_MPC52xx_PSC=m
 #
 CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
@@ -957,16 +996,27 @@ CONFIG_GPIOLIB=y
 # PCI GPIO expanders:
 #
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADCXX is not set
@@ -1019,6 +1069,8 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -1031,9 +1083,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -1073,31 +1123,20 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
 # CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
 CONFIG_DRM=y
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1167,6 +1206,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y
 # CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
 # CONFIG_LCD_LTV350QV is not set
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
@@ -1198,7 +1238,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1217,10 +1256,11 @@ CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
 # CONFIG_HID_CHICONY is not set
 CONFIG_HID_CYPRESS=y
-# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=y
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
@@ -1231,10 +1271,11 @@ CONFIG_HID_EZKEY=y
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
 # CONFIG_HID_SUNPLUS is not set
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
 # CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1261,15 +1302,17 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PCI=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -1400,6 +1443,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1411,6 +1455,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_R9701 is not set
 # CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -1434,6 +1479,10 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1453,10 +1502,13 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1533,12 +1585,12 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1624,6 +1676,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -1633,6 +1686,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
@@ -1650,10 +1704,14 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1665,11 +1723,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1678,23 +1737,25 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1719,7 +1780,6 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD2=y
@@ -1761,11 +1821,13 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
new file mode 100644 (file)
index 0000000..18af460
--- /dev/null
@@ -0,0 +1,2199 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Fri Oct 16 11:37:15 2009
+#
+CONFIG_PPC64=y
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_64 is not set
+CONFIG_PPC_BOOK3E_64=y
+CONFIG_PPC_BOOK3E=y
+CONFIG_PPC_FPU=y
+CONFIG_BOOKE=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_64=y
+CONFIG_PPC_BOOK3E_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+CONFIG_PPC_PERF_CTRS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+# CONFIG_PPC_OF_PLATFORM_PCI is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_TASK_XACCT is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_U3_DART is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# CPU Frequency drivers
+#
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_IOMMU_VMERGE=y
+CONFIG_IOMMU_HELPER=y
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_PPC_HAS_HASH_64K is not set
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_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
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_HOTPLUG_PCI=m
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HAS_RAPIDIO is not set
+# CONFIG_RELOCATABLE is not set
+CONFIG_PAGE_OFFSET=0xc000000000000000
+CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=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_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+# CONFIG_NF_CONNTRACK_SANE is not set
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# 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
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=y
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+CONFIG_SCSI_IPR=y
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+CONFIG_SCSI_DEBUG=m
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=y
+CONFIG_ATA_SFF=y
+CONFIG_SATA_SVW=y
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=y
+CONFIG_MD_RAID456=y
+# CONFIG_MULTICORE_RAID456 is not set
+CONFIG_MD_RAID6_PQ=y
+# CONFIG_ASYNC_RAID6_TEST is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+# CONFIG_DM_LOG_USERSPACE is not set
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_QL is not set
+# CONFIG_DM_MULTIPATH_ST is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+CONFIG_IEEE1394=y
+CONFIG_IEEE1394_OHCI1394=y
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_RAWIO=y
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_DV1394=m
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_I2O is not set
+CONFIG_MACINTOSH_DRIVERS=y
+# CONFIG_MAC_EMUMOUSEBTN is not set
+CONFIG_WINDFARM=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+CONFIG_BROADCOM_PHY=m
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+CONFIG_SUNGEM=y
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ACENIC=y
+CONFIG_ACENIC_OMIT_TIGON_I=y
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+CONFIG_IXGB=m
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+CONFIG_TR=y
+CONFIG_IBMOL=y
+# CONFIG_3C359 is not set
+# CONFIG_TMS380TR is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_NET_PCMCIA is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+CONFIG_I2C_AMD8111=y
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_IBM_GXT4500=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# 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_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CTXFI is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LX6464ES is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_PPC=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_PCMCIA=y
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_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
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+CONFIG_USB_APPLEDISPLAY=m
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_INFINIBAND=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+# CONFIG_INFINIBAND_IPATH is not set
+# CONFIG_INFINIBAND_AMSO1100 is not set
+# CONFIG_MLX4_INFINIBAND is not set
+# CONFIG_INFINIBAND_NES is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+# CONFIG_INFINIBAND_SRP is not set
+CONFIG_INFINIBAND_ISER=m
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+# CONFIG_EDAC_CPC925 is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=y
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_XPRT_RDMA=m
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# Kernel hacking
+#
+# 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_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_TRACE_IRQFLAGS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_SCHED_TRACER=y
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_PPC_EMULATED_STATS is not set
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
+CONFIG_XMON=y
+# CONFIG_XMON_DEFAULT is not set
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
+CONFIG_ASYNC_PQ=y
+CONFIG_ASYNC_RAID6_RECOV=y
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index 3a17982..20778a4 100644 (file)
@@ -37,7 +37,7 @@
 #define FW_FEATURE_VIO         ASM_CONST(0x0000000000004000)
 #define FW_FEATURE_RDMA                ASM_CONST(0x0000000000008000)
 #define FW_FEATURE_LLAN                ASM_CONST(0x0000000000010000)
-#define FW_FEATURE_BULK                ASM_CONST(0x0000000000020000)
+#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000000020000)
 #define FW_FEATURE_XDABR       ASM_CONST(0x0000000000040000)
 #define FW_FEATURE_MULTITCE    ASM_CONST(0x0000000000080000)
 #define FW_FEATURE_SPLPAR      ASM_CONST(0x0000000000100000)
@@ -45,8 +45,7 @@
 #define FW_FEATURE_LPAR                ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1     ASM_CONST(0x0000000000800000)
 #define FW_FEATURE_BEAT                ASM_CONST(0x0000000001000000)
-#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000)
-#define FW_FEATURE_CMO         ASM_CONST(0x0000000004000000)
+#define FW_FEATURE_CMO         ASM_CONST(0x0000000002000000)
 
 #ifndef __ASSEMBLY__
 
@@ -58,8 +57,9 @@ enum {
                FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT |
                FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
                FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
-               FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE |
-               FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO,
+               FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
+               FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
+               FW_FEATURE_CMO,
        FW_FEATURE_PSERIES_ALWAYS = 0,
        FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
        FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
index 0b9c913..03c862b 100644 (file)
@@ -711,6 +711,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_setup              = __setup_cpu_750,
                .machine_check          = machine_check_generic,
                .platform               = "ppc750",
+               .oprofile_cpu_type      = "ppc/750",
+               .oprofile_type          = PPC_OPROFILE_G4,
        },
        {       /* 745/755 */
                .pvr_mask               = 0xfffff000,
index 900e0ee..9763267 100644 (file)
@@ -658,42 +658,43 @@ do_work:
        cmpdi   r0,0
        crandc  eq,cr1*4+eq,eq
        bne     restore
-       /* here we are preempting the current task */
-1:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       bl      .trace_hardirqs_on
-       /* Note: we just clobbered r10 which used to contain the previous
-        * MSR before the hard-disabling done by the caller of do_work.
-        * We don't have that value anymore, but it doesn't matter as
-        * we will hard-enable unconditionally, we can just reload the
-        * current MSR into r10
+
+       /* Here we are preempting the current task.
+        *
+        * Ensure interrupts are soft-disabled. We also properly mark
+        * the PACA to reflect the fact that they are hard-disabled
+        * and trace the change
         */
-       mfmsr   r10
-#endif /* CONFIG_TRACE_IRQFLAGS */
-       li      r0,1
+       li      r0,0
        stb     r0,PACASOFTIRQEN(r13)
        stb     r0,PACAHARDIRQEN(r13)
+       TRACE_DISABLE_INTS
+
+       /* Call the scheduler with soft IRQs off */
+1:     bl      .preempt_schedule_irq
+
+       /* Hard-disable interrupts again (and update PACA) */
 #ifdef CONFIG_PPC_BOOK3E
-       wrteei  1
-       bl      .preempt_schedule
        wrteei  0
 #else
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10,1           /* reenable interrupts */
-       bl      .preempt_schedule
        mfmsr   r10
-       clrrdi  r9,r1,THREAD_SHIFT
-       rldicl  r10,r10,48,1    /* disable interrupts again */
+       rldicl  r10,r10,48,1
        rotldi  r10,r10,16
        mtmsrd  r10,1
 #endif /* CONFIG_PPC_BOOK3E */
+       li      r0,0
+       stb     r0,PACAHARDIRQEN(r13)
+
+       /* Re-test flags and eventually loop */
+       clrrdi  r9,r1,THREAD_SHIFT
        ld      r4,TI_FLAGS(r9)
        andi.   r0,r4,_TIF_NEED_RESCHED
        bne     1b
        b       restore
 
 user_work:
-#endif
+#endif /* CONFIG_PREEMPT */
+
        /* Enable interrupts */
 #ifdef CONFIG_PPC_BOOK3E
        wrteei  1
@@ -1038,8 +1039,7 @@ _GLOBAL(mod_return_to_handler)
         * We are in a module using the module's TOC.
         * Switch to our TOC to run inside the core kernel.
         */
-       LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
-       ld      r2, 8(r4)
+       ld      r2, PACATOC(r13)
 
        bl      .ftrace_return_to_handler
        nop
index fe8f71d..641c74b 100644 (file)
@@ -282,12 +282,6 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
        unsigned long *ptr = gdb_regs;
        int reg;
-#ifdef CONFIG_SPE
-       union {
-               u32 v32[2];
-               u64 v64;
-       } acc;
-#endif
 
        for (reg = 0; reg < 32; reg++)
                UNPACK64(regs->gpr[reg], ptr);
index bb8209e..e8dfdbd 100644 (file)
@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
  * Reparent resource children of pr that conflict with res
  * under res, and make res replace those children.
  */
-static int __init reparent_resources(struct resource *parent,
+static int reparent_resources(struct resource *parent,
                                     struct resource *res)
 {
        struct resource *p, **pp;
index ba949a2..ccf56ac 100644 (file)
@@ -97,7 +97,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
         * to do an appropriate TLB flush here too
         */
        if (bus->self) {
+#ifdef CONFIG_PPC_STD_MMU_64
                struct resource *res = bus->resource[0];
+#endif
 
                pr_debug("IO unmapping for PCI-PCI bridge %s\n",
                         pci_name(bus->self));
index bbcbae1..87f1663 100644 (file)
@@ -116,20 +116,23 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
 static inline u32 perf_get_misc_flags(struct pt_regs *regs)
 {
        unsigned long mmcra = regs->dsisr;
+       unsigned long sihv = MMCRA_SIHV;
+       unsigned long sipr = MMCRA_SIPR;
 
        if (TRAP(regs) != 0xf00)
                return 0;       /* not a PMU interrupt */
 
        if (ppmu->flags & PPMU_ALT_SIPR) {
-               if (mmcra & POWER6_MMCRA_SIHV)
-                       return PERF_RECORD_MISC_HYPERVISOR;
-               return (mmcra & POWER6_MMCRA_SIPR) ?
-                       PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL;
+               sihv = POWER6_MMCRA_SIHV;
+               sipr = POWER6_MMCRA_SIPR;
        }
-       if (mmcra & MMCRA_SIHV)
+
+       /* PR has priority over HV, so order below is important */
+       if (mmcra & sipr)
+               return PERF_RECORD_MISC_USER;
+       if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV))
                return PERF_RECORD_MISC_HYPERVISOR;
-       return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER :
-               PERF_RECORD_MISC_KERNEL;
+       return PERF_RECORD_MISC_KERNEL;
 }
 
 /*
index 1168c5f..c930ac3 100644 (file)
@@ -1016,9 +1016,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        int curr_frame = current->curr_ret_stack;
        extern void return_to_handler(void);
-       unsigned long addr = (unsigned long)return_to_handler;
+       unsigned long rth = (unsigned long)return_to_handler;
+       unsigned long mrth = -1;
 #ifdef CONFIG_PPC64
-       addr = *(unsigned long*)addr;
+       extern void mod_return_to_handler(void);
+       rth = *(unsigned long *)rth;
+       mrth = (unsigned long)mod_return_to_handler;
+       mrth = *(unsigned long *)mrth;
 #endif
 #endif
 
@@ -1044,7 +1048,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
                if (!firstframe || ip != lr) {
                        printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-                       if (ip == addr && curr_frame >= 0) {
+                       if ((ip == rth || ip == mrth) && curr_frame >= 0) {
                                printk(" (%pS)",
                                       (void *)current->ret_stack[curr_frame].ret);
                                curr_frame--;
@@ -1168,7 +1172,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
        unsigned long base = mm->brk;
        unsigned long ret;
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
        /*
         * If we are using 1TB segments and we are allowed to randomise
         * the heap, we can put it above 1TB so it is backed by a 1TB
index 797ea95..04f638d 100644 (file)
@@ -57,7 +57,6 @@
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/mmu-hash64.h>
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
index 94e2df3..137dc22 100644 (file)
@@ -50,6 +50,9 @@
 /* Max supported size for symbol names */
 #define MAX_SYMNAME    64
 
+/* The alignment of the vDSO */
+#define VDSO_ALIGNMENT (1 << 16)
+
 extern char vdso32_start, vdso32_end;
 static void *vdso32_kbase = &vdso32_start;
 static unsigned int vdso32_pages;
@@ -231,15 +234,21 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
         * pick a base address for the vDSO in process space. We try to put it
         * at vdso_base which is the "natural" base for it, but we might fail
         * and end up putting it elsewhere.
+        * Add enough to the size so that the result can be aligned.
         */
        down_write(&mm->mmap_sem);
        vdso_base = get_unmapped_area(NULL, vdso_base,
-                                     vdso_pages << PAGE_SHIFT, 0, 0);
+                                     (vdso_pages << PAGE_SHIFT) +
+                                     ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
+                                     0, 0);
        if (IS_ERR_VALUE(vdso_base)) {
                rc = vdso_base;
                goto fail_mmapsem;
        }
 
+       /* Add required alignment. */
+       vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
+
        /*
         * Put vDSO base into mm struct. We need to do this before calling
         * install_special_mapping or the perf counter mmap tracking code
index 904ef13..0546bcd 100644 (file)
@@ -25,7 +25,7 @@ SECTIONS
        . = ALIGN(16);
        .text           : {
                *(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*)
-       }
+       }                                               :text
        PROVIDE(__etext = .);
        PROVIDE(_etext = .);
        PROVIDE(etext = .);
@@ -56,7 +56,7 @@ SECTIONS
        .fixup          : { *(.fixup) }
 
        .dynamic        : { *(.dynamic) }               :text   :dynamic
-       .got            : { *(.got) }
+       .got            : { *(.got) }                   :text
        .plt            : { *(.plt) }
 
        _end = .;
index f564293..27735a7 100644 (file)
@@ -236,6 +236,7 @@ SECTIONS
                READ_MOSTLY_DATA(L1_CACHE_BYTES)
        }
 
+       . = ALIGN(PAGE_SIZE);
        .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
                NOSAVE_DATA
        }
index bc44dc4..95ce355 100644 (file)
@@ -72,19 +72,17 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
 1:
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
-       /* vmalloc/ioremap mapping encoding bits, the "li" instructions below
-        * will be patched by the kernel at boot
+       /* vmalloc mapping gets the encoding from the PACA as the mapping
+        * can be demoted from 64K -> 4K dynamically on some machines
         */
-BEGIN_FTR_SECTION
-       /* check whether this is in vmalloc or ioremap space */
        clrldi  r11,r10,48
        cmpldi  r11,(VMALLOC_SIZE >> 28) - 1
        bgt     5f
        lhz     r11,PACAVMALLOCSLLP(r13)
        b       6f
 5:
-END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE)
-_GLOBAL(slb_miss_kernel_load_io)
+       /* IO mapping */
+       _GLOBAL(slb_miss_kernel_load_io)
        li      r11,0
 6:
 BEGIN_FTR_SECTION
index c31e5b5..d45be5b 100644 (file)
@@ -51,6 +51,8 @@ static void __init mpc5200_simple_setup_arch(void)
 /* list of the supported boards */
 static char *board[] __initdata = {
        "intercontrol,digsy-mtc",
+       "manroland,mucmc52",
+       "manroland,uc101",
        "phytec,pcm030",
        "phytec,pcm032",
        "promess,motionpro",
index aca5741..a86c34b 100644 (file)
@@ -365,7 +365,7 @@ static int axon_msi_probe(struct of_device *device,
                printk(KERN_ERR
                       "axon_msi: couldn't parse dcr properties on %s\n",
                        dn->full_name);
-               goto out;
+               goto out_free_msic;
        }
 
        msic->dcr_host = dcr_map(dn, dcr_base, dcr_len);
index cc7161f..ce01492 100644 (file)
@@ -1,18 +1,9 @@
 EXTRA_CFLAGS   += -mno-minimal-toc
 
-extra-y += dt.o
-
 obj-y += exception.o
-obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
+obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt.o mf.o lpevents.o \
        hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_VIOPATH) += viopath.o vio.o
 obj-$(CONFIG_MODULES) += ksyms.o
-
-quiet_cmd_dt_strings = DT_STR  $@
-      cmd_dt_strings = $(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings \
-                               $< $@
-
-$(obj)/dt_mod.o:       $(obj)/dt.o
-       $(call if_changed,dt_strings)
index c5a87a7..7f45a51 100644 (file)
 
 /*
  * These are created by the linker script at the start and end
- * of the section containing all the strings from this file.
+ * of the section containing all the strings marked with the DS macro.
  */
 extern char __dt_strings_start[];
 extern char __dt_strings_end[];
 
+#define DS(s)  ({      \
+       static const char __s[] __attribute__((section(".dt_strings"))) = s; \
+       __s;            \
+})
+
 struct iseries_flat_dt {
        struct boot_param_header header;
        u64 reserve_map[2];
@@ -64,9 +69,8 @@ struct iseries_flat_dt {
 static void * __initdata dt_data;
 
 /*
- * Putting these strings here keeps them out of the section
- * that we rename to .dt_strings using objcopy and capture
- * for the strings blob of the flattened device tree.
+ * Putting these strings here keeps them out of the .dt_strings section
+ * that we capture for the strings blob of the flattened device tree.
  */
 static char __initdata device_type_cpu[] = "cpu";
 static char __initdata device_type_memory[] = "memory";
@@ -173,7 +177,7 @@ static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name)
 
 #define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
 
-static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
+static void __init __dt_prop(struct iseries_flat_dt *dt, const char *name,
                const void *data, int len)
 {
        unsigned long offset;
@@ -191,44 +195,32 @@ static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
        /* The actual data. */
        dt_push_bytes(dt, data, len);
 }
+#define dt_prop(dt, name, data, len)   __dt_prop((dt), DS(name), (data), (len))
 
-static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name,
-               const char *data)
-{
-       dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
-}
+#define dt_prop_str(dt, name, data)    \
+       dt_prop((dt), name, (data), strlen((data)) + 1); /* + 1 for NULL */
 
-static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
+static void __init __dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
                u32 data)
 {
-       dt_prop(dt, name, &data, sizeof(u32));
+       __dt_prop(dt, name, &data, sizeof(u32));
 }
+#define dt_prop_u32(dt, name, data)    __dt_prop_u32((dt), DS(name), (data))
 
-static void __init __maybe_unused dt_prop_u64(struct iseries_flat_dt *dt,
-                                             const char *name,
-               u64 data)
+static void __init __maybe_unused __dt_prop_u64(struct iseries_flat_dt *dt,
+               const char *name, u64 data)
 {
-       dt_prop(dt, name, &data, sizeof(u64));
+       __dt_prop(dt, name, &data, sizeof(u64));
 }
+#define dt_prop_u64(dt, name, data)    __dt_prop_u64((dt), DS(name), (data))
 
-static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
-               const char *name, u64 *data, int n)
-{
-       dt_prop(dt, name, data, sizeof(u64) * n);
-}
+#define dt_prop_u64_list(dt, name, data, n)    \
+       dt_prop((dt), name, (data), sizeof(u64) * (n))
 
-static void __init dt_prop_u32_list(struct iseries_flat_dt *dt,
-               const char *name, u32 *data, int n)
-{
-       dt_prop(dt, name, data, sizeof(u32) * n);
-}
+#define dt_prop_u32_list(dt, name, data, n)    \
+       dt_prop((dt), name, (data), sizeof(u32) * (n))
 
-#ifdef notyet
-static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name)
-{
-       dt_prop(dt, name, NULL, 0);
-}
-#endif
+#define dt_prop_empty(dt, name)                dt_prop((dt), name, NULL, 0)
 
 static void __init dt_cpus(struct iseries_flat_dt *dt)
 {
index 21226b7..414ca98 100644 (file)
@@ -540,8 +540,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
        /* Make sure IRQ is disabled */
        kw_write_reg(reg_ier, 0);
 
-       /* Request chip interrupt */
-       if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host))
+       /* Request chip interrupt. We set IRQF_TIMER because we don't
+        * want that interrupt disabled between the 2 passes of driver
+        * suspend or we'll have issues running the pfuncs
+        */
+       if (request_irq(host->irq, kw_i2c_irq, IRQF_TIMER, "keywest i2c", host))
                host->irq = NO_IRQ;
 
        printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
index 5a707da..0a14d8c 100644 (file)
@@ -51,11 +51,10 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
        {FW_FEATURE_VIO,                "hcall-vio"},
        {FW_FEATURE_RDMA,               "hcall-rdma"},
        {FW_FEATURE_LLAN,               "hcall-lLAN"},
-       {FW_FEATURE_BULK,               "hcall-bulk"},
+       {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
        {FW_FEATURE_XDABR,              "hcall-xdabr"},
        {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
        {FW_FEATURE_SPLPAR,             "hcall-splpar"},
-       {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
 };
 
 /* Build up the firmware features bitmask using the contents of
index c6f0a71..bdbe96c 100644 (file)
@@ -517,6 +517,15 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
        in_xmon = 0;
 #endif
 
+#ifdef CONFIG_BOOKE
+       if (regs->msr & MSR_DE) {
+               bp = at_breakpoint(regs->nip);
+               if (bp != NULL) {
+                       regs->nip = (unsigned long) &bp->instr[0];
+                       atomic_inc(&bp->ref_count);
+               }
+       }
+#else
        if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
                bp = at_breakpoint(regs->nip);
                if (bp != NULL) {
@@ -530,7 +539,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
                        }
                }
        }
-
+#endif
        insert_cpu_bpts();
 
        local_irq_restore(flags);
@@ -894,6 +903,14 @@ cmds(struct pt_regs *excp)
        }
 }
 
+#ifdef CONFIG_BOOKE
+static int do_step(struct pt_regs *regs)
+{
+       regs->msr |= MSR_DE;
+       mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+       return 1;
+}
+#else
 /*
  * Step a single instruction.
  * Some instructions we emulate, others we execute with MSR_SE set.
@@ -924,6 +941,7 @@ static int do_step(struct pt_regs *regs)
        regs->msr |= MSR_SE;
        return 1;
 }
+#endif
 
 static void bootcmds(void)
 {
index 704dd39..77df726 100644 (file)
@@ -438,7 +438,7 @@ static int diag204_probe(void)
                }
                if (diag204((unsigned long)SUBC_STIB6 |
                            (unsigned long)INFO_EXT, pages, buf) >= 0) {
-                       diag204_store_sc = SUBC_STIB7;
+                       diag204_store_sc = SUBC_STIB6;
                        diag204_info_type = INFO_EXT;
                        goto out;
                }
index 24b1244..f23961a 100644 (file)
@@ -78,7 +78,7 @@ cputime64_to_jiffies64(cputime64_t cputime)
 static inline unsigned int
 cputime_to_msecs(const cputime_t cputime)
 {
-       return __div(cputime, 4096000);
+       return cputime_div(cputime, 4096000);
 }
 
 static inline cputime_t
@@ -160,7 +160,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value)
 static inline clock_t
 cputime_to_clock_t(cputime_t cputime)
 {
-       return __div(cputime, 4096000000ULL / USER_HZ);
+       return cputime_div(cputime, 4096000000ULL / USER_HZ);
 }
 
 static inline cputime_t
@@ -175,7 +175,7 @@ clock_t_to_cputime(unsigned long x)
 static inline clock_t
 cputime64_to_clock_t(cputime64_t cputime)
 {
-       return __div(cputime, 4096000000ULL / USER_HZ);
+       return cputime_div(cputime, 4096000000ULL / USER_HZ);
 }
 
 struct s390_idle_data {
index ee57a42..4890ac6 100644 (file)
@@ -1595,10 +1595,9 @@ static void stop_run(struct shutdown_trigger *trigger)
 {
        if (strcmp(trigger->name, ON_PANIC_STR) == 0)
                disabled_wait((unsigned long) __builtin_return_address(0));
-       else {
-               signal_processor(smp_processor_id(), sigp_stop);
-               for (;;);
-       }
+       while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+               cpu_relax();
+       for (;;);
 }
 
 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
index 802c8ab..0729f36 100644 (file)
@@ -31,9 +31,9 @@ void __cpuinit print_cpu_info(void)
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-       static const char *hwcap_str[9] = {
+       static const char *hwcap_str[10] = {
                "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
-               "edat", "etf3eh"
+               "edat", "etf3eh", "highgprs"
        };
        struct _lowcore *lc;
        unsigned long n = (unsigned long) v - 1;
@@ -48,7 +48,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                           num_online_cpus(), loops_per_jiffy/(500000/HZ),
                           (loops_per_jiffy/(5000/HZ))%100);
                seq_puts(m, "features\t: ");
-               for (i = 0; i < 9; i++)
+               for (i = 0; i < 10; i++)
                        if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
                                seq_printf(m, "%s ", hwcap_str[i]);
                seq_puts(m, "\n");
index c932caa..93e5203 100644 (file)
@@ -76,7 +76,6 @@ static int cpu_stopped(int cpu)
        __u32 status;
 
        switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
-       case sigp_order_code_accepted:
        case sigp_status_stored:
                /* Check for stopped and check stop state */
                if (status & 0x50)
@@ -638,6 +637,8 @@ void __cpu_die(unsigned int cpu)
        /* Wait until target cpu is down */
        while (!cpu_stopped(cpu))
                cpu_relax();
+       while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy)
+               udelay(10);
        smp_free_lowcore(cpu);
        pr_info("Processor %d stopped\n", cpu);
 }
@@ -645,8 +646,8 @@ void __cpu_die(unsigned int cpu)
 void cpu_die(void)
 {
        idle_task_exit();
-       signal_processor(smp_processor_id(), sigp_stop);
-       BUG();
+       while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+               cpu_relax();
        for (;;);
 }
 
index 7c8653e..0c26cc1 100644 (file)
@@ -199,6 +199,7 @@ pgm_check_entry:
        brc     2,4b                    /* busy, try again */
 5:
        sigp    %r9,%r2,__SIGP_STOP     /* stop resume (current) CPU */
+       brc     2,5b                    /* busy, try again */
 6:     j       6b
 
 restart_suspend:
@@ -206,6 +207,7 @@ restart_suspend:
        llgh    %r2,0(%r1)
 7:
        sigp    %r9,%r2,__SIGP_SENSE    /* Wait for resume CPU */
+       brc     8,7b                    /* accepted, status 0, still running */
        brc     2,7b                    /* busy, try again */
        tmll    %r9,0x40                /* Test if resume CPU is stopped */
        jz      7b
index b940424..88cdeb9 100644 (file)
@@ -37,7 +37,6 @@ config SUPERH32
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
-       select HAVE_FTRACE_SYSCALLS
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_ARCH_KGDB
        select ARCH_HIBERNATION_POSSIBLE if MMU
@@ -122,6 +121,9 @@ config SYS_SUPPORTS_APM_EMULATION
        bool
        select ARCH_SUSPEND_POSSIBLE
 
+config SYS_SUPPORTS_HUGETLBFS
+       bool
+
 config SYS_SUPPORTS_SMP
        bool
 
@@ -196,6 +198,7 @@ config CPU_SH4
        select CPU_HAS_SR_RB
        select CPU_HAS_FPU if !CPU_SH4AL_DSP
        select SYS_SUPPORTS_TMU
+       select SYS_SUPPORTS_HUGETLBFS if MMU
 
 config CPU_SH4A
        bool
@@ -210,6 +213,7 @@ config CPU_SH5
        bool
        select CPU_HAS_FPU
        select SYS_SUPPORTS_TMU
+       select SYS_SUPPORTS_HUGETLBFS if MMU
 
 config CPU_SHX2
        bool
index fc51a91..66e40aa 100644 (file)
@@ -199,7 +199,7 @@ endif
 libs-$(CONFIG_SUPERH32)                := arch/sh/lib/ $(libs-y)
 libs-$(CONFIG_SUPERH64)                := arch/sh/lib64/ $(libs-y)
 
-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \
               zImage vmlinux.srec romImage
 PHONY += maketools $(BOOT_TARGETS) FORCE
 
@@ -225,6 +225,7 @@ define archhelp
        @echo '  vmlinux.srec              - Create an ELF S-record'
        @echo '* uImage                    - Alias to bootable U-Boot image'
        @echo '  uImage.srec               - Create an S-record for U-Boot'
+       @echo '  uImage.bin                - Kernel-only image for U-Boot (bin)'
        @echo '* uImage.gz                 - Kernel-only image for U-Boot (gzip)'
        @echo '  uImage.bz2                - Kernel-only image for U-Boot (bzip2)'
        @echo '  uImage.lzma               - Kernel-only image for U-Boot (lzma)'
index 25cdf73..5280131 100644 (file)
@@ -14,7 +14,6 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/kdev_t.h>
 #include <linux/cdev.h>
 #include <linux/fs.h>
@@ -35,7 +34,7 @@ static int gio_open(struct inode *inode, struct file *filp)
        int minor;
        int ret = -ENOENT;
 
-       lock_kernel();
+       preempt_disable();
        minor = MINOR(inode->i_rdev);
        if (minor < DEVCOUNT) {
                if (openCnt > 0) {
@@ -45,7 +44,7 @@ static int gio_open(struct inode *inode, struct file *filp)
                        ret = 0;
                }
        }
-       unlock_kernel();
+       preempt_enable();
        return ret;
 }
 
@@ -60,8 +59,7 @@ static int gio_close(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static int gio_ioctl(struct inode *inode, struct file *filp,
-                            unsigned int cmd, unsigned long arg)
+static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        unsigned int data;
        static unsigned int addr = 0;
@@ -129,7 +127,7 @@ static const struct file_operations gio_fops = {
        .owner = THIS_MODULE,
        .open = gio_open,       /* open */
        .release = gio_close,   /* release */
-       .ioctl = gio_ioctl,     /* ioctl */
+       .unlocked_ioctl = gio_ioctl,
 };
 
 static int __init gio_init(void)
index 4af3a77..c37617e 100644 (file)
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/map.h>
 #include <linux/smsc911x.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
index af64d03..a5c0df7 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#ifdef CONFIG_MTD
 #include <linux/mtd/map.h>
+#endif
 #include <asm/machvec.h>
 #include <asm/io.h>
 
-static const char *probes[] = { "cmdlinepart", NULL };
-
-static struct mtd_partition *parsed_partitions;
-
 static struct mtd_partition rsk_partitions[] = {
        {
                .name           = "Bootloader",
@@ -41,6 +39,8 @@ static struct mtd_partition rsk_partitions[] = {
 };
 
 static struct physmap_flash_data flash_data = {
+       .parts          = rsk_partitions,
+       .nr_parts       = ARRAY_SIZE(rsk_partitions),
        .width          = 2,
 };
 
@@ -60,7 +60,8 @@ static struct platform_device flash_device = {
        },
 };
 
-static struct mtd_info *flash_mtd;
+#ifdef CONFIG_MTD
+static const char *probes[] = { "cmdlinepart", NULL };
 
 static struct map_info rsk_flash_map = {
        .name           = "RSK+ Flash",
@@ -68,6 +69,10 @@ static struct map_info rsk_flash_map = {
        .bankwidth      = 2,
 };
 
+static struct mtd_info *flash_mtd;
+
+static struct mtd_partition *parsed_partitions;
+
 static void __init set_mtd_partitions(void)
 {
        int nr_parts = 0;
@@ -77,14 +82,14 @@ static void __init set_mtd_partitions(void)
        nr_parts = parse_mtd_partitions(flash_mtd, probes,
                                        &parsed_partitions, 0);
        /* If there is no partition table, used the hard coded table */
-       if (nr_parts <= 0) {
-               flash_data.parts = rsk_partitions;
-               flash_data.nr_parts = ARRAY_SIZE(rsk_partitions);
-       } else {
+       if (nr_parts > 0) {
                flash_data.nr_parts = nr_parts;
                flash_data.parts = parsed_partitions;
        }
 }
+#else
+static inline void set_mtd_partitions(void) {}
+#endif
 
 static struct platform_device *rsk_devices[] __initdata = {
        &flash_device,
index a131687..cb8cf55 100644 (file)
@@ -20,11 +20,12 @@ CONFIG_BOOT_LINK_OFFSET     ?= 0x00800000
 CONFIG_ZERO_PAGE_OFFSET        ?= 0x00001000
 CONFIG_ENTRY_OFFSET    ?= 0x00001000
 
+suffix-y := bin
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
 
-targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma uImage.bin
 extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
 subdir- := compressed romimage
 
@@ -88,6 +89,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
        $(call if_changed,uimage,lzma)
 
+$(obj)/uImage.bin: $(obj)/vmlinux.bin
+       $(call if_changed,uimage,none)
+
 OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
 $(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
        $(call if_changed,objcopy)
index 03b3616..2d07084 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/mempool.h>
 #include <linux/mm.h>
+#include <linux/ftrace.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
@@ -557,6 +558,27 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
        if (!pc && !prev)
                pc = (unsigned long)current_text_addr();
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       /*
+        * If our stack has been patched by the function graph tracer
+        * then we might see the address of return_to_handler() where we
+        * expected to find the real return address.
+        */
+       if (pc == (unsigned long)&return_to_handler) {
+               int index = current->curr_ret_stack;
+
+               /*
+                * We currently have no way of tracking how many
+                * return_to_handler()'s we've seen. If there is more
+                * than one patched return address on our stack,
+                * complain loudly.
+                */
+               WARN_ON(index > 0);
+
+               pc = current->ret_stack[index].ret;
+       }
+#endif
+
        frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
        if (!frame) {
                printk(KERN_ERR "Unable to allocate a dwarf frame\n");
index 68d9223..3eb8493 100644 (file)
@@ -121,7 +121,7 @@ noresched:
 ENTRY(resume_userspace)
        ! r8: current_thread_info
        cli
-       TRACE_IRQS_OfF
+       TRACE_IRQS_OFF
        mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
        tst     #(_TIF_WORK_MASK & 0xff), r0
        bt/s    __restore_all
index a3dcc6d..2c48e26 100644 (file)
@@ -291,31 +291,48 @@ struct syscall_metadata *syscall_nr_to_meta(int nr)
        return syscalls_metadata[nr];
 }
 
-void arch_init_ftrace_syscalls(void)
+int syscall_name_to_nr(char *name)
+{
+       int i;
+
+       if (!syscalls_metadata)
+               return -1;
+       for (i = 0; i < NR_syscalls; i++)
+               if (syscalls_metadata[i])
+                       if (!strcmp(syscalls_metadata[i]->name, name))
+                               return i;
+       return -1;
+}
+
+void set_syscall_enter_id(int num, int id)
+{
+       syscalls_metadata[num]->enter_id = id;
+}
+
+void set_syscall_exit_id(int num, int id)
+{
+       syscalls_metadata[num]->exit_id = id;
+}
+
+static int __init arch_init_ftrace_syscalls(void)
 {
        int i;
        struct syscall_metadata *meta;
        unsigned long **psys_syscall_table = &sys_call_table;
-       static atomic_t refs;
-
-       if (atomic_inc_return(&refs) != 1)
-               goto end;
 
        syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
                                        FTRACE_SYSCALL_MAX, GFP_KERNEL);
        if (!syscalls_metadata) {
                WARN_ON(1);
-               return;
+               return -ENOMEM;
        }
 
        for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
                meta = find_syscall_meta(psys_syscall_table[i]);
                syscalls_metadata[i] = meta;
        }
-       return;
 
-       /* Paranoid: avoid overflow */
-end:
-       atomic_dec(&refs);
+       return 0;
 }
+arch_initcall(arch_init_ftrace_syscalls);
 #endif /* CONFIG_FTRACE_SYSCALLS */
index 7cb933b..eac7da7 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <asm/processor.h>
 #include <asm/machvec.h>
 #include <asm/uaccess.h>
@@ -106,7 +107,7 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 #endif
 
-asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
 #ifdef CONFIG_IRQSTACKS
index f9d44f8..99b4fb5 100644 (file)
@@ -549,6 +549,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        if (cpu == 0)
                seq_printf(m, "machine\t\t: %s\n", get_system_type());
+       else
+               seq_printf(m, "\n");
 
        seq_printf(m, "processor\t: %d\n", cpu);
        seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
index 86c2704..444cce3 100644 (file)
@@ -85,6 +85,20 @@ DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
 DECLARE_EXPORT(__movstrSI12_i4);
 DECLARE_EXPORT(__movmem);
+DECLARE_EXPORT(__movmemSI8);
+DECLARE_EXPORT(__movmemSI12);
+DECLARE_EXPORT(__movmemSI16);
+DECLARE_EXPORT(__movmemSI20);
+DECLARE_EXPORT(__movmemSI24);
+DECLARE_EXPORT(__movmemSI28);
+DECLARE_EXPORT(__movmemSI32);
+DECLARE_EXPORT(__movmemSI36);
+DECLARE_EXPORT(__movmemSI40);
+DECLARE_EXPORT(__movmemSI44);
+DECLARE_EXPORT(__movmemSI48);
+DECLARE_EXPORT(__movmemSI52);
+DECLARE_EXPORT(__movmemSI56);
+DECLARE_EXPORT(__movmemSI60);
 DECLARE_EXPORT(__movmem_i4_even);
 DECLARE_EXPORT(__movmem_i4_odd);
 DECLARE_EXPORT(__movmemSI12_i4);
index 6729703..3db3742 100644 (file)
@@ -145,7 +145,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
 {
        struct task_struct *tsk = current;
 
-       if (!(current_cpu_data.flags & CPU_HAS_FPU))
+       if (!(boot_cpu_data.flags & CPU_HAS_FPU))
                return 0;
 
        set_used_math();
@@ -158,7 +158,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
 {
        struct task_struct *tsk = current;
 
-       if (!(current_cpu_data.flags & CPU_HAS_FPU))
+       if (!(boot_cpu_data.flags & CPU_HAS_FPU))
                return 0;
 
        if (!used_math()) {
@@ -199,7 +199,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
 #undef COPY
 
 #ifdef CONFIG_SH_FPU
-       if (current_cpu_data.flags & CPU_HAS_FPU) {
+       if (boot_cpu_data.flags & CPU_HAS_FPU) {
                int owned_fp;
                struct task_struct *tsk = current;
 
@@ -472,6 +472,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                err |= __put_user(OR_R0_R0, &frame->retcode[6]);
                err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
                regs->pr = (unsigned long) frame->retcode;
+               flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
        }
 
        if (err)
@@ -497,8 +498,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
                 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
-       flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
-
        return 0;
 
 give_sigsegv:
index 442d8d4..160db10 100644 (file)
@@ -35,6 +35,8 @@ static inline void __init smp_store_cpu_info(unsigned int cpu)
 {
        struct sh_cpuinfo *c = cpu_data + cpu;
 
+       memcpy(c, &boot_cpu_data, sizeof(struct sh_cpuinfo));
+
        c->loops_per_jiffy = loops_per_jiffy;
 }
 
index e0b5e4b..7a2ee3a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kexec.h>
 #include <linux/limits.h>
 #include <linux/proc_fs.h>
+#include <linux/sysfs.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/fpu.h>
@@ -159,12 +160,12 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        oops_enter();
 
-       console_verbose();
        spin_lock_irq(&die_lock);
+       console_verbose();
        bust_spinlocks(1);
 
        printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-
+       sysfs_printk_last_file();
        print_modules();
        show_regs(regs);
 
@@ -180,6 +181,7 @@ void die(const char * str, struct pt_regs * regs, long err)
        bust_spinlocks(0);
        add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
+       oops_exit();
 
        if (kexec_should_crash(current))
                crash_kexec(regs);
@@ -190,7 +192,6 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (panic_on_oops)
                panic("Fatal exception");
 
-       oops_exit();
        do_exit(SIGSEGV);
 }
 
index 64dc1ad..7f7b52f 100644 (file)
@@ -227,7 +227,7 @@ endchoice
 
 choice
        prompt "HugeTLB page size"
-       depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
+       depends on HUGETLB_PAGE
        default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB
        default HUGETLB_PAGE_SIZE_64K
 
index a98c7d8..519e2d1 100644 (file)
@@ -26,7 +26,7 @@
 #define MAX_DCACHE_PAGES       64      /* XXX: Tune for ways */
 #define MAX_ICACHE_PAGES       32
 
-static void __flush_cache_4096(unsigned long addr, unsigned long phys,
+static void __flush_cache_one(unsigned long addr, unsigned long phys,
                               unsigned long exec_offset);
 
 /*
@@ -89,8 +89,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
        local_irq_restore(flags);
 }
 
-static inline void flush_cache_4096(unsigned long start,
-                                   unsigned long phys)
+static inline void flush_cache_one(unsigned long start, unsigned long phys)
 {
        unsigned long flags, exec_offset = 0;
 
@@ -103,8 +102,7 @@ static inline void flush_cache_4096(unsigned long start,
                exec_offset = 0x20000000;
 
        local_irq_save(flags);
-       __flush_cache_4096(start | SH_CACHE_ASSOC,
-                          P1SEGADDR(phys), exec_offset);
+       __flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset);
        local_irq_restore(flags);
 }
 
@@ -129,8 +127,8 @@ static void sh4_flush_dcache_page(void *arg)
 
                /* Loop all the D-cache */
                n = boot_cpu_data.dcache.n_aliases;
-               for (i = 0; i < n; i++, addr += 4096)
-                       flush_cache_4096(addr, phys);
+               for (i = 0; i < n; i++, addr += PAGE_SIZE)
+                       flush_cache_one(addr, phys);
        }
 
        wmb();
@@ -318,11 +316,11 @@ static void sh4_flush_cache_page(void *args)
        /* We only need to flush D-cache when we have alias */
        if ((address^phys) & alias_mask) {
                /* Loop 4K of the D-cache */
-               flush_cache_4096(
+               flush_cache_one(
                        CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
                        phys);
                /* Loop another 4K of the D-cache */
-               flush_cache_4096(
+               flush_cache_one(
                        CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
                        phys);
        }
@@ -337,7 +335,7 @@ static void sh4_flush_cache_page(void *args)
                 * kernel has never executed the code through its identity
                 * translation.
                 */
-               flush_cache_4096(
+               flush_cache_one(
                        CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
                        phys);
        }
@@ -393,7 +391,7 @@ static void sh4_flush_cache_range(void *args)
 }
 
 /**
- * __flush_cache_4096
+ * __flush_cache_one
  *
  * @addr:  address in memory mapped cache array
  * @phys:  P1 address to flush (has to match tags if addr has 'A' bit
@@ -406,7 +404,7 @@ static void sh4_flush_cache_range(void *args)
  * operation (purge/write-back) is selected by the lower 2 bits of
  * 'phys'.
  */
-static void __flush_cache_4096(unsigned long addr, unsigned long phys,
+static void __flush_cache_one(unsigned long addr, unsigned long phys,
                               unsigned long exec_offset)
 {
        int way_count;
index 35c37b7..a2dc7f9 100644 (file)
@@ -128,7 +128,7 @@ void __update_cache(struct vm_area_struct *vma,
                return;
 
        page = pfn_to_page(pfn);
-       if (pfn_valid(pfn) && page_mapping(page)) {
+       if (pfn_valid(pfn)) {
                int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
                if (dirty) {
                        unsigned long addr = (unsigned long)page_address(page);
@@ -265,6 +265,8 @@ static void __init emit_cache_params(void)
 
 void __init cpu_cache_init(void)
 {
+       unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE);
+
        compute_alias(&boot_cpu_data.icache);
        compute_alias(&boot_cpu_data.dcache);
        compute_alias(&boot_cpu_data.scache);
@@ -273,6 +275,13 @@ void __init cpu_cache_init(void)
        __flush_purge_region            = noop__flush_region;
        __flush_invalidate_region       = noop__flush_region;
 
+       /*
+        * No flushing is necessary in the disabled cache case so we can
+        * just keep the noop functions in local_flush_..() and __flush_..()
+        */
+       if (unlikely(cache_disabled))
+               goto skip;
+
        if (boot_cpu_data.family == CPU_FAMILY_SH2) {
                extern void __weak sh2_cache_init(void);
 
@@ -312,5 +321,6 @@ void __init cpu_cache_init(void)
                sh5_cache_init();
        }
 
+skip:
        emit_cache_params();
 }
index adf5f27..cb3c72c 100644 (file)
@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
        snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
 
        err = request_irq(lp->cfg.rx_irq, ldc_rx,
-                         IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+                         IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
                          lp->rx_irq_name, lp);
        if (err)
                return err;
 
        err = request_irq(lp->cfg.tx_irq, ldc_tx,
-                         IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+                         IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
                          lp->tx_irq_name, lp);
        if (err) {
                free_irq(lp->cfg.rx_irq, lp);
index 04db927..fa5936e 100644 (file)
@@ -437,7 +437,7 @@ static const struct sparc_pmu niagara2_pmu = {
        .lower_shift    = 6,
        .event_mask     = 0xfff,
        .hv_bit         = 0x8,
-       .irq_bit        = 0x03,
+       .irq_bit        = 0x30,
        .upper_nop      = 0x220,
        .lower_nop      = 0x220,
 };
index a70a5e1..1886d37 100644 (file)
@@ -265,7 +265,7 @@ static void flush_dcache(unsigned long pfn)
        struct page *page;
 
        page = pfn_to_page(pfn);
-       if (page && page_mapping(page)) {
+       if (page) {
                unsigned long pg_flags;
 
                pg_flags = page->flags;
index c876bac..72ace95 100644 (file)
@@ -491,7 +491,7 @@ if PARAVIRT_GUEST
 source "arch/x86/xen/Kconfig"
 
 config VMI
-       bool "VMI Guest support"
+       bool "VMI Guest support (DEPRECATED)"
        select PARAVIRT
        depends on X86_32
        ---help---
@@ -500,6 +500,15 @@ config VMI
          at the moment), by linking the kernel to a GPL-ed ROM module
          provided by the hypervisor.
 
+         As of September 2009, VMware has started a phased retirement
+         of this feature from VMware's products. Please see
+         feature-removal-schedule.txt for details.  If you are
+         planning to enable this option, please note that you cannot
+         live migrate a VMI enabled VM to a future VMware product,
+         which doesn't support VMI. So if you expect your kernel to
+         seamlessly migrate to newer VMware products, keep this
+         disabled.
+
 config KVM_CLOCK
        bool "KVM paravirtualized clock"
        select PARAVIRT
@@ -1434,12 +1443,8 @@ config SECCOMP
 
          If unsure, say Y. Only embedded should say N here.
 
-config CC_STACKPROTECTOR_ALL
-       bool
-
 config CC_STACKPROTECTOR
        bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
-       select CC_STACKPROTECTOR_ALL
        ---help---
          This option turns on the -fstack-protector GCC feature. This
          feature puts, at the beginning of functions, a canary value on
index f2824fb..2649840 100644 (file)
@@ -400,7 +400,7 @@ config X86_TSC
 
 config X86_CMPXCHG64
        def_bool y
-       depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
+       depends on !M386 && !M486
 
 # this should be set for all -march=.. options where the compiler
 # generates cmov.
index a012ee8..d2d24c9 100644 (file)
@@ -76,7 +76,6 @@ ifdef CONFIG_CC_STACKPROTECTOR
        cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
         ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
                 stackp-y := -fstack-protector
-                stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
                 KBUILD_CFLAGS += $(stackp-y)
         else
                 $(warning stack protector enabled but no compiler support)
index 0f6ec45..03c0683 100644 (file)
@@ -53,6 +53,9 @@ SECTIONS
 
        /DISCARD/ : { *(.note*) }
 
+       /*
+        * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+        */
        . = ASSERT(_end <= 0x8000, "Setup too big!");
        . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
        /* Necessary for the very-old-loader check to work... */
index 585edeb..49c552c 100644 (file)
@@ -82,7 +82,7 @@ static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
                return -EINVAL;
        }
 
-       if (irq_fpu_usable())
+       if (!irq_fpu_usable())
                err = crypto_aes_expand_key(ctx, in_key, key_len);
        else {
                kernel_fpu_begin();
@@ -103,7 +103,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
        struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
 
-       if (irq_fpu_usable())
+       if (!irq_fpu_usable())
                crypto_aes_encrypt_x86(ctx, dst, src);
        else {
                kernel_fpu_begin();
@@ -116,7 +116,7 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
        struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
 
-       if (irq_fpu_usable())
+       if (!irq_fpu_usable())
                crypto_aes_decrypt_x86(ctx, dst, src);
        else {
                kernel_fpu_begin();
@@ -342,7 +342,7 @@ static int ablk_encrypt(struct ablkcipher_request *req)
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-       if (irq_fpu_usable()) {
+       if (!irq_fpu_usable()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
                memcpy(cryptd_req, req, sizeof(*req));
@@ -363,7 +363,7 @@ static int ablk_decrypt(struct ablkcipher_request *req)
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-       if (irq_fpu_usable()) {
+       if (!irq_fpu_usable()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
                memcpy(cryptd_req, req, sizeof(*req));
index 1733f9f..581b056 100644 (file)
@@ -204,7 +204,7 @@ sysexit_from_sys_call:
        movl RDI-ARGOFFSET(%rsp),%r8d   /* reload 5th syscall arg */
        .endm
 
-       .macro auditsys_exit exit,ebpsave=RBP
+       .macro auditsys_exit exit
        testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
        jnz ia32_ret_from_sys_call
        TRACE_IRQS_ON
@@ -217,7 +217,6 @@ sysexit_from_sys_call:
        call audit_syscall_exit
        GET_THREAD_INFO(%r10)
        movl RAX-ARGOFFSET(%rsp),%eax   /* reload syscall return value */
-       movl \ebpsave-ARGOFFSET(%rsp),%ebp /* reload user register value */
        movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
        cli
        TRACE_IRQS_OFF
@@ -351,7 +350,7 @@ cstar_auditsys:
        jmp cstar_dispatch
 
 sysretl_audit:
-       auditsys_exit sysretl_from_sys_call, RCX /* user %ebp in RCX slot */
+       auditsys_exit sysretl_from_sys_call
 #endif
 
 cstar_tracesys:
index 8aebcc4..efb3899 100644 (file)
@@ -840,42 +840,22 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
 
 static inline unsigned long __raw_local_save_flags(void)
 {
-       unsigned long f;
-
-       asm volatile(paravirt_alt(PARAVIRT_CALL)
-                    : "=a"(f)
-                    : paravirt_type(pv_irq_ops.save_fl),
-                      paravirt_clobber(CLBR_EAX)
-                    : "memory", "cc");
-       return f;
+       return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
 }
 
 static inline void raw_local_irq_restore(unsigned long f)
 {
-       asm volatile(paravirt_alt(PARAVIRT_CALL)
-                    : "=a"(f)
-                    : PV_FLAGS_ARG(f),
-                      paravirt_type(pv_irq_ops.restore_fl),
-                      paravirt_clobber(CLBR_EAX)
-                    : "memory", "cc");
+       PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
 }
 
 static inline void raw_local_irq_disable(void)
 {
-       asm volatile(paravirt_alt(PARAVIRT_CALL)
-                    :
-                    : paravirt_type(pv_irq_ops.irq_disable),
-                      paravirt_clobber(CLBR_EAX)
-                    : "memory", "eax", "cc");
+       PVOP_VCALLEE0(pv_irq_ops.irq_disable);
 }
 
 static inline void raw_local_irq_enable(void)
 {
-       asm volatile(paravirt_alt(PARAVIRT_CALL)
-                    :
-                    : paravirt_type(pv_irq_ops.irq_enable),
-                      paravirt_clobber(CLBR_EAX)
-                    : "memory", "eax", "cc");
+       PVOP_VCALLEE0(pv_irq_ops.irq_enable);
 }
 
 static inline unsigned long __raw_local_irq_save(void)
index dd0f5b3..9357473 100644 (file)
@@ -494,10 +494,11 @@ int paravirt_disable_iospace(void);
 #define EXTRA_CLOBBERS
 #define VEXTRA_CLOBBERS
 #else  /* CONFIG_X86_64 */
+/* [re]ax isn't an arg, but the return val */
 #define PVOP_VCALL_ARGS                                        \
        unsigned long __edi = __edi, __esi = __esi,     \
-               __edx = __edx, __ecx = __ecx
-#define PVOP_CALL_ARGS         PVOP_VCALL_ARGS, __eax
+               __edx = __edx, __ecx = __ecx, __eax = __eax
+#define PVOP_CALL_ARGS         PVOP_VCALL_ARGS
 
 #define PVOP_CALL_ARG1(x)              "D" ((unsigned long)(x))
 #define PVOP_CALL_ARG2(x)              "S" ((unsigned long)(x))
@@ -509,6 +510,7 @@ int paravirt_disable_iospace(void);
                                "=c" (__ecx)
 #define PVOP_CALL_CLOBBERS     PVOP_VCALL_CLOBBERS, "=a" (__eax)
 
+/* void functions are still allowed [re]ax for scratch */
 #define PVOP_VCALLEE_CLOBBERS  "=a" (__eax)
 #define PVOP_CALLEE_CLOBBERS   PVOP_VCALLEE_CLOBBERS
 
@@ -583,8 +585,8 @@ int paravirt_disable_iospace(void);
                       VEXTRA_CLOBBERS,                                 \
                       pre, post, ##__VA_ARGS__)
 
-#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...)                        \
-       ____PVOP_CALL(rettype, op.func, CLBR_RET_REG,                   \
+#define __PVOP_VCALLEESAVE(op, pre, post, ...)                         \
+       ____PVOP_VCALL(op.func, CLBR_RET_REG,                           \
                      PVOP_VCALLEE_CLOBBERS, ,                          \
                      pre, post, ##__VA_ARGS__)
 
index 25a9284..d823c24 100644 (file)
@@ -143,6 +143,7 @@ extern unsigned long node_remap_size[];
                                | 1*SD_BALANCE_FORK                     \
                                | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
+                               | 1*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
                                | 0*SD_SHARE_PKG_RESOURCES              \
index 04eb6c9..d1414af 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/types.h>
 #include <asm/percpu.h>
 #include <asm/uv/uv_mmrs.h>
+#include <asm/irq_vectors.h>
+#include <asm/io_apic.h>
 
 
 /*
 /*
  * The largest possible NASID of a C or M brick (+ 2)
  */
-#define UV_MAX_NASID_VALUE     (UV_MAX_NUMALINK_NODES * 2)
+#define UV_MAX_NASID_VALUE     (UV_MAX_NUMALINK_BLADES * 2)
 
 struct uv_scir_s {
        struct timer_list timer;
@@ -230,6 +232,20 @@ static inline unsigned long uv_gpa(void *v)
        return uv_soc_phys_ram_to_gpa(__pa(v));
 }
 
+/* gnode -> pnode */
+static inline unsigned long uv_gpa_to_gnode(unsigned long gpa)
+{
+       return gpa >> uv_hub_info->m_val;
+}
+
+/* gpa -> pnode */
+static inline int uv_gpa_to_pnode(unsigned long gpa)
+{
+       unsigned long n_mask = (1UL << uv_hub_info->n_val) - 1;
+
+       return uv_gpa_to_gnode(gpa) & n_mask;
+}
+
 /* pnode, offset --> socket virtual */
 static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
 {
@@ -421,9 +437,14 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
 static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
 {
        unsigned long val;
+       unsigned long dmode = dest_Fixed;
+
+       if (vector == NMI_VECTOR)
+               dmode = dest_NMI;
 
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
                        ((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
+                       (dmode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
                        (vector << UVH_IPI_INT_VECTOR_SHFT);
        uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
 }
index 7da00b7..060fff8 100644 (file)
@@ -57,5 +57,8 @@ SECTIONS
                *(.note*)
        }
 
+       /*
+        * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+        */
        . = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!");
 }
index f5f5886..326c254 100644 (file)
@@ -352,14 +352,14 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
 
        for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
                alias.v = uv_read_local_mmr(redir_addrs[i].alias);
-               if (alias.s.base == 0) {
+               if (alias.s.enable && alias.s.base == 0) {
                        *size = (1UL << alias.s.m_alias);
                        redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
                        *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
                        return;
                }
        }
-       BUG();
+       *base = *size = 0;
 }
 
 enum map_type {map_wb, map_uc};
@@ -619,12 +619,12 @@ void __init uv_system_init(void)
                uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
                uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
                uv_cpu_hub_info(cpu)->m_val = m_val;
-               uv_cpu_hub_info(cpu)->n_val = m_val;
+               uv_cpu_hub_info(cpu)->n_val = n_val;
                uv_cpu_hub_info(cpu)->numa_blade_id = blade;
                uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
                uv_cpu_hub_info(cpu)->pnode = pnode;
                uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
-               uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+               uv_cpu_hub_info(cpu)->gpa_mask = (1UL << (m_val + n_val)) - 1;
                uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
                uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
                uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
index b1598a9..721a77c 100644 (file)
@@ -1214,7 +1214,8 @@ static int __cpuinit mce_cap_init(void)
        rdmsrl(MSR_IA32_MCG_CAP, cap);
 
        b = cap & MCG_BANKCNT_MASK;
-       printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b);
+       if (!banks)
+               printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b);
 
        if (b > MAX_NR_BANKS) {
                printk(KERN_WARNING
index f7cdb3b..cd97ce1 100644 (file)
@@ -16,6 +16,22 @@ static void *kdump_buf_page;
 /* Stores the physical address of elf header of crash image. */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
+static inline bool is_crashed_pfn_valid(unsigned long pfn)
+{
+#ifndef CONFIG_X86_PAE
+       /*
+        * non-PAE kdump kernel executed from a PAE one will crop high pte
+        * bits and poke unwanted space counting again from address 0, we
+        * don't want that. pte must fit into unsigned long. In fact the
+        * test checks high 12 bits for being zero (pfn will be shifted left
+        * by PAGE_SHIFT).
+        */
+       return pte_pfn(pfn_pte(pfn, __pgprot(0))) == pfn;
+#else
+       return true;
+#endif
+}
+
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -41,6 +57,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
        if (!csize)
                return 0;
 
+       if (!is_crashed_pfn_valid(pfn))
+               return -EFAULT;
+
        vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
 
        if (!userbuf) {
index ad5bd98..cdcfb12 100644 (file)
@@ -454,8 +454,10 @@ void __init efi_init(void)
        if (add_efi_memmap)
                do_add_efi_memmap();
 
+#ifdef CONFIG_X86_32
        x86_platform.get_wallclock = efi_get_time;
        x86_platform.set_wallclock = efi_set_rtc_mmss;
+#endif
 
        /* Setup for EFI runtime service */
        reboot_type = BOOT_EFI;
index 3912061..04bbd52 100644 (file)
@@ -63,10 +63,10 @@ static int show_other_interrupts(struct seq_file *p, int prec)
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
        seq_printf(p, "  Spurious interrupts\n");
-       seq_printf(p, "%*s: ", prec, "CNT");
+       seq_printf(p, "%*s: ", prec, "PMI");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
-       seq_printf(p, "  Performance counter interrupts\n");
+       seq_printf(p, "  Performance monitoring interrupts\n");
        seq_printf(p, "%*s: ", prec, "PND");
        for_each_online_cpu(j)
                seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
@@ -244,7 +244,6 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
                                __func__, smp_processor_id(), vector, irq);
        }
 
-       run_local_timers();
        irq_exit();
 
        set_irq_regs(old_regs);
@@ -269,7 +268,6 @@ void smp_generic_interrupt(struct pt_regs *regs)
        if (generic_interrupt_extension)
                generic_interrupt_extension();
 
-       run_local_timers();
        irq_exit();
 
        set_irq_regs(old_regs);
index d20009b..b2a71dc 100644 (file)
@@ -311,7 +311,7 @@ void pci_iommu_shutdown(void)
        amd_iommu_shutdown();
 }
 /* Must execute after PCI subsystem */
-fs_initcall(pci_iommu_init);
+rootfs_initcall(pci_iommu_init);
 
 #ifdef CONFIG_PCI
 /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
index d915d95..ec1de97 100644 (file)
@@ -198,7 +198,6 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
 {
        ack_APIC_irq();
        inc_irq_stat(irq_resched_count);
-       run_local_timers();
        /*
         * KVM uses this interrupt to force a cpu out of guest mode
         */
index dcb00d2..be25734 100644 (file)
@@ -38,7 +38,8 @@ unsigned long profile_pc(struct pt_regs *regs)
 #ifdef CONFIG_FRAME_POINTER
                return *(unsigned long *)(regs->bp + sizeof(long));
 #else
-               unsigned long *sp = (unsigned long *)regs->sp;
+               unsigned long *sp =
+                       (unsigned long *)kernel_stack_pointer(regs);
                /*
                 * Return address is either directly at stack pointer
                 * or above a saved flags. Eflags has bits 22-31 zero,
index 503c1f2..1740c85 100644 (file)
@@ -23,8 +23,6 @@
 static struct bau_control      **uv_bau_table_bases __read_mostly;
 static int                     uv_bau_retry_limit __read_mostly;
 
-/* position of pnode (which is nasid>>1): */
-static int                     uv_nshift __read_mostly;
 /* base pnode in this partition */
 static int                     uv_partition_base_pnode __read_mostly;
 
@@ -723,7 +721,7 @@ uv_activation_descriptor_init(int node, int pnode)
        BUG_ON(!adp);
 
        pa = uv_gpa(adp); /* need the real nasid*/
-       n = pa >> uv_nshift;
+       n = uv_gpa_to_pnode(pa);
        m = pa & uv_mmask;
 
        uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
@@ -778,7 +776,7 @@ uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
         * need the pnode of where the memory was really allocated
         */
        pa = uv_gpa(pqp);
-       pn = pa >> uv_nshift;
+       pn = uv_gpa_to_pnode(pa);
        uv_write_global_mmr64(pnode,
                              UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
                              ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
@@ -843,8 +841,7 @@ static int __init uv_bau_init(void)
                                       GFP_KERNEL, cpu_to_node(cur_cpu));
 
        uv_bau_retry_limit = 1;
-       uv_nshift = uv_hub_info->n_val;
-       uv_mmask = (1UL << uv_hub_info->n_val) - 1;
+       uv_mmask = (1UL << uv_hub_info->m_val) - 1;
        nblades = uv_num_possible_blades();
 
        uv_bau_table_bases = (struct bau_control **)
index 699f7ee..cd02212 100644 (file)
@@ -3,8 +3,16 @@
 #include <asm/trampoline.h>
 #include <asm/e820.h>
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
+#define __trampinit
+#define __trampinitdata
+#else
+#define __trampinit __cpuinit
+#define __trampinitdata __cpuinitdata
+#endif
+
 /* ready for x86_64 and x86 */
-unsigned char *__cpuinitdata trampoline_base = __va(TRAMPOLINE_BASE);
+unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
 
 void __init reserve_trampoline_memory(void)
 {
@@ -26,7 +34,7 @@ void __init reserve_trampoline_memory(void)
  * bootstrap into the page concerned. The caller
  * has made sure it's suitably aligned.
  */
-unsigned long __cpuinit setup_trampoline(void)
+unsigned long __trampinit setup_trampoline(void)
 {
        memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
        return virt_to_phys(trampoline_base);
index 596d54c..3af2dff 100644 (file)
 #include <asm/segment.h>
 #include <asm/processor-flags.h>
 
+#ifdef CONFIG_ACPI_SLEEP
+.section .rodata, "a", @progbits
+#else
 /* We can free up the trampoline after bootup if cpu hotplug is not supported. */
 __CPUINITRODATA
+#endif
 .code16
 
 ENTRY(trampoline_data)
index 31e6f6c..d430e4c 100644 (file)
@@ -648,7 +648,7 @@ static inline int __init activate_vmi(void)
 
        pv_info.paravirt_enabled = 1;
        pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
-       pv_info.name = "vmi";
+       pv_info.name = "vmi [deprecated]";
 
        pv_init_ops.patch = vmi_patch;
 
index 92929fb..3c68fe2 100644 (file)
@@ -305,6 +305,9 @@ SECTIONS
 
 
 #ifdef CONFIG_X86_32
+/*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
 . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
           "kernel image bigger than KERNEL_IMAGE_SIZE");
 #else
index 82ad523..144e7f6 100644 (file)
@@ -116,7 +116,7 @@ static s64 __kpit_elapsed(struct kvm *kvm)
         * itself with the initial count and continues counting
         * from there.
         */
-       remaining = hrtimer_expires_remaining(&ps->pit_timer.timer);
+       remaining = hrtimer_get_remaining(&ps->pit_timer.timer);
        elapsed = ps->pit_timer.period - ktime_to_ns(remaining);
        elapsed = mod_64(elapsed, ps->pit_timer.period);
 
index 7024224..23c2176 100644 (file)
@@ -521,7 +521,7 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
        if (apic_get_reg(apic, APIC_TMICT) == 0)
                return 0;
 
-       remaining = hrtimer_expires_remaining(&apic->lapic_timer.timer);
+       remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
        if (ktime_to_ns(remaining) < 0)
                remaining = ktime_set(0, 0);
 
index 685a4ff..818b92a 100644 (file)
@@ -748,7 +748,8 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
        return write_protected;
 }
 
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
+                          unsigned long data)
 {
        u64 *spte;
        int need_tlb_flush = 0;
@@ -763,7 +764,8 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
        return need_tlb_flush;
 }
 
-static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
+                            unsigned long data)
 {
        int need_flush = 0;
        u64 *spte, new_spte;
@@ -799,9 +801,10 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
        return 0;
 }
 
-static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, u64 data,
+static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
+                         unsigned long data,
                          int (*handler)(struct kvm *kvm, unsigned long *rmapp,
-                                        u64 data))
+                                        unsigned long data))
 {
        int i, j;
        int retval = 0;
@@ -846,10 +849,11 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
 
 void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
 {
-       kvm_handle_hva(kvm, hva, (u64)&pte, kvm_set_pte_rmapp);
+       kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
 }
 
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
+                        unsigned long data)
 {
        u64 *spte;
        int young = 0;
index 3439616..23a4d80 100644 (file)
@@ -1075,6 +1075,8 @@ asmlinkage void __init xen_start_kernel(void)
         * Set up some pagetable state before starting to set any ptes.
         */
 
+       xen_init_mmu_ops();
+
        /* Prevent unwanted bits from being set in PTEs. */
        __supported_pte_mask &= ~_PAGE_GLOBAL;
        if (!xen_initial_domain())
@@ -1099,7 +1101,6 @@ asmlinkage void __init xen_start_kernel(void)
         */
        xen_setup_stackprotector();
 
-       xen_init_mmu_ops();
        xen_init_irq_ops();
        xen_init_cpuid_mask();
 
index 81f3431..71da511 100644 (file)
@@ -70,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
                part_stat_inc(cpu, part, merges[rw]);
        else {
                part_round_stats(cpu, part);
-               part_inc_in_flight(part);
+               part_inc_in_flight(part, rw);
        }
 
        part_stat_unlock();
@@ -1030,9 +1030,9 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
        if (now == part->stamp)
                return;
 
-       if (part->in_flight) {
+       if (part_in_flight(part)) {
                __part_stat_add(cpu, part, time_in_queue,
-                               part->in_flight * (now - part->stamp));
+                               part_in_flight(part) * (now - part->stamp));
                __part_stat_add(cpu, part, io_ticks, (now - part->stamp));
        }
        part->stamp = now;
@@ -1161,7 +1161,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
        const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
        int rw_flags;
 
-       if (bio_rw_flagged(bio, BIO_RW_BARRIER) && bio_has_data(bio) &&
+       if (bio_rw_flagged(bio, BIO_RW_BARRIER) &&
            (q->next_ordered == QUEUE_ORDERED_NONE)) {
                bio_endio(bio, -EOPNOTSUPP);
                return 0;
@@ -1739,7 +1739,7 @@ static void blk_account_io_done(struct request *req)
                part_stat_inc(cpu, part, ios[rw]);
                part_stat_add(cpu, part, ticks[rw], duration);
                part_round_stats(cpu, part);
-               part_dec_in_flight(part);
+               part_dec_in_flight(part, rw);
 
                part_stat_unlock();
        }
@@ -2492,14 +2492,6 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
 }
 EXPORT_SYMBOL(kblockd_schedule_work);
 
-int kblockd_schedule_delayed_work(struct request_queue *q,
-                                 struct delayed_work *work,
-                                 unsigned long delay)
-{
-       return queue_delayed_work(kblockd_workqueue, work, delay);
-}
-EXPORT_SYMBOL(kblockd_schedule_delayed_work);
-
 int __init blk_dev_init(void)
 {
        BUILD_BUG_ON(__REQ_NR_BITS > 8 *
index b0de857..99cb5cf 100644 (file)
@@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req)
                part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
 
                part_round_stats(cpu, part);
-               part_dec_in_flight(part);
+               part_dec_in_flight(part, rq_data_dir(req));
 
                part_stat_unlock();
        }
index e0695bc..66d4aa8 100644 (file)
@@ -242,7 +242,7 @@ EXPORT_SYMBOL(blk_queue_max_hw_sectors);
 /**
  * blk_queue_max_discard_sectors - set max sectors for a single discard
  * @q:  the request queue for the device
- * @max_discard: maximum number of sectors to discard
+ * @max_discard_sectors: maximum number of sectors to discard
  **/
 void blk_queue_max_discard_sectors(struct request_queue *q,
                unsigned int max_discard_sectors)
index 2e5cfeb..6b0f52c 100644 (file)
@@ -359,7 +359,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
                max_depth -= 2;
                if (!max_depth)
                        max_depth = 1;
-               if (q->in_flight[0] > max_depth)
+               if (q->in_flight[BLK_RW_ASYNC] > max_depth)
                        return 1;
        }
 
index 9c4b679..069a610 100644 (file)
@@ -150,7 +150,7 @@ struct cfq_data {
         * idle window management
         */
        struct timer_list idle_slice_timer;
-       struct delayed_work unplug_work;
+       struct work_struct unplug_work;
 
        struct cfq_queue *active_queue;
        struct cfq_io_context *active_cic;
@@ -230,7 +230,7 @@ CFQ_CFQQ_FNS(coop);
        blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
 
 static void cfq_dispatch_insert(struct request_queue *, struct request *);
-static struct cfq_queue *cfq_get_queue(struct cfq_data *, int,
+static struct cfq_queue *cfq_get_queue(struct cfq_data *, bool,
                                       struct io_context *, gfp_t);
 static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
                                                struct io_context *);
@@ -241,40 +241,35 @@ static inline int rq_in_driver(struct cfq_data *cfqd)
 }
 
 static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
-                                           int is_sync)
+                                           bool is_sync)
 {
-       return cic->cfqq[!!is_sync];
+       return cic->cfqq[is_sync];
 }
 
 static inline void cic_set_cfqq(struct cfq_io_context *cic,
-                               struct cfq_queue *cfqq, int is_sync)
+                               struct cfq_queue *cfqq, bool is_sync)
 {
-       cic->cfqq[!!is_sync] = cfqq;
+       cic->cfqq[is_sync] = cfqq;
 }
 
 /*
  * We regard a request as SYNC, if it's either a read or has the SYNC bit
  * set (in which case it could also be direct WRITE).
  */
-static inline int cfq_bio_sync(struct bio *bio)
+static inline bool cfq_bio_sync(struct bio *bio)
 {
-       if (bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO))
-               return 1;
-
-       return 0;
+       return bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO);
 }
 
 /*
  * scheduler run of queue, if there are requests pending and no one in the
  * driver that will restart queueing
  */
-static inline void cfq_schedule_dispatch(struct cfq_data *cfqd,
-                                        unsigned long delay)
+static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
 {
        if (cfqd->busy_queues) {
                cfq_log(cfqd, "schedule dispatch");
-               kblockd_schedule_delayed_work(cfqd->queue, &cfqd->unplug_work,
-                                               delay);
+               kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work);
        }
 }
 
@@ -290,7 +285,7 @@ static int cfq_queue_empty(struct request_queue *q)
  * if a queue is marked sync and has sync io queued. A sync queue with async
  * io only, should not get full sync slice length.
  */
-static inline int cfq_prio_slice(struct cfq_data *cfqd, int sync,
+static inline int cfq_prio_slice(struct cfq_data *cfqd, bool sync,
                                 unsigned short prio)
 {
        const int base_slice = cfqd->cfq_slice[sync];
@@ -318,7 +313,7 @@ cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
  * isn't valid until the first request from the dispatch is activated
  * and the slice time set.
  */
-static inline int cfq_slice_used(struct cfq_queue *cfqq)
+static inline bool cfq_slice_used(struct cfq_queue *cfqq)
 {
        if (cfq_cfqq_slice_new(cfqq))
                return 0;
@@ -493,7 +488,7 @@ static unsigned long cfq_slice_offset(struct cfq_data *cfqd,
  * we will service the queues.
  */
 static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                                int add_front)
+                                bool add_front)
 {
        struct rb_node **p, *parent;
        struct cfq_queue *__cfqq;
@@ -509,11 +504,20 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
                } else
                        rb_key += jiffies;
        } else if (!add_front) {
+               /*
+                * Get our rb key offset. Subtract any residual slice
+                * value carried from last service. A negative resid
+                * count indicates slice overrun, and this should position
+                * the next service time further away in the tree.
+                */
                rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies;
-               rb_key += cfqq->slice_resid;
+               rb_key -= cfqq->slice_resid;
                cfqq->slice_resid = 0;
-       } else
-               rb_key = 0;
+       } else {
+               rb_key = -HZ;
+               __cfqq = cfq_rb_first(&cfqd->service_tree);
+               rb_key += __cfqq ? __cfqq->rb_key : jiffies;
+       }
 
        if (!RB_EMPTY_NODE(&cfqq->rb_node)) {
                /*
@@ -547,7 +551,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
                        n = &(*p)->rb_left;
                else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq))
                        n = &(*p)->rb_right;
-               else if (rb_key < __cfqq->rb_key)
+               else if (time_before(rb_key, __cfqq->rb_key))
                        n = &(*p)->rb_left;
                else
                        n = &(*p)->rb_right;
@@ -827,8 +831,10 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
         * reposition in fifo if next is older than rq
         */
        if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
-           time_before(next->start_time, rq->start_time))
+           time_before(rq_fifo_time(next), rq_fifo_time(rq))) {
                list_move(&rq->queuelist, &next->queuelist);
+               rq_set_fifo_time(rq, rq_fifo_time(next));
+       }
 
        cfq_remove_request(next);
 }
@@ -844,7 +850,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
         * Disallow merge of a sync bio into an async request.
         */
        if (cfq_bio_sync(bio) && !rq_is_sync(rq))
-               return 0;
+               return false;
 
        /*
         * Lookup the cfqq that this bio will be queued with. Allow
@@ -852,13 +858,10 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
         */
        cic = cfq_cic_lookup(cfqd, current->io_context);
        if (!cic)
-               return 0;
+               return false;
 
        cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
-       if (cfqq == RQ_CFQQ(rq))
-               return 1;
-
-       return 0;
+       return cfqq == RQ_CFQQ(rq);
 }
 
 static void __cfq_set_active_queue(struct cfq_data *cfqd,
@@ -886,7 +889,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
  */
 static void
 __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                   int timed_out)
+                   bool timed_out)
 {
        cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out);
 
@@ -914,7 +917,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
        }
 }
 
-static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out)
+static inline void cfq_slice_expired(struct cfq_data *cfqd, bool timed_out)
 {
        struct cfq_queue *cfqq = cfqd->active_queue;
 
@@ -1026,7 +1029,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
  */
 static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
                                              struct cfq_queue *cur_cfqq,
-                                             int probe)
+                                             bool probe)
 {
        struct cfq_queue *cfqq;
 
@@ -1090,6 +1093,15 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
        if (!cic || !atomic_read(&cic->ioc->nr_tasks))
                return;
 
+       /*
+        * If our average think time is larger than the remaining time
+        * slice, then don't idle. This avoids overrunning the allotted
+        * time slice.
+        */
+       if (sample_valid(cic->ttime_samples) &&
+           (cfqq->slice_end - jiffies < cic->ttime_mean))
+               return;
+
        cfq_mark_cfqq_wait_request(cfqq);
 
        /*
@@ -1129,9 +1141,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
  */
 static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
 {
-       struct cfq_data *cfqd = cfqq->cfqd;
-       struct request *rq;
-       int fifo;
+       struct request *rq = NULL;
 
        if (cfq_cfqq_fifo_expire(cfqq))
                return NULL;
@@ -1141,13 +1151,11 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
        if (list_empty(&cfqq->fifo))
                return NULL;
 
-       fifo = cfq_cfqq_sync(cfqq);
        rq = rq_entry_fifo(cfqq->fifo.next);
-
-       if (time_before(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo]))
+       if (time_before(jiffies, rq_fifo_time(rq)))
                rq = NULL;
 
-       cfq_log_cfqq(cfqd, cfqq, "fifo=%p", rq);
+       cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
        return rq;
 }
 
@@ -1248,67 +1256,21 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
        return dispatched;
 }
 
-/*
- * Dispatch a request from cfqq, moving them to the request queue
- * dispatch list.
- */
-static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
-       struct request *rq;
-
-       BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
-
-       /*
-        * follow expired path, else get first next available
-        */
-       rq = cfq_check_fifo(cfqq);
-       if (!rq)
-               rq = cfqq->next_rq;
-
-       /*
-        * insert request into driver dispatch list
-        */
-       cfq_dispatch_insert(cfqd->queue, rq);
-
-       if (!cfqd->active_cic) {
-               struct cfq_io_context *cic = RQ_CIC(rq);
-
-               atomic_long_inc(&cic->ioc->refcount);
-               cfqd->active_cic = cic;
-       }
-}
-
-/*
- * Find the cfqq that we need to service and move a request from that to the
- * dispatch list
- */
-static int cfq_dispatch_requests(struct request_queue *q, int force)
-{
-       struct cfq_data *cfqd = q->elevator->elevator_data;
-       struct cfq_queue *cfqq;
        unsigned int max_dispatch;
 
-       if (!cfqd->busy_queues)
-               return 0;
-
-       if (unlikely(force))
-               return cfq_forced_dispatch(cfqd);
-
-       cfqq = cfq_select_queue(cfqd);
-       if (!cfqq)
-               return 0;
-
        /*
         * Drain async requests before we start sync IO
         */
        if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
-               return 0;
+               return false;
 
        /*
         * If this is an async queue and we have sync IO in flight, let it wait
         */
        if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
-               return 0;
+               return false;
 
        max_dispatch = cfqd->cfq_quantum;
        if (cfq_class_idle(cfqq))
@@ -1322,13 +1284,13 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
                 * idle queue must always only have a single IO in flight
                 */
                if (cfq_class_idle(cfqq))
-                       return 0;
+                       return false;
 
                /*
                 * We have other queues, don't allow more IO from this one
                 */
                if (cfqd->busy_queues > 1)
-                       return 0;
+                       return false;
 
                /*
                 * Sole queue user, allow bigger slice
@@ -1352,13 +1314,72 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
                        max_dispatch = depth;
        }
 
-       if (cfqq->dispatched >= max_dispatch)
+       /*
+        * If we're below the current max, allow a dispatch
+        */
+       return cfqq->dispatched < max_dispatch;
+}
+
+/*
+ * Dispatch a request from cfqq, moving them to the request queue
+ * dispatch list.
+ */
+static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+       struct request *rq;
+
+       BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
+
+       if (!cfq_may_dispatch(cfqd, cfqq))
+               return false;
+
+       /*
+        * follow expired path, else get first next available
+        */
+       rq = cfq_check_fifo(cfqq);
+       if (!rq)
+               rq = cfqq->next_rq;
+
+       /*
+        * insert request into driver dispatch list
+        */
+       cfq_dispatch_insert(cfqd->queue, rq);
+
+       if (!cfqd->active_cic) {
+               struct cfq_io_context *cic = RQ_CIC(rq);
+
+               atomic_long_inc(&cic->ioc->refcount);
+               cfqd->active_cic = cic;
+       }
+
+       return true;
+}
+
+/*
+ * Find the cfqq that we need to service and move a request from that to the
+ * dispatch list
+ */
+static int cfq_dispatch_requests(struct request_queue *q, int force)
+{
+       struct cfq_data *cfqd = q->elevator->elevator_data;
+       struct cfq_queue *cfqq;
+
+       if (!cfqd->busy_queues)
+               return 0;
+
+       if (unlikely(force))
+               return cfq_forced_dispatch(cfqd);
+
+       cfqq = cfq_select_queue(cfqd);
+       if (!cfqq)
                return 0;
 
        /*
-        * Dispatch a request from this cfqq
+        * Dispatch a request from this cfqq, if it is allowed
         */
-       cfq_dispatch_request(cfqd, cfqq);
+       if (!cfq_dispatch_request(cfqd, cfqq))
+               return 0;
+
        cfqq->slice_dispatch++;
        cfq_clear_cfqq_must_dispatch(cfqq);
 
@@ -1399,7 +1420,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
 
        if (unlikely(cfqd->active_queue == cfqq)) {
                __cfq_slice_expired(cfqd, cfqq, 0);
-               cfq_schedule_dispatch(cfqd, 0);
+               cfq_schedule_dispatch(cfqd);
        }
 
        kmem_cache_free(cfq_pool, cfqq);
@@ -1494,7 +1515,7 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        if (unlikely(cfqq == cfqd->active_queue)) {
                __cfq_slice_expired(cfqd, cfqq, 0);
-               cfq_schedule_dispatch(cfqd, 0);
+               cfq_schedule_dispatch(cfqd);
        }
 
        cfq_put_queue(cfqq);
@@ -1658,7 +1679,7 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
 }
 
 static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                         pid_t pid, int is_sync)
+                         pid_t pid, bool is_sync)
 {
        RB_CLEAR_NODE(&cfqq->rb_node);
        RB_CLEAR_NODE(&cfqq->p_node);
@@ -1678,7 +1699,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 }
 
 static struct cfq_queue *
-cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
+cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync,
                     struct io_context *ioc, gfp_t gfp_mask)
 {
        struct cfq_queue *cfqq, *new_cfqq = NULL;
@@ -1742,7 +1763,7 @@ cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio)
 }
 
 static struct cfq_queue *
-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc,
+cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
              gfp_t gfp_mask)
 {
        const int ioprio = task_ioprio(ioc);
@@ -1977,7 +1998,10 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
            (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic)))
                enable_idle = 0;
        else if (sample_valid(cic->ttime_samples)) {
-               if (cic->ttime_mean > cfqd->cfq_slice_idle)
+               unsigned int slice_idle = cfqd->cfq_slice_idle;
+               if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
+                       slice_idle = msecs_to_jiffies(CFQ_MIN_TT);
+               if (cic->ttime_mean > slice_idle)
                        enable_idle = 0;
                else
                        enable_idle = 1;
@@ -1996,7 +2020,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
  * Check if new_cfqq should preempt the currently active queue. Return 0 for
  * no or if we aren't sure, a 1 will cause a preempt.
  */
-static int
+static bool
 cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
                   struct request *rq)
 {
@@ -2004,48 +2028,48 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
 
        cfqq = cfqd->active_queue;
        if (!cfqq)
-               return 0;
+               return false;
 
        if (cfq_slice_used(cfqq))
-               return 1;
+               return true;
 
        if (cfq_class_idle(new_cfqq))
-               return 0;
+               return false;
 
        if (cfq_class_idle(cfqq))
-               return 1;
+               return true;
 
        /*
         * if the new request is sync, but the currently running queue is
         * not, let the sync request have priority.
         */
        if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
-               return 1;
+               return true;
 
        /*
         * So both queues are sync. Let the new request get disk time if
         * it's a metadata request and the current queue is doing regular IO.
         */
        if (rq_is_meta(rq) && !cfqq->meta_pending)
-               return 1;
+               return false;
 
        /*
         * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice.
         */
        if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq))
-               return 1;
+               return true;
 
        if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq))
-               return 0;
+               return false;
 
        /*
         * if this request is as-good as one we would expect from the
         * current cfqq, let it preempt
         */
        if (cfq_rq_close(cfqd, rq))
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
 /*
@@ -2130,6 +2154,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
 
        cfq_add_rq_rb(rq);
 
+       rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
        list_add_tail(&rq->queuelist, &cfqq->fifo);
 
        cfq_rq_enqueued(cfqd, cfqq, rq);
@@ -2211,7 +2236,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
        }
 
        if (!rq_in_driver(cfqd))
-               cfq_schedule_dispatch(cfqd, 0);
+               cfq_schedule_dispatch(cfqd);
 }
 
 /*
@@ -2309,7 +2334,7 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct cfq_io_context *cic;
        const int rw = rq_data_dir(rq);
-       const int is_sync = rq_is_sync(rq);
+       const bool is_sync = rq_is_sync(rq);
        struct cfq_queue *cfqq;
        unsigned long flags;
 
@@ -2341,7 +2366,7 @@ queue_fail:
        if (cic)
                put_io_context(cic->ioc);
 
-       cfq_schedule_dispatch(cfqd, 0);
+       cfq_schedule_dispatch(cfqd);
        spin_unlock_irqrestore(q->queue_lock, flags);
        cfq_log(cfqd, "set_request fail");
        return 1;
@@ -2350,7 +2375,7 @@ queue_fail:
 static void cfq_kick_queue(struct work_struct *work)
 {
        struct cfq_data *cfqd =
-               container_of(work, struct cfq_data, unplug_work.work);
+               container_of(work, struct cfq_data, unplug_work);
        struct request_queue *q = cfqd->queue;
 
        spin_lock_irq(q->queue_lock);
@@ -2404,7 +2429,7 @@ static void cfq_idle_slice_timer(unsigned long data)
 expire:
        cfq_slice_expired(cfqd, timed_out);
 out_kick:
-       cfq_schedule_dispatch(cfqd, 0);
+       cfq_schedule_dispatch(cfqd);
 out_cont:
        spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
@@ -2412,7 +2437,7 @@ out_cont:
 static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
 {
        del_timer_sync(&cfqd->idle_slice_timer);
-       cancel_delayed_work_sync(&cfqd->unplug_work);
+       cancel_work_sync(&cfqd->unplug_work);
 }
 
 static void cfq_put_async_queues(struct cfq_data *cfqd)
@@ -2494,7 +2519,7 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
        cfqd->idle_slice_timer.data = (unsigned long) cfqd;
 
-       INIT_DELAYED_WORK(&cfqd->unplug_work, cfq_kick_queue);
+       INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
 
        cfqd->cfq_quantum = cfq_quantum;
        cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
index 1975b61..a847046 100644 (file)
@@ -1059,9 +1059,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
                return count;
 
        strlcpy(elevator_name, name, sizeof(elevator_name));
-       strstrip(elevator_name);
-
-       e = elevator_get(elevator_name);
+       e = elevator_get(strstrip(elevator_name));
        if (!e) {
                printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
                return -EINVAL;
index 5a0861d..517e433 100644 (file)
@@ -869,6 +869,7 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
 static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
+static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
        __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -888,6 +889,7 @@ static struct attribute *disk_attrs[] = {
        &dev_attr_alignment_offset.attr,
        &dev_attr_capability.attr,
        &dev_attr_stat.attr,
+       &dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &dev_attr_fail.attr,
 #endif
@@ -1053,7 +1055,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
                           part_stat_read(hd, merges[1]),
                           (unsigned long long)part_stat_read(hd, sectors[1]),
                           jiffies_to_msecs(part_stat_read(hd, ticks[1])),
-                          hd->in_flight,
+                          part_in_flight(hd),
                           jiffies_to_msecs(part_stat_read(hd, io_ticks)),
                           jiffies_to_msecs(part_stat_read(hd, time_in_queue))
                        );
index b88db6d..6b5cc4f 100644 (file)
 #include <linux/async_tx.h>
 
 /**
- * scribble - space to hold throwaway P buffer for synchronous gen_syndrome
+ * pq_scribble_page - space to hold throwaway P or Q buffer for
+ * synchronous gen_syndrome
  */
-static struct page *scribble;
-
-static bool is_raid6_zero_block(struct page *p)
-{
-       return p == (void *) raid6_empty_zero_page;
-}
+static struct page *pq_scribble_page;
 
 /* the struct page *blocks[] parameter passed to async_gen_syndrome()
  * and async_syndrome_val() contains the 'P' destination address at
@@ -83,7 +79,7 @@ do_async_gen_syndrome(struct dma_chan *chan, struct page **blocks,
         * sources and update the coefficients accordingly
         */
        for (i = 0, idx = 0; i < src_cnt; i++) {
-               if (is_raid6_zero_block(blocks[i]))
+               if (blocks[i] == NULL)
                        continue;
                dma_src[idx] = dma_map_page(dma->dev, blocks[i], offset, len,
                                            DMA_TO_DEVICE);
@@ -160,9 +156,9 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
                srcs = (void **) blocks;
 
        for (i = 0; i < disks; i++) {
-               if (is_raid6_zero_block(blocks[i])) {
+               if (blocks[i] == NULL) {
                        BUG_ON(i > disks - 3); /* P or Q can't be zero */
-                       srcs[i] = blocks[i];
+                       srcs[i] = (void*)raid6_empty_zero_page;
                } else
                        srcs[i] = page_address(blocks[i]) + offset;
        }
@@ -186,10 +182,14 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
  * blocks[disks-1] to NULL.  When P or Q is omitted 'len' must be <=
  * PAGE_SIZE as a temporary buffer of this size is used in the
  * synchronous path.  'disks' always accounts for both destination
- * buffers.
+ * buffers.  If any source buffers (blocks[i] where i < disks - 2) are
+ * set to NULL those buffers will be replaced with the raid6_zero_page
+ * in the synchronous path and omitted in the hardware-asynchronous
+ * path.
  *
  * 'blocks' note: if submit->scribble is NULL then the contents of
- * 'blocks' may be overridden
+ * 'blocks' may be overwritten to perform address conversions
+ * (dma_map_page() or page_address()).
  */
 struct dma_async_tx_descriptor *
 async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
@@ -227,11 +227,11 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
        async_tx_quiesce(&submit->depend_tx);
 
        if (!P(blocks, disks)) {
-               P(blocks, disks) = scribble;
+               P(blocks, disks) = pq_scribble_page;
                BUG_ON(len + offset > PAGE_SIZE);
        }
        if (!Q(blocks, disks)) {
-               Q(blocks, disks) = scribble;
+               Q(blocks, disks) = pq_scribble_page;
                BUG_ON(len + offset > PAGE_SIZE);
        }
        do_sync_gen_syndrome(blocks, offset, disks, len, submit);
@@ -265,8 +265,10 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
                                                      len);
        struct dma_device *device = chan ? chan->device : NULL;
        struct dma_async_tx_descriptor *tx;
+       unsigned char coefs[disks-2];
        enum dma_ctrl_flags dma_flags = submit->cb_fn ? DMA_PREP_INTERRUPT : 0;
        dma_addr_t *dma_src = NULL;
+       int src_cnt = 0;
 
        BUG_ON(disks < 4);
 
@@ -285,22 +287,32 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
                         __func__, disks, len);
                if (!P(blocks, disks))
                        dma_flags |= DMA_PREP_PQ_DISABLE_P;
+               else
+                       pq[0] = dma_map_page(dev, P(blocks, disks),
+                                            offset, len,
+                                            DMA_TO_DEVICE);
                if (!Q(blocks, disks))
                        dma_flags |= DMA_PREP_PQ_DISABLE_Q;
+               else
+                       pq[1] = dma_map_page(dev, Q(blocks, disks),
+                                            offset, len,
+                                            DMA_TO_DEVICE);
+
                if (submit->flags & ASYNC_TX_FENCE)
                        dma_flags |= DMA_PREP_FENCE;
-               for (i = 0; i < disks; i++)
+               for (i = 0; i < disks-2; i++)
                        if (likely(blocks[i])) {
-                               BUG_ON(is_raid6_zero_block(blocks[i]));
-                               dma_src[i] = dma_map_page(dev, blocks[i],
-                                                         offset, len,
-                                                         DMA_TO_DEVICE);
+                               dma_src[src_cnt] = dma_map_page(dev, blocks[i],
+                                                               offset, len,
+                                                               DMA_TO_DEVICE);
+                               coefs[src_cnt] = raid6_gfexp[i];
+                               src_cnt++;
                        }
 
                for (;;) {
                        tx = device->device_prep_dma_pq_val(chan, pq, dma_src,
-                                                           disks - 2,
-                                                           raid6_gfexp,
+                                                           src_cnt,
+                                                           coefs,
                                                            len, pqres,
                                                            dma_flags);
                        if (likely(tx))
@@ -373,9 +385,9 @@ EXPORT_SYMBOL_GPL(async_syndrome_val);
 
 static int __init async_pq_init(void)
 {
-       scribble = alloc_page(GFP_KERNEL);
+       pq_scribble_page = alloc_page(GFP_KERNEL);
 
-       if (scribble)
+       if (pq_scribble_page)
                return 0;
 
        pr_err("%s: failed to allocate required spare page\n", __func__);
@@ -385,7 +397,7 @@ static int __init async_pq_init(void)
 
 static void __exit async_pq_exit(void)
 {
-       put_page(scribble);
+       put_page(pq_scribble_page);
 }
 
 module_init(async_pq_init);
index 6d73dde..943f2ab 100644 (file)
@@ -131,8 +131,8 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
 }
 
 static struct dma_async_tx_descriptor *
-__2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
-             struct async_submit_ctl *submit)
+__2data_recov_4(int disks, size_t bytes, int faila, int failb,
+               struct page **blocks, struct async_submit_ctl *submit)
 {
        struct dma_async_tx_descriptor *tx = NULL;
        struct page *p, *q, *a, *b;
@@ -143,8 +143,8 @@ __2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
        void *cb_param = submit->cb_param;
        void *scribble = submit->scribble;
 
-       p = blocks[4-2];
-       q = blocks[4-1];
+       p = blocks[disks-2];
+       q = blocks[disks-1];
 
        a = blocks[faila];
        b = blocks[failb];
@@ -170,8 +170,8 @@ __2data_recov_4(size_t bytes, int faila, int failb, struct page **blocks,
 }
 
 static struct dma_async_tx_descriptor *
-__2data_recov_5(size_t bytes, int faila, int failb, struct page **blocks,
-             struct async_submit_ctl *submit)
+__2data_recov_5(int disks, size_t bytes, int faila, int failb,
+               struct page **blocks, struct async_submit_ctl *submit)
 {
        struct dma_async_tx_descriptor *tx = NULL;
        struct page *p, *q, *g, *dp, *dq;
@@ -181,21 +181,22 @@ __2data_recov_5(size_t bytes, int faila, int failb, struct page **blocks,
        dma_async_tx_callback cb_fn = submit->cb_fn;
        void *cb_param = submit->cb_param;
        void *scribble = submit->scribble;
-       int uninitialized_var(good);
-       int i;
+       int good_srcs, good, i;
 
-       for (i = 0; i < 3; i++) {
+       good_srcs = 0;
+       good = -1;
+       for (i = 0; i < disks-2; i++) {
+               if (blocks[i] == NULL)
+                       continue;
                if (i == faila || i == failb)
                        continue;
-               else {
-                       good = i;
-                       break;
-               }
+               good = i;
+               good_srcs++;
        }
-       BUG_ON(i >= 3);
+       BUG_ON(good_srcs > 1);
 
-       p = blocks[5-2];
-       q = blocks[5-1];
+       p = blocks[disks-2];
+       q = blocks[disks-1];
        g = blocks[good];
 
        /* Compute syndrome with zero for the missing data pages
@@ -263,10 +264,10 @@ __2data_recov_n(int disks, size_t bytes, int faila, int failb,
         * delta p and delta q
         */
        dp = blocks[faila];
-       blocks[faila] = (void *)raid6_empty_zero_page;
+       blocks[faila] = NULL;
        blocks[disks-2] = dp;
        dq = blocks[failb];
-       blocks[failb] = (void *)raid6_empty_zero_page;
+       blocks[failb] = NULL;
        blocks[disks-1] = dq;
 
        init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
@@ -323,6 +324,8 @@ struct dma_async_tx_descriptor *
 async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
                        struct page **blocks, struct async_submit_ctl *submit)
 {
+       int non_zero_srcs, i;
+
        BUG_ON(faila == failb);
        if (failb < faila)
                swap(faila, failb);
@@ -334,11 +337,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
         */
        if (!submit->scribble) {
                void **ptrs = (void **) blocks;
-               int i;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
-                       ptrs[i] = page_address(blocks[i]);
+                       if (blocks[i] == NULL)
+                               ptrs[i] = (void *) raid6_empty_zero_page;
+                       else
+                               ptrs[i] = page_address(blocks[i]);
 
                raid6_2data_recov(disks, bytes, faila, failb, ptrs);
 
@@ -347,19 +352,30 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
                return NULL;
        }
 
-       switch (disks) {
-       case 4:
+       non_zero_srcs = 0;
+       for (i = 0; i < disks-2 && non_zero_srcs < 4; i++)
+               if (blocks[i])
+                       non_zero_srcs++;
+       switch (non_zero_srcs) {
+       case 0:
+       case 1:
+               /* There must be at least 2 sources - the failed devices. */
+               BUG();
+
+       case 2:
                /* dma devices do not uniformly understand a zero source pq
                 * operation (in contrast to the synchronous case), so
-                * explicitly handle the 4 disk special case
+                * explicitly handle the special case of a 4 disk array with
+                * both data disks missing.
                 */
-               return __2data_recov_4(bytes, faila, failb, blocks, submit);
-       case 5:
+               return __2data_recov_4(disks, bytes, faila, failb, blocks, submit);
+       case 3:
                /* dma devices do not uniformly understand a single
                 * source pq operation (in contrast to the synchronous
-                * case), so explicitly handle the 5 disk special case
+                * case), so explicitly handle the special case of a 5 disk
+                * array with 2 of 3 data disks missing.
                 */
-               return __2data_recov_5(bytes, faila, failb, blocks, submit);
+               return __2data_recov_5(disks, bytes, faila, failb, blocks, submit);
        default:
                return __2data_recov_n(disks, bytes, faila, failb, blocks, submit);
        }
@@ -385,6 +401,7 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
        dma_async_tx_callback cb_fn = submit->cb_fn;
        void *cb_param = submit->cb_param;
        void *scribble = submit->scribble;
+       int good_srcs, good, i;
        struct page *srcs[2];
 
        pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
@@ -394,11 +411,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
         */
        if (!scribble) {
                void **ptrs = (void **) blocks;
-               int i;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
-                       ptrs[i] = page_address(blocks[i]);
+                       if (blocks[i] == NULL)
+                               ptrs[i] = (void*)raid6_empty_zero_page;
+                       else
+                               ptrs[i] = page_address(blocks[i]);
 
                raid6_datap_recov(disks, bytes, faila, ptrs);
 
@@ -407,6 +426,20 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
                return NULL;
        }
 
+       good_srcs = 0;
+       good = -1;
+       for (i = 0; i < disks-2; i++) {
+               if (i == faila)
+                       continue;
+               if (blocks[i]) {
+                       good = i;
+                       good_srcs++;
+                       if (good_srcs > 1)
+                               break;
+               }
+       }
+       BUG_ON(good_srcs == 0);
+
        p = blocks[disks-2];
        q = blocks[disks-1];
 
@@ -414,14 +447,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
         * Use the dead data page as temporary storage for delta q
         */
        dq = blocks[faila];
-       blocks[faila] = (void *)raid6_empty_zero_page;
+       blocks[faila] = NULL;
        blocks[disks-1] = dq;
 
-       /* in the 4 disk case we only need to perform a single source
-        * multiplication
+       /* in the 4-disk case we only need to perform a single source
+        * multiplication with the one good data block.
         */
-       if (disks == 4) {
-               int good = faila == 0 ? 1 : 0;
+       if (good_srcs == 1) {
                struct page *g = blocks[good];
 
                init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL,
index b459a90..79182dc 100644 (file)
@@ -44,20 +44,23 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
        void *cb_param_orig = submit->cb_param;
        enum async_tx_flags flags_orig = submit->flags;
        enum dma_ctrl_flags dma_flags;
-       int xor_src_cnt;
+       int xor_src_cnt = 0;
        dma_addr_t dma_dest;
 
        /* map the dest bidrectional in case it is re-used as a source */
        dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL);
        for (i = 0; i < src_cnt; i++) {
                /* only map the dest once */
+               if (!src_list[i])
+                       continue;
                if (unlikely(src_list[i] == dest)) {
-                       dma_src[i] = dma_dest;
+                       dma_src[xor_src_cnt++] = dma_dest;
                        continue;
                }
-               dma_src[i] = dma_map_page(dma->dev, src_list[i], offset,
-                                         len, DMA_TO_DEVICE);
+               dma_src[xor_src_cnt++] = dma_map_page(dma->dev, src_list[i], offset,
+                                                     len, DMA_TO_DEVICE);
        }
+       src_cnt = xor_src_cnt;
 
        while (src_cnt) {
                submit->flags = flags_orig;
@@ -123,7 +126,7 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
            int src_cnt, size_t len, struct async_submit_ctl *submit)
 {
        int i;
-       int xor_src_cnt;
+       int xor_src_cnt = 0;
        int src_off = 0;
        void *dest_buf;
        void **srcs;
@@ -135,8 +138,9 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
 
        /* convert to buffer pointers */
        for (i = 0; i < src_cnt; i++)
-               srcs[i] = page_address(src_list[i]) + offset;
-
+               if (src_list[i])
+                       srcs[xor_src_cnt++] = page_address(src_list[i]) + offset;
+       src_cnt = xor_src_cnt;
        /* set destination address */
        dest_buf = page_address(dest) + offset;
 
index 0ed42d8..93d2c79 100644 (file)
@@ -218,10 +218,10 @@ config ACPI_PROCESSOR_AGGREGATOR
        depends on X86
        help
          ACPI 4.0 defines processor Aggregator, which enables OS to perform
-         specfic processor configuration and control that applies to all
+         specific processor configuration and control that applies to all
          processors in the platform. Currently only logical processor idling
          is defined, which is to reduce power consumption. This driver
-         support the new device.
+         supports the new device.
 
 config ACPI_THERMAL
        tristate "Thermal Zone"
index 98b9690..b6ed60b 100644 (file)
@@ -245,6 +245,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
                acpi_bus_generate_netlink_event(device->pnp.device_class,
                                                  dev_name(&device->dev), event,
                                                  (u32) ac->state);
+               acpi_notifier_call_chain(device, event, (u32) ac->state);
 #ifdef CONFIG_ACPI_SYSFS_POWER
                kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
 #endif
index 9335b87..0c9c6a9 100644 (file)
@@ -251,6 +251,9 @@ int acpi_lid_open(void)
        acpi_status status;
        unsigned long long state;
 
+       if (!lid_device)
+               return -ENODEV;
+
        status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
                                       &state);
        if (ACPI_FAILURE(status))
index 3112221..1af8081 100644 (file)
@@ -389,6 +389,17 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
 
                pbus = pdev->subordinate;
                pci_dev_put(pdev);
+
+               /*
+                * This function may be called for a non-PCI device that has a
+                * PCI parent (eg. a disk under a PCI SATA controller).  In that
+                * case pdev->subordinate will be NULL for the parent.
+                */
+               if (!pbus) {
+                       dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
+                       pdev = NULL;
+                       break;
+               }
        }
 out:
        list_for_each_entry_safe(node, tmp, &device_list, node)
index f6e54bf..64e3c58 100644 (file)
@@ -1109,7 +1109,12 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
         */
 
        /* Does this device support video switching? */
-       if (video->cap._DOS) {
+       if (video->cap._DOS || video->cap._DOD) {
+               if (!video->cap._DOS) {
+                       printk(KERN_WARNING FW_BUG
+                               "ACPI(%s) defines _DOD but not _DOS\n",
+                               acpi_device_bid(video->device));
+               }
                video->flags.multihead = 1;
                status = 0;
        }
index 7032f25..575593a 100644 (file)
@@ -84,7 +84,7 @@ long acpi_is_video_device(struct acpi_device *device)
                return 0;
 
        /* Does this device able to support video switching ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
            ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
                video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
 
index b1a2577..a06f5d6 100644 (file)
@@ -575,7 +575,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
 
        /* AMD */
-       { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD SB900 */
+       { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
        /* AMD is using RAID class only for ahci controllers */
        { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -605,6 +605,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq },     /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq },     /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq },     /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq },     /* Linux ID */
        { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq },     /* MCP73 */
        { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq },     /* MCP73 */
        { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq },     /* MCP73 */
index b525a09..d7f0f1b 100644 (file)
@@ -5028,12 +5028,14 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                        qc->flags |= ATA_QCFLAG_FAILED;
 
                if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
-                       if (!ata_tag_internal(qc->tag)) {
-                               /* always fill result TF for failed qc */
-                               fill_result_tf(qc);
+                       /* always fill result TF for failed qc */
+                       fill_result_tf(qc);
+
+                       if (!ata_tag_internal(qc->tag))
                                ata_qc_schedule_eh(qc);
-                               return;
-                       }
+                       else
+                               __ata_qc_complete(qc);
+                       return;
                }
 
                WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
index 0a97822..bba2ae5 100644 (file)
@@ -2981,12 +2981,14 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
         * device detection messages backwards.
         */
        ata_for_each_dev(dev, link, ALL) {
-               if (!(new_mask & (1 << dev->devno)) ||
-                   dev->class == ATA_DEV_PMP)
+               if (!(new_mask & (1 << dev->devno)))
                        continue;
 
                dev->class = ehc->classes[dev->devno];
 
+               if (dev->class == ATA_DEV_PMP)
+                       continue;
+
                ehc->i.flags |= ATA_EHI_PRINTINFO;
                rc = ata_dev_configure(dev);
                ehc->i.flags &= ~ATA_EHI_PRINTINFO;
index aa4b3f6..ae4454d 100644 (file)
@@ -246,7 +246,7 @@ static const struct pci_device_id atiixp[] = {
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), },
 
        { },
 };
index f49814d..3bbed83 100644 (file)
@@ -235,8 +235,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = ATA_UDMA2,
                .port_ops = &sc1200_port_ops
        };
-       /* Can't enable port 2 yet, see top comments */
-       const struct ata_port_info *ppi[] = { &info, };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
 }
index 45657ca..88984b8 100644 (file)
@@ -111,7 +111,7 @@ static const struct via_isa_bridge {
        { "vt8251",     PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
        { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
-       { "vt6415",     PCI_DEVICE_ID_VIA_6415,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+       { "vt6415",     PCI_DEVICE_ID_VIA_6415,     0x00, 0xff, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
        { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
index 17f9ff9..6f5093b 100644 (file)
@@ -1382,6 +1382,25 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
         */
        if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
                return ATA_DEFER_PORT;
+
+       /* PIO commands need exclusive link: no other commands [DMA or PIO]
+        * can run concurrently.
+        * set excl_link when we want to send a PIO command in DMA mode
+        * or a non-NCQ command in NCQ mode.
+        * When we receive a command from that link, and there are no
+        * outstanding commands, mark a flag to clear excl_link and let
+        * the command go through.
+        */
+       if (unlikely(ap->excl_link)) {
+               if (link == ap->excl_link) {
+                       if (ap->nr_active_links)
+                               return ATA_DEFER_PORT;
+                       qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
+                       return 0;
+               } else
+                       return ATA_DEFER_PORT;
+       }
+
        /*
         * If the port is completely idle, then allow the new qc.
         */
@@ -1395,8 +1414,14 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
         * doesn't allow it.
         */
        if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
-           (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
-               return 0;
+           (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) {
+               if (ata_is_ncq(qc->tf.protocol))
+                       return 0;
+               else {
+                       ap->excl_link = link;
+                       return ATA_DEFER_PORT;
+               }
+       }
 
        return ATA_DEFER_PORT;
 }
index 86a4058..1eb4e02 100644 (file)
@@ -1594,9 +1594,21 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
            !ata_dev_enabled(link->device))
                sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
                                    NULL, NULL);
-       else if (!(ehc->i.flags & ATA_EHI_QUIET))
-               ata_link_printk(link, KERN_INFO,
-                               "nv: skipping hardreset on occupied port\n");
+       else {
+               const unsigned long *timing = sata_ehc_deb_timing(ehc);
+               int rc;
+
+               if (!(ehc->i.flags & ATA_EHI_QUIET))
+                       ata_link_printk(link, KERN_INFO, "nv: skipping "
+                                       "hardreset on occupied port\n");
+
+               /* make sure the link is online */
+               rc = sata_link_resume(link, timing, deadline);
+               /* whine about phy resume failure but proceed */
+               if (rc && rc != -EOPNOTSUPP)
+                       ata_link_printk(link, KERN_WARNING, "failed to resume "
+                                       "link (errno=%d)\n", rc);
+       }
 
        /* device signature acquisition is unreliable */
        return -EAGAIN;
index 973bf2a..63c143e 100644 (file)
@@ -689,15 +689,19 @@ int bus_add_driver(struct device_driver *drv)
                printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
                        __func__, drv->name);
        }
-       error = add_bind_files(drv);
-       if (error) {
-               /* Ditto */
-               printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
-                       __func__, drv->name);
+
+       if (!drv->suppress_bind_attrs) {
+               error = add_bind_files(drv);
+               if (error) {
+                       /* Ditto */
+                       printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
+                               __func__, drv->name);
+               }
        }
 
        kobject_uevent(&priv->kobj, KOBJ_ADD);
        return 0;
+
 out_unregister:
        kfree(drv->p);
        drv->p = NULL;
@@ -720,7 +724,8 @@ void bus_remove_driver(struct device_driver *drv)
        if (!drv->bus)
                return;
 
-       remove_bind_files(drv);
+       if (!drv->suppress_bind_attrs)
+               remove_bind_files(drv);
        driver_remove_attrs(drv->bus, drv);
        driver_remove_file(drv, &driver_attr_uevent);
        klist_remove(&drv->p->knode_bus);
index ed2ebd3..f367885 100644 (file)
@@ -236,7 +236,7 @@ int driver_register(struct device_driver *drv)
                put_driver(other);
                printk(KERN_ERR "Error: Driver '%s' is already registered, "
                        "aborting...\n", drv->name);
-               return -EEXIST;
+               return -EBUSY;
        }
 
        ret = bus_add_driver(drv);
index ed156a1..4fa954b 100644 (file)
@@ -521,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
 {
        int retval, code;
 
+       /* make sure driver won't have bind/unbind attributes */
+       drv->driver.suppress_bind_attrs = true;
+
        /* temporary section violation during probe() */
        drv->probe = probe;
        retval = code = platform_driver_register(drv);
 
-       /* Fixup that section violation, being paranoid about code scanning
+       /*
+        * Fixup that section violation, being paranoid about code scanning
         * the list of drivers in order to probe new devices.  Check to see
         * if the probe was successful, and make sure any forced probes of
         * new devices fail.
index fb5be2d..6399e50 100644 (file)
@@ -68,6 +68,12 @@ MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
 MODULE_VERSION("3.6.20");
 MODULE_LICENSE("GPL");
 
+static int cciss_allow_hpsa;
+module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(cciss_allow_hpsa,
+       "Prevent cciss driver from accessing hardware known to be "
+       " supported by the hpsa driver");
+
 #include "cciss_cmd.h"
 #include "cciss.h"
 #include <linux/cciss_ioctl.h>
@@ -101,8 +107,6 @@ static const struct pci_device_id cciss_pci_device_id[] = {
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324A},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324B},
-       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,      PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
        {0,}
 };
 
@@ -123,8 +127,6 @@ static struct board_type products[] = {
        {0x409D0E11, "Smart Array 6400 EM", &SA5_access},
        {0x40910E11, "Smart Array 6i", &SA5_access},
        {0x3225103C, "Smart Array P600", &SA5_access},
-       {0x3223103C, "Smart Array P800", &SA5_access},
-       {0x3234103C, "Smart Array P400", &SA5_access},
        {0x3235103C, "Smart Array P400i", &SA5_access},
        {0x3211103C, "Smart Array E200i", &SA5_access},
        {0x3212103C, "Smart Array E200", &SA5_access},
@@ -132,6 +134,10 @@ static struct board_type products[] = {
        {0x3214103C, "Smart Array E200i", &SA5_access},
        {0x3215103C, "Smart Array E200i", &SA5_access},
        {0x3237103C, "Smart Array E500", &SA5_access},
+/* controllers below this line are also supported by the hpsa driver. */
+#define HPSA_BOUNDARY 0x3223103C
+       {0x3223103C, "Smart Array P800", &SA5_access},
+       {0x3234103C, "Smart Array P400", &SA5_access},
        {0x323D103C, "Smart Array P700m", &SA5_access},
        {0x3241103C, "Smart Array P212", &SA5_access},
        {0x3243103C, "Smart Array P410", &SA5_access},
@@ -140,7 +146,6 @@ static struct board_type products[] = {
        {0x3249103C, "Smart Array P812", &SA5_access},
        {0x324A103C, "Smart Array P712m", &SA5_access},
        {0x324B103C, "Smart Array P711m", &SA5_access},
-       {0xFFFF103C, "Unknown Smart Array", &SA5_access},
 };
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
@@ -3754,7 +3759,27 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        __u64 cfg_offset;
        __u32 cfg_base_addr;
        __u64 cfg_base_addr_index;
-       int i, err;
+       int i, prod_index, err;
+
+       subsystem_vendor_id = pdev->subsystem_vendor;
+       subsystem_device_id = pdev->subsystem_device;
+       board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
+                   subsystem_vendor_id);
+
+       for (i = 0; i < ARRAY_SIZE(products); i++) {
+               /* Stand aside for hpsa driver on request */
+               if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY)
+                       return -ENODEV;
+               if (board_id == products[i].board_id)
+                       break;
+       }
+       prod_index = i;
+       if (prod_index == ARRAY_SIZE(products)) {
+               dev_warn(&pdev->dev,
+                       "unrecognized board ID: 0x%08lx, ignoring.\n",
+                       (unsigned long) board_id);
+               return -ENODEV;
+       }
 
        /* check to see if controller has been disabled */
        /* BEFORE trying to enable it */
@@ -3778,11 +3803,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                return err;
        }
 
-       subsystem_vendor_id = pdev->subsystem_vendor;
-       subsystem_device_id = pdev->subsystem_device;
-       board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
-                   subsystem_vendor_id);
-
 #ifdef CCISS_DEBUG
        printk("command = %x\n", command);
        printk("irq = %x\n", pdev->irq);
@@ -3868,14 +3888,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
         * leave a little room for ioctl calls.
         */
        c->max_commands = readl(&(c->cfgtable->CmdsOutMax));
-       for (i = 0; i < ARRAY_SIZE(products); i++) {
-               if (board_id == products[i].board_id) {
-                       c->product_name = products[i].product_name;
-                       c->access = *(products[i].access);
-                       c->nr_cmds = c->max_commands - 4;
-                       break;
-               }
-       }
+       c->product_name = products[prod_index].product_name;
+       c->access = *(products[prod_index].access);
+       c->nr_cmds = c->max_commands - 4;
        if ((readb(&c->cfgtable->Signature[0]) != 'C') ||
            (readb(&c->cfgtable->Signature[1]) != 'I') ||
            (readb(&c->cfgtable->Signature[2]) != 'S') ||
@@ -3884,27 +3899,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                err = -ENODEV;
                goto err_out_free_res;
        }
-       /* We didn't find the controller in our list. We know the
-        * signature is valid. If it's an HP device let's try to
-        * bind to the device and fire it up. Otherwise we bail.
-        */
-       if (i == ARRAY_SIZE(products)) {
-               if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
-                       c->product_name = products[i-1].product_name;
-                       c->access = *(products[i-1].access);
-                       c->nr_cmds = c->max_commands - 4;
-                       printk(KERN_WARNING "cciss: This is an unknown "
-                               "Smart Array controller.\n"
-                               "cciss: Please update to the latest driver "
-                               "available from www.hp.com.\n");
-               } else {
-                       printk(KERN_WARNING "cciss: Sorry, I don't know how"
-                               " to access the Smart Array controller %08lx\n"
-                                       , (unsigned long)board_id);
-                       err = -ENODEV;
-                       goto err_out_free_res;
-               }
-       }
 #ifdef CONFIG_X86
        {
                /* Need to enable prefetch in the SCSI core for 6400 in x86 */
@@ -4254,7 +4248,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        mutex_init(&hba[i]->busy_shutting_down);
 
        if (cciss_pci_init(hba[i], pdev) != 0)
-               goto clean0;
+               goto clean_no_release_regions;
 
        sprintf(hba[i]->devname, "cciss%d", i);
        hba[i]->ctlr = i;
@@ -4391,13 +4385,14 @@ clean2:
 clean1:
        cciss_destroy_hba_sysfs_entry(hba[i]);
 clean0:
+       pci_release_regions(pdev);
+clean_no_release_regions:
        hba[i]->busy_initializing = 0;
 
        /*
         * Deliberately omit pci_disable_device(): it does something nasty to
         * Smart Array controllers that pci_enable_device does not undo
         */
-       pci_release_regions(pdev);
        pci_set_drvdata(pdev, NULL);
        free_hba(i);
        return -1;
index edda9ea..bd112c8 100644 (file)
@@ -949,7 +949,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        lo->lo_state = Lo_unbound;
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
-       if (max_part > 0)
+       if (max_part > 0 && bdev)
                ioctl_by_bdev(bdev, BLKRRPART, 0);
        mutex_unlock(&lo->lo_ctl_mutex);
        /*
index 43f1938..51042f0 100644 (file)
@@ -3,7 +3,6 @@
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_blk.h>
 #include <linux/scatterlist.h>
 
@@ -183,34 +182,6 @@ static void do_virtblk_request(struct request_queue *q)
                vblk->vq->vq_ops->kick(vblk->vq);
 }
 
-/* return ATA identify data
- */
-static int virtblk_identify(struct gendisk *disk, void *argp)
-{
-       struct virtio_blk *vblk = disk->private_data;
-       void *opaque;
-       int err = -ENOMEM;
-
-       opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL);
-       if (!opaque)
-               goto out;
-
-       err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY,
-               offsetof(struct virtio_blk_config, identify), opaque,
-               VIRTIO_BLK_ID_BYTES);
-
-       if (err)
-               goto out_kfree;
-
-       if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES))
-               err = -EFAULT;
-
-out_kfree:
-       kfree(opaque);
-out:
-       return err;
-}
-
 static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
 {
        req->cmd_type = REQ_TYPE_LINUX_BLOCK;
@@ -222,10 +193,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
 {
        struct gendisk *disk = bdev->bd_disk;
        struct virtio_blk *vblk = disk->private_data;
-       void __user *argp = (void __user *)data;
-
-       if (cmd == HDIO_GET_IDENTITY)
-               return virtblk_identify(disk, argp);
 
        /*
         * Only allow the generic SCSI ioctls if the host can support it.
@@ -233,7 +200,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
        if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
                return -ENOTTY;
 
-       return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
+       return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
+                             (void __user *)data);
 }
 
 /* We provide getgeo only to please some old bootloader/partitioning tools */
@@ -332,7 +300,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        }
 
        vblk->disk->queue->queuedata = vblk;
-       queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue);
 
        if (index < 26) {
                sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
@@ -445,7 +412,7 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
        VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
        VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
-       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
+       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH
 };
 
 /*
index 08a6f50..6aad99e 100644 (file)
@@ -323,7 +323,7 @@ config SPECIALIX
 
 config SX
        tristate "Specialix SX (and SI) card support"
-       depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
+       depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN
        help
          This is a driver for the SX and SI multiport serial cards.
          Please read the file <file:Documentation/serial/sx.txt> for details.
@@ -334,7 +334,7 @@ config SX
 
 config RIO
        tristate "Specialix RIO system support"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && BROKEN
        help
          This is a driver for the Specialix RIO, a smart serial card which
          drives an outboard box that can support up to 128 ports.  Product
@@ -395,7 +395,7 @@ config NOZOMI
 
 config A2232
        tristate "Commodore A2232 serial support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
+       depends on EXPERIMENTAL && ZORRO && BROKEN
        ---help---
          This option supports the 2232 7-port serial card shipped with the
          Amiga 2000 and other Zorro-bus machines, dating from 1989.  At
index aac0985..31e7c91 100644 (file)
@@ -43,6 +43,7 @@
 #define RTC_VERSION    "1.07"
 
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
 #include <linux/fcntl.h>
index 962968f..915157f 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/scatterlist.h>
 #include <linux/spinlock.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_rng.h>
 
 /* The host will fill any buffer we give it with sweet, sweet randomness.  We
@@ -117,7 +116,7 @@ static int virtrng_probe(struct virtio_device *vdev)
        return 0;
 }
 
-static void virtrng_remove(struct virtio_device *vdev)
+static void __devexit virtrng_remove(struct virtio_device *vdev)
 {
        vdev->config->reset(vdev);
        hwrng_unregister(&virtio_hwrng);
index e0d0f8b..bc4ab3e 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
+#include <linux/sched.h>
 #include <linux/sysctl.h>
 #include <linux/wait.h>
 #include <linux/bcd.h>
index fd3dced..8c262aa 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/input.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index 3108991..66fa4e1 100644 (file)
@@ -402,28 +402,26 @@ static void flush_to_ldisc(struct work_struct *work)
                container_of(work, struct tty_struct, buf.work.work);
        unsigned long   flags;
        struct tty_ldisc *disc;
-       struct tty_buffer *tbuf, *head;
-       char *char_buf;
-       unsigned char *flag_buf;
 
        disc = tty_ldisc_ref(tty);
        if (disc == NULL)       /*  !TTY_LDISC */
                return;
 
        spin_lock_irqsave(&tty->buf.lock, flags);
-       /* So we know a flush is running */
-       set_bit(TTY_FLUSHING, &tty->flags);
-       head = tty->buf.head;
-       if (head != NULL) {
-               tty->buf.head = NULL;
-               for (;;) {
-                       int count = head->commit - head->read;
+
+       if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
+               struct tty_buffer *head;
+               while ((head = tty->buf.head) != NULL) {
+                       int count;
+                       char *char_buf;
+                       unsigned char *flag_buf;
+
+                       count = head->commit - head->read;
                        if (!count) {
                                if (head->next == NULL)
                                        break;
-                               tbuf = head;
-                               head = head->next;
-                               tty_buffer_free(tty, tbuf);
+                               tty->buf.head = head->next;
+                               tty_buffer_free(tty, head);
                                continue;
                        }
                        /* Ldisc or user is trying to flush the buffers
@@ -445,9 +443,9 @@ static void flush_to_ldisc(struct work_struct *work)
                                                        flag_buf, count);
                        spin_lock_irqsave(&tty->buf.lock, flags);
                }
-               /* Restore the queue head */
-               tty->buf.head = head;
+               clear_bit(TTY_FLUSHING, &tty->flags);
        }
+
        /* We may have a deferred request to flush the input buffer,
           if so pull the chain under the lock and empty the queue */
        if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
@@ -455,7 +453,6 @@ static void flush_to_ldisc(struct work_struct *work)
                clear_bit(TTY_FLUSHPENDING, &tty->flags);
                wake_up(&tty->read_wait);
        }
-       clear_bit(TTY_FLUSHING, &tty->flags);
        spin_unlock_irqrestore(&tty->buf.lock, flags);
 
        tty_ldisc_deref(disc);
@@ -471,7 +468,7 @@ static void flush_to_ldisc(struct work_struct *work)
  */
 void tty_flush_to_ldisc(struct tty_struct *tty)
 {
-       flush_to_ldisc(&tty->buf.work.work);
+       flush_delayed_work(&tty->buf.work);
 }
 
 /**
index 0d328b5..a035ae3 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_console.h>
 #include "hvc_console.h"
 
index 6b36ee5..ed86d3b 100644 (file)
@@ -1532,7 +1532,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
 
        case PIO_UNIMAP:
        case GIO_UNIMAP:
-               ret = do_unimap_ioctl(cmd, up, perm, vc);
+               ret = compat_unimap_ioctl(cmd, up, perm, vc);
                break;
 
        /*
index ad41f19..12fdd39 100644 (file)
@@ -76,8 +76,11 @@ static void cpuidle_idle_call(void)
 #endif
        /* ask the governor for the next state */
        next_state = cpuidle_curr_governor->select(dev);
-       if (need_resched())
+       if (need_resched()) {
+               local_irq_enable();
                return;
+       }
+
        target_state = &dev->states[next_state];
 
        /* enter the state and update stats */
index 76cb6b3..0af8057 100644 (file)
 #include <asm/i387.h>
 #include "padlock.h"
 
+#ifdef CONFIG_64BIT
+#define STACK_ALIGN 16
+#else
+#define STACK_ALIGN 4
+#endif
+
 struct padlock_sha_desc {
        struct shash_desc fallback;
 };
@@ -64,7 +70,9 @@ static int padlock_sha1_finup(struct shash_desc *desc, const u8 *in,
        /* We can't store directly to *out as it may be unaligned. */
        /* BTW Don't reduce the buffer size below 128 Bytes!
         *     PadLock microcode needs it that big. */
-       char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+       char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+               ((aligned(STACK_ALIGN)));
+       char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
        struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
        struct sha1_state state;
        unsigned int space;
@@ -128,7 +136,9 @@ static int padlock_sha256_finup(struct shash_desc *desc, const u8 *in,
        /* We can't store directly to *out as it may be unaligned. */
        /* BTW Don't reduce the buffer size below 128 Bytes!
         *     PadLock microcode needs it that big. */
-       char result[128] __attribute__ ((aligned(PADLOCK_ALIGNMENT)));
+       char buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+               ((aligned(STACK_ALIGN)));
+       char *result = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
        struct padlock_sha_desc *dctx = shash_desc_ctx(desc);
        struct sha256_state state;
        unsigned int space;
index 4f4ac82..d4560d9 100644 (file)
@@ -1122,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
                debugf0("Reading K8_DRAM_BASE_LOW failed\n");
 
        /* Extract parts into separate data entries */
-       pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
+       pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
        pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
        pvt->dram_rw_en[dram] = (low & 0x3);
 
@@ -1135,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
         * Extract parts into separate data entries. Limit is the HIGHEST memory
         * location of the region, so lower 24 bits need to be all ones
         */
-       pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
+       pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
        pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
        pvt->dram_DstNode[dram] = (low & 0x7);
 }
@@ -1369,7 +1369,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
        pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
 
        pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
-                              (((u64)low_base  & 0xFFFF0000) << 24);
+                              (((u64)low_base  & 0xFFFF0000) << 8);
 
        low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
        high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1391,7 +1391,7 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
         * memory location of the region, so low 24 bits need to be all ones.
         */
        pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
-                               (((u64) low_limit & 0xFFFF0000) << 24) |
+                               (((u64) low_limit & 0xFFFF0000) << 8) |
                                0x00FFFFFF;
 }
 
index d335086..77a9579 100644 (file)
@@ -1173,7 +1173,7 @@ static void i5000_get_mc_regs(struct mem_ctl_info *mci)
                        pci_read_config_word(pvt->branch_1, where,
                                        &pvt->b1_mtr[slot_row]);
                        debugf2("MTR%d where=0x%x B1 value=0x%x\n", slot_row,
-                               where, pvt->b0_mtr[slot_row]);
+                               where, pvt->b1_mtr[slot_row]);
                } else {
                        pvt->b1_mtr[slot_row] = 0;
                }
@@ -1232,7 +1232,7 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
        struct csrow_info *p_csrow;
        int empty, channel_count;
        int max_csrows;
-       int mtr;
+       int mtr, mtr1;
        int csrow_megs;
        int channel;
        int csrow;
@@ -1251,9 +1251,10 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
 
                /* use branch 0 for the basis */
                mtr = pvt->b0_mtr[csrow >> 1];
+               mtr1 = pvt->b1_mtr[csrow >> 1];
 
                /* if no DIMMS on this row, continue */
-               if (!MTR_DIMMS_PRESENT(mtr))
+               if (!MTR_DIMMS_PRESENT(mtr) && !MTR_DIMMS_PRESENT(mtr1))
                        continue;
 
                /* FAKE OUT VALUES, FIXME */
index b08b6d8..f99d106 100644 (file)
 /* Limits for i5400 */
 #define NUM_MTRS_PER_BRANCH    4
 #define CHANNELS_PER_BRANCH    2
+#define MAX_DIMMS_PER_CHANNEL  NUM_MTRS_PER_BRANCH
 #define        MAX_CHANNELS            4
-#define MAX_DIMMS              (MAX_CHANNELS * 4)      /* Up to 4 DIMM's per channel */
-#define MAX_CSROWS             (MAX_DIMMS * 2)         /* max possible csrows per channel */
+/* max possible csrows per channel */
+#define MAX_CSROWS             (MAX_DIMMS_PER_CHANNEL)
 
 /* Device 16,
  * Function 0: System Address
@@ -331,7 +332,6 @@ static const struct i5400_dev_info i5400_devs[] = {
 
 struct i5400_dimm_info {
        int megabytes;          /* size, 0 means not present  */
-       int dual_rank;
 };
 
 /* driver private data structure */
@@ -849,11 +849,9 @@ static int determine_mtr(struct i5400_pvt *pvt, int csrow, int channel)
        int n;
 
        /* There is one MTR for each slot pair of FB-DIMMs,
-          Each slot may have one or two ranks (2 csrows),
           Each slot pair may be at branch 0 or branch 1.
-          So, csrow should be divided by eight
         */
-       n = csrow >> 3;
+       n = csrow;
 
        if (n >= NUM_MTRS_PER_BRANCH) {
                debugf0("ERROR: trying to access an invalid csrow: %d\n",
@@ -905,25 +903,22 @@ static void handle_channel(struct i5400_pvt *pvt, int csrow, int channel,
                amb_present_reg = determine_amb_present_reg(pvt, channel);
 
                /* Determine if there is a DIMM present in this DIMM slot */
-               if (amb_present_reg & (1 << (csrow >> 1))) {
-                       dinfo->dual_rank = MTR_DIMM_RANK(mtr);
-
-                       if (!((dinfo->dual_rank == 0) &&
-                               ((csrow & 0x1) == 0x1))) {
-                               /* Start with the number of bits for a Bank
-                                * on the DRAM */
-                               addrBits = MTR_DRAM_BANKS_ADDR_BITS(mtr);
-                               /* Add thenumber of ROW bits */
-                               addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr);
-                               /* add the number of COLUMN bits */
-                               addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
-
-                               addrBits += 6;  /* add 64 bits per DIMM */
-                               addrBits -= 20; /* divide by 2^^20 */
-                               addrBits -= 3;  /* 8 bits per bytes */
-
-                               dinfo->megabytes = 1 << addrBits;
-                       }
+               if (amb_present_reg & (1 << csrow)) {
+                       /* Start with the number of bits for a Bank
+                        * on the DRAM */
+                       addrBits = MTR_DRAM_BANKS_ADDR_BITS(mtr);
+                       /* Add thenumber of ROW bits */
+                       addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr);
+                       /* add the number of COLUMN bits */
+                       addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
+                       /* add the number of RANK bits */
+                       addrBits += MTR_DIMM_RANK(mtr);
+
+                       addrBits += 6;  /* add 64 bits per DIMM */
+                       addrBits -= 20; /* divide by 2^^20 */
+                       addrBits -= 3;  /* 8 bits per bytes */
+
+                       dinfo->megabytes = 1 << addrBits;
                }
        }
 }
@@ -951,12 +946,12 @@ static void calculate_dimm_size(struct i5400_pvt *pvt)
                return;
        }
 
-       /* Scan all the actual CSROWS (which is # of DIMMS * 2)
+       /* Scan all the actual CSROWS
         * and calculate the information for each DIMM
         * Start with the highest csrow first, to display it first
         * and work toward the 0th csrow
         */
-       max_csrows = pvt->maxdimmperch * 2;
+       max_csrows = pvt->maxdimmperch;
        for (csrow = max_csrows - 1; csrow >= 0; csrow--) {
 
                /* on an odd csrow, first output a 'boundary' marker,
@@ -1064,7 +1059,7 @@ static void i5400_get_mc_regs(struct mem_ctl_info *mci)
 
        /* Get the set of MTR[0-3] regs by each branch */
        for (slot_row = 0; slot_row < NUM_MTRS_PER_BRANCH; slot_row++) {
-               int where = MTR0 + (slot_row * sizeof(u32));
+               int where = MTR0 + (slot_row * sizeof(u16));
 
                /* Branch 0 set of MTR registers */
                pci_read_config_word(pvt->branch_0, where,
@@ -1146,7 +1141,7 @@ static int i5400_init_csrows(struct mem_ctl_info *mci)
        pvt = mci->pvt_info;
 
        channel_count = pvt->maxch;
-       max_csrows = pvt->maxdimmperch * 2;
+       max_csrows = pvt->maxdimmperch;
 
        empty = 1;              /* Assume NO memory */
 
@@ -1214,28 +1209,6 @@ static void i5400_enable_error_reporting(struct mem_ctl_info *mci)
                        fbd_error_mask);
 }
 
-/*
- * i5400_get_dimm_and_channel_counts(pdev, &num_csrows, &num_channels)
- *
- *     ask the device how many channels are present and how many CSROWS
- *      as well
- */
-static void i5400_get_dimm_and_channel_counts(struct pci_dev *pdev,
-                                       int *num_dimms_per_channel,
-                                       int *num_channels)
-{
-       u8 value;
-
-       /* Need to retrieve just how many channels and dimms per channel are
-        * supported on this memory controller
-        */
-       pci_read_config_byte(pdev, MAXDIMMPERCH, &value);
-       *num_dimms_per_channel = (int)value * 2;
-
-       pci_read_config_byte(pdev, MAXCH, &value);
-       *num_channels = (int)value;
-}
-
 /*
  *     i5400_probe1    Probe for ONE instance of device to see if it is
  *                     present.
@@ -1263,22 +1236,16 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx)
        if (PCI_FUNC(pdev->devfn) != 0)
                return -ENODEV;
 
-       /* Ask the devices for the number of CSROWS and CHANNELS so
-        * that we can calculate the memory resources, etc
-        *
-        * The Chipset will report what it can handle which will be greater
-        * or equal to what the motherboard manufacturer will implement.
-        *
-        * As we don't have a motherboard identification routine to determine
+       /* As we don't have a motherboard identification routine to determine
         * actual number of slots/dimms per channel, we thus utilize the
         * resource as specified by the chipset. Thus, we might have
         * have more DIMMs per channel than actually on the mobo, but this
         * allows the driver to support upto the chipset max, without
         * some fancy mobo determination.
         */
-       i5400_get_dimm_and_channel_counts(pdev, &num_dimms_per_channel,
-                                       &num_channels);
-       num_csrows = num_dimms_per_channel * 2;
+       num_dimms_per_channel = MAX_DIMMS_PER_CHANNEL;
+       num_channels = MAX_CHANNELS;
+       num_csrows = num_dimms_per_channel;
 
        debugf0("MC: %s(): Number of - Channels= %d  DIMMS= %d  CSROWS= %d\n",
                __func__, num_channels, num_dimms_per_channel, num_csrows);
index 157f650..cf27402 100644 (file)
@@ -26,7 +26,9 @@
 #include "mpc85xx_edac.h"
 
 static int edac_dev_idx;
+#ifdef CONFIG_PCI
 static int edac_pci_idx;
+#endif
 static int edac_mc_idx;
 
 static u32 orig_ddr_err_disable;
index 50f0176..98dbbda 100644 (file)
@@ -188,14 +188,7 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
 /* Impossible login_id, to detect logout attempt before successful login */
 #define INVALID_LOGIN_ID 0x10000
 
-/*
- * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
- * provided in the config rom. Most devices do provide a value, which
- * we'll use for login management orbs, but with some sane limits.
- */
-#define SBP2_MIN_LOGIN_ORB_TIMEOUT     5000U   /* Timeout in ms */
-#define SBP2_MAX_LOGIN_ORB_TIMEOUT     40000U  /* Timeout in ms */
-#define SBP2_ORB_TIMEOUT               2000U   /* Timeout in ms */
+#define SBP2_ORB_TIMEOUT               2000U           /* Timeout in ms */
 #define SBP2_ORB_NULL                  0x80000000
 #define SBP2_RETRY_LIMIT               0xf             /* 15 retries */
 #define SBP2_CYCLE_LIMIT               (0xc8 << 12)    /* 200 125us cycles */
@@ -1034,7 +1027,6 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
 {
        struct fw_csr_iterator ci;
        int key, value;
-       unsigned int timeout;
 
        fw_csr_iterator_init(&ci, directory);
        while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -1059,17 +1051,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
 
                case SBP2_CSR_UNIT_CHARACTERISTICS:
                        /* the timeout value is stored in 500ms units */
-                       timeout = ((unsigned int) value >> 8 & 0xff) * 500;
-                       timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
-                       tgt->mgt_orb_timeout =
-                                 min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
-
-                       if (timeout > tgt->mgt_orb_timeout)
-                               fw_notify("%s: config rom contains %ds "
-                                         "management ORB timeout, limiting "
-                                         "to %ds\n", tgt->bus_id,
-                                         timeout / 1000,
-                                         tgt->mgt_orb_timeout / 1000);
+                       tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500;
                        break;
 
                case SBP2_CSR_LOGICAL_UNIT_NUMBER:
@@ -1087,6 +1069,22 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
        return 0;
 }
 
+/*
+ * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
+ * provided in the config rom. Most devices do provide a value, which
+ * we'll use for login management orbs, but with some sane limits.
+ */
+static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt)
+{
+       unsigned int timeout = tgt->mgt_orb_timeout;
+
+       if (timeout > 40000)
+               fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n",
+                         tgt->bus_id, timeout / 1000);
+
+       tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000);
+}
+
 static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
                                  u32 firmware_revision)
 {
@@ -1171,6 +1169,7 @@ static int sbp2_probe(struct device *dev)
                               &firmware_revision) < 0)
                goto fail_tgt_put;
 
+       sbp2_clamp_management_orb_timeout(tgt);
        sbp2_init_workarounds(tgt, model, firmware_revision);
 
        /*
index afad147..49384a7 100644 (file)
@@ -460,7 +460,8 @@ no_irqs:
        return ret;
 }
 
-static int __devexit gpio_twl4030_remove(struct platform_device *pdev)
+/* Cannot use __devexit as gpio_twl4030_probe() calls us */
+static int gpio_twl4030_remove(struct platform_device *pdev)
 {
        struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
        int status;
@@ -493,7 +494,7 @@ static struct platform_driver gpio_twl4030_driver = {
        .driver.name    = "twl4030_gpio",
        .driver.owner   = THIS_MODULE,
        .probe          = gpio_twl4030_probe,
-       .remove         = __devexit_p(gpio_twl4030_remove),
+       .remove         = gpio_twl4030_remove,
 };
 
 static int __init gpio_twl4030_init(void)
index 3c0d2b3..cea665d 100644 (file)
@@ -626,6 +626,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
                return NULL;
        }
 
+       /* it is incorrect if hsync/vsync width is zero */
+       if (!hsync_pulse_width || !vsync_pulse_width) {
+               DRM_DEBUG_KMS("Incorrect Detailed timing. "
+                               "Wrong Hsync/Vsync pulse width\n");
+               return NULL;
+       }
        mode = drm_mode_create(dev);
        if (!mode)
                return NULL;
@@ -647,6 +653,15 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
        mode->vsync_end = mode->vsync_start + vsync_pulse_width;
        mode->vtotal = mode->vdisplay + vblank;
 
+       /* perform the basic check for the detailed timing */
+       if (mode->hsync_end > mode->htotal ||
+               mode->vsync_end > mode->vtotal) {
+               drm_mode_destroy(dev, mode);
+               DRM_DEBUG_KMS("Incorrect detailed timing. "
+                               "Sync is beyond the blank.\n");
+               return NULL;
+       }
+
        drm_mode_set_name(mode);
 
        if (pt->misc & DRM_EDID_PT_INTERLACED)
index 23dc9c1..9c92461 100644 (file)
@@ -454,22 +454,39 @@ out_free:
 }
 EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
 
-static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
+static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
                     u16 blue, u16 regno, struct fb_info *info)
 {
        struct drm_fb_helper *fb_helper = info->par;
        struct drm_framebuffer *fb = fb_helper->fb;
        int pindex;
 
+       if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+               u32 *palette;
+               u32 value;
+               /* place color in psuedopalette */
+               if (regno > 16)
+                       return -EINVAL;
+               palette = (u32 *)info->pseudo_palette;
+               red >>= (16 - info->var.red.length);
+               green >>= (16 - info->var.green.length);
+               blue >>= (16 - info->var.blue.length);
+               value = (red << info->var.red.offset) |
+                       (green << info->var.green.offset) |
+                       (blue << info->var.blue.offset);
+               palette[regno] = value;
+               return 0;
+       }
+
        pindex = regno;
 
        if (fb->bits_per_pixel == 16) {
                pindex = regno << 3;
 
                if (fb->depth == 16 && regno > 63)
-                       return;
+                       return -EINVAL;
                if (fb->depth == 15 && regno > 31)
-                       return;
+                       return -EINVAL;
 
                if (fb->depth == 16) {
                        u16 r, g, b;
@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
 
        if (fb->depth != 16)
                fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
-
-       if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-               ((u32 *) fb->pseudo_palette)[regno] =
-                       (regno << info->var.red.offset) |
-                       (regno << info->var.green.offset) |
-                       (regno << info->var.blue.offset);
-       }
+       return 0;
 }
 
 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
@@ -536,7 +547,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
                        if (transp)
                                htransp = *transp++;
 
-                       setcolreg(crtc, hred, hgreen, hblue, start++, info);
+                       rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
+                       if (rc)
+                               return rc;
                }
                crtc_funcs->load_lut(crtc);
        }
@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno,
        struct drm_device *dev = fb_helper->dev;
        struct drm_crtc *crtc;
        int i;
+       int ret;
 
        if (regno > 255)
                return 1;
@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno,
                if (i == fb_helper->crtc_count)
                        continue;
 
+               ret = setcolreg(crtc, red, green, blue, regno, info);
+               if (ret)
+                       return ret;
 
-               setcolreg(crtc, red, green, blue, regno, info);
                crtc_funcs->load_lut(crtc);
        }
        return 0;
@@ -928,7 +944,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
 {
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
-               FB_VISUAL_DIRECTCOLOR;
+               FB_VISUAL_TRUECOLOR;
        info->fix.type_aux = 0;
        info->fix.xpanstep = 1; /* doing it in hw */
        info->fix.ypanstep = 1; /* doing it in hw */
index b93814c..7f436ec 100644 (file)
@@ -89,7 +89,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
                pci_set_power_state(dev->pdev, PCI_D3hot);
        }
 
-       dev_priv->suspended = 1;
+       /* Modeset on resume, not lid events */
+       dev_priv->modeset_on_lid = 0;
 
        return 0;
 }
@@ -124,7 +125,7 @@ static int i915_resume(struct drm_device *dev)
                drm_helper_resume_force_mode(dev);
        }
 
-       dev_priv->suspended = 0;
+       dev_priv->modeset_on_lid = 0;
 
        return ret;
 }
index 6035d3d..c5df223 100644 (file)
@@ -274,7 +274,7 @@ typedef struct drm_i915_private {
        struct drm_i915_display_funcs display;
 
        /* Register state */
-       bool suspended;
+       bool modeset_on_lid;
        u8 saveLBB;
        u32 saveDSPACNTR;
        u32 saveDSPBCNTR;
index 98ae3d7..808bbe4 100644 (file)
@@ -656,6 +656,15 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
        return 0;
 }
 
+/*
+ * Lid events. Note the use of 'modeset_on_lid':
+ *  - we set it on lid close, and reset it on open
+ *  - we use it as a "only once" bit (ie we ignore
+ *    duplicate events where it was already properly
+ *    set/reset)
+ *  - the suspend/resume paths will also set it to
+ *    zero, since they restore the mode ("lid open").
+ */
 static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
                            void *unused)
 {
@@ -663,13 +672,19 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
                container_of(nb, struct drm_i915_private, lid_notifier);
        struct drm_device *dev = dev_priv->dev;
 
-       if (acpi_lid_open() && !dev_priv->suspended) {
-               mutex_lock(&dev->mode_config.mutex);
-               drm_helper_resume_force_mode(dev);
-               mutex_unlock(&dev->mode_config.mutex);
+       if (!acpi_lid_open()) {
+               dev_priv->modeset_on_lid = 1;
+               return NOTIFY_OK;
        }
 
-       drm_sysfs_hotplug_event(dev_priv->dev);
+       if (!dev_priv->modeset_on_lid)
+               return NOTIFY_OK;
+
+       dev_priv->modeset_on_lid = 0;
+
+       mutex_lock(&dev->mode_config.mutex);
+       drm_helper_resume_force_mode(dev);
+       mutex_unlock(&dev->mode_config.mutex);
 
        return NOTIFY_OK;
 }
index 3d66703..df98814 100644 (file)
@@ -582,10 +582,9 @@ int radeon_device_init(struct radeon_device *rdev,
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
        /* if we have > 1 VGA cards, then disable the radeon VGA resources */
-       r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
-       if (r) {
-               return -EINVAL;
-       }
+       /* this will fail for cards that aren't VGA class devices, just
+        * ignore it */
+       vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 
        r = radeon_init(rdev);
        if (r)
index be34d32..7d05c4b 100644 (file)
@@ -1066,7 +1066,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
  * @type: HID report type (HID_*_REPORT)
  * @data: report contents
  * @size: size of data parameter
- * @interrupt: called from atomic?
+ * @interrupt: distinguish between interrupt and control transfers
  *
  * This is data entry for lower layers.
  */
index b05f602..c40afc5 100644 (file)
@@ -132,12 +132,12 @@ static struct hid_driver twinhan_driver = {
        .input_mapping = twinhan_input_mapping,
 };
 
-static int twinhan_init(void)
+static int __init twinhan_init(void)
 {
        return hid_register_driver(&twinhan_driver);
 }
 
-static void twinhan_exit(void)
+static void __exit twinhan_exit(void)
 {
        hid_unregister_driver(&twinhan_driver);
 }
index ba05275..cdd1369 100644 (file)
@@ -48,10 +48,9 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
        char *report;
        DECLARE_WAITQUEUE(wait, current);
 
-       while (ret == 0) {
-
-               mutex_lock(&list->read_mutex);
+       mutex_lock(&list->read_mutex);
 
+       while (ret == 0) {
                if (list->head == list->tail) {
                        add_wait_queue(&list->hidraw->wait, &wait);
                        set_current_state(TASK_INTERRUPTIBLE);
index 2c2cb1e..27d6257 100644 (file)
@@ -572,7 +572,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
        /* Sample register contents every 1 sec */
        if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
-               if (data->type != sch5027) {
+               if (data->type == dme1737) {
                        data->vid = dme1737_read(data, DME1737_REG_VID) &
                                0x3f;
                }
@@ -1621,9 +1621,6 @@ static struct attribute *dme1737_misc_attr[] = {
        &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
        &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
        &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
-       /* Misc */
-       &dev_attr_vrm.attr,
-       &dev_attr_cpu0_vid.attr,
        NULL
 };
 
@@ -1631,6 +1628,18 @@ static const struct attribute_group dme1737_misc_group = {
        .attrs = dme1737_misc_attr,
 };
 
+/* The following struct holds VID-related attributes. Their creation
+   depends on the chip type which is determined during module load. */
+static struct attribute *dme1737_vid_attr[] = {
+       &dev_attr_vrm.attr,
+       &dev_attr_cpu0_vid.attr,
+       NULL
+};
+
+static const struct attribute_group dme1737_vid_group = {
+       .attrs = dme1737_vid_attr,
+};
+
 /* The following structs hold the PWM attributes, some of which are optional.
  * Their creation depends on the chip configuration which is determined during
  * module load. */
@@ -1902,6 +1911,9 @@ static void dme1737_remove_files(struct device *dev)
        if (data->type != sch5027) {
                sysfs_remove_group(&dev->kobj, &dme1737_misc_group);
        }
+       if (data->type == dme1737) {
+               sysfs_remove_group(&dev->kobj, &dme1737_vid_group);
+       }
 
        sysfs_remove_group(&dev->kobj, &dme1737_group);
 
@@ -1933,6 +1945,13 @@ static int dme1737_create_files(struct device *dev)
                goto exit_remove;
        }
 
+       /* Create VID-related sysfs attributes */
+       if ((data->type == dme1737) &&
+           (err = sysfs_create_group(&dev->kobj,
+                                     &dme1737_vid_group))) {
+               goto exit_remove;
+       }
+
        /* Create fan sysfs attributes */
        for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
                if (data->has_fan & (1 << ix)) {
@@ -2127,7 +2146,7 @@ static int dme1737_init_device(struct device *dev)
        data->pwm_acz[2] = 4;   /* pwm3 -> zone3 */
 
        /* Set VRM */
-       if (data->type != sch5027) {
+       if (data->type == dme1737) {
                data->vrm = vid_which_vrm();
        }
 
index 2a7a85a..da1b1f9 100644 (file)
@@ -819,7 +819,7 @@ static int watchdog_release(struct inode *inode, struct file *filp)
 static ssize_t watchdog_write(struct file *filp, const char __user *buf,
        size_t count, loff_t *offset)
 {
-       size_t ret;
+       int ret;
        struct fschmd_data *data = filp->private_data;
 
        if (count) {
index 6679854..be475e8 100644 (file)
@@ -197,11 +197,13 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
        AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
        AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
        AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
-       AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
+       AXIS_DMI_MATCH("NC6730b", "HP Compaq 6730b", xy_rotated_left_usd),
+       AXIS_DMI_MATCH("NC6730s", "HP Compaq 6730s", xy_swap),
        AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
        AXIS_DMI_MATCH("NC6710x", "HP Compaq 6710", xy_swap_yz_inverted),
        AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted),
        AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right),
+       AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap),
        /* Intel-based HP Pavilion dv5 */
        AXIS_DMI_MATCH2("HPDV5_I",
                        PRODUCT_NAME, "HP Pavilion dv5",
@@ -214,6 +216,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
                        y_inverted),
        AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
        AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
+       AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted),
        { NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
index ffeb2a1..a3749cb 100644 (file)
@@ -1028,12 +1028,11 @@ static int __init it87_find(unsigned short *address,
                chip_type, *address, sio_data->revision);
 
        /* Read GPIO config and VID value from LDN 7 (GPIO) */
-       if (chip_type != IT8705F_DEVID) {
+       if (sio_data->type != it87) {
                int reg;
 
                superio_select(GPIO);
-               if ((chip_type == it8718) ||
-                   (chip_type == it8720))
+               if (sio_data->type == it8718 || sio_data->type == it8720)
                        sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
 
                reg = superio_inb(IT87_SIO_PINX2_REG);
index 6396c3a..837322b 100644 (file)
@@ -177,7 +177,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = {
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
        { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
-       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_SB900_IDE), 0 },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), 0 },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
index 680e597..ca0c46f 100644 (file)
@@ -379,7 +379,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
                .enablebits     = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
                .port_ops       = &cmd64x_port_ops,
                .host_flags     = IDE_HFLAG_CLEAR_SIMPLEX |
-                                 IDE_HFLAG_ABUSE_PREFETCH,
+                                 IDE_HFLAG_ABUSE_PREFETCH |
+                                 IDE_HFLAG_SERIALIZE,
                .pio_mask       = ATA_PIO5,
                .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = 0x00, /* no udma */
@@ -389,7 +390,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
                .init_chipset   = init_chipset_cmd64x,
                .enablebits     = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
                .port_ops       = &cmd648_port_ops,
-               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
+               .host_flags     = IDE_HFLAG_ABUSE_PREFETCH |
+                                 IDE_HFLAG_SERIALIZE,
                .pio_mask       = ATA_PIO5,
                .mwdma_mask     = ATA_MWDMA2,
                .udma_mask      = ATA_UDMA2,
index c6f88eb..cc763c9 100644 (file)
@@ -782,10 +782,29 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
        return 0;
 }
 
+union input_seq_state {
+       struct {
+               unsigned short pos;
+               bool mutex_acquired;
+       };
+       void *p;
+};
+
 static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       if (mutex_lock_interruptible(&input_mutex))
-               return NULL;
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+       int error;
+
+       /* We need to fit into seq->private pointer */
+       BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+       error = mutex_lock_interruptible(&input_mutex);
+       if (error) {
+               state->mutex_acquired = false;
+               return ERR_PTR(error);
+       }
+
+       state->mutex_acquired = true;
 
        return seq_list_start(&input_dev_list, *pos);
 }
@@ -795,9 +814,12 @@ static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        return seq_list_next(v, &input_dev_list, pos);
 }
 
-static void input_devices_seq_stop(struct seq_file *seq, void *v)
+static void input_seq_stop(struct seq_file *seq, void *v)
 {
-       mutex_unlock(&input_mutex);
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+
+       if (state->mutex_acquired)
+               mutex_unlock(&input_mutex);
 }
 
 static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@ -861,7 +883,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
 static const struct seq_operations input_devices_seq_ops = {
        .start  = input_devices_seq_start,
        .next   = input_devices_seq_next,
-       .stop   = input_devices_seq_stop,
+       .stop   = input_seq_stop,
        .show   = input_devices_seq_show,
 };
 
@@ -881,40 +903,49 @@ static const struct file_operations input_devices_fileops = {
 
 static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       if (mutex_lock_interruptible(&input_mutex))
-               return NULL;
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
+       int error;
+
+       /* We need to fit into seq->private pointer */
+       BUILD_BUG_ON(sizeof(union input_seq_state) != sizeof(seq->private));
+
+       error = mutex_lock_interruptible(&input_mutex);
+       if (error) {
+               state->mutex_acquired = false;
+               return ERR_PTR(error);
+       }
+
+       state->mutex_acquired = true;
+       state->pos = *pos;
 
-       seq->private = (void *)(unsigned long)*pos;
        return seq_list_start(&input_handler_list, *pos);
 }
 
 static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       seq->private = (void *)(unsigned long)(*pos + 1);
-       return seq_list_next(v, &input_handler_list, pos);
-}
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
 
-static void input_handlers_seq_stop(struct seq_file *seq, void *v)
-{
-       mutex_unlock(&input_mutex);
+       state->pos = *pos + 1;
+       return seq_list_next(v, &input_handler_list, pos);
 }
 
 static int input_handlers_seq_show(struct seq_file *seq, void *v)
 {
        struct input_handler *handler = container_of(v, struct input_handler, node);
+       union input_seq_state *state = (union input_seq_state *)&seq->private;
 
-       seq_printf(seq, "N: Number=%ld Name=%s",
-                  (unsigned long)seq->private, handler->name);
+       seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
        if (handler->fops)
                seq_printf(seq, " Minor=%d", handler->minor);
        seq_putc(seq, '\n');
 
        return 0;
 }
+
 static const struct seq_operations input_handlers_seq_ops = {
        .start  = input_handlers_seq_start,
        .next   = input_handlers_seq_next,
-       .stop   = input_handlers_seq_stop,
+       .stop   = input_seq_stop,
        .show   = input_handlers_seq_show,
 };
 
index 4709e15..a651237 100644 (file)
@@ -574,11 +574,22 @@ static void atkbd_event_work(struct work_struct *work)
 
        mutex_lock(&atkbd->event_mutex);
 
-       if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
-               atkbd_set_leds(atkbd);
+       if (!atkbd->enabled) {
+               /*
+                * Serio ports are resumed asynchronously so while driver core
+                * thinks that device is already fully operational in reality
+                * it may not be ready yet. In this case we need to keep
+                * rescheduling till reconnect completes.
+                */
+               schedule_delayed_work(&atkbd->event_work,
+                                       msecs_to_jiffies(100));
+       } else {
+               if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
+                       atkbd_set_leds(atkbd);
 
-       if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
-               atkbd_set_repeat_rate(atkbd);
+               if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
+                       atkbd_set_repeat_rate(atkbd);
+       }
 
        mutex_unlock(&atkbd->event_mutex);
 }
@@ -770,6 +781,30 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
        return 3;
 }
 
+static int atkbd_reset_state(struct atkbd *atkbd)
+{
+        struct ps2dev *ps2dev = &atkbd->ps2dev;
+       unsigned char param[1];
+
+/*
+ * Set the LEDs to a predefined state (all off).
+ */
+
+       param[0] = 0;
+       if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
+               return -1;
+
+/*
+ * Set autorepeat to fastest possible.
+ */
+
+       param[0] = 0;
+       if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP))
+               return -1;
+
+       return 0;
+}
+
 static int atkbd_activate(struct atkbd *atkbd)
 {
        struct ps2dev *ps2dev = &atkbd->ps2dev;
@@ -851,29 +886,6 @@ static unsigned int atkbd_hp_forced_release_keys[] = {
        0x94, -1U
 };
 
-/*
- * Inventec system with broken key release on volume keys
- */
-static unsigned int atkbd_inventec_forced_release_keys[] = {
-       0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
- * for its volume buttons
- */
-static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
-       0xae, 0xb0, -1U
-};
-
-/*
- * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
- * release for their volume buttons
- */
-static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
-       0xae, 0xb0, -1U
-};
-
 /*
  * Samsung NC10,NC20 with Fn+F? key release not working
  */
@@ -881,14 +893,6 @@ static unsigned int atkbd_samsung_forced_release_keys[] = {
        0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
 };
 
-/*
- * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
- * do not generate release events so we have to do it ourselves.
- */
-static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
-       0xb0, 0xae, -1U
-};
-
 /*
  * Amilo Pi 3525 key release for Fn+Volume keys not working
  */
@@ -910,6 +914,14 @@ static unsigned int atkdb_soltech_ta12_forced_release_keys[] = {
        0xa0, 0xae, 0xb0, -1U
 };
 
+/*
+ * Many notebooks don't send key release event for volume up/down
+ * keys, with key list below common among them
+ */
+static unsigned int atkbd_volume_forced_release_keys[] = {
+       0xae, 0xb0, -1U
+};
+
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
@@ -1087,6 +1099,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
                }
 
                atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
+               atkbd_reset_state(atkbd);
                atkbd_activate(atkbd);
 
        } else {
@@ -1267,6 +1280,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
 
                atkbd->dev = new_dev;
                atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
+               atkbd_reset_state(atkbd);
                atkbd_activate(atkbd);
                atkbd_set_keycode_table(atkbd);
                atkbd_set_device_attrs(atkbd);
@@ -1548,7 +1562,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_zv6100_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4000",
@@ -1557,7 +1571,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4100",
@@ -1566,7 +1580,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "HP Presario R4200",
@@ -1575,7 +1589,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_hp_r4000_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Inventec Symphony",
@@ -1584,7 +1598,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_inventec_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Samsung NC10",
@@ -1620,7 +1634,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
                },
                .callback = atkbd_setup_forced_release,
-               .driver_data = atkbd_amilo_pa1510_forced_release_keys,
+               .driver_data = atkbd_volume_forced_release_keys,
        },
        {
                .ident = "Fujitsu Amilo Pi 3525",
index 216a559..ea821b5 100644 (file)
@@ -209,7 +209,7 @@ static inline int hp_sdc_rtc_read_rt(struct timeval *res) {
 
 /* Read the i8042 fast handshake timer */
 static inline int hp_sdc_rtc_read_fhs(struct timeval *res) {
-       uint64_t raw;
+       int64_t raw;
        unsigned int tenms;
 
        raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2);
index de745d7..ab5dc5f 100644 (file)
@@ -219,7 +219,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
                                PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
                                PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
                { 72,   PS2PP_KIND_TRACKMAN,    0 },                    /* T-CH11: TrackMan Marble */
-               { 73,   0,                      PS2PP_SIDE_BTN },
+               { 73,   PS2PP_KIND_TRACKMAN,    PS2PP_SIDE_BTN },       /* TrackMan FX */
                { 75,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 76,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 79,   PS2PP_KIND_TRACKMAN,    PS2PP_WHEEL },          /* TrackMan with wheel */
index b66ff1a..f4a6125 100644 (file)
@@ -652,6 +652,16 @@ static const struct dmi_system_id toshiba_dmi_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
                },
+
+       },
+       {
+               .ident = "Toshiba Portege M300",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
+               },
+
        },
        { }
 };
index a39bc4e..a537925 100644 (file)
@@ -326,6 +326,17 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
                },
        },
+       {
+               /*
+                * Reset and GET ID commands issued via KBD port are
+                * sometimes being delivered to AUX3.
+                */
+               .ident = "Sony Vaio FZ-240E",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
+               },
+       },
        {
                .ident = "Amoi M636/A737",
                .matches = {
@@ -661,7 +672,7 @@ static void i8042_pnp_exit(void)
 static int __init i8042_pnp_init(void)
 {
        char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
-       int pnp_data_busted = false;
+       bool pnp_data_busted = false;
        int err;
 
 #ifdef CONFIG_X86
index 74032d0..7511f08 100644 (file)
@@ -83,19 +83,19 @@ static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd)
 
        spin_lock_irqsave(&nd->queue_lock, flags);
        lp = nd->queue;         /* get lp on top of queue */
-       spin_lock(&nd->queue->xmit_lock);
        while (isdn_net_lp_busy(nd->queue)) {
-               spin_unlock(&nd->queue->xmit_lock);
                nd->queue = nd->queue->next;
                if (nd->queue == lp) { /* not found -- should never happen */
                        lp = NULL;
                        goto errout;
                }
-               spin_lock(&nd->queue->xmit_lock);
        }
        lp = nd->queue;
        nd->queue = nd->queue->next;
+       spin_unlock_irqrestore(&nd->queue_lock, flags);
+       spin_lock(&lp->xmit_lock);
        local_bh_disable();
+       return lp;
 errout:
        spin_unlock_irqrestore(&nd->queue_lock, flags);
        return lp;
index b40fb9b..6f308a4 100644 (file)
@@ -405,7 +405,11 @@ static int __init via_pmu_start(void)
                printk(KERN_ERR "via-pmu: can't map interrupt\n");
                return -ENODEV;
        }
-       if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) {
+       /* We set IRQF_TIMER because we don't want the interrupt to be disabled
+        * between the 2 passes of driver suspend, we control our own disabling
+        * for that one
+        */
+       if (request_irq(irq, via_pmu_interrupt, IRQF_TIMER, "VIA-PMU", (void *)0)) {
                printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
                return -ENODEV;
        }
@@ -419,7 +423,7 @@ static int __init via_pmu_start(void)
                        gpio_irq = irq_of_parse_and_map(gpio_node, 0);
 
                if (gpio_irq != NO_IRQ) {
-                       if (request_irq(gpio_irq, gpio1_interrupt, 0,
+                       if (request_irq(gpio_irq, gpio1_interrupt, IRQF_TIMER,
                                        "GPIO1 ADB", (void *)0))
                                printk(KERN_ERR "pmu: can't get irq %d"
                                       " (GPIO1)\n", gpio_irq);
@@ -925,8 +929,7 @@ proc_write_options(struct file *file, const char __user *buffer,
 
 #ifdef CONFIG_ADB
 /* Send an ADB command */
-static int
-pmu_send_request(struct adb_request *req, int sync)
+static int pmu_send_request(struct adb_request *req, int sync)
 {
        int i, ret;
 
@@ -1005,16 +1008,11 @@ pmu_send_request(struct adb_request *req, int sync)
 }
 
 /* Enable/disable autopolling */
-static int
-pmu_adb_autopoll(int devs)
+static int __pmu_adb_autopoll(int devs)
 {
        struct adb_request req;
 
-       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
-               return -ENXIO;
-
        if (devs) {
-               adb_dev_map = devs;
                pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
                            adb_dev_map >> 8, adb_dev_map);
                pmu_adb_flags = 2;
@@ -1027,9 +1025,17 @@ pmu_adb_autopoll(int devs)
        return 0;
 }
 
+static int pmu_adb_autopoll(int devs)
+{
+       if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
+               return -ENXIO;
+
+       adb_dev_map = devs;
+       return __pmu_adb_autopoll(devs);
+}
+
 /* Reset the ADB bus */
-static int
-pmu_adb_reset_bus(void)
+static int pmu_adb_reset_bus(void)
 {
        struct adb_request req;
        int save_autopoll = adb_dev_map;
@@ -1038,13 +1044,13 @@ pmu_adb_reset_bus(void)
                return -ENXIO;
 
        /* anyone got a better idea?? */
-       pmu_adb_autopoll(0);
+       __pmu_adb_autopoll(0);
 
-       req.nbytes = 5;
+       req.nbytes = 4;
        req.done = NULL;
        req.data[0] = PMU_ADB_CMD;
-       req.data[1] = 0;
-       req.data[2] = ADB_BUSRESET;
+       req.data[1] = ADB_BUSRESET;
+       req.data[2] = 0;
        req.data[3] = 0;
        req.data[4] = 0;
        req.reply_len = 0;
@@ -1056,7 +1062,7 @@ pmu_adb_reset_bus(void)
        pmu_wait_complete(&req);
 
        if (save_autopoll != 0)
-               pmu_adb_autopoll(save_autopoll);
+               __pmu_adb_autopoll(save_autopoll);
 
        return 0;
 }
index 1dc4185..e355e7f 100644 (file)
@@ -46,7 +46,7 @@ obj-$(CONFIG_DM_LOG_USERSPACE)        += dm-log-userspace.o
 obj-$(CONFIG_DM_ZERO)          += dm-zero.o
 
 quiet_cmd_unroll = UNROLL  $@
-      cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
+      cmd_unroll = $(AWK) -f$(srctree)/$(src)/unroll.awk -vN=$(UNROLL) \
                    < $< > $@ || ( rm -f $@ && exit 1 )
 
 ifeq ($(CONFIG_ALTIVEC),y)
@@ -59,56 +59,56 @@ endif
 
 targets += raid6int1.c
 $(obj)/raid6int1.c:   UNROLL := 1
-$(obj)/raid6int1.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int1.c:   $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 targets += raid6int2.c
 $(obj)/raid6int2.c:   UNROLL := 2
-$(obj)/raid6int2.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int2.c:   $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 targets += raid6int4.c
 $(obj)/raid6int4.c:   UNROLL := 4
-$(obj)/raid6int4.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int4.c:   $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 targets += raid6int8.c
 $(obj)/raid6int8.c:   UNROLL := 8
-$(obj)/raid6int8.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int8.c:   $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 targets += raid6int16.c
 $(obj)/raid6int16.c:  UNROLL := 16
-$(obj)/raid6int16.c:  $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int16.c:  $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 targets += raid6int32.c
 $(obj)/raid6int32.c:  UNROLL := 32
-$(obj)/raid6int32.c:  $(src)/raid6int.uc $(src)/unroll.pl FORCE
+$(obj)/raid6int32.c:  $(src)/raid6int.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 CFLAGS_raid6altivec1.o += $(altivec_flags)
 targets += raid6altivec1.c
 $(obj)/raid6altivec1.c:   UNROLL := 1
-$(obj)/raid6altivec1.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec1.c:   $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 CFLAGS_raid6altivec2.o += $(altivec_flags)
 targets += raid6altivec2.c
 $(obj)/raid6altivec2.c:   UNROLL := 2
-$(obj)/raid6altivec2.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec2.c:   $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 CFLAGS_raid6altivec4.o += $(altivec_flags)
 targets += raid6altivec4.c
 $(obj)/raid6altivec4.c:   UNROLL := 4
-$(obj)/raid6altivec4.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec4.c:   $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 CFLAGS_raid6altivec8.o += $(altivec_flags)
 targets += raid6altivec8.c
 $(obj)/raid6altivec8.c:   UNROLL := 8
-$(obj)/raid6altivec8.c:   $(src)/raid6altivec.uc $(src)/unroll.pl FORCE
+$(obj)/raid6altivec8.c:   $(src)/raid6altivec.uc $(src)/unroll.awk FORCE
        $(call if_changed,unroll)
 
 quiet_cmd_mktable = TABLE   $@
index 6986b00..60e2b32 100644 (file)
@@ -1624,10 +1624,11 @@ int bitmap_create(mddev_t *mddev)
        bitmap->offset = mddev->bitmap_offset;
        if (file) {
                get_file(file);
-               do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX,
-                                     SYNC_FILE_RANGE_WAIT_BEFORE |
-                                     SYNC_FILE_RANGE_WRITE |
-                                     SYNC_FILE_RANGE_WAIT_AFTER);
+               /* As future accesses to this file will use bmap,
+                * and bypass the page cache, we must sync the file
+                * first.
+                */
+               vfs_fsync(file, file->f_dentry, 1);
        }
        /* read superblock from bitmap file (this sets bitmap->chunksize) */
        err = bitmap_read_sb(bitmap);
index 556acff..7dbe652 100644 (file)
@@ -138,16 +138,6 @@ int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
 }
 EXPORT_SYMBOL(dm_exception_store_type_unregister);
 
-/*
- * Round a number up to the nearest 'size' boundary.  size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
-       size--;
-       return (n + size) & ~size;
-}
-
 static int set_chunk_size(struct dm_exception_store *store,
                          const char *chunk_size_arg, char **error)
 {
@@ -155,7 +145,8 @@ static int set_chunk_size(struct dm_exception_store *store,
        char *value;
 
        chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
-       if (*chunk_size_arg == '\0' || *value != '\0') {
+       if (*chunk_size_arg == '\0' || *value != '\0' ||
+           chunk_size_ulong > UINT_MAX) {
                *error = "Invalid chunk size";
                return -EINVAL;
        }
@@ -165,40 +156,35 @@ static int set_chunk_size(struct dm_exception_store *store,
                return 0;
        }
 
-       /*
-        * Chunk size must be multiple of page size.  Silently
-        * round up if it's not.
-        */
-       chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
-
-       return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
+       return dm_exception_store_set_chunk_size(store,
+                                                (unsigned) chunk_size_ulong,
                                                 error);
 }
 
 int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
-                                     unsigned long chunk_size_ulong,
+                                     unsigned chunk_size,
                                      char **error)
 {
        /* Check chunk_size is a power of 2 */
-       if (!is_power_of_2(chunk_size_ulong)) {
+       if (!is_power_of_2(chunk_size)) {
                *error = "Chunk size is not a power of 2";
                return -EINVAL;
        }
 
        /* Validate the chunk size against the device block size */
-       if (chunk_size_ulong % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
+       if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
                *error = "Chunk size is not a multiple of device blocksize";
                return -EINVAL;
        }
 
-       if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
+       if (chunk_size > INT_MAX >> SECTOR_SHIFT) {
                *error = "Chunk size is too high";
                return -EINVAL;
        }
 
-       store->chunk_size = chunk_size_ulong;
-       store->chunk_mask = chunk_size_ulong - 1;
-       store->chunk_shift = ffs(chunk_size_ulong) - 1;
+       store->chunk_size = chunk_size;
+       store->chunk_mask = chunk_size - 1;
+       store->chunk_shift = ffs(chunk_size) - 1;
 
        return 0;
 }
@@ -251,7 +237,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
 
        r = set_chunk_size(tmp_store, argv[2], &ti->error);
        if (r)
-               goto bad_cow;
+               goto bad_ctr;
 
        r = type->ctr(tmp_store, 0, NULL);
        if (r) {
index 812c718..8a223a4 100644 (file)
@@ -101,9 +101,9 @@ struct dm_exception_store {
        struct dm_dev *cow;
 
        /* Size of data blocks saved - must be a power of 2 */
-       chunk_t chunk_size;
-       chunk_t chunk_mask;
-       chunk_t chunk_shift;
+       unsigned chunk_size;
+       unsigned chunk_mask;
+       unsigned chunk_shift;
 
        void *context;
 };
@@ -169,7 +169,7 @@ int dm_exception_store_type_register(struct dm_exception_store_type *type);
 int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
 
 int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
-                                     unsigned long chunk_size_ulong,
+                                     unsigned chunk_size,
                                      char **error);
 
 int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
index 652bd33..7ac2c14 100644 (file)
@@ -156,7 +156,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
        }
 
        /* The ptr value is sufficient for local unique id */
-       lc->luid = (uint64_t)lc;
+       lc->luid = (unsigned long)lc;
 
        lc->ti = ti;
 
index d5b2e08..0c74642 100644 (file)
@@ -284,12 +284,13 @@ static int read_header(struct pstore *ps, int *new_snapshot)
 {
        int r;
        struct disk_header *dh;
-       chunk_t chunk_size;
+       unsigned chunk_size;
        int chunk_size_supplied = 1;
        char *chunk_err;
 
        /*
-        * Use default chunk size (or hardsect_size, if larger) if none supplied
+        * Use default chunk size (or logical_block_size, if larger)
+        * if none supplied
         */
        if (!ps->store->chunk_size) {
                ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
@@ -334,10 +335,9 @@ static int read_header(struct pstore *ps, int *new_snapshot)
                return 0;
 
        if (chunk_size_supplied)
-               DMWARN("chunk size %llu in device metadata overrides "
-                      "table chunk size of %llu.",
-                      (unsigned long long)chunk_size,
-                      (unsigned long long)ps->store->chunk_size);
+               DMWARN("chunk size %u in device metadata overrides "
+                      "table chunk size of %u.",
+                      chunk_size, ps->store->chunk_size);
 
        /* We had a bogus chunk_size. Fix stuff up. */
        free_area(ps);
@@ -345,8 +345,8 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
                                              &chunk_err);
        if (r) {
-               DMERR("invalid on-disk chunk size %llu: %s.",
-                     (unsigned long long)chunk_size, chunk_err);
+               DMERR("invalid on-disk chunk size %u: %s.",
+                     chunk_size, chunk_err);
                return r;
        }
 
index 57f1bf7..3a3ba46 100644 (file)
@@ -296,6 +296,7 @@ static void __insert_origin(struct origin *o)
  */
 static int register_snapshot(struct dm_snapshot *snap)
 {
+       struct dm_snapshot *l;
        struct origin *o, *new_o;
        struct block_device *bdev = snap->origin->bdev;
 
@@ -319,7 +320,11 @@ static int register_snapshot(struct dm_snapshot *snap)
                __insert_origin(o);
        }
 
-       list_add_tail(&snap->list, &o->snapshots);
+       /* Sort the list according to chunk size, largest-first smallest-last */
+       list_for_each_entry(l, &o->snapshots, list)
+               if (l->store->chunk_size < snap->store->chunk_size)
+                       break;
+       list_add_tail(&snap->list, &l->list);
 
        up_write(&_origins_lock);
        return 0;
@@ -668,6 +673,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        bio_list_init(&s->queued_bios);
        INIT_WORK(&s->queued_bios_work, flush_queued_bios);
 
+       if (!s->store->chunk_size) {
+               ti->error = "Chunk size not set";
+               goto bad_load_and_register;
+       }
+
        /* Add snapshot to the list of snapshots for this origin */
        /* Exceptions aren't triggered till snapshot_resume() is called */
        if (register_snapshot(s)) {
@@ -951,7 +961,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
 
        src.bdev = bdev;
        src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
-       src.count = min(s->store->chunk_size, dev_size - src.sector);
+       src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);
 
        dest.bdev = s->store->cow->bdev;
        dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
@@ -1142,6 +1152,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
        unsigned sz = 0;
        struct dm_snapshot *snap = ti->private;
 
+       down_write(&snap->lock);
+
        switch (type) {
        case STATUSTYPE_INFO:
                if (!snap->valid)
@@ -1173,6 +1185,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
                break;
        }
 
+       up_write(&snap->lock);
+
        return 0;
 }
 
@@ -1388,7 +1402,7 @@ static void origin_resume(struct dm_target *ti)
        struct dm_dev *dev = ti->private;
        struct dm_snapshot *snap;
        struct origin *o;
-       chunk_t chunk_size = 0;
+       unsigned chunk_size = 0;
 
        down_read(&_origins_lock);
        o = __lookup_origin(dev->bdev);
@@ -1465,7 +1479,7 @@ static int __init dm_snapshot_init(void)
        r = dm_register_target(&snapshot_target);
        if (r) {
                DMERR("snapshot target register failed %d", r);
-               return r;
+               goto bad_register_snapshot_target;
        }
 
        r = dm_register_target(&origin_target);
@@ -1522,6 +1536,9 @@ bad2:
        dm_unregister_target(&origin_target);
 bad1:
        dm_unregister_target(&snapshot_target);
+
+bad_register_snapshot_target:
+       dm_exception_store_exit();
        return r;
 }
 
index 23e76fe..724efc6 100644 (file)
@@ -47,6 +47,7 @@ struct dm_io {
        atomic_t io_count;
        struct bio *bio;
        unsigned long start_time;
+       spinlock_t endio_lock;
 };
 
 /*
@@ -130,7 +131,7 @@ struct mapped_device {
        /*
         * A list of ios that arrived while we were suspended.
         */
-       atomic_t pending;
+       atomic_t pending[2];
        wait_queue_head_t wait;
        struct work_struct work;
        struct bio_list deferred;
@@ -453,13 +454,14 @@ static void start_io_acct(struct dm_io *io)
 {
        struct mapped_device *md = io->md;
        int cpu;
+       int rw = bio_data_dir(io->bio);
 
        io->start_time = jiffies;
 
        cpu = part_stat_lock();
        part_round_stats(cpu, &dm_disk(md)->part0);
        part_stat_unlock();
-       dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
+       dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]);
 }
 
 static void end_io_acct(struct dm_io *io)
@@ -479,8 +481,9 @@ static void end_io_acct(struct dm_io *io)
         * After this is decremented the bio must not be touched if it is
         * a barrier.
         */
-       dm_disk(md)->part0.in_flight = pending =
-               atomic_dec_return(&md->pending);
+       dm_disk(md)->part0.in_flight[rw] = pending =
+               atomic_dec_return(&md->pending[rw]);
+       pending += atomic_read(&md->pending[rw^0x1]);
 
        /* nudge anyone waiting on suspend queue */
        if (!pending)
@@ -576,8 +579,12 @@ static void dec_pending(struct dm_io *io, int error)
        struct mapped_device *md = io->md;
 
        /* Push-back supersedes any I/O errors */
-       if (error && !(io->error > 0 && __noflush_suspending(md)))
-               io->error = error;
+       if (unlikely(error)) {
+               spin_lock_irqsave(&io->endio_lock, flags);
+               if (!(io->error > 0 && __noflush_suspending(md)))
+                       io->error = error;
+               spin_unlock_irqrestore(&io->endio_lock, flags);
+       }
 
        if (atomic_dec_and_test(&io->io_count)) {
                if (io->error == DM_ENDIO_REQUEUE) {
@@ -1224,6 +1231,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
        atomic_set(&ci.io->io_count, 1);
        ci.io->bio = bio;
        ci.io->md = md;
+       spin_lock_init(&ci.io->endio_lock);
        ci.sector = bio->bi_sector;
        ci.sector_count = bio_sectors(bio);
        if (unlikely(bio_empty_barrier(bio)))
@@ -1785,7 +1793,8 @@ static struct mapped_device *alloc_dev(int minor)
        if (!md->disk)
                goto bad_disk;
 
-       atomic_set(&md->pending, 0);
+       atomic_set(&md->pending[0], 0);
+       atomic_set(&md->pending[1], 0);
        init_waitqueue_head(&md->wait);
        INIT_WORK(&md->work, dm_wq_work);
        init_waitqueue_head(&md->eventq);
@@ -1819,6 +1828,7 @@ static struct mapped_device *alloc_dev(int minor)
 bad_bdev:
        destroy_workqueue(md->wq);
 bad_thread:
+       del_gendisk(md->disk);
        put_disk(md->disk);
 bad_disk:
        blk_cleanup_queue(md->queue);
@@ -2088,7 +2098,8 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
                                break;
                        }
                        spin_unlock_irqrestore(q->queue_lock, flags);
-               } else if (!atomic_read(&md->pending))
+               } else if (!atomic_read(&md->pending[0]) &&
+                                       !atomic_read(&md->pending[1]))
                        break;
 
                if (interruptible == TASK_INTERRUPTIBLE &&
index 26ba42a..10eb1fc 100644 (file)
@@ -2631,7 +2631,7 @@ static void analyze_sbs(mddev_t * mddev)
                        rdev->desc_nr = i++;
                        rdev->raid_disk = rdev->desc_nr;
                        set_bit(In_sync, &rdev->flags);
-               } else if (rdev->raid_disk >= mddev->raid_disks) {
+               } else if (rdev->raid_disk >= (mddev->raid_disks - min(0, mddev->delta_disks))) {
                        rdev->raid_disk = -1;
                        clear_bit(In_sync, &rdev->flags);
                }
index d1b9bd5..a053423 100644 (file)
@@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
 
        /* allocate a r1bio with room for raid_disks entries in the bios array */
        r1_bio = kzalloc(size, gfp_flags);
-       if (!r1_bio)
+       if (!r1_bio && pi->mddev)
                unplug_slaves(pi->mddev);
 
        return r1_bio;
@@ -1683,6 +1683,7 @@ static void raid1d(mddev_t *mddev)
                                generic_make_request(bio);
                        }
                }
+               cond_resched();
        }
        if (unplug)
                unplug_slaves(mddev);
@@ -1978,13 +1979,14 @@ static int run(mddev_t *mddev)
        conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
        if (!conf->poolinfo)
                goto out_no_mem;
-       conf->poolinfo->mddev = mddev;
+       conf->poolinfo->mddev = NULL;
        conf->poolinfo->raid_disks = mddev->raid_disks;
        conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
                                          r1bio_pool_free,
                                          conf->poolinfo);
        if (!conf->r1bio_pool)
                goto out_no_mem;
+       conf->poolinfo->mddev = mddev;
 
        spin_lock_init(&conf->device_lock);
        mddev->queue->queue_lock = &conf->device_lock;
index 51c4c5c..c2cb7b8 100644 (file)
@@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
 
        /* allocate a r10bio with room for raid_disks entries in the bios array */
        r10_bio = kzalloc(size, gfp_flags);
-       if (!r10_bio)
+       if (!r10_bio && conf->mddev)
                unplug_slaves(conf->mddev);
 
        return r10_bio;
@@ -1632,6 +1632,7 @@ static void raid10d(mddev_t *mddev)
                                generic_make_request(bio);
                        }
                }
+               cond_resched();
        }
        if (unplug)
                unplug_slaves(mddev);
@@ -2095,7 +2096,6 @@ static int run(mddev_t *mddev)
        if (!conf->tmppage)
                goto out_free_conf;
 
-       conf->mddev = mddev;
        conf->raid_disks = mddev->raid_disks;
        conf->near_copies = nc;
        conf->far_copies = fc;
@@ -2132,6 +2132,7 @@ static int run(mddev_t *mddev)
                goto out_free_conf;
        }
 
+       conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        mddev->queue->queue_lock = &conf->device_lock;
 
index 9482980..81abefc 100644 (file)
@@ -156,13 +156,16 @@ static inline int raid6_next_disk(int disk, int raid_disks)
 static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
                             int *count, int syndrome_disks)
 {
-       int slot;
+       int slot = *count;
 
+       if (sh->ddf_layout)
+               (*count)++;
        if (idx == sh->pd_idx)
                return syndrome_disks;
        if (idx == sh->qd_idx)
                return syndrome_disks + 1;
-       slot = (*count)++;
+       if (!sh->ddf_layout)
+               (*count)++;
        return slot;
 }
 
@@ -717,7 +720,7 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh)
        int i;
 
        for (i = 0; i < disks; i++)
-               srcs[i] = (void *)raid6_empty_zero_page;
+               srcs[i] = NULL;
 
        count = 0;
        i = d0_idx;
@@ -727,9 +730,8 @@ static int set_syndrome_sources(struct page **srcs, struct stripe_head *sh)
                srcs[slot] = sh->dev[i].page;
                i = raid6_next_disk(i, disks);
        } while (i != d0_idx);
-       BUG_ON(count != syndrome_disks);
 
-       return count;
+       return syndrome_disks;
 }
 
 static struct dma_async_tx_descriptor *
@@ -814,7 +816,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
         * slot number conversion for 'faila' and 'failb'
         */
        for (i = 0; i < disks ; i++)
-               blocks[i] = (void *)raid6_empty_zero_page;
+               blocks[i] = NULL;
        count = 0;
        i = d0_idx;
        do {
@@ -828,7 +830,6 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
                        failb = slot;
                i = raid6_next_disk(i, disks);
        } while (i != d0_idx);
-       BUG_ON(count != syndrome_disks);
 
        BUG_ON(faila == failb);
        if (failb < faila)
@@ -845,7 +846,7 @@ ops_run_compute6_2(struct stripe_head *sh, struct raid5_percpu *percpu)
                        init_async_submit(&submit, ASYNC_TX_FENCE, NULL,
                                          ops_complete_compute, sh,
                                          to_addr_conv(sh, percpu));
-                       return async_gen_syndrome(blocks, 0, count+2,
+                       return async_gen_syndrome(blocks, 0, syndrome_disks+2,
                                                  STRIPE_SIZE, &submit);
                } else {
                        struct page *dest;
@@ -1139,7 +1140,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu
                           &sh->ops.zero_sum_result, percpu->spare_page, &submit);
 }
 
-static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
 {
        int overlap_clear = 0, i, disks = sh->disks;
        struct dma_async_tx_descriptor *tx = NULL;
@@ -1204,22 +1205,55 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
        put_cpu();
 }
 
+#ifdef CONFIG_MULTICORE_RAID456
+static void async_run_ops(void *param, async_cookie_t cookie)
+{
+       struct stripe_head *sh = param;
+       unsigned long ops_request = sh->ops.request;
+
+       clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state);
+       wake_up(&sh->ops.wait_for_ops);
+
+       __raid_run_ops(sh, ops_request);
+       release_stripe(sh);
+}
+
+static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+{
+       /* since handle_stripe can be called outside of raid5d context
+        * we need to ensure sh->ops.request is de-staged before another
+        * request arrives
+        */
+       wait_event(sh->ops.wait_for_ops,
+                  !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state));
+       sh->ops.request = ops_request;
+
+       atomic_inc(&sh->count);
+       async_schedule(async_run_ops, sh);
+}
+#else
+#define raid_run_ops __raid_run_ops
+#endif
+
 static int grow_one_stripe(raid5_conf_t *conf)
 {
        struct stripe_head *sh;
+       int disks = max(conf->raid_disks, conf->previous_raid_disks);
        sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
        if (!sh)
                return 0;
-       memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
+       memset(sh, 0, sizeof(*sh) + (disks-1)*sizeof(struct r5dev));
        sh->raid_conf = conf;
        spin_lock_init(&sh->lock);
+       #ifdef CONFIG_MULTICORE_RAID456
+       init_waitqueue_head(&sh->ops.wait_for_ops);
+       #endif
 
-       if (grow_buffers(sh, conf->raid_disks)) {
-               shrink_buffers(sh, conf->raid_disks);
+       if (grow_buffers(sh, disks)) {
+               shrink_buffers(sh, disks);
                kmem_cache_free(conf->slab_cache, sh);
                return 0;
        }
-       sh->disks = conf->raid_disks;
        /* we just created an active stripe so... */
        atomic_set(&sh->count, 1);
        atomic_inc(&conf->active_stripes);
@@ -1231,7 +1265,7 @@ static int grow_one_stripe(raid5_conf_t *conf)
 static int grow_stripes(raid5_conf_t *conf, int num)
 {
        struct kmem_cache *sc;
-       int devs = conf->raid_disks;
+       int devs = max(conf->raid_disks, conf->previous_raid_disks);
 
        sprintf(conf->cache_name[0],
                "raid%d-%s", conf->level, mdname(conf->mddev));
@@ -1329,6 +1363,9 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
 
                nsh->raid_conf = conf;
                spin_lock_init(&nsh->lock);
+               #ifdef CONFIG_MULTICORE_RAID456
+               init_waitqueue_head(&nsh->ops.wait_for_ops);
+               #endif
 
                list_add(&nsh->lru, &newstripes);
        }
@@ -1899,10 +1936,15 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
                case ALGORITHM_PARITY_N:
                        break;
                case ALGORITHM_ROTATING_N_CONTINUE:
+                       /* Like left_symmetric, but P is before Q */
                        if (sh->pd_idx == 0)
                                i--;    /* P D D D Q */
-                       else if (i > sh->pd_idx)
-                               i -= 2; /* D D Q P D */
+                       else {
+                               /* D D Q P D */
+                               if (i < sh->pd_idx)
+                                       i += raid_disks;
+                               i -= (sh->pd_idx + 1);
+                       }
                        break;
                case ALGORITHM_LEFT_ASYMMETRIC_6:
                case ALGORITHM_RIGHT_ASYMMETRIC_6:
@@ -2896,7 +2938,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
  *
  */
 
-static bool handle_stripe5(struct stripe_head *sh)
+static void handle_stripe5(struct stripe_head *sh)
 {
        raid5_conf_t *conf = sh->raid_conf;
        int disks = sh->disks, i;
@@ -3167,11 +3209,9 @@ static bool handle_stripe5(struct stripe_head *sh)
        ops_run_io(sh, &s);
 
        return_io(return_bi);
-
-       return blocked_rdev == NULL;
 }
 
-static bool handle_stripe6(struct stripe_head *sh)
+static void handle_stripe6(struct stripe_head *sh)
 {
        raid5_conf_t *conf = sh->raid_conf;
        int disks = sh->disks;
@@ -3455,17 +3495,14 @@ static bool handle_stripe6(struct stripe_head *sh)
        ops_run_io(sh, &s);
 
        return_io(return_bi);
-
-       return blocked_rdev == NULL;
 }
 
-/* returns true if the stripe was handled */
-static bool handle_stripe(struct stripe_head *sh)
+static void handle_stripe(struct stripe_head *sh)
 {
        if (sh->raid_conf->level == 6)
-               return handle_stripe6(sh);
+               handle_stripe6(sh);
        else
-               return handle_stripe5(sh);
+               handle_stripe5(sh);
 }
 
 static void raid5_activate_delayed(raid5_conf_t *conf)
@@ -3503,9 +3540,10 @@ static void unplug_slaves(mddev_t *mddev)
 {
        raid5_conf_t *conf = mddev->private;
        int i;
+       int devs = max(conf->raid_disks, conf->previous_raid_disks);
 
        rcu_read_lock();
-       for (i = 0; i < conf->raid_disks; i++) {
+       for (i = 0; i < devs; i++) {
                mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
                if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
                        struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
@@ -4277,9 +4315,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
        clear_bit(STRIPE_INSYNC, &sh->state);
        spin_unlock(&sh->lock);
 
-       /* wait for any blocked device to be handled */
-       while (unlikely(!handle_stripe(sh)))
-               ;
+       handle_stripe(sh);
        release_stripe(sh);
 
        return STRIPE_SECTORS;
@@ -4349,37 +4385,6 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
        return handled;
 }
 
-#ifdef CONFIG_MULTICORE_RAID456
-static void __process_stripe(void *param, async_cookie_t cookie)
-{
-       struct stripe_head *sh = param;
-
-       handle_stripe(sh);
-       release_stripe(sh);
-}
-
-static void process_stripe(struct stripe_head *sh, struct list_head *domain)
-{
-       async_schedule_domain(__process_stripe, sh, domain);
-}
-
-static void synchronize_stripe_processing(struct list_head *domain)
-{
-       async_synchronize_full_domain(domain);
-}
-#else
-static void process_stripe(struct stripe_head *sh, struct list_head *domain)
-{
-       handle_stripe(sh);
-       release_stripe(sh);
-       cond_resched();
-}
-
-static void synchronize_stripe_processing(struct list_head *domain)
-{
-}
-#endif
-
 
 /*
  * This is our raid5 kernel thread.
@@ -4393,7 +4398,6 @@ static void raid5d(mddev_t *mddev)
        struct stripe_head *sh;
        raid5_conf_t *conf = mddev->private;
        int handled;
-       LIST_HEAD(raid_domain);
 
        pr_debug("+++ raid5d active\n");
 
@@ -4430,7 +4434,9 @@ static void raid5d(mddev_t *mddev)
                spin_unlock_irq(&conf->device_lock);
                
                handled++;
-               process_stripe(sh, &raid_domain);
+               handle_stripe(sh);
+               release_stripe(sh);
+               cond_resched();
 
                spin_lock_irq(&conf->device_lock);
        }
@@ -4438,7 +4444,6 @@ static void raid5d(mddev_t *mddev)
 
        spin_unlock_irq(&conf->device_lock);
 
-       synchronize_stripe_processing(&raid_domain);
        async_tx_issue_pending_all();
        unplug_slaves(mddev);
 
@@ -4558,13 +4563,9 @@ raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
 
        if (!sectors)
                sectors = mddev->dev_sectors;
-       if (!raid_disks) {
+       if (!raid_disks)
                /* size is defined by the smallest of previous and new size */
-               if (conf->raid_disks < conf->previous_raid_disks)
-                       raid_disks = conf->raid_disks;
-               else
-                       raid_disks = conf->previous_raid_disks;
-       }
+               raid_disks = min(conf->raid_disks, conf->previous_raid_disks);
 
        sectors &= ~((sector_t)mddev->chunk_sectors - 1);
        sectors &= ~((sector_t)mddev->new_chunk_sectors - 1);
@@ -4665,7 +4666,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf)
                        }
                        per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page;
                }
-               scribble = kmalloc(scribble_len(conf->raid_disks), GFP_KERNEL);
+               scribble = kmalloc(conf->scribble_len, GFP_KERNEL);
                if (!scribble) {
                        err = -ENOMEM;
                        break;
@@ -4686,7 +4687,7 @@ static int raid5_alloc_percpu(raid5_conf_t *conf)
 static raid5_conf_t *setup_conf(mddev_t *mddev)
 {
        raid5_conf_t *conf;
-       int raid_disk, memory;
+       int raid_disk, memory, max_disks;
        mdk_rdev_t *rdev;
        struct disk_info *disk;
 
@@ -4722,15 +4723,28 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
        conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
        if (conf == NULL)
                goto abort;
+       spin_lock_init(&conf->device_lock);
+       init_waitqueue_head(&conf->wait_for_stripe);
+       init_waitqueue_head(&conf->wait_for_overlap);
+       INIT_LIST_HEAD(&conf->handle_list);
+       INIT_LIST_HEAD(&conf->hold_list);
+       INIT_LIST_HEAD(&conf->delayed_list);
+       INIT_LIST_HEAD(&conf->bitmap_list);
+       INIT_LIST_HEAD(&conf->inactive_list);
+       atomic_set(&conf->active_stripes, 0);
+       atomic_set(&conf->preread_active_stripes, 0);
+       atomic_set(&conf->active_aligned_reads, 0);
+       conf->bypass_threshold = BYPASS_THRESHOLD;
 
        conf->raid_disks = mddev->raid_disks;
-       conf->scribble_len = scribble_len(conf->raid_disks);
        if (mddev->reshape_position == MaxSector)
                conf->previous_raid_disks = mddev->raid_disks;
        else
                conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
+       max_disks = max(conf->raid_disks, conf->previous_raid_disks);
+       conf->scribble_len = scribble_len(max_disks);
 
-       conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
+       conf->disks = kzalloc(max_disks * sizeof(struct disk_info),
                              GFP_KERNEL);
        if (!conf->disks)
                goto abort;
@@ -4744,24 +4758,11 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
        if (raid5_alloc_percpu(conf) != 0)
                goto abort;
 
-       spin_lock_init(&conf->device_lock);
-       init_waitqueue_head(&conf->wait_for_stripe);
-       init_waitqueue_head(&conf->wait_for_overlap);
-       INIT_LIST_HEAD(&conf->handle_list);
-       INIT_LIST_HEAD(&conf->hold_list);
-       INIT_LIST_HEAD(&conf->delayed_list);
-       INIT_LIST_HEAD(&conf->bitmap_list);
-       INIT_LIST_HEAD(&conf->inactive_list);
-       atomic_set(&conf->active_stripes, 0);
-       atomic_set(&conf->preread_active_stripes, 0);
-       atomic_set(&conf->active_aligned_reads, 0);
-       conf->bypass_threshold = BYPASS_THRESHOLD;
-
        pr_debug("raid5: run(%s) called.\n", mdname(mddev));
 
        list_for_each_entry(rdev, &mddev->disks, same_set) {
                raid_disk = rdev->raid_disk;
-               if (raid_disk >= conf->raid_disks
+               if (raid_disk >= max_disks
                    || raid_disk < 0)
                        continue;
                disk = conf->disks + raid_disk;
@@ -4793,7 +4794,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
        }
 
        memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
-                conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+                max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
        if (grow_stripes(conf, conf->max_nr_stripes)) {
                printk(KERN_ERR
                        "raid5: couldn't allocate %dkB for buffers\n", memory);
@@ -4918,7 +4919,8 @@ static int run(mddev_t *mddev)
                    test_bit(In_sync, &rdev->flags))
                        working_disks++;
 
-       mddev->degraded = conf->raid_disks - working_disks;
+       mddev->degraded = (max(conf->raid_disks, conf->previous_raid_disks)
+                          - working_disks);
 
        if (mddev->degraded > conf->max_degraded) {
                printk(KERN_ERR "raid5: not enough operational devices for %s"
index 2390e0e..dd70835 100644 (file)
@@ -214,12 +214,20 @@ struct stripe_head {
        int                     disks;          /* disks in stripe */
        enum check_states       check_state;
        enum reconstruct_states reconstruct_state;
-       /* stripe_operations
+       /**
+        * struct stripe_operations
         * @target - STRIPE_OP_COMPUTE_BLK target
+        * @target2 - 2nd compute target in the raid6 case
+        * @zero_sum_result - P and Q verification flags
+        * @request - async service request flags for raid_run_ops
         */
        struct stripe_operations {
                int                  target, target2;
                enum sum_check_flags zero_sum_result;
+               #ifdef CONFIG_MULTICORE_RAID456
+               unsigned long        request;
+               wait_queue_head_t    wait_for_ops;
+               #endif
        } ops;
        struct r5dev {
                struct bio      req;
@@ -294,6 +302,8 @@ struct r6_state {
 #define        STRIPE_FULL_WRITE       13 /* all blocks are set to be overwritten */
 #define        STRIPE_BIOFILL_RUN      14
 #define        STRIPE_COMPUTE_RUN      15
+#define        STRIPE_OPS_REQ_PENDING  16
+
 /*
  * Operation request flags
  */
@@ -478,7 +488,7 @@ static inline int algorithm_valid_raid6(int layout)
 {
        return (layout >= 0 && layout <= 5)
                ||
-               (layout == 8 || layout == 10)
+               (layout >= 8 && layout <= 10)
                ||
                (layout >= 16 && layout <= 20);
 }
index 699dfee..2654d5c 100644 (file)
@@ -15,7 +15,7 @@
  *
  * $#-way unrolled portable integer math RAID-6 instruction set
  *
- * This file is postprocessed using unroll.pl
+ * This file is postprocessed using unroll.awk
  *
  * <benh> hpa: in process,
  * you can just "steal" the vec unit with enable_kernel_altivec() (but
index f9bf9cb..d1e276a 100644 (file)
@@ -15,7 +15,7 @@
  *
  * $#-way unrolled portable integer math RAID-6 instruction set
  *
- * This file is postprocessed using unroll.pl
+ * This file is postprocessed using unroll.awk
  */
 
 #include <linux/raid/pq.h>
index 58ffdf4..2874cbe 100644 (file)
@@ -7,7 +7,7 @@ CC       = gcc
 OPTFLAGS = -O2                 # Adjust as desired
 CFLAGS  = -I.. -I ../../../include -g $(OPTFLAGS)
 LD      = ld
-PERL    = perl
+AWK     = awk
 AR      = ar
 RANLIB  = ranlib
 
@@ -35,35 +35,35 @@ raid6.a: raid6int1.o raid6int2.o raid6int4.o raid6int8.o raid6int16.o \
 raid6test: test.c raid6.a
        $(CC) $(CFLAGS) -o raid6test $^
 
-raid6altivec1.c: raid6altivec.uc ../unroll.pl
-       $(PERL) ../unroll.pl 1 < raid6altivec.uc > $@
+raid6altivec1.c: raid6altivec.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=1 < raid6altivec.uc > $@
 
-raid6altivec2.c: raid6altivec.uc ../unroll.pl
-       $(PERL) ../unroll.pl 2 < raid6altivec.uc > $@
+raid6altivec2.c: raid6altivec.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=2 < raid6altivec.uc > $@
 
-raid6altivec4.c: raid6altivec.uc ../unroll.pl
-       $(PERL) ../unroll.pl 4 < raid6altivec.uc > $@
+raid6altivec4.c: raid6altivec.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=4 < raid6altivec.uc > $@
 
-raid6altivec8.c: raid6altivec.uc ../unroll.pl
-       $(PERL) ../unroll.pl 8 < raid6altivec.uc > $@
+raid6altivec8.c: raid6altivec.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=8 < raid6altivec.uc > $@
 
-raid6int1.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 1 < raid6int.uc > $@
+raid6int1.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=1 < raid6int.uc > $@
 
-raid6int2.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 2 < raid6int.uc > $@
+raid6int2.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=2 < raid6int.uc > $@
 
-raid6int4.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 4 < raid6int.uc > $@
+raid6int4.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=4 < raid6int.uc > $@
 
-raid6int8.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 8 < raid6int.uc > $@
+raid6int8.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=8 < raid6int.uc > $@
 
-raid6int16.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 16 < raid6int.uc > $@
+raid6int16.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=16 < raid6int.uc > $@
 
-raid6int32.c: raid6int.uc ../unroll.pl
-       $(PERL) ../unroll.pl 32 < raid6int.uc > $@
+raid6int32.c: raid6int.uc ../unroll.awk
+       $(AWK) ../unroll.awk -vN=32 < raid6int.uc > $@
 
 raid6tables.c: mktables
        ./mktables > raid6tables.c
diff --git a/drivers/md/unroll.awk b/drivers/md/unroll.awk
new file mode 100644 (file)
index 0000000..c6aa036
--- /dev/null
@@ -0,0 +1,20 @@
+
+# This filter requires one command line option of form -vN=n
+# where n must be a decimal number.
+#
+# Repeat each input line containing $$ n times, replacing $$ with 0...n-1.
+# Replace each $# with n, and each $* with a single $.
+
+BEGIN {
+       n = N + 0
+}
+{
+       if (/\$\$/) { rep = n } else { rep = 1 }
+       for (i = 0; i < rep; ++i) {
+               tmp = $0
+               gsub(/\$\$/, i, tmp)
+               gsub(/\$\#/, n, tmp)
+               gsub(/\$\*/, "$", tmp)
+               print tmp
+       }
+}
diff --git a/drivers/md/unroll.pl b/drivers/md/unroll.pl
deleted file mode 100644 (file)
index 3acc710..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/perl
-#
-# Take a piece of C code and for each line which contains the sequence $$
-# repeat n times with $ replaced by 0...n-1; the sequence $# is replaced
-# by the unrolling factor, and $* with a single $
-#
-
-($n) = @ARGV;
-$n += 0;
-
-while ( defined($line = <STDIN>) ) {
-    if ( $line =~ /\$\$/ ) {
-       $rep = $n;
-    } else {
-       $rep = 1;
-    }
-    for ( $i = 0 ; $i < $rep ; $i++ ) {
-       $tmp = $line;
-       $tmp =~ s/\$\$/$i/g;
-       $tmp =~ s/\$\#/$n/g;
-       $tmp =~ s/\$\*/\$/g;
-       print $tmp;
-    }
-}
index e424cf6..a1c47ee 100644 (file)
@@ -480,7 +480,6 @@ static int
 add_children(struct twl4030_platform_data *pdata, unsigned long features)
 {
        struct device   *child;
-       struct device   *usb_transceiver = NULL;
 
        if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) {
                child = add_child(3, "twl4030_bci",
@@ -532,16 +531,61 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
        }
 
        if (twl_has_usb() && pdata->usb) {
+
+               static struct regulator_consumer_supply usb1v5 = {
+                       .supply =       "usb1v5",
+               };
+               static struct regulator_consumer_supply usb1v8 = {
+                       .supply =       "usb1v8",
+               };
+               static struct regulator_consumer_supply usb3v1 = {
+                       .supply =       "usb3v1",
+               };
+
+       /* First add the regulators so that they can be used by transceiver */
+               if (twl_has_regulator()) {
+                       /* this is a template that gets copied */
+                       struct regulator_init_data usb_fixed = {
+                               .constraints.valid_modes_mask =
+                                       REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+                               .constraints.valid_ops_mask =
+                                       REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+                       };
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB1V5,
+                                                     &usb_fixed, &usb1v5, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB1V8,
+                                                     &usb_fixed, &usb1v8, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB3V1,
+                                                     &usb_fixed, &usb3v1, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+               }
+
                child = add_child(0, "twl4030_usb",
                                pdata->usb, sizeof(*pdata->usb),
                                true,
                                /* irq0 = USB_PRES, irq1 = USB */
                                pdata->irq_base + 8 + 2, pdata->irq_base + 4);
+
                if (IS_ERR(child))
                        return PTR_ERR(child);
 
                /* we need to connect regulators to this transceiver */
-               usb_transceiver = child;
+               if (twl_has_regulator() && child) {
+                       usb1v5.dev = child;
+                       usb1v8.dev = child;
+                       usb3v1.dev = child;
+               }
        }
 
        if (twl_has_watchdog()) {
@@ -580,47 +624,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
                        return PTR_ERR(child);
        }
 
-       if (twl_has_regulator() && usb_transceiver) {
-               static struct regulator_consumer_supply usb1v5 = {
-                       .supply =       "usb1v5",
-               };
-               static struct regulator_consumer_supply usb1v8 = {
-                       .supply =       "usb1v8",
-               };
-               static struct regulator_consumer_supply usb3v1 = {
-                       .supply =       "usb3v1",
-               };
-
-               /* this is a template that gets copied */
-               struct regulator_init_data usb_fixed = {
-                       .constraints.valid_modes_mask =
-                                 REGULATOR_MODE_NORMAL
-                               | REGULATOR_MODE_STANDBY,
-                       .constraints.valid_ops_mask =
-                                 REGULATOR_CHANGE_MODE
-                               | REGULATOR_CHANGE_STATUS,
-               };
-
-               usb1v5.dev = usb_transceiver;
-               usb1v8.dev = usb_transceiver;
-               usb3v1.dev = usb_transceiver;
-
-               child = add_regulator_linked(TWL4030_REG_VUSB1V5, &usb_fixed,
-                               &usb1v5, 1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator_linked(TWL4030_REG_VUSB1V8, &usb_fixed,
-                               &usb1v8, 1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator_linked(TWL4030_REG_VUSB3V1, &usb_fixed,
-                               &usb3v1, 1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
        /* maybe add LDOs that are omitted on cost-reduced parts */
        if (twl_has_regulator() && !(features & TPS_SUBSET)) {
                child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
@@ -792,7 +795,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
                        twl->client = i2c_new_dummy(client->adapter,
                                        twl->address);
                        if (!twl->client) {
-                               dev_err(&twl->client->dev,
+                               dev_err(&client->dev,
                                        "can't attach client %d\n", i);
                                status = -ENOMEM;
                                goto fail;
index d3015df..ac056ea 100644 (file)
@@ -507,6 +507,8 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
 {
        int i, ret;
 
+       mutex_init(&wm831x->irq_lock);
+
        if (!irq) {
                dev_warn(wm831x->dev,
                         "No interrupt specified - functionality limited\n");
@@ -521,7 +523,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
        }
 
        wm831x->irq = irq;
-       mutex_init(&wm831x->irq_lock);
        INIT_WORK(&wm831x->irq_work, wm831x_irq_worker);
 
        /* Mask the individual interrupt sources */
index e556d42..63924e0 100644 (file)
@@ -72,7 +72,6 @@
 #include <asm/irq.h>
 #include <asm/gpio.h>
 
-#include <asm/mach/mmc.h>
 #include <mach/board.h>
 #include <mach/cpu.h>
 #include <mach/at91_mci.h>
index 4487cc0..0aecaae 100644 (file)
@@ -2013,7 +2013,7 @@ static struct platform_driver omap_hsmmc_driver = {
 static int __init omap_hsmmc_init(void)
 {
        /* Register the MMC driver */
-       return platform_driver_register(&omap_hsmmc_driver);
+       return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
 }
 
 static void __exit omap_hsmmc_cleanup(void)
index 5e0b152..b00d673 100644 (file)
@@ -693,7 +693,7 @@ static int pxamci_probe(struct platform_device *pdev)
        if (gpio_is_valid(gpio_ro)) {
                ret = gpio_request(gpio_ro, "mmc card read only");
                if (ret) {
-                       dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_power);
+                       dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
                        goto err_gpio_ro;
                }
                gpio_direction_input(gpio_ro);
@@ -701,7 +701,7 @@ static int pxamci_probe(struct platform_device *pdev)
        if (gpio_is_valid(gpio_cd)) {
                ret = gpio_request(gpio_cd, "mmc card detect");
                if (ret) {
-                       dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_power);
+                       dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd);
                        goto err_gpio_cd;
                }
                gpio_direction_input(gpio_cd);
index e1f7d0a..14cec04 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/log2.h>
 #include <linux/kthread.h>
 #include <linux/reboot.h>
+#include <linux/kernel.h>
 #include "ubi.h"
 
 /* Maximum length of the 'mtd=' parameter */
@@ -1257,7 +1258,7 @@ static int __init bytes_str_to_int(const char *str)
        unsigned long result;
 
        result = simple_strtoul(str, &endp, 0);
-       if (str == endp || result < 0) {
+       if (str == endp || result >= INT_MAX) {
                printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
                       str);
                return -EINVAL;
index e7161ad..90af61a 100644 (file)
@@ -794,16 +794,15 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
                 * number.
                 */
                image_seq = be32_to_cpu(ech->image_seq);
-               if (!si->image_seq_set) {
+               if (!ubi->image_seq && image_seq)
                        ubi->image_seq = image_seq;
-                       si->image_seq_set = 1;
-               } else if (ubi->image_seq && ubi->image_seq != image_seq) {
+               if (ubi->image_seq && image_seq &&
+                   ubi->image_seq != image_seq) {
                        ubi_err("bad image sequence number %d in PEB %d, "
                                "expected %d", image_seq, pnum, ubi->image_seq);
                        ubi_dbg_dump_ec_hdr(ech);
                        return -EINVAL;
                }
-
        }
 
        /* OK, we've done with the EC header, let's look at the VID header */
index bab3169..ff179ad 100644 (file)
@@ -103,7 +103,6 @@ struct ubi_scan_volume {
  * @ec_sum: a temporary variable used when calculating @mean_ec
  * @ec_count: a temporary variable used when calculating @mean_ec
  * @corr_count: count of corrupted PEBs
- * @image_seq_set: indicates @ubi->image_seq is known
  *
  * This data structure contains the result of scanning and may be used by other
  * UBI sub-systems to build final UBI data structures, further error-recovery
@@ -127,7 +126,6 @@ struct ubi_scan_info {
        uint64_t ec_sum;
        int ec_count;
        int corr_count;
-       int image_seq_set;
 };
 
 struct ubi_device;
index 7127760..e19ca4b 100644 (file)
@@ -1741,6 +1741,7 @@ config KS8851
 config KS8851_MLL
        tristate "Micrel KS8851 MLL"
        depends on HAS_IOMEM
+       select MII
        help
          This platform driver is for Micrel KS8851 Address/data bus
          multiplexed network chip.
@@ -2482,6 +2483,8 @@ config S6GMAC
          To compile this driver as a module, choose M here. The module
          will be called s6gmac.
 
+source "drivers/net/stmmac/Kconfig"
+
 endif # NETDEV_1000
 
 #
@@ -3230,4 +3233,12 @@ config VIRTIO_NET
          This is the virtual network driver for virtio.  It can be used with
           lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
 
+config VMXNET3
+       tristate "VMware VMXNET3 ethernet driver"
+       depends on PCI && X86 && INET
+       help
+         This driver supports VMware's vmxnet3 virtual ethernet NIC.
+         To compile this driver as a module, choose M here: the
+         module will be called vmxnet3.
+
 endif # NETDEVICES
index d866b8c..246323d 100644 (file)
@@ -2,6 +2,10 @@
 # Makefile for the Linux network (ethercard) device drivers.
 #
 
+obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
+obj-$(CONFIG_PHYLIB) += phy/
+
 obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
 
 obj-$(CONFIG_E1000) += e1000/
@@ -26,6 +30,7 @@ obj-$(CONFIG_TEHUTI) += tehuti.o
 obj-$(CONFIG_ENIC) += enic/
 obj-$(CONFIG_JME) += jme.o
 obj-$(CONFIG_BE2NET) += benet/
+obj-$(CONFIG_VMXNET3) += vmxnet3/
 
 gianfar_driver-objs := gianfar.o \
                gianfar_ethtool.o \
@@ -95,15 +100,12 @@ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
 obj-$(CONFIG_RIONET) += rionet.o
 obj-$(CONFIG_SH_ETH) += sh_eth.o
+obj-$(CONFIG_STMMAC_ETH) += stmmac/
 
 #
 # end link order section
 #
 
-obj-$(CONFIG_MII) += mii.o
-obj-$(CONFIG_MDIO) += mdio.o
-obj-$(CONFIG_PHYLIB) += phy/
-
 obj-$(CONFIG_SUNDANCE) += sundance.o
 obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o loopback.o
index 5f0b05c..d82a9a9 100644 (file)
@@ -1209,7 +1209,8 @@ static int __devinit ace_init(struct net_device *dev)
        memset(ap->info, 0, sizeof(struct ace_info));
        memset(ap->skb, 0, sizeof(struct ace_skb));
 
-       if (ace_load_firmware(dev))
+       ecode = ace_load_firmware(dev);
+       if (ecode)
                goto init_error;
 
        ap->fw_running = 0;
index 04f63c7..ce6f1ac 100644 (file)
@@ -34,6 +34,7 @@
  *
  *
  */
+#include <linux/capability.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
index 89876ad..28a0eda 100644 (file)
@@ -243,15 +243,26 @@ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
 
 int be_cmd_POST(struct be_adapter *adapter)
 {
-       u16 stage, error;
+       u16 stage;
+       int status, timeout = 0;
 
-       error = be_POST_stage_get(adapter, &stage);
-       if (error || stage != POST_STAGE_ARMFW_RDY) {
-               dev_err(&adapter->pdev->dev, "POST failed.\n");
-               return -1;
-       }
+       do {
+               status = be_POST_stage_get(adapter, &stage);
+               if (status) {
+                       dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
+                               stage);
+                       return -1;
+               } else if (stage != POST_STAGE_ARMFW_RDY) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(2 * HZ);
+                       timeout += 2;
+               } else {
+                       return 0;
+               }
+       } while (timeout < 20);
 
-       return 0;
+       dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
+       return -1;
 }
 
 static inline void *embedded_payload(struct be_mcc_wrb *wrb)
@@ -729,8 +740,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 /* Create an rx filtering policy configuration on an i/f
  * Uses mbox
  */
-int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
-               bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
+int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
+               u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_if_create *req;
@@ -746,8 +757,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
 
-       req->capability_flags = cpu_to_le32(flags);
-       req->enable_flags = cpu_to_le32(flags);
+       req->capability_flags = cpu_to_le32(cap_flags);
+       req->enable_flags = cpu_to_le32(en_flags);
        req->pmac_invalid = pmac_invalid;
        if (!pmac_invalid)
                memcpy(req->mac_addr, mac, ETH_ALEN);
index a86f917..4995378 100644 (file)
@@ -720,8 +720,9 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
 extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
                        u32 if_id, u32 *pmac_id);
 extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
-extern int be_cmd_if_create(struct be_adapter *adapter, u32 if_flags, u8 *mac,
-                       bool pmac_invalid, u32 *if_handle, u32 *pmac_id);
+extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
+                       u32 en_flags, u8 *mac, bool pmac_invalid,
+                       u32 *if_handle, u32 *pmac_id);
 extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
 extern int be_cmd_eq_create(struct be_adapter *adapter,
                        struct be_queue_info *eq, int eq_delay);
index 6d5e81f..1f941f0 100644 (file)
@@ -1620,19 +1620,22 @@ static int be_open(struct net_device *netdev)
 static int be_setup(struct be_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       u32 if_flags;
+       u32 cap_flags, en_flags;
        int status;
 
-       if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS |
-               BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED |
-               BE_IF_FLAGS_PASS_L3L4_ERRORS;
-       status = be_cmd_if_create(adapter, if_flags, netdev->dev_addr,
-                       false/* pmac_invalid */, &adapter->if_handle,
-                       &adapter->pmac_id);
+       cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+                       BE_IF_FLAGS_MCAST_PROMISCUOUS |
+                       BE_IF_FLAGS_PROMISCUOUS |
+                       BE_IF_FLAGS_PASS_L3L4_ERRORS;
+       en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+                       BE_IF_FLAGS_PASS_L3L4_ERRORS;
+
+       status = be_cmd_if_create(adapter, cap_flags, en_flags,
+                       netdev->dev_addr, false/* pmac_invalid */,
+                       &adapter->if_handle, &adapter->pmac_id);
        if (status != 0)
                goto do_none;
 
-
        status = be_tx_queues_create(adapter);
        if (status != 0)
                goto if_destroy;
@@ -2055,6 +2058,10 @@ static int be_hw_up(struct be_adapter *adapter)
        if (status)
                return status;
 
+       status = be_cmd_reset_function(adapter);
+       if (status)
+               return status;
+
        status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
        if (status)
                return status;
@@ -2108,10 +2115,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
        if (status)
                goto free_netdev;
 
-       status = be_cmd_reset_function(adapter);
-       if (status)
-               goto ctrl_clean;
-
        status = be_stats_init(adapter);
        if (status)
                goto ctrl_clean;
index 6c7f795..a4d8340 100644 (file)
@@ -361,9 +361,12 @@ struct l2_fhdr {
 #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE       (1<<28)
 
 #define BNX2_L2CTX_HOST_BDIDX                          0x00000004
-#define BNX2_L2CTX_STATUSB_NUM_SHIFT                    16
-#define BNX2_L2CTX_STATUSB_NUM(sb_id)                   \
-       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_STATUSB_NUM_SHIFT) : 0)
+#define BNX2_L2CTX_L5_STATUSB_NUM_SHIFT                         16
+#define BNX2_L2CTX_L2_STATUSB_NUM_SHIFT                         24
+#define BNX2_L2CTX_L5_STATUSB_NUM(sb_id)               \
+       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L5_STATUSB_NUM_SHIFT) : 0)
+#define BNX2_L2CTX_L2_STATUSB_NUM(sb_id)               \
+       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT) : 0)
 #define BNX2_L2CTX_HOST_BSEQ                           0x00000008
 #define BNX2_L2CTX_NX_BSEQ                             0x0000000c
 #define BNX2_L2CTX_NX_BDHADDR_HI                       0x00000010
index 69c5b15..40fb5ee 100644 (file)
@@ -691,7 +691,7 @@ static int bond_check_dev_link(struct bonding *bond,
                               struct net_device *slave_dev, int reporting)
 {
        const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
-       static int (*ioctl)(struct net_device *, struct ifreq *, int);
+       int (*ioctl)(struct net_device *, struct ifreq *, int);
        struct ifreq ifr;
        struct mii_ioctl_data *mii;
 
@@ -3665,10 +3665,10 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
 
        if (skb->protocol == htons(ETH_P_IP)) {
                return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
-                       (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
+                       (data->h_dest[5] ^ data->h_source[5])) % count;
        }
 
-       return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+       return (data->h_dest[5] ^ data->h_source[5]) % count;
 }
 
 /*
@@ -3695,7 +3695,7 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
 
        }
 
-       return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+       return (data->h_dest[5] ^ data->h_source[5]) % count;
 }
 
 /*
@@ -3706,7 +3706,7 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
 {
        struct ethhdr *data = (struct ethhdr *)skb->data;
 
-       return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+       return (data->h_dest[5] ^ data->h_source[5]) % count;
 }
 
 /*-------------------------- Device entry points ----------------------------*/
index 3373560..9dd076a 100644 (file)
@@ -213,6 +213,7 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = {
        {.compatible = "nxp,sja1000"},
        {},
 };
+MODULE_DEVICE_TABLE(of, sja1000_ofp_table);
 
 static struct of_platform_driver sja1000_ofp_driver = {
        .owner = THIS_MODULE,
index 46c87ec..3bf1b04 100644 (file)
@@ -2264,9 +2264,9 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev)
        cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_CTX_TYPE, val);
 
        if (sb_id == 0)
-               val = 2 << BNX2_L2CTX_STATUSB_NUM_SHIFT;
+               val = 2 << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT;
        else
-               val = BNX2_L2CTX_STATUSB_NUM(sb_id);
+               val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id);
        cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val);
 
        rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE);
@@ -2423,7 +2423,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
        cp->int_num = 0;
        if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
                u32 sb_id = cp->status_blk_num;
-               u32 sb = BNX2_L2CTX_STATUSB_NUM(sb_id);
+               u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id);
 
                cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT;
                cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
index 65a2d0b..f72c56d 100644 (file)
@@ -333,6 +333,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_DM646X_MAC_EOI_C0_RXEN    (0x01)
 #define EMAC_DM646X_MAC_EOI_C0_TXEN    (0x02)
 
+/* EMAC Stats Clear Mask */
+#define EMAC_STATS_CLR_MASK    (0xFFFFFFFF)
+
 /** net_buf_obj: EMAC network bufferdata structure
  *
  * EMAC network buffer data structure
@@ -2548,40 +2551,49 @@ static int emac_dev_stop(struct net_device *ndev)
 static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
 {
        struct emac_priv *priv = netdev_priv(ndev);
+       u32 mac_control;
+       u32 stats_clear_mask;
 
        /* update emac hardware stats and reset the registers*/
 
+       mac_control = emac_read(EMAC_MACCONTROL);
+
+       if (mac_control & EMAC_MACCONTROL_GMIIEN)
+               stats_clear_mask = EMAC_STATS_CLR_MASK;
+       else
+               stats_clear_mask = 0;
+
        priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
-       emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
 
        priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
                                           emac_read(EMAC_TXSINGLECOLL) +
                                           emac_read(EMAC_TXMULTICOLL));
-       emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
-       emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
-       emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_TXCOLLISION, stats_clear_mask);
+       emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
+       emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
 
        priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
                                                emac_read(EMAC_RXJABBER) +
                                                emac_read(EMAC_RXUNDERSIZED));
-       emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
-       emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
-       emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
+       emac_write(EMAC_RXJABBER, stats_clear_mask);
+       emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
 
        priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
                                               emac_read(EMAC_RXMOFOVERRUNS));
-       emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
-       emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
+       emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
 
        priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
-       emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
 
        priv->net_dev_stats.tx_carrier_errors +=
                emac_read(EMAC_TXCARRIERSENSE);
-       emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
 
        priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
-       emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
 
        return &priv->net_dev_stats;
 }
index 80817c2..fb1c924 100644 (file)
@@ -50,7 +50,7 @@
 #define DM9000_RCSR           0x32
 
 #define CHIPR_DM9000A         0x19
-#define CHIPR_DM9000B         0x1B
+#define CHIPR_DM9000B         0x1A
 
 #define DM9000_MRCMDX          0xF0
 #define DM9000_MRCMD           0xF2
index 981936c..405a144 100644 (file)
@@ -519,9 +519,13 @@ extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
 extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
 extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
 extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
+                                          u16 *data);
 extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
 extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
 extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
+                                           u16 data);
 extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
 extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
 extern s32 e1000e_get_cfg_done(struct e1000_hw *hw);
@@ -538,7 +542,11 @@ extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
 extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
 extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
+                                        u16 data);
 extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
+                                       u16 *data);
 extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
                               u32 usec_interval, bool *success);
 extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
@@ -546,7 +554,11 @@ extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_check_downshift(struct e1000_hw *hw);
 extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
+                                        u16 *data);
 extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
+                                         u16 data);
 extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
 extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
 extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
index fd44d9f..7b05cf4 100644 (file)
@@ -764,11 +764,13 @@ struct e1000_phy_operations {
        s32  (*get_cable_length)(struct e1000_hw *);
        s32  (*get_phy_info)(struct e1000_hw *);
        s32  (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
+       s32  (*read_phy_reg_locked)(struct e1000_hw *, u32, u16 *);
        void (*release_phy)(struct e1000_hw *);
        s32  (*reset_phy)(struct e1000_hw *);
        s32  (*set_d0_lplu_state)(struct e1000_hw *, bool);
        s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
        s32  (*write_phy_reg)(struct e1000_hw *, u32, u16);
+       s32  (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
        s32  (*cfg_on_link_up)(struct e1000_hw *);
 };
 
index 99df2ab..b6388b9 100644 (file)
 
 #define HV_LED_CONFIG          PHY_REG(768, 30) /* LED Configuration */
 
+#define SW_FLAG_TIMEOUT    1000 /* SW Semaphore flag timeout in milliseconds */
+
+/* OEM Bits Phy Register */
+#define HV_OEM_BITS            PHY_REG(768, 25)
+#define HV_OEM_BITS_LPLU       0x0004 /* Low Power Link Up */
+#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
+
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
 union ich8_hws_flash_status {
@@ -200,6 +207,7 @@ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
 static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
 static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
 static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
+static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -242,7 +250,11 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 
        phy->ops.check_polarity       = e1000_check_polarity_ife_ich8lan;
        phy->ops.read_phy_reg         = e1000_read_phy_reg_hv;
+       phy->ops.read_phy_reg_locked  = e1000_read_phy_reg_hv_locked;
+       phy->ops.set_d0_lplu_state    = e1000_set_lplu_state_pchlan;
+       phy->ops.set_d3_lplu_state    = e1000_set_lplu_state_pchlan;
        phy->ops.write_phy_reg        = e1000_write_phy_reg_hv;
+       phy->ops.write_phy_reg_locked = e1000_write_phy_reg_hv_locked;
        phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
        phy->id = e1000_phy_unknown;
@@ -303,6 +315,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
        case IGP03E1000_E_PHY_ID:
                phy->type = e1000_phy_igp_3;
                phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+               phy->ops.read_phy_reg_locked = e1000e_read_phy_reg_igp_locked;
+               phy->ops.write_phy_reg_locked = e1000e_write_phy_reg_igp_locked;
                break;
        case IFE_E_PHY_ID:
        case IFE_PLUS_E_PHY_ID:
@@ -567,13 +581,40 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
 
 static DEFINE_MUTEX(nvm_mutex);
 
+/**
+ *  e1000_acquire_nvm_ich8lan - Acquire NVM mutex
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquires the mutex for performing NVM operations.
+ **/
+static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw)
+{
+       mutex_lock(&nvm_mutex);
+
+       return 0;
+}
+
+/**
+ *  e1000_release_nvm_ich8lan - Release NVM mutex
+ *  @hw: pointer to the HW structure
+ *
+ *  Releases the mutex used while performing NVM operations.
+ **/
+static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
+{
+       mutex_unlock(&nvm_mutex);
+
+       return;
+}
+
+static DEFINE_MUTEX(swflag_mutex);
+
 /**
  *  e1000_acquire_swflag_ich8lan - Acquire software control flag
  *  @hw: pointer to the HW structure
  *
- *  Acquires the software control flag for performing NVM and PHY
- *  operations.  This is a function pointer entry point only called by
- *  read/write routines for the PHY and NVM parts.
+ *  Acquires the software control flag for performing PHY and select
+ *  MAC CSR accesses.
  **/
 static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 {
@@ -582,7 +623,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        might_sleep();
 
-       mutex_lock(&nvm_mutex);
+       mutex_lock(&swflag_mutex);
 
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -599,7 +640,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
                goto out;
        }
 
-       timeout = PHY_CFG_TIMEOUT * 2;
+       timeout = SW_FLAG_TIMEOUT;
 
        extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
        ew32(EXTCNF_CTRL, extcnf_ctrl);
@@ -623,7 +664,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
 out:
        if (ret_val)
-               mutex_unlock(&nvm_mutex);
+               mutex_unlock(&swflag_mutex);
 
        return ret_val;
 }
@@ -632,9 +673,8 @@ out:
  *  e1000_release_swflag_ich8lan - Release software control flag
  *  @hw: pointer to the HW structure
  *
- *  Releases the software control flag for performing NVM and PHY operations.
- *  This is a function pointer entry point only called by read/write
- *  routines for the PHY and NVM parts.
+ *  Releases the software control flag for performing PHY and select
+ *  MAC CSR accesses.
  **/
 static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
 {
@@ -644,7 +684,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
        extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
        ew32(EXTCNF_CTRL, extcnf_ctrl);
 
-       mutex_unlock(&nvm_mutex);
+       mutex_unlock(&swflag_mutex);
+
+       return;
 }
 
 /**
@@ -844,7 +886,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
        u32 i;
        u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
        s32 ret_val;
-       u16 word_addr, reg_data, reg_addr, phy_page = 0;
+       u16 reg, word_addr, reg_data, reg_addr, phy_page = 0;
 
        ret_val = e1000e_phy_hw_reset_generic(hw);
        if (ret_val)
@@ -859,6 +901,10 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
                        return ret_val;
        }
 
+       /* Dummy read to clear the phy wakeup bit after lcd reset */
+       if (hw->mac.type == e1000_pchlan)
+               e1e_rphy(hw, BM_WUC, &reg);
+
        /*
         * Initialize the PHY from the NVM on ICH platforms.  This
         * is needed due to an issue where the NVM configuration is
@@ -1053,6 +1099,38 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
        return ret_val;
 }
 
+/**
+ *  e1000_set_lplu_state_pchlan - Set Low Power Link Up state
+ *  @hw: pointer to the HW structure
+ *  @active: true to enable LPLU, false to disable
+ *
+ *  Sets the LPLU state according to the active flag.  For PCH, if OEM write
+ *  bit are disabled in the NVM, writing the LPLU bits in the MAC will not set
+ *  the phy speed. This function will manually set the LPLU bit and restart
+ *  auto-neg as hw would do. D3 and D0 LPLU will call the same function
+ *  since it configures the same bit.
+ **/
+static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active)
+{
+       s32 ret_val = 0;
+       u16 oem_reg;
+
+       ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg);
+       if (ret_val)
+               goto out;
+
+       if (active)
+               oem_reg |= HV_OEM_BITS_LPLU;
+       else
+               oem_reg &= ~HV_OEM_BITS_LPLU;
+
+       oem_reg |= HV_OEM_BITS_RESTART_AN;
+       ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg);
+
+out:
+       return ret_val;
+}
+
 /**
  *  e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
  *  @hw: pointer to the HW structure
@@ -1314,12 +1392,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
        if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
            (words == 0)) {
                hw_dbg(hw, "nvm parameter(s) out of bounds\n");
-               return -E1000_ERR_NVM;
+               ret_val = -E1000_ERR_NVM;
+               goto out;
        }
 
-       ret_val = e1000_acquire_swflag_ich8lan(hw);
-       if (ret_val)
-               goto out;
+       nvm->ops.acquire_nvm(hw);
 
        ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
        if (ret_val) {
@@ -1345,7 +1422,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                }
        }
 
-       e1000_release_swflag_ich8lan(hw);
+       nvm->ops.release_nvm(hw);
 
 out:
        if (ret_val)
@@ -1603,11 +1680,15 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                return -E1000_ERR_NVM;
        }
 
+       nvm->ops.acquire_nvm(hw);
+
        for (i = 0; i < words; i++) {
                dev_spec->shadow_ram[offset+i].modified = 1;
                dev_spec->shadow_ram[offset+i].value = data[i];
        }
 
+       nvm->ops.release_nvm(hw);
+
        return 0;
 }
 
@@ -1637,9 +1718,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        if (nvm->type != e1000_nvm_flash_sw)
                goto out;
 
-       ret_val = e1000_acquire_swflag_ich8lan(hw);
-       if (ret_val)
-               goto out;
+       nvm->ops.acquire_nvm(hw);
 
        /*
         * We're writing to the opposite bank so if we're on bank 1,
@@ -1657,7 +1736,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                old_bank_offset = 0;
                ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
                if (ret_val) {
-                       e1000_release_swflag_ich8lan(hw);
+                       nvm->ops.release_nvm(hw);
                        goto out;
                }
        } else {
@@ -1665,7 +1744,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                new_bank_offset = 0;
                ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
                if (ret_val) {
-                       e1000_release_swflag_ich8lan(hw);
+                       nvm->ops.release_nvm(hw);
                        goto out;
                }
        }
@@ -1723,7 +1802,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        if (ret_val) {
                /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
                hw_dbg(hw, "Flash commit failed.\n");
-               e1000_release_swflag_ich8lan(hw);
+               nvm->ops.release_nvm(hw);
                goto out;
        }
 
@@ -1736,7 +1815,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
        ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
        if (ret_val) {
-               e1000_release_swflag_ich8lan(hw);
+               nvm->ops.release_nvm(hw);
                goto out;
        }
        data &= 0xBFFF;
@@ -1744,7 +1823,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                                                       act_offset * 2 + 1,
                                                       (u8)(data >> 8));
        if (ret_val) {
-               e1000_release_swflag_ich8lan(hw);
+               nvm->ops.release_nvm(hw);
                goto out;
        }
 
@@ -1757,7 +1836,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
        ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
        if (ret_val) {
-               e1000_release_swflag_ich8lan(hw);
+               nvm->ops.release_nvm(hw);
                goto out;
        }
 
@@ -1767,7 +1846,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                dev_spec->shadow_ram[i].value = 0xFFFF;
        }
 
-       e1000_release_swflag_ich8lan(hw);
+       nvm->ops.release_nvm(hw);
 
        /*
         * Reload the EEPROM, or else modifications will not appear
@@ -1831,14 +1910,12 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
  **/
 void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
 {
+       struct e1000_nvm_info *nvm = &hw->nvm;
        union ich8_flash_protected_range pr0;
        union ich8_hws_flash_status hsfsts;
        u32 gfpreg;
-       s32 ret_val;
 
-       ret_val = e1000_acquire_swflag_ich8lan(hw);
-       if (ret_val)
-               return;
+       nvm->ops.acquire_nvm(hw);
 
        gfpreg = er32flash(ICH_FLASH_GFPREG);
 
@@ -1859,7 +1936,7 @@ void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
        hsfsts.hsf_status.flockdn = true;
        ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 
-       e1000_release_swflag_ich8lan(hw);
+       nvm->ops.release_nvm(hw);
 }
 
 /**
@@ -2229,6 +2306,7 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
  **/
 static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 {
+       u16 reg;
        u32 ctrl, icr, kab;
        s32 ret_val;
 
@@ -2304,6 +2382,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
                        hw_dbg(hw, "Auto Read Done did not complete\n");
                }
        }
+       /* Dummy read to clear the phy wakeup bit after lcd reset */
+       if (hw->mac.type == e1000_pchlan)
+               e1e_rphy(hw, BM_WUC, &reg);
 
        /*
         * For PCH, this write will make sure that any noise
@@ -2843,9 +2924,8 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
                            E1000_PHY_CTRL_GBE_DISABLE;
                ew32(PHY_CTRL, phy_ctrl);
 
-               /* Workaround SWFLAG unexpectedly set during S0->Sx */
                if (hw->mac.type == e1000_pchlan)
-                       udelay(500);
+                       e1000_phy_hw_reset_ich8lan(hw);
        default:
                break;
        }
@@ -3113,9 +3193,9 @@ static struct e1000_phy_operations ich8_phy_ops = {
 };
 
 static struct e1000_nvm_operations ich8_nvm_ops = {
-       .acquire_nvm            = e1000_acquire_swflag_ich8lan,
+       .acquire_nvm            = e1000_acquire_nvm_ich8lan,
        .read_nvm               = e1000_read_nvm_ich8lan,
-       .release_nvm            = e1000_release_swflag_ich8lan,
+       .release_nvm            = e1000_release_nvm_ich8lan,
        .update_nvm             = e1000_update_nvm_checksum_ich8lan,
        .valid_led_default      = e1000_valid_led_default_ich8lan,
        .validate_nvm           = e1000_validate_nvm_checksum_ich8lan,
index 994401f..f9d33ab 100644 (file)
@@ -164,16 +164,25 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
                 * MDIC mode. No harm in trying again in this case since
                 * the PHY ID is unknown at this point anyway
                 */
+               ret_val = phy->ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
                ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
                if (ret_val)
                        goto out;
+               phy->ops.release_phy(hw);
 
                retry_count++;
        }
 out:
        /* Revert to MDIO fast mode, if applicable */
-       if (retry_count)
+       if (retry_count) {
+               ret_val = phy->ops.acquire_phy(hw);
+               if (ret_val)
+                       return ret_val;
                ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+               phy->ops.release_phy(hw);
+       }
 
        return ret_val;
 }
@@ -354,94 +363,173 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
 }
 
 /**
- *  e1000e_read_phy_reg_igp - Read igp PHY register
+ *  __e1000e_read_phy_reg_igp - Read igp PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
  *  @data: pointer to the read data
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary, then reads the PHY register at offset
- *  and storing the retrieved information in data.  Release any acquired
+ *  and stores the retrieved information in data.  Release any acquired
  *  semaphores before exiting.
  **/
-s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
+                                    bool locked)
 {
-       s32 ret_val;
+       s32 ret_val = 0;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
+       if (!locked) {
+               if (!(hw->phy.ops.acquire_phy))
+                       goto out;
+
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
+       }
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
                ret_val = e1000e_write_phy_reg_mdic(hw,
                                                    IGP01E1000_PHY_PAGE_SELECT,
                                                    (u16)offset);
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
-                       return ret_val;
-               }
+               if (ret_val)
+                       goto release;
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-                                          data);
-
-       hw->phy.ops.release_phy(hw);
+                                         data);
 
+release:
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
+out:
        return ret_val;
 }
 
+/**
+ *  e1000e_read_phy_reg_igp - Read igp PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore then reads the PHY register at offset and stores the
+ *  retrieved information in data.
+ *  Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000e_read_phy_reg_igp(hw, offset, data, false);
+}
+
+/**
+ *  e1000e_read_phy_reg_igp_locked - Read igp PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the PHY register at offset and stores the retrieved information
+ *  in data.  Assumes semaphore already acquired.
+ **/
+s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000e_read_phy_reg_igp(hw, offset, data, true);
+}
+
 /**
  *  e1000e_write_phy_reg_igp - Write igp PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to write to
  *  @data: data to write at register offset
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary, then writes the data to PHY register
  *  at the offset.  Release any acquired semaphores before exiting.
  **/
-s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
+                                     bool locked)
 {
-       s32 ret_val;
+       s32 ret_val = 0;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
+       if (!locked) {
+               if (!(hw->phy.ops.acquire_phy))
+                       goto out;
+
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
+       }
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
                ret_val = e1000e_write_phy_reg_mdic(hw,
                                                    IGP01E1000_PHY_PAGE_SELECT,
                                                    (u16)offset);
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
-                       return ret_val;
-               }
+               if (ret_val)
+                       goto release;
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
                                            data);
 
-       hw->phy.ops.release_phy(hw);
+release:
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
 
+out:
        return ret_val;
 }
 
 /**
- *  e1000e_read_kmrn_reg - Read kumeran register
+ *  e1000e_write_phy_reg_igp - Write igp PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore then writes the data to PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000e_write_phy_reg_igp(hw, offset, data, false);
+}
+
+/**
+ *  e1000e_write_phy_reg_igp_locked - Write igp PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Writes the data to PHY register at the offset.
+ *  Assumes semaphore already acquired.
+ **/
+s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000e_write_phy_reg_igp(hw, offset, data, true);
+}
+
+/**
+ *  __e1000_read_kmrn_reg - Read kumeran register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
  *  @data: pointer to the read data
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary.  Then reads the PHY register at offset
  *  using the kumeran interface.  The information retrieved is stored in data.
  *  Release any acquired semaphores before exiting.
  **/
-s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
+                                 bool locked)
 {
        u32 kmrnctrlsta;
-       s32 ret_val;
+       s32 ret_val = 0;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
+       if (!locked) {
+               if (!(hw->phy.ops.acquire_phy))
+                       goto out;
+
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
+       }
 
        kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
                       E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
@@ -452,40 +540,110 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
        kmrnctrlsta = er32(KMRNCTRLSTA);
        *data = (u16)kmrnctrlsta;
 
-       hw->phy.ops.release_phy(hw);
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
 
+out:
        return ret_val;
 }
 
 /**
- *  e1000e_write_kmrn_reg - Write kumeran register
+ *  e1000e_read_kmrn_reg -  Read kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore then reads the PHY register at offset using the
+ *  kumeran interface.  The information retrieved is stored in data.
+ *  Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000_read_kmrn_reg(hw, offset, data, false);
+}
+
+/**
+ *  e1000_read_kmrn_reg_locked -  Read kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the PHY register at offset using the kumeran interface.  The
+ *  information retrieved is stored in data.
+ *  Assumes semaphore already acquired.
+ **/
+s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000_read_kmrn_reg(hw, offset, data, true);
+}
+
+/**
+ *  __e1000_write_kmrn_reg - Write kumeran register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to write to
  *  @data: data to write at register offset
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary.  Then write the data to PHY register
  *  at the offset using the kumeran interface.  Release any acquired semaphores
  *  before exiting.
  **/
-s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
+                                  bool locked)
 {
        u32 kmrnctrlsta;
-       s32 ret_val;
+       s32 ret_val = 0;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
+       if (!locked) {
+               if (!(hw->phy.ops.acquire_phy))
+                       goto out;
+
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
+       }
 
        kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
                       E1000_KMRNCTRLSTA_OFFSET) | data;
        ew32(KMRNCTRLSTA, kmrnctrlsta);
 
        udelay(2);
-       hw->phy.ops.release_phy(hw);
 
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
+
+out:
        return ret_val;
 }
 
+/**
+ *  e1000e_write_kmrn_reg -  Write kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore then writes the data to the PHY register at the offset
+ *  using the kumeran interface.  Release the acquired semaphore before exiting.
+ **/
+s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000_write_kmrn_reg(hw, offset, data, false);
+}
+
+/**
+ *  e1000_write_kmrn_reg_locked -  Write kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Write the data to PHY register at the offset using the kumeran interface.
+ *  Assumes semaphore already acquired.
+ **/
+s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000_write_kmrn_reg(hw, offset, data, true);
+}
+
 /**
  *  e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
  *  @hw: pointer to the HW structure
@@ -2105,6 +2263,10 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
        u32 page = offset >> IGP_PAGE_SHIFT;
        u32 page_shift = 0;
 
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+
        /* Page 800 works differently than the rest so it has its own func */
        if (page == BM_WUC_PAGE) {
                ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
@@ -2112,10 +2274,6 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
                goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               goto out;
-
        hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2135,18 +2293,15 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
                /* Page is shifted left, PHY expects (page x 32) */
                ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
                                                    (page << page_shift));
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
+               if (ret_val)
                        goto out;
-               }
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
                                            data);
 
-       hw->phy.ops.release_phy(hw);
-
 out:
+       hw->phy.ops.release_phy(hw);
        return ret_val;
 }
 
@@ -2167,6 +2322,10 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
        u32 page = offset >> IGP_PAGE_SHIFT;
        u32 page_shift = 0;
 
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+
        /* Page 800 works differently than the rest so it has its own func */
        if (page == BM_WUC_PAGE) {
                ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
@@ -2174,10 +2333,6 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
                goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               goto out;
-
        hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2197,17 +2352,14 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
                /* Page is shifted left, PHY expects (page x 32) */
                ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
                                                    (page << page_shift));
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
+               if (ret_val)
                        goto out;
-               }
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
                                           data);
-       hw->phy.ops.release_phy(hw);
-
 out:
+       hw->phy.ops.release_phy(hw);
        return ret_val;
 }
 
@@ -2226,17 +2378,17 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
        s32 ret_val;
        u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
 
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+
        /* Page 800 works differently than the rest so it has its own func */
        if (page == BM_WUC_PAGE) {
                ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
                                                         true);
-               return ret_val;
+               goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
-
        hw->phy.addr = 1;
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2245,16 +2397,14 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
                ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
                                                    page);
 
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
-                       return ret_val;
-               }
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
                                           data);
+out:
        hw->phy.ops.release_phy(hw);
-
        return ret_val;
 }
 
@@ -2272,17 +2422,17 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
        s32 ret_val;
        u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
 
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+
        /* Page 800 works differently than the rest so it has its own func */
        if (page == BM_WUC_PAGE) {
                ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
                                                         false);
-               return ret_val;
+               goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
-
        hw->phy.addr = 1;
 
        if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2290,17 +2440,15 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
                ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
                                                    page);
 
-               if (ret_val) {
-                       hw->phy.ops.release_phy(hw);
-                       return ret_val;
-               }
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
                                            data);
 
+out:
        hw->phy.ops.release_phy(hw);
-
        return ret_val;
 }
 
@@ -2320,6 +2468,8 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
  *  3) Write the address using the address opcode (0x11)
  *  4) Read or write the data using the data opcode (0x12)
  *  5) Restore 769_17.2 to its original value
+ *
+ *  Assumes semaphore already acquired.
  **/
 static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
                                          u16 *data, bool read)
@@ -2327,20 +2477,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
        s32 ret_val;
        u16 reg = BM_PHY_REG_NUM(offset);
        u16 phy_reg = 0;
-       u8  phy_acquired = 1;
-
 
        /* Gig must be disabled for MDIO accesses to page 800 */
        if ((hw->mac.type == e1000_pchlan) &&
           (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
                hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val) {
-               phy_acquired = 0;
-               goto out;
-       }
-
        /* All operations in this function are phy address 1 */
        hw->phy.addr = 1;
 
@@ -2397,8 +2539,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
        ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
 
 out:
-       if (phy_acquired == 1)
-               hw->phy.ops.release_phy(hw);
        return ret_val;
 }
 
@@ -2439,52 +2579,63 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
        return 0;
 }
 
+/**
+ *  e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
+ *  @hw:   pointer to the HW structure
+ *  @slow: true for slow mode, false for normal mode
+ *
+ *  Assumes semaphore already acquired.
+ **/
 s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
 {
        s32 ret_val = 0;
        u16 data = 0;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               return ret_val;
-
        /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
        hw->phy.addr = 1;
        ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
                                         (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
-       if (ret_val) {
-               hw->phy.ops.release_phy(hw);
-               return ret_val;
-       }
+       if (ret_val)
+               goto out;
+
        ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
                                           (0x2180 | (slow << 10)));
+       if (ret_val)
+               goto out;
 
        /* dummy read when reverting to fast mode - throw away result */
        if (!slow)
-               e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
-
-       hw->phy.ops.release_phy(hw);
+               ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
 
+out:
        return ret_val;
 }
 
 /**
- *  e1000_read_phy_reg_hv -  Read HV PHY register
+ *  __e1000_read_phy_reg_hv -  Read HV PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
  *  @data: pointer to the read data
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary, then reads the PHY register at offset
- *  and storing the retrieved information in data.  Release any acquired
+ *  and stores the retrieved information in data.  Release any acquired
  *  semaphore before exiting.
  **/
-s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
+                                   bool locked)
 {
        s32 ret_val;
        u16 page = BM_PHY_REG_PAGE(offset);
        u16 reg = BM_PHY_REG_NUM(offset);
        bool in_slow_mode = false;
 
+       if (!locked) {
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Workaround failure in MDIO access while cable is disconnected */
        if ((hw->phy.type == e1000_phy_82577) &&
            !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2508,10 +2659,6 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
                goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               goto out;
-
        hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
 
        if (page == HV_INTC_FC_PAGE_START)
@@ -2529,42 +2676,76 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
                        ret_val = e1000e_write_phy_reg_mdic(hw,
                                                     IGP01E1000_PHY_PAGE_SELECT,
                                                     (page << IGP_PAGE_SHIFT));
-                       if (ret_val) {
-                               hw->phy.ops.release_phy(hw);
-                               goto out;
-                       }
                        hw->phy.addr = phy_addr;
                }
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
                                          data);
-       hw->phy.ops.release_phy(hw);
-
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
                ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
 
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
+
        return ret_val;
 }
 
 /**
- *  e1000_write_phy_reg_hv - Write HV PHY register
+ *  e1000_read_phy_reg_hv -  Read HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore then reads the PHY register at offset and stores
+ *  the retrieved information in data.  Release the acquired semaphore
+ *  before exiting.
+ **/
+s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000_read_phy_reg_hv(hw, offset, data, false);
+}
+
+/**
+ *  e1000_read_phy_reg_hv_locked -  Read HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the PHY register at offset and stores the retrieved information
+ *  in data.  Assumes semaphore already acquired.
+ **/
+s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       return __e1000_read_phy_reg_hv(hw, offset, data, true);
+}
+
+/**
+ *  __e1000_write_phy_reg_hv - Write HV PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to write to
  *  @data: data to write at register offset
+ *  @locked: semaphore has already been acquired or not
  *
  *  Acquires semaphore, if necessary, then writes the data to PHY register
  *  at the offset.  Release any acquired semaphores before exiting.
  **/
-s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
+                                    bool locked)
 {
        s32 ret_val;
        u16 page = BM_PHY_REG_PAGE(offset);
        u16 reg = BM_PHY_REG_NUM(offset);
        bool in_slow_mode = false;
 
+       if (!locked) {
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Workaround failure in MDIO access while cable is disconnected */
        if ((hw->phy.type == e1000_phy_82577) &&
            !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2588,10 +2769,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
                goto out;
        }
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val)
-               goto out;
-
        hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
 
        if (page == HV_INTC_FC_PAGE_START)
@@ -2607,15 +2784,10 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
            ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
            (data & (1 << 11))) {
                u16 data2 = 0x7EFF;
-               hw->phy.ops.release_phy(hw);
                ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
                                                         &data2, false);
                if (ret_val)
                        goto out;
-
-               ret_val = hw->phy.ops.acquire_phy(hw);
-               if (ret_val)
-                       goto out;
        }
 
        if (reg > MAX_PHY_MULTI_PAGE_REG) {
@@ -2630,26 +2802,52 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
                        ret_val = e1000e_write_phy_reg_mdic(hw,
                                                     IGP01E1000_PHY_PAGE_SELECT,
                                                     (page << IGP_PAGE_SHIFT));
-                       if (ret_val) {
-                               hw->phy.ops.release_phy(hw);
-                               goto out;
-                       }
                        hw->phy.addr = phy_addr;
                }
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
                                          data);
-       hw->phy.ops.release_phy(hw);
 
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
                ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
 
+       if (!locked)
+               hw->phy.ops.release_phy(hw);
+
        return ret_val;
 }
 
+/**
+ *  e1000_write_phy_reg_hv - Write HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore then writes the data to PHY register at the offset.
+ *  Release the acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000_write_phy_reg_hv(hw, offset, data, false);
+}
+
+/**
+ *  e1000_write_phy_reg_hv_locked - Write HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Writes the data to PHY register at the offset.  Assumes semaphore
+ *  already acquired.
+ **/
+s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       return __e1000_write_phy_reg_hv(hw, offset, data, true);
+}
+
 /**
  *  e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
  *  @page: page to be accessed
@@ -2671,10 +2869,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page)
  *  @data: pointer to the data to be read or written
  *  @read: determines if operation is read or written
  *
- *  Acquires semaphore, if necessary, then reads the PHY register at offset
- *  and storing the retreived information in data.  Release any acquired
- *  semaphores before exiting.  Note that the procedure to read these regs
- *  uses the address port and data port to read/write.
+ *  Reads the PHY register at offset and stores the retreived information
+ *  in data.  Assumes semaphore already acquired.  Note that the procedure
+ *  to read these regs uses the address port and data port to read/write.
  **/
 static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
                                           u16 *data, bool read)
@@ -2682,20 +2879,12 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
        s32 ret_val;
        u32 addr_reg = 0;
        u32 data_reg = 0;
-       u8  phy_acquired = 1;
 
        /* This takes care of the difference with desktop vs mobile phy */
        addr_reg = (hw->phy.type == e1000_phy_82578) ?
                   I82578_ADDR_REG : I82577_ADDR_REG;
        data_reg = addr_reg + 1;
 
-       ret_val = hw->phy.ops.acquire_phy(hw);
-       if (ret_val) {
-               hw_dbg(hw, "Could not acquire PHY\n");
-               phy_acquired = 0;
-               goto out;
-       }
-
        /* All operations in this function are phy address 2 */
        hw->phy.addr = 2;
 
@@ -2718,8 +2907,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
        }
 
 out:
-       if (phy_acquired == 1)
-               hw->phy.ops.release_phy(hw);
        return ret_val;
 }
 
index 96f5b2a..f7d9ac8 100644 (file)
@@ -223,24 +223,25 @@ struct ethoc_bd {
        u32 addr;
 };
 
-static u32 ethoc_read(struct ethoc *dev, loff_t offset)
+static inline u32 ethoc_read(struct ethoc *dev, loff_t offset)
 {
        return ioread32(dev->iobase + offset);
 }
 
-static void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
+static inline void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
 {
        iowrite32(data, dev->iobase + offset);
 }
 
-static void ethoc_read_bd(struct ethoc *dev, int index, struct ethoc_bd *bd)
+static inline void ethoc_read_bd(struct ethoc *dev, int index,
+               struct ethoc_bd *bd)
 {
        loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
        bd->stat = ethoc_read(dev, offset + 0);
        bd->addr = ethoc_read(dev, offset + 4);
 }
 
-static void ethoc_write_bd(struct ethoc *dev, int index,
+static inline void ethoc_write_bd(struct ethoc *dev, int index,
                const struct ethoc_bd *bd)
 {
        loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
@@ -248,33 +249,33 @@ static void ethoc_write_bd(struct ethoc *dev, int index,
        ethoc_write(dev, offset + 4, bd->addr);
 }
 
-static void ethoc_enable_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_enable_irq(struct ethoc *dev, u32 mask)
 {
        u32 imask = ethoc_read(dev, INT_MASK);
        imask |= mask;
        ethoc_write(dev, INT_MASK, imask);
 }
 
-static void ethoc_disable_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_disable_irq(struct ethoc *dev, u32 mask)
 {
        u32 imask = ethoc_read(dev, INT_MASK);
        imask &= ~mask;
        ethoc_write(dev, INT_MASK, imask);
 }
 
-static void ethoc_ack_irq(struct ethoc *dev, u32 mask)
+static inline void ethoc_ack_irq(struct ethoc *dev, u32 mask)
 {
        ethoc_write(dev, INT_SOURCE, mask);
 }
 
-static void ethoc_enable_rx_and_tx(struct ethoc *dev)
+static inline void ethoc_enable_rx_and_tx(struct ethoc *dev)
 {
        u32 mode = ethoc_read(dev, MODER);
        mode |= MODER_RXEN | MODER_TXEN;
        ethoc_write(dev, MODER, mode);
 }
 
-static void ethoc_disable_rx_and_tx(struct ethoc *dev)
+static inline void ethoc_disable_rx_and_tx(struct ethoc *dev)
 {
        u32 mode = ethoc_read(dev, MODER);
        mode &= ~(MODER_RXEN | MODER_TXEN);
@@ -508,7 +509,7 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       ethoc_ack_irq(priv, INT_MASK_ALL);
+       ethoc_ack_irq(priv, pending);
 
        if (pending & INT_MASK_BUSY) {
                dev_err(&dev->dev, "packet dropped\n");
@@ -664,7 +665,8 @@ static int ethoc_open(struct net_device *dev)
                return ret;
 
        /* calculate the number of TX/RX buffers, maximum 128 supported */
-       num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
+       num_bd = min_t(unsigned int,
+               128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
        priv->num_tx = max(min_tx, num_bd / 4);
        priv->num_rx = num_bd - priv->num_tx;
        ethoc_write(priv, TX_BD_NUM, priv->num_tx);
index 2923438..16a1d58 100644 (file)
@@ -1654,7 +1654,7 @@ static const struct net_device_ops fec_netdev_ops = {
   *
   * index is only used in legacy code
   */
-int __init fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev, int index)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
        struct bufdesc *cbd_base;
index c40113f..66dace6 100644 (file)
@@ -759,12 +759,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
 
        mpc52xx_fec_hw_init(dev);
 
-       if (priv->phydev) {
-               phy_stop(priv->phydev);
-               phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
-               phy_start(priv->phydev);
-       }
-
        bcom_fec_rx_reset(priv->rx_dmatsk);
        bcom_fec_tx_reset(priv->tx_dmatsk);
 
index 31e6d62..ee0f3c6 100644 (file)
@@ -155,6 +155,7 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = {
        { .compatible = "mpc5200b-fec-phy", },
        {}
 };
+MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match);
 
 struct of_platform_driver mpc52xx_fec_mdio_driver = {
        .name = "mpc5200b-fec-phy",
index 2bc2d2b..ec2f503 100644 (file)
@@ -1110,6 +1110,7 @@ static struct of_device_id fs_enet_match[] = {
 #endif
        {}
 };
+MODULE_DEVICE_TABLE(of, fs_enet_match);
 
 static struct of_platform_driver fs_enet_driver = {
        .name   = "fs_enet",
index 93b481b..24ff9f4 100644 (file)
@@ -221,6 +221,7 @@ static struct of_device_id fs_enet_mdio_bb_match[] = {
        },
        {},
 };
+MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match);
 
 static struct of_platform_driver fs_enet_bb_mdio_driver = {
        .name = "fsl-bb-mdio",
index a2d69c1..96eba42 100644 (file)
@@ -219,6 +219,7 @@ static struct of_device_id fs_enet_mdio_fec_match[] = {
 #endif
        {},
 };
+MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match);
 
 static struct of_platform_driver fs_enet_fec_mdio_driver = {
        .name = "fsl-fec-mdio",
index d167090..6ac4648 100644 (file)
@@ -407,6 +407,7 @@ static struct of_device_id fsl_pq_mdio_match[] = {
        },
        {},
 };
+MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
 
 static struct of_platform_driver fsl_pq_mdio_driver = {
        .name = "fsl-pq_mdio",
index 1e5289f..5bf31f1 100644 (file)
@@ -2325,9 +2325,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:fsl-gianfar");
-
 static struct of_device_id gfar_match[] =
 {
        {
@@ -2336,6 +2333,7 @@ static struct of_device_id gfar_match[] =
        },
        {},
 };
+MODULE_DEVICE_TABLE(of, gfar_match);
 
 /* Structure for a device driver */
 static struct of_platform_driver gfar_driver = {
index 89c82c5..3fae875 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/errno.h>
@@ -443,7 +444,7 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
                ret |= EMAC_MR1_TFS_2K;
                break;
        default:
-               printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n",
+               printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
                       dev->ndev->name, tx_size);
        }
 
@@ -470,6 +471,9 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
        DBG2(dev, "__emac4_calc_base_mr1" NL);
 
        switch(tx_size) {
+       case 16384:
+               ret |= EMAC4_MR1_TFS_16K;
+               break;
        case 4096:
                ret |= EMAC4_MR1_TFS_4K;
                break;
@@ -477,7 +481,7 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
                ret |= EMAC4_MR1_TFS_2K;
                break;
        default:
-               printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n",
+               printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
                       dev->ndev->name, tx_size);
        }
 
@@ -2985,6 +2989,7 @@ static struct of_device_id emac_match[] =
        },
        {},
 };
+MODULE_DEVICE_TABLE(of, emac_match);
 
 static struct of_platform_driver emac_driver = {
        .name = "emac",
index 0afc2cf..d34adf9 100644 (file)
@@ -153,6 +153,7 @@ struct emac_regs {
 #define EMAC4_MR1_RFS_16K              0x00280000
 #define EMAC4_MR1_TFS_2K                       0x00020000
 #define EMAC4_MR1_TFS_4K               0x00030000
+#define EMAC4_MR1_TFS_16K              0x00050000
 #define EMAC4_MR1_TR                   0x00008000
 #define EMAC4_MR1_MWSW_001             0x00001000
 #define EMAC4_MR1_JPSM                 0x00000800
index 801f088..030913f 100644 (file)
@@ -98,12 +98,13 @@ static void ri_tasklet(unsigned long dev)
                stats->tx_packets++;
                stats->tx_bytes +=skb->len;
 
-               skb->dev = __dev_get_by_index(&init_net, skb->iif);
+               skb->dev = dev_get_by_index(&init_net, skb->iif);
                if (!skb->dev) {
                        dev_kfree_skb(skb);
                        stats->tx_dropped++;
                        break;
                }
+               dev_put(skb->dev);
                skb->iif = _dev->ifindex;
 
                if (from & AT_EGRESS) {
index deaea8f..b243ed3 100644 (file)
@@ -732,7 +732,7 @@ static int igb_set_ringparam(struct net_device *netdev,
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct igb_ring *temp_ring;
-       int i, err;
+       int i, err = 0;
        u32 new_rx_count, new_tx_count;
 
        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -752,18 +752,30 @@ static int igb_set_ringparam(struct net_device *netdev,
                return 0;
        }
 
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (!netif_running(adapter->netdev)) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].count = new_tx_count;
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       adapter->rx_ring[i].count = new_rx_count;
+               adapter->tx_ring_count = new_tx_count;
+               adapter->rx_ring_count = new_rx_count;
+               goto clear_reset;
+       }
+
        if (adapter->num_tx_queues > adapter->num_rx_queues)
                temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring));
        else
                temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring));
-       if (!temp_ring)
-               return -ENOMEM;
 
-       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-               msleep(1);
+       if (!temp_ring) {
+               err = -ENOMEM;
+               goto clear_reset;
+       }
 
-       if (netif_running(adapter->netdev))
-               igb_down(adapter);
+       igb_down(adapter);
 
        /*
         * We can't just free everything and then setup again,
@@ -820,14 +832,11 @@ static int igb_set_ringparam(struct net_device *netdev,
 
                adapter->rx_ring_count = new_rx_count;
        }
-
-       err = 0;
 err_setup:
-       if (netif_running(adapter->netdev))
-               igb_up(adapter);
-
-       clear_bit(__IGB_RESETTING, &adapter->state);
+       igb_up(adapter);
        vfree(temp_ring);
+clear_reset:
+       clear_bit(__IGB_RESETTING, &adapter->state);
        return err;
 }
 
index ee17a09..c68265b 100644 (file)
@@ -279,7 +279,7 @@ static int igbvf_set_ringparam(struct net_device *netdev,
 {
        struct igbvf_adapter *adapter = netdev_priv(netdev);
        struct igbvf_ring *temp_ring;
-       int err;
+       int err = 0;
        u32 new_rx_count, new_tx_count;
 
        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
@@ -299,15 +299,22 @@ static int igbvf_set_ringparam(struct net_device *netdev,
                return 0;
        }
 
-       temp_ring = vmalloc(sizeof(struct igbvf_ring));
-       if (!temp_ring)
-               return -ENOMEM;
-
        while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
                msleep(1);
 
-       if (netif_running(adapter->netdev))
-               igbvf_down(adapter);
+       if (!netif_running(adapter->netdev)) {
+               adapter->tx_ring->count = new_tx_count;
+               adapter->rx_ring->count = new_rx_count;
+               goto clear_reset;
+       }
+
+       temp_ring = vmalloc(sizeof(struct igbvf_ring));
+       if (!temp_ring) {
+               err = -ENOMEM;
+               goto clear_reset;
+       }
+
+       igbvf_down(adapter);
 
        /*
         * We can't just free everything and then setup again,
@@ -339,14 +346,11 @@ static int igbvf_set_ringparam(struct net_device *netdev,
 
                memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring));
        }
-
-       err = 0;
 err_setup:
-       if (netif_running(adapter->netdev))
-               igbvf_up(adapter);
-
-       clear_bit(__IGBVF_RESETTING, &adapter->state);
+       igbvf_up(adapter);
        vfree(temp_ring);
+clear_reset:
+       clear_bit(__IGBVF_RESETTING, &adapter->state);
        return err;
 }
 
index 38bf7cf..c412e80 100644 (file)
@@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
        /*
         * Ensure that the ports for this device are setup correctly.
         */
-       if (si->pdata->startup)
-               si->pdata->startup(si->dev);
+       if (si->pdata->startup) {
+               ret = si->pdata->startup(si->dev);
+               if (ret)
+                       return ret;
+       }
 
        /*
         * Configure PPC for IRDA - we want to drive TXD2 low.
index fa314cb..856c18c 100644 (file)
@@ -798,7 +798,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_ring *temp_tx_ring, *temp_rx_ring;
-       int i, err;
+       int i, err = 0;
        u32 new_rx_count, new_tx_count;
        bool need_update = false;
 
@@ -822,6 +822,16 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
        while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
                msleep(1);
 
+       if (!netif_running(adapter->netdev)) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].count = new_tx_count;
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       adapter->rx_ring[i].count = new_rx_count;
+               adapter->tx_ring_count = new_tx_count;
+               adapter->rx_ring_count = new_rx_count;
+               goto err_setup;
+       }
+
        temp_tx_ring = kcalloc(adapter->num_tx_queues,
                               sizeof(struct ixgbe_ring), GFP_KERNEL);
        if (!temp_tx_ring) {
@@ -879,8 +889,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 
        /* if rings need to be updated, here's the place to do it in one shot */
        if (need_update) {
-               if (netif_running(netdev))
-                       ixgbe_down(adapter);
+               ixgbe_down(adapter);
 
                /* tx */
                if (new_tx_count != adapter->tx_ring_count) {
@@ -897,13 +906,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
                        temp_rx_ring = NULL;
                        adapter->rx_ring_count = new_rx_count;
                }
-       }
-
-       /* success! */
-       err = 0;
-       if (netif_running(netdev))
                ixgbe_up(adapter);
-
+       }
 err_setup:
        clear_bit(__IXGBE_RESETTING, &adapter->state);
        return err;
index b02a981..34a6cfd 100644 (file)
@@ -119,24 +119,9 @@ static struct ixp2400_msf_parameters enp2611_msf_parameters =
        }
 };
 
-struct enp2611_ixpdev_priv
-{
-       struct ixpdev_priv              ixpdev_priv;
-       struct net_device_stats         stats;
-};
-
 static struct net_device *nds[3];
 static struct timer_list link_check_timer;
 
-static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
-{
-       struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
-
-       pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
-
-       return &(ip->stats);
-}
-
 /* @@@ Poll the SFP moddef0 line too.  */
 /* @@@ Try to use the pm3386 DOOL interrupt as well.  */
 static void enp2611_check_link_status(unsigned long __dummy)
@@ -203,14 +188,13 @@ static int __init enp2611_init_module(void)
 
        ports = pm3386_port_count();
        for (i = 0; i < ports; i++) {
-               nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
+               nds[i] = ixpdev_alloc(i, sizeof(struct ixpdev_priv));
                if (nds[i] == NULL) {
                        while (--i >= 0)
                                free_netdev(nds[i]);
                        return -ENOMEM;
                }
 
-               nds[i]->get_stats = enp2611_get_stats;
                pm3386_init_port(i);
                pm3386_get_mac(i, nds[i]->dev_addr);
        }
index 1272434..9aee0cc 100644 (file)
@@ -21,6 +21,7 @@
 #include "ixp2400_tx.ucode"
 #include "ixpdev_priv.h"
 #include "ixpdev.h"
+#include "pm3386.h"
 
 #define DRV_MODULE_VERSION     "0.2"
 
@@ -271,6 +272,15 @@ static int ixpdev_close(struct net_device *dev)
        return 0;
 }
 
+static struct net_device_stats *ixpdev_get_stats(struct net_device *dev)
+{
+       struct ixpdev_priv *ip = netdev_priv(dev);
+
+       pm3386_get_stats(ip->channel, &(dev->stats));
+
+       return &(dev->stats);
+}
+
 static const struct net_device_ops ixpdev_netdev_ops = {
        .ndo_open               = ixpdev_open,
        .ndo_stop               = ixpdev_close,
@@ -278,6 +288,7 @@ static const struct net_device_ops ixpdev_netdev_ops = {
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_get_stats          = ixpdev_get_stats,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = ixpdev_poll_controller,
 #endif
index 2378358..a23f739 100644 (file)
@@ -170,6 +170,36 @@ static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val)
                ks_err(ks, "spi_sync() failed\n");
 }
 
+/**
+ * ks8851_wrreg8 - write 8bit register value to chip
+ * @ks: The chip state
+ * @reg: The register address
+ * @val: The value to write
+ *
+ * Issue a write to put the value @val into the register specified in @reg.
+ */
+static void ks8851_wrreg8(struct ks8851_net *ks, unsigned reg, unsigned val)
+{
+       struct spi_transfer *xfer = &ks->spi_xfer1;
+       struct spi_message *msg = &ks->spi_msg1;
+       __le16 txb[2];
+       int ret;
+       int bit;
+
+       bit = 1 << (reg & 3);
+
+       txb[0] = cpu_to_le16(MK_OP(bit, reg) | KS_SPIOP_WR);
+       txb[1] = val;
+
+       xfer->tx_buf = txb;
+       xfer->rx_buf = NULL;
+       xfer->len = 3;
+
+       ret = spi_sync(ks->spidev, msg);
+       if (ret < 0)
+               ks_err(ks, "spi_sync() failed\n");
+}
+
 /**
  * ks8851_rx_1msg - select whether to use one or two messages for spi read
  * @ks: The device structure
@@ -322,13 +352,12 @@ static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op)
 static int ks8851_write_mac_addr(struct net_device *dev)
 {
        struct ks8851_net *ks = netdev_priv(dev);
-       u16 *mcp = (u16 *)dev->dev_addr;
+       int i;
 
        mutex_lock(&ks->lock);
 
-       ks8851_wrreg16(ks, KS_MARL, mcp[0]);
-       ks8851_wrreg16(ks, KS_MARM, mcp[1]);
-       ks8851_wrreg16(ks, KS_MARH, mcp[2]);
+       for (i = 0; i < ETH_ALEN; i++)
+               ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]);
 
        mutex_unlock(&ks->lock);
 
@@ -951,7 +980,7 @@ static void ks8851_set_rx_mode(struct net_device *dev)
                        mcptr = mcptr->next;
                }
 
-               rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA;
+               rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA;
        } else {
                /* just accept broadcast / unicast */
                rxctrl.rxcr1 = RXCR1_RXPAFMA;
@@ -1239,6 +1268,9 @@ static int __devinit ks8851_probe(struct spi_device *spi)
        ndev->netdev_ops = &ks8851_netdev_ops;
        ndev->irq = spi->irq;
 
+       /* issue a global soft reset to reset the device. */
+       ks8851_soft_reset(ks, GRR_GSR);
+
        /* simple check for a valid chip being connected to the bus */
 
        if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
index 85abe14..f52c312 100644 (file)
@@ -16,6 +16,7 @@
 #define CCR_32PIN                              (1 << 0)
 
 /* MAC address registers */
+#define KS_MAR(_m)                             0x15 - (_m)
 #define KS_MARL                                        0x10
 #define KS_MARM                                        0x12
 #define KS_MARH                                        0x14
index 5dd7225..291a505 100644 (file)
@@ -1282,6 +1282,7 @@ static struct pci_device_id mlx4_pci_table[] = {
        { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
        { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
        { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/
+       { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */
        { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */
        { 0, }
 };
index 6930c87..f362451 100644 (file)
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.5.0-1.432"
+#define MYRI10GE_VERSION_STR "1.5.1-1.451"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -1624,10 +1624,21 @@ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
                        return 0;
                }
        }
-       if (*ptr == 'R' || *ptr == 'Q') {
-               /* We've found either an XFP or quad ribbon fiber */
+       if (*ptr == '2')
+               ptr++;
+       if (*ptr == 'R' || *ptr == 'Q' || *ptr == 'S') {
+               /* We've found either an XFP, quad ribbon fiber, or SFP+ */
                cmd->port = PORT_FIBRE;
+               cmd->supported |= SUPPORTED_FIBRE;
+               cmd->advertising |= ADVERTISED_FIBRE;
+       } else {
+               cmd->port = PORT_OTHER;
        }
+       if (*ptr == 'R' || *ptr == 'S')
+               cmd->transceiver = XCVR_EXTERNAL;
+       else
+               cmd->transceiver = XCVR_INTERNAL;
+
        return 0;
 }
 
index 7a71774..1c46da6 100644 (file)
@@ -419,6 +419,7 @@ enum {
 #define NETXEN_CRB_ROMUSB      \
        NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB)
 #define NETXEN_CRB_I2Q         NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q)
+#define NETXEN_CRB_I2C0                NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2C0)
 #define NETXEN_CRB_SMB         NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SMB)
 #define NETXEN_CRB_MAX         NETXEN_PCI_CRB_WINDOW(64)
 
index 3231400..3185a98 100644 (file)
@@ -1901,22 +1901,16 @@ netxen_setup_hwops(struct netxen_adapter *adapter)
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 {
-       int offset, board_type, magic, header_version;
+       int offset, board_type, magic;
        struct pci_dev *pdev = adapter->pdev;
 
        offset = NX_FW_MAGIC_OFFSET;
        if (netxen_rom_fast_read(adapter, offset, &magic))
                return -EIO;
 
-       offset = NX_HDR_VERSION_OFFSET;
-       if (netxen_rom_fast_read(adapter, offset, &header_version))
-               return -EIO;
-
-       if (magic != NETXEN_BDINFO_MAGIC ||
-                       header_version != NETXEN_BDINFO_VERSION) {
-               dev_err(&pdev->dev,
-                       "invalid board config, magic=%08x, version=%08x\n",
-                       magic, header_version);
+       if (magic != NETXEN_BDINFO_MAGIC) {
+               dev_err(&pdev->dev, "invalid board config, magic=%08x\n",
+                       magic);
                return -EIO;
        }
 
index 91c2bc6..e40b914 100644 (file)
@@ -531,6 +531,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                        continue;
 
                if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+                       if (off == (NETXEN_CRB_I2C0 + 0x1c))
+                               continue;
                        /* do not reset PCI */
                        if (off == (ROMUSB_GLB + 0xbc))
                                continue;
@@ -553,12 +555,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                                continue;
                }
 
-               if (off == NETXEN_ADDR_ERROR) {
-                       printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n",
-                                       netxen_nic_driver_name, buf[i].addr);
-                       continue;
-               }
-
                init_delay = 1;
                /* After writing this register, HW needs time for CRB */
                /* to quiet down (else crb_window returns 0xffffffff) */
index 9b9eab1..0b4a56a 100644 (file)
@@ -595,7 +595,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
        void __iomem *mem_ptr2 = NULL;
        void __iomem *db_ptr = NULL;
 
-       unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
+       resource_size_t mem_base, db_base;
+       unsigned long mem_len, db_len = 0, pci_len0 = 0;
 
        struct pci_dev *pdev = adapter->pdev;
        int pci_func = adapter->ahw.pci_func;
@@ -1918,6 +1919,7 @@ static void netxen_tx_timeout_task(struct work_struct *work)
 
 request_reset:
        adapter->need_fw_reset = 1;
+       clear_bit(__NX_RESETTING, &adapter->state);
 }
 
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
index f9364d0..d6c7ac6 100644 (file)
@@ -3545,7 +3545,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
        rp->rcr_index = index;
 
        skb_reserve(skb, NET_IP_ALIGN);
-       __pskb_pull_tail(skb, min(len, NIU_RXPULL_MAX));
+       __pskb_pull_tail(skb, min(len, VLAN_ETH_HLEN));
 
        rp->rx_packets++;
        rp->rx_bytes += skb->len;
index ee8ad3e..b58965a 100644 (file)
@@ -251,6 +251,7 @@ static void el3_tx_timeout(struct net_device *dev);
 static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static const struct ethtool_ops netdev_ethtool_ops;
 static void set_rx_mode(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
 
 static void tc574_detach(struct pcmcia_device *p_dev);
 
@@ -266,7 +267,7 @@ static const struct net_device_ops el3_netdev_ops = {
        .ndo_tx_timeout         = el3_tx_timeout,
        .ndo_get_stats          = el3_get_stats,
        .ndo_do_ioctl           = el3_ioctl,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_multicast_list = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
@@ -1161,6 +1162,16 @@ static void set_rx_mode(struct net_device *dev)
                outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
 }
 
+static void set_multicast_list(struct net_device *dev)
+{
+       struct el3_private *lp = netdev_priv(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&lp->window_lock, flags);
+       set_rx_mode(dev);
+       spin_unlock_irqrestore(&lp->window_lock, flags);
+}
+
 static int el3_close(struct net_device *dev)
 {
        unsigned int ioaddr = dev->base_addr;
index 250e10f..8659d34 100644 (file)
@@ -238,6 +238,7 @@ static struct of_device_id mdio_ofgpio_match[] = {
        },
        {},
 };
+MODULE_DEVICE_TABLE(of, mdio_ofgpio_match);
 
 static struct of_platform_driver mdio_ofgpio_driver = {
        .name = "mdio-gpio",
index 7cbf6f9..2559991 100644 (file)
@@ -111,9 +111,6 @@ struct pppoe_net {
        rwlock_t hash_lock;
 };
 
-/* to eliminate a race btw pppoe_flush_dev and pppoe_release */
-static DEFINE_SPINLOCK(flush_lock);
-
 /*
  * PPPoE could be in the following stages:
  * 1) Discovery stage (to obtain remote MAC and Session ID)
@@ -303,45 +300,48 @@ static void pppoe_flush_dev(struct net_device *dev)
        write_lock_bh(&pn->hash_lock);
        for (i = 0; i < PPPOE_HASH_SIZE; i++) {
                struct pppox_sock *po = pn->hash_table[i];
+               struct sock *sk;
 
-               while (po != NULL) {
-                       struct sock *sk;
-                       if (po->pppoe_dev != dev) {
+               while (po) {
+                       while (po && po->pppoe_dev != dev) {
                                po = po->next;
-                               continue;
                        }
+
+                       if (!po)
+                               break;
+
                        sk = sk_pppox(po);
-                       spin_lock(&flush_lock);
-                       po->pppoe_dev = NULL;
-                       spin_unlock(&flush_lock);
-                       dev_put(dev);
 
                        /* We always grab the socket lock, followed by the
-                        * hash_lock, in that order.  Since we should
-                        * hold the sock lock while doing any unbinding,
-                        * we need to release the lock we're holding.
-                        * Hold a reference to the sock so it doesn't disappear
-                        * as we're jumping between locks.
+                        * hash_lock, in that order.  Since we should hold the
+                        * sock lock while doing any unbinding, we need to
+                        * release the lock we're holding.  Hold a reference to
+                        * the sock so it doesn't disappear as we're jumping
+                        * between locks.
                         */
 
                        sock_hold(sk);
-
                        write_unlock_bh(&pn->hash_lock);
                        lock_sock(sk);
 
-                       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+                       if (po->pppoe_dev == dev
+                           && sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
                                pppox_unbind_sock(sk);
                                sk->sk_state = PPPOX_ZOMBIE;
                                sk->sk_state_change(sk);
+                               po->pppoe_dev = NULL;
+                               dev_put(dev);
                        }
 
                        release_sock(sk);
                        sock_put(sk);
 
-                       /* Restart scan at the beginning of this hash chain.
-                        * While the lock was dropped the chain contents may
-                        * have changed.
+                       /* Restart the process from the start of the current
+                        * hash chain. We dropped locks so the world may have
+                        * change from underneath us.
                         */
+
+                       BUG_ON(pppoe_pernet(dev_net(dev)) == NULL);
                        write_lock_bh(&pn->hash_lock);
                        po = pn->hash_table[i];
                }
@@ -388,11 +388,16 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
        struct pppox_sock *po = pppox_sk(sk);
        struct pppox_sock *relay_po;
 
+       /* Backlog receive. Semantics of backlog rcv preclude any code from
+        * executing in lock_sock()/release_sock() bounds; meaning sk->sk_state
+        * can't change.
+        */
+
        if (sk->sk_state & PPPOX_BOUND) {
                ppp_input(&po->chan, skb);
        } else if (sk->sk_state & PPPOX_RELAY) {
-               relay_po = get_item_by_addr(dev_net(po->pppoe_dev),
-                                               &po->pppoe_relay);
+               relay_po = get_item_by_addr(sock_net(sk),
+                                           &po->pppoe_relay);
                if (relay_po == NULL)
                        goto abort_kfree;
 
@@ -447,6 +452,10 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
                goto drop;
 
        pn = pppoe_pernet(dev_net(dev));
+
+       /* Note that get_item does a sock_hold(), so sk_pppox(po)
+        * is known to be safe.
+        */
        po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
        if (!po)
                goto drop;
@@ -561,6 +570,7 @@ static int pppoe_release(struct socket *sock)
        struct sock *sk = sock->sk;
        struct pppox_sock *po;
        struct pppoe_net *pn;
+       struct net *net = NULL;
 
        if (!sk)
                return 0;
@@ -571,44 +581,28 @@ static int pppoe_release(struct socket *sock)
                return -EBADF;
        }
 
+       po = pppox_sk(sk);
+
+       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+               dev_put(po->pppoe_dev);
+               po->pppoe_dev = NULL;
+       }
+
        pppox_unbind_sock(sk);
 
        /* Signal the death of the socket. */
        sk->sk_state = PPPOX_DEAD;
 
-       /*
-        * pppoe_flush_dev could lead to a race with
-        * this routine so we use flush_lock to eliminate
-        * such a case (we only need per-net specific data)
-        */
-       spin_lock(&flush_lock);
-       po = pppox_sk(sk);
-       if (!po->pppoe_dev) {
-               spin_unlock(&flush_lock);
-               goto out;
-       }
-       pn = pppoe_pernet(dev_net(po->pppoe_dev));
-       spin_unlock(&flush_lock);
+       net = sock_net(sk);
+       pn = pppoe_pernet(net);
 
        /*
         * protect "po" from concurrent updates
         * on pppoe_flush_dev
         */
-       write_lock_bh(&pn->hash_lock);
+       delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
+                   po->pppoe_ifindex);
 
-       po = pppox_sk(sk);
-       if (stage_session(po->pppoe_pa.sid))
-               __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
-                               po->pppoe_ifindex);
-
-       if (po->pppoe_dev) {
-               dev_put(po->pppoe_dev);
-               po->pppoe_dev = NULL;
-       }
-
-       write_unlock_bh(&pn->hash_lock);
-
-out:
        sock_orphan(sk);
        sock->sk = NULL;
 
@@ -625,8 +619,9 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
        struct sock *sk = sock->sk;
        struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
        struct pppox_sock *po = pppox_sk(sk);
-       struct net_device *dev;
+       struct net_device *dev = NULL;
        struct pppoe_net *pn;
+       struct net *net = NULL;
        int error;
 
        lock_sock(sk);
@@ -652,12 +647,14 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
        /* Delete the old binding */
        if (stage_session(po->pppoe_pa.sid)) {
                pppox_unbind_sock(sk);
+               pn = pppoe_pernet(sock_net(sk));
+               delete_item(pn, po->pppoe_pa.sid,
+                           po->pppoe_pa.remote, po->pppoe_ifindex);
                if (po->pppoe_dev) {
-                       pn = pppoe_pernet(dev_net(po->pppoe_dev));
-                       delete_item(pn, po->pppoe_pa.sid,
-                               po->pppoe_pa.remote, po->pppoe_ifindex);
                        dev_put(po->pppoe_dev);
+                       po->pppoe_dev = NULL;
                }
+
                memset(sk_pppox(po) + 1, 0,
                       sizeof(struct pppox_sock) - sizeof(struct sock));
                sk->sk_state = PPPOX_NONE;
@@ -666,16 +663,15 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
        /* Re-bind in session stage only */
        if (stage_session(sp->sa_addr.pppoe.sid)) {
                error = -ENODEV;
-               dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev);
+               net = sock_net(sk);
+               dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev);
                if (!dev)
-                       goto end;
+                       goto err_put;
 
                po->pppoe_dev = dev;
                po->pppoe_ifindex = dev->ifindex;
-               pn = pppoe_pernet(dev_net(dev));
-               write_lock_bh(&pn->hash_lock);
+               pn = pppoe_pernet(net);
                if (!(dev->flags & IFF_UP)) {
-                       write_unlock_bh(&pn->hash_lock);
                        goto err_put;
                }
 
@@ -683,6 +679,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
                       &sp->sa_addr.pppoe,
                       sizeof(struct pppoe_addr));
 
+               write_lock_bh(&pn->hash_lock);
                error = __set_item(pn, po);
                write_unlock_bh(&pn->hash_lock);
                if (error < 0)
@@ -696,8 +693,11 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
                po->chan.ops = &pppoe_chan_ops;
 
                error = ppp_register_net_channel(dev_net(dev), &po->chan);
-               if (error)
+               if (error) {
+                       delete_item(pn, po->pppoe_pa.sid,
+                                   po->pppoe_pa.remote, po->pppoe_ifindex);
                        goto err_put;
+               }
 
                sk->sk_state = PPPOX_CONNECTED;
        }
@@ -915,6 +915,14 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
        struct pppoe_hdr *ph;
        int data_len = skb->len;
 
+       /* The higher-level PPP code (ppp_unregister_channel()) ensures the PPP
+        * xmit operations conclude prior to an unregistration call.  Thus
+        * sk->sk_state cannot change, so we don't need to do lock_sock().
+        * But, we also can't do a lock_sock since that introduces a potential
+        * deadlock as we'd reverse the lock ordering used when calling
+        * ppp_unregister_channel().
+        */
+
        if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
                goto abort;
 
@@ -944,7 +952,6 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
                        po->pppoe_pa.remote, NULL, data_len);
 
        dev_queue_xmit(skb);
-
        return 1;
 
 abort:
index 3ec6e85..c2383ad 100644 (file)
@@ -95,6 +95,7 @@ enum {
 
        /* Misc. stuff */
        MAILBOX_COUNT = 16,
+       MAILBOX_TIMEOUT = 5,
 
        PROC_ADDR_RDY = (1 << 31),
        PROC_ADDR_R = (1 << 30),
@@ -803,6 +804,12 @@ enum {
        MB_CMD_SET_PORT_CFG = 0x00000122,
        MB_CMD_GET_PORT_CFG = 0x00000123,
        MB_CMD_GET_LINK_STS = 0x00000124,
+       MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
+       MB_SET_MPI_TFK_STOP = (1 << 0),
+       MB_SET_MPI_TFK_RESUME = (1 << 1),
+       MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
+       MB_GET_MPI_TFK_STOPPED = (1 << 0),
+       MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
 
        /* Mailbox Command Status. */
        MB_CMD_STS_GOOD = 0x00004000,   /* Success. */
@@ -1168,7 +1175,7 @@ struct ricb {
 #define RSS_RI6 0x40
 #define RSS_RT6 0x80
        __le16 mask;
-       __le32 hash_cq_id[256];
+       u8 hash_cq_id[1024];
        __le32 ipv6_hash_key[10];
        __le32 ipv4_hash_key[4];
 } __attribute((packed));
@@ -1606,6 +1613,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
 int ql_mb_about_fw(struct ql_adapter *qdev);
 void ql_link_on(struct ql_adapter *qdev);
 void ql_link_off(struct ql_adapter *qdev);
+int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
+int ql_wait_fifo_empty(struct ql_adapter *qdev);
 
 #if 1
 #define QL_ALL_DUMP
index 6168071..cea7531 100644 (file)
@@ -320,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
 
        switch (type) {
        case MAC_ADDR_TYPE_MULTI_MAC:
+               {
+                       u32 upper = (addr[0] << 8) | addr[1];
+                       u32 lower = (addr[2] << 24) | (addr[3] << 16) |
+                                       (addr[4] << 8) | (addr[5]);
+
+                       status =
+                               ql_wait_reg_rdy(qdev,
+                               MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+                       if (status)
+                               goto exit;
+                       ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
+                               (index << MAC_ADDR_IDX_SHIFT) |
+                               type | MAC_ADDR_E);
+                       ql_write32(qdev, MAC_ADDR_DATA, lower);
+                       status =
+                               ql_wait_reg_rdy(qdev,
+                               MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+                       if (status)
+                               goto exit;
+                       ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
+                               (index << MAC_ADDR_IDX_SHIFT) |
+                               type | MAC_ADDR_E);
+
+                       ql_write32(qdev, MAC_ADDR_DATA, upper);
+                       status =
+                               ql_wait_reg_rdy(qdev,
+                               MAC_ADDR_IDX, MAC_ADDR_MW, 0);
+                       if (status)
+                               goto exit;
+                       break;
+               }
        case MAC_ADDR_TYPE_CAM_MAC:
                {
                        u32 cam_output;
@@ -365,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
                           and possibly the function id.  Right now we hardcode
                           the route field to NIC core.
                         */
-                       if (type == MAC_ADDR_TYPE_CAM_MAC) {
-                               cam_output = (CAM_OUT_ROUTE_NIC |
-                                             (qdev->
-                                              func << CAM_OUT_FUNC_SHIFT) |
-                                               (0 << CAM_OUT_CQ_ID_SHIFT));
-                               if (qdev->vlgrp)
-                                       cam_output |= CAM_OUT_RV;
-                               /* route to NIC core */
-                               ql_write32(qdev, MAC_ADDR_DATA, cam_output);
-                       }
+                       cam_output = (CAM_OUT_ROUTE_NIC |
+                                     (qdev->
+                                      func << CAM_OUT_FUNC_SHIFT) |
+                                       (0 << CAM_OUT_CQ_ID_SHIFT));
+                       if (qdev->vlgrp)
+                               cam_output |= CAM_OUT_RV;
+                       /* route to NIC core */
+                       ql_write32(qdev, MAC_ADDR_DATA, cam_output);
                        break;
                }
        case MAC_ADDR_TYPE_VLAN:
@@ -546,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
                }
        case RT_IDX_MCAST:      /* Pass up All Multicast frames. */
                {
-                       value = RT_IDX_DST_CAM_Q |      /* dest */
+                       value = RT_IDX_DST_DFLT_Q |     /* dest */
                            RT_IDX_TYPE_NICQ |  /* type */
                            (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */
                        break;
                }
        case RT_IDX_MCAST_MATCH:        /* Pass up matched Multicast frames. */
                {
-                       value = RT_IDX_DST_CAM_Q |      /* dest */
+                       value = RT_IDX_DST_DFLT_Q |     /* dest */
                            RT_IDX_TYPE_NICQ |  /* type */
                            (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */
                        break;
@@ -3077,6 +3106,12 @@ err_irq:
 
 static int ql_start_rss(struct ql_adapter *qdev)
 {
+       u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+                               0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
+                               0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
+                               0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
+                               0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
+                               0xbe, 0xac, 0x01, 0xfa};
        struct ricb *ricb = &qdev->ricb;
        int status = 0;
        int i;
@@ -3086,21 +3121,17 @@ static int ql_start_rss(struct ql_adapter *qdev)
 
        ricb->base_cq = RSS_L4K;
        ricb->flags =
-           (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 |
-            RSS_RT6);
-       ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1);
+               (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6);
+       ricb->mask = cpu_to_le16((u16)(0x3ff));
 
        /*
         * Fill out the Indirection Table.
         */
-       for (i = 0; i < 256; i++)
-               hash_id[i] = i & (qdev->rss_ring_count - 1);
+       for (i = 0; i < 1024; i++)
+               hash_id[i] = (i & (qdev->rss_ring_count - 1));
 
-       /*
-        * Random values for the IPv6 and IPv4 Hash Keys.
-        */
-       get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
-       get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
+       memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
+       memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
 
        QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
 
@@ -3239,6 +3270,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
        ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
                min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
 
+       /* Set RX packet routing to use port/pci function on which the
+        * packet arrived on in addition to usual frame routing.
+        * This is helpful on bonding where both interfaces can have
+        * the same MAC address.
+        */
+       ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
+
        /* Start up the rx queues. */
        for (i = 0; i < qdev->rx_ring_count; i++) {
                status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
@@ -3311,6 +3349,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
 
        end_jiffies = jiffies +
                max((unsigned long)1, usecs_to_jiffies(30));
+
+       /* Stop management traffic. */
+       ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
+
+       /* Wait for the NIC and MGMNT FIFOs to empty. */
+       ql_wait_fifo_empty(qdev);
+
        ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
 
        do {
@@ -3326,6 +3371,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
                status = -ETIMEDOUT;
        }
 
+       /* Resume management traffic. */
+       ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME);
        return status;
 }
 
@@ -3704,6 +3751,12 @@ static void ql_asic_reset_work(struct work_struct *work)
        status = ql_adapter_up(qdev);
        if (status)
                goto error;
+
+       /* Restore rx mode. */
+       clear_bit(QL_ALLMULTI, &qdev->flags);
+       clear_bit(QL_PROMISCUOUS, &qdev->flags);
+       qlge_set_multicast_list(qdev->ndev);
+
        rtnl_unlock();
        return;
 error:
@@ -3863,6 +3916,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
                goto err_out;
        }
 
+       pci_save_state(pdev);
        qdev->reg_base =
            ioremap_nocache(pci_resource_start(pdev, 1),
                            pci_resource_len(pdev, 1));
@@ -4017,6 +4071,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
        free_netdev(ndev);
 }
 
+/* Clean up resources without touching hardware. */
+static void ql_eeh_close(struct net_device *ndev)
+{
+       int i;
+       struct ql_adapter *qdev = netdev_priv(ndev);
+
+       if (netif_carrier_ok(ndev)) {
+               netif_carrier_off(ndev);
+               netif_stop_queue(ndev);
+       }
+
+       if (test_bit(QL_ADAPTER_UP, &qdev->flags))
+               cancel_delayed_work_sync(&qdev->asic_reset_work);
+       cancel_delayed_work_sync(&qdev->mpi_reset_work);
+       cancel_delayed_work_sync(&qdev->mpi_work);
+       cancel_delayed_work_sync(&qdev->mpi_idc_work);
+       cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+
+       for (i = 0; i < qdev->rss_ring_count; i++)
+               netif_napi_del(&qdev->rx_ring[i].napi);
+
+       clear_bit(QL_ADAPTER_UP, &qdev->flags);
+       ql_tx_ring_clean(qdev);
+       ql_free_rx_buffers(qdev);
+       ql_release_adapter_resources(qdev);
+}
+
 /*
  * This callback is called by the PCI subsystem whenever
  * a PCI bus error is detected.
@@ -4025,17 +4106,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
                                               enum pci_channel_state state)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
-       struct ql_adapter *qdev = netdev_priv(ndev);
 
-       netif_device_detach(ndev);
-
-       if (state == pci_channel_io_perm_failure)
+       switch (state) {
+       case pci_channel_io_normal:
+               return PCI_ERS_RESULT_CAN_RECOVER;
+       case pci_channel_io_frozen:
+               netif_device_detach(ndev);
+               if (netif_running(ndev))
+                       ql_eeh_close(ndev);
+               pci_disable_device(pdev);
+               return PCI_ERS_RESULT_NEED_RESET;
+       case pci_channel_io_perm_failure:
+               dev_err(&pdev->dev,
+                       "%s: pci_channel_io_perm_failure.\n", __func__);
                return PCI_ERS_RESULT_DISCONNECT;
-
-       if (netif_running(ndev))
-               ql_adapter_down(qdev);
-
-       pci_disable_device(pdev);
+       }
 
        /* Request a slot reset. */
        return PCI_ERS_RESULT_NEED_RESET;
@@ -4052,25 +4137,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
        struct net_device *ndev = pci_get_drvdata(pdev);
        struct ql_adapter *qdev = netdev_priv(ndev);
 
+       pdev->error_state = pci_channel_io_normal;
+
+       pci_restore_state(pdev);
        if (pci_enable_device(pdev)) {
                QPRINTK(qdev, IFUP, ERR,
                        "Cannot re-enable PCI device after reset.\n");
                return PCI_ERS_RESULT_DISCONNECT;
        }
-
        pci_set_master(pdev);
-
-       netif_carrier_off(ndev);
-       ql_adapter_reset(qdev);
-
-       /* Make sure the EEPROM is good */
-       memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
-
-       if (!is_valid_ether_addr(ndev->perm_addr)) {
-               QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n");
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
-
        return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -4078,17 +4153,21 @@ static void qlge_io_resume(struct pci_dev *pdev)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
        struct ql_adapter *qdev = netdev_priv(ndev);
+       int err = 0;
 
-       pci_set_master(pdev);
-
+       if (ql_adapter_reset(qdev))
+               QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
        if (netif_running(ndev)) {
-               if (ql_adapter_up(qdev)) {
+               err = qlge_open(ndev);
+               if (err) {
                        QPRINTK(qdev, IFUP, ERR,
                                "Device initialization failed after reset.\n");
                        return;
                }
+       } else {
+               QPRINTK(qdev, IFUP, ERR,
+                       "Device was not running prior to EEH.\n");
        }
-
        netif_device_attach(ndev);
 }
 
index c2e4307..bcf13c9 100644 (file)
@@ -470,7 +470,8 @@ end:
  */
 static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
-       int status, count;
+       int status;
+       unsigned long count;
 
 
        /* Begin polled mode for MPI */
@@ -491,9 +492,9 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
        /* Wait for the command to complete. We loop
         * here because some AEN might arrive while
         * we're waiting for the mailbox command to
-        * complete. If more than 5 arrive then we can
+        * complete. If more than 5 seconds expire we can
         * assume something is wrong. */
-       count = 5;
+       count = jiffies + HZ * MAILBOX_TIMEOUT;
        do {
                /* Wait for the interrupt to come in. */
                status = ql_wait_mbx_cmd_cmplt(qdev);
@@ -517,15 +518,15 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
                                        MB_CMD_STS_GOOD) ||
                        ((mbcp->mbox_out[0] & 0x0000f000) ==
                                        MB_CMD_STS_INTRMDT))
-                       break;
-       } while (--count);
+                       goto done;
+       } while (time_before(jiffies, count));
 
-       if (!count) {
-               QPRINTK(qdev, DRV, ERR,
-                       "Timed out waiting for mailbox complete.\n");
-               status = -ETIMEDOUT;
-               goto end;
-       }
+       QPRINTK(qdev, DRV, ERR,
+               "Timed out waiting for mailbox complete.\n");
+       status = -ETIMEDOUT;
+       goto end;
+
+done:
 
        /* Now we can clear the interrupt condition
         * and look at our status.
@@ -768,6 +769,95 @@ static int ql_idc_wait(struct ql_adapter *qdev)
        return status;
 }
 
+int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
+{
+       struct mbox_params mbc;
+       struct mbox_params *mbcp = &mbc;
+       int status;
+
+       memset(mbcp, 0, sizeof(struct mbox_params));
+
+       mbcp->in_count = 1;
+       mbcp->out_count = 2;
+
+       mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL;
+       mbcp->mbox_in[1] = control;
+
+       status = ql_mailbox_command(qdev, mbcp);
+       if (status)
+               return status;
+
+       if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD)
+               return status;
+
+       if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
+               QPRINTK(qdev, DRV, ERR,
+                       "Command not supported by firmware.\n");
+               status = -EINVAL;
+       } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
+               /* This indicates that the firmware is
+                * already in the state we are trying to
+                * change it to.
+                */
+               QPRINTK(qdev, DRV, ERR,
+                       "Command parameters make no change.\n");
+       }
+       return status;
+}
+
+/* Returns a negative error code or the mailbox command status. */
+static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control)
+{
+       struct mbox_params mbc;
+       struct mbox_params *mbcp = &mbc;
+       int status;
+
+       memset(mbcp, 0, sizeof(struct mbox_params));
+       *control = 0;
+
+       mbcp->in_count = 1;
+       mbcp->out_count = 1;
+
+       mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL;
+
+       status = ql_mailbox_command(qdev, mbcp);
+       if (status)
+               return status;
+
+       if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) {
+               *control = mbcp->mbox_in[1];
+               return status;
+       }
+
+       if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
+               QPRINTK(qdev, DRV, ERR,
+                       "Command not supported by firmware.\n");
+               status = -EINVAL;
+       } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
+               QPRINTK(qdev, DRV, ERR,
+                       "Failed to get MPI traffic control.\n");
+               status = -EIO;
+       }
+       return status;
+}
+
+int ql_wait_fifo_empty(struct ql_adapter *qdev)
+{
+       int count = 5;
+       u32 mgmnt_fifo_empty;
+       u32 nic_fifo_empty;
+
+       do {
+               nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE;
+               ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty);
+               mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY;
+               if (nic_fifo_empty && mgmnt_fifo_empty)
+                       return 0;
+               msleep(100);
+       } while (count-- > 0);
+       return -ETIMEDOUT;
+}
+
 /* API called in work thread context to set new TX/RX
  * maximum frame size values to match MTU.
  */
@@ -876,6 +966,8 @@ void ql_mpi_work(struct work_struct *work)
        int err = 0;
 
        rtnl_lock();
+       /* Begin polled mode for MPI */
+       ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
 
        while (ql_read32(qdev, STS) & STS_PI) {
                memset(mbcp, 0, sizeof(struct mbox_params));
@@ -888,6 +980,8 @@ void ql_mpi_work(struct work_struct *work)
                        break;
        }
 
+       /* End polled mode for MPI */
+       ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
        rtnl_unlock();
        ql_enable_completion_interrupt(qdev, 0);
 }
index 50c6a3c..f98ef52 100644 (file)
@@ -115,7 +115,9 @@ enum mac_version {
        RTL_GIGA_MAC_VER_22 = 0x16, // 8168C
        RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP
        RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
-       RTL_GIGA_MAC_VER_25 = 0x19  // 8168D
+       RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
+       RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
+       RTL_GIGA_MAC_VER_27 = 0x1b  // 8168DP
 };
 
 #define _R(NAME,MAC,MASK) \
@@ -150,7 +152,9 @@ static const struct {
        _R("RTL8168c/8111c",    RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E
        _R("RTL8168cp/8111cp",  RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E
        _R("RTL8168cp/8111cp",  RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
-       _R("RTL8168d/8111d",    RTL_GIGA_MAC_VER_25, 0xff7e1880)  // PCI-E
+       _R("RTL8168d/8111d",    RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
+       _R("RTL8168d/8111d",    RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
+       _R("RTL8168dp/8111dp",  RTL_GIGA_MAC_VER_27, 0xff7e1880)  // PCI-E
 };
 #undef _R
 
@@ -253,6 +257,13 @@ enum rtl8168_8101_registers {
        DBG_REG                 = 0xd1,
 #define        FIX_NAK_1                       (1 << 4)
 #define        FIX_NAK_2                       (1 << 3)
+       EFUSEAR                 = 0xdc,
+#define        EFUSEAR_FLAG                    0x80000000
+#define        EFUSEAR_WRITE_CMD               0x80000000
+#define        EFUSEAR_READ_CMD                0x00000000
+#define        EFUSEAR_REG_MASK                0x03ff
+#define        EFUSEAR_REG_SHIFT               8
+#define        EFUSEAR_DATA_MASK               0xff
 };
 
 enum rtl_register_content {
@@ -568,6 +579,14 @@ static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
        mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
 }
 
+static void mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m)
+{
+       int val;
+
+       val = mdio_read(ioaddr, reg_addr);
+       mdio_write(ioaddr, reg_addr, (val | p) & ~m);
+}
+
 static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
                           int val)
 {
@@ -651,6 +670,24 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
        return value;
 }
 
+static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
+{
+       u8 value = 0xff;
+       unsigned int i;
+
+       RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
+
+       for (i = 0; i < 300; i++) {
+               if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
+                       value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
+                       break;
+               }
+               udelay(100);
+       }
+
+       return value;
+}
+
 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
 {
        RTL_W16(IntrMask, 0x0000);
@@ -992,7 +1029,10 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
 
        spin_lock_irqsave(&tp->lock, flags);
        tp->vlgrp = grp;
-       if (tp->vlgrp)
+       /*
+        * Do not disable RxVlan on 8110SCd.
+        */
+       if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05))
                tp->cp_cmd |= RxVlan;
        else
                tp->cp_cmd &= ~RxVlan;
@@ -1243,7 +1283,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
                int mac_version;
        } mac_info[] = {
                /* 8168D family. */
-               { 0x7c800000, 0x28000000,       RTL_GIGA_MAC_VER_25 },
+               { 0x7cf00000, 0x28300000,       RTL_GIGA_MAC_VER_26 },
+               { 0x7cf00000, 0x28100000,       RTL_GIGA_MAC_VER_25 },
+               { 0x7c800000, 0x28800000,       RTL_GIGA_MAC_VER_27 },
+               { 0x7c800000, 0x28000000,       RTL_GIGA_MAC_VER_26 },
 
                /* 8168C family. */
                { 0x7cf00000, 0x3ca00000,       RTL_GIGA_MAC_VER_24 },
@@ -1648,74 +1691,903 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
        rtl8168c_3_hw_phy_config(ioaddr);
 }
 
-static void rtl8168d_hw_phy_config(void __iomem *ioaddr)
+static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
 {
-       struct phy_reg phy_reg_init_0[] = {
+       static struct phy_reg phy_reg_init_0[] = {
                { 0x1f, 0x0001 },
-               { 0x09, 0x2770 },
-               { 0x08, 0x04d0 },
-               { 0x0b, 0xad15 },
-               { 0x0c, 0x5bf0 },
-               { 0x1c, 0xf101 },
+               { 0x06, 0x4064 },
+               { 0x07, 0x2863 },
+               { 0x08, 0x059c },
+               { 0x09, 0x26b4 },
+               { 0x0a, 0x6a19 },
+               { 0x0b, 0xdcc8 },
+               { 0x10, 0xf06d },
+               { 0x14, 0x7f68 },
+               { 0x18, 0x7fd9 },
+               { 0x1c, 0xf0ff },
+               { 0x1d, 0x3d9c },
                { 0x1f, 0x0003 },
-               { 0x14, 0x94d7 },
-               { 0x12, 0xf4d6 },
-               { 0x09, 0xca0f },
-               { 0x1f, 0x0002 },
-               { 0x0b, 0x0b10 },
-               { 0x0c, 0xd1f7 },
-               { 0x1f, 0x0002 },
-               { 0x06, 0x5461 },
+               { 0x12, 0xf49f },
+               { 0x13, 0x070b },
+               { 0x1a, 0x05ad },
+               { 0x14, 0x94c0 }
+       };
+       static struct phy_reg phy_reg_init_1[] = {
                { 0x1f, 0x0002 },
-               { 0x05, 0x6662 },
+               { 0x06, 0x5561 },
+               { 0x1f, 0x0005 },
+               { 0x05, 0x8332 },
+               { 0x06, 0x5561 }
+       };
+       static struct phy_reg phy_reg_init_2[] = {
+               { 0x1f, 0x0005 },
+               { 0x05, 0xffc2 },
+               { 0x1f, 0x0005 },
+               { 0x05, 0x8000 },
+               { 0x06, 0xf8f9 },
+               { 0x06, 0xfaef },
+               { 0x06, 0x59ee },
+               { 0x06, 0xf8ea },
+               { 0x06, 0x00ee },
+               { 0x06, 0xf8eb },
+               { 0x06, 0x00e0 },
+               { 0x06, 0xf87c },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x7d59 },
+               { 0x06, 0x0fef },
+               { 0x06, 0x0139 },
+               { 0x06, 0x029e },
+               { 0x06, 0x06ef },
+               { 0x06, 0x1039 },
+               { 0x06, 0x089f },
+               { 0x06, 0x2aee },
+               { 0x06, 0xf8ea },
+               { 0x06, 0x00ee },
+               { 0x06, 0xf8eb },
+               { 0x06, 0x01e0 },
+               { 0x06, 0xf87c },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x7d58 },
+               { 0x06, 0x409e },
+               { 0x06, 0x0f39 },
+               { 0x06, 0x46aa },
+               { 0x06, 0x0bbf },
+               { 0x06, 0x8290 },
+               { 0x06, 0xd682 },
+               { 0x06, 0x9802 },
+               { 0x06, 0x014f },
+               { 0x06, 0xae09 },
+               { 0x06, 0xbf82 },
+               { 0x06, 0x98d6 },
+               { 0x06, 0x82a0 },
+               { 0x06, 0x0201 },
+               { 0x06, 0x4fef },
+               { 0x06, 0x95fe },
+               { 0x06, 0xfdfc },
+               { 0x06, 0x05f8 },
+               { 0x06, 0xf9fa },
+               { 0x06, 0xeef8 },
+               { 0x06, 0xea00 },
+               { 0x06, 0xeef8 },
+               { 0x06, 0xeb00 },
+               { 0x06, 0xe2f8 },
+               { 0x06, 0x7ce3 },
+               { 0x06, 0xf87d },
+               { 0x06, 0xa511 },
+               { 0x06, 0x1112 },
+               { 0x06, 0xd240 },
+               { 0x06, 0xd644 },
+               { 0x06, 0x4402 },
+               { 0x06, 0x8217 },
+               { 0x06, 0xd2a0 },
+               { 0x06, 0xd6aa },
+               { 0x06, 0xaa02 },
+               { 0x06, 0x8217 },
+               { 0x06, 0xae0f },
+               { 0x06, 0xa544 },
+               { 0x06, 0x4402 },
+               { 0x06, 0xae4d },
+               { 0x06, 0xa5aa },
+               { 0x06, 0xaa02 },
+               { 0x06, 0xae47 },
+               { 0x06, 0xaf82 },
+               { 0x06, 0x13ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x00ee },
+               { 0x06, 0x834d },
+               { 0x06, 0x0fee },
+               { 0x06, 0x834c },
+               { 0x06, 0x0fee },
+               { 0x06, 0x834f },
+               { 0x06, 0x00ee },
+               { 0x06, 0x8351 },
+               { 0x06, 0x00ee },
+               { 0x06, 0x834a },
+               { 0x06, 0xffee },
+               { 0x06, 0x834b },
+               { 0x06, 0xffe0 },
+               { 0x06, 0x8330 },
+               { 0x06, 0xe183 },
+               { 0x06, 0x3158 },
+               { 0x06, 0xfee4 },
+               { 0x06, 0xf88a },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x8be0 },
+               { 0x06, 0x8332 },
+               { 0x06, 0xe183 },
+               { 0x06, 0x3359 },
+               { 0x06, 0x0fe2 },
+               { 0x06, 0x834d },
+               { 0x06, 0x0c24 },
+               { 0x06, 0x5af0 },
+               { 0x06, 0x1e12 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x8ce5 },
+               { 0x06, 0xf88d },
+               { 0x06, 0xaf82 },
+               { 0x06, 0x13e0 },
+               { 0x06, 0x834f },
+               { 0x06, 0x10e4 },
+               { 0x06, 0x834f },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x009f },
+               { 0x06, 0x0ae0 },
+               { 0x06, 0x834f },
+               { 0x06, 0xa010 },
+               { 0x06, 0xa5ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x01e0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7805 },
+               { 0x06, 0x9e9a },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x049e },
+               { 0x06, 0x10e0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7803 },
+               { 0x06, 0x9e0f },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x019e },
+               { 0x06, 0x05ae },
+               { 0x06, 0x0caf },
+               { 0x06, 0x81f8 },
+               { 0x06, 0xaf81 },
+               { 0x06, 0xa3af },
+               { 0x06, 0x81dc },
+               { 0x06, 0xaf82 },
+               { 0x06, 0x13ee },
+               { 0x06, 0x8348 },
+               { 0x06, 0x00ee },
+               { 0x06, 0x8349 },
+               { 0x06, 0x00e0 },
+               { 0x06, 0x8351 },
+               { 0x06, 0x10e4 },
+               { 0x06, 0x8351 },
+               { 0x06, 0x5801 },
+               { 0x06, 0x9fea },
+               { 0x06, 0xd000 },
+               { 0x06, 0xd180 },
+               { 0x06, 0x1f66 },
+               { 0x06, 0xe2f8 },
+               { 0x06, 0xeae3 },
+               { 0x06, 0xf8eb },
+               { 0x06, 0x5af8 },
+               { 0x06, 0x1e20 },
+               { 0x06, 0xe6f8 },
+               { 0x06, 0xeae5 },
+               { 0x06, 0xf8eb },
+               { 0x06, 0xd302 },
+               { 0x06, 0xb3fe },
+               { 0x06, 0xe2f8 },
+               { 0x06, 0x7cef },
+               { 0x06, 0x325b },
+               { 0x06, 0x80e3 },
+               { 0x06, 0xf87d },
+               { 0x06, 0x9e03 },
+               { 0x06, 0x7dff },
+               { 0x06, 0xff0d },
+               { 0x06, 0x581c },
+               { 0x06, 0x551a },
+               { 0x06, 0x6511 },
+               { 0x06, 0xa190 },
+               { 0x06, 0xd3e2 },
+               { 0x06, 0x8348 },
+               { 0x06, 0xe383 },
+               { 0x06, 0x491b },
+               { 0x06, 0x56ab },
+               { 0x06, 0x08ef },
+               { 0x06, 0x56e6 },
+               { 0x06, 0x8348 },
+               { 0x06, 0xe783 },
+               { 0x06, 0x4910 },
+               { 0x06, 0xd180 },
+               { 0x06, 0x1f66 },
+               { 0x06, 0xa004 },
+               { 0x06, 0xb9e2 },
+               { 0x06, 0x8348 },
+               { 0x06, 0xe383 },
+               { 0x06, 0x49ef },
+               { 0x06, 0x65e2 },
+               { 0x06, 0x834a },
+               { 0x06, 0xe383 },
+               { 0x06, 0x4b1b },
+               { 0x06, 0x56aa },
+               { 0x06, 0x0eef },
+               { 0x06, 0x56e6 },
+               { 0x06, 0x834a },
+               { 0x06, 0xe783 },
+               { 0x06, 0x4be2 },
+               { 0x06, 0x834d },
+               { 0x06, 0xe683 },
+               { 0x06, 0x4ce0 },
+               { 0x06, 0x834d },
+               { 0x06, 0xa000 },
+               { 0x06, 0x0caf },
+               { 0x06, 0x81dc },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4d10 },
+               { 0x06, 0xe483 },
+               { 0x06, 0x4dae },
+               { 0x06, 0x0480 },
+               { 0x06, 0xe483 },
+               { 0x06, 0x4de0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7803 },
+               { 0x06, 0x9e0b },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x049e },
+               { 0x06, 0x04ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x02e0 },
+               { 0x06, 0x8332 },
+               { 0x06, 0xe183 },
+               { 0x06, 0x3359 },
+               { 0x06, 0x0fe2 },
+               { 0x06, 0x834d },
+               { 0x06, 0x0c24 },
+               { 0x06, 0x5af0 },
+               { 0x06, 0x1e12 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x8ce5 },
+               { 0x06, 0xf88d },
+               { 0x06, 0xe083 },
+               { 0x06, 0x30e1 },
+               { 0x06, 0x8331 },
+               { 0x06, 0x6801 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x8ae5 },
+               { 0x06, 0xf88b },
+               { 0x06, 0xae37 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e03 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4ce1 },
+               { 0x06, 0x834d },
+               { 0x06, 0x1b01 },
+               { 0x06, 0x9e04 },
+               { 0x06, 0xaaa1 },
+               { 0x06, 0xaea8 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e04 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4f00 },
+               { 0x06, 0xaeab },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4f78 },
+               { 0x06, 0x039f },
+               { 0x06, 0x14ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x05d2 },
+               { 0x06, 0x40d6 },
+               { 0x06, 0x5554 },
+               { 0x06, 0x0282 },
+               { 0x06, 0x17d2 },
+               { 0x06, 0xa0d6 },
+               { 0x06, 0xba00 },
+               { 0x06, 0x0282 },
+               { 0x06, 0x17fe },
+               { 0x06, 0xfdfc },
+               { 0x06, 0x05f8 },
+               { 0x06, 0xe0f8 },
+               { 0x06, 0x60e1 },
+               { 0x06, 0xf861 },
+               { 0x06, 0x6802 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x60e5 },
+               { 0x06, 0xf861 },
+               { 0x06, 0xe0f8 },
+               { 0x06, 0x48e1 },
+               { 0x06, 0xf849 },
+               { 0x06, 0x580f },
+               { 0x06, 0x1e02 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x48e5 },
+               { 0x06, 0xf849 },
+               { 0x06, 0xd000 },
+               { 0x06, 0x0282 },
+               { 0x06, 0x5bbf },
+               { 0x06, 0x8350 },
+               { 0x06, 0xef46 },
+               { 0x06, 0xdc19 },
+               { 0x06, 0xddd0 },
+               { 0x06, 0x0102 },
+               { 0x06, 0x825b },
+               { 0x06, 0x0282 },
+               { 0x06, 0x77e0 },
+               { 0x06, 0xf860 },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x6158 },
+               { 0x06, 0xfde4 },
+               { 0x06, 0xf860 },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x61fc },
+               { 0x06, 0x04f9 },
+               { 0x06, 0xfafb },
+               { 0x06, 0xc6bf },
+               { 0x06, 0xf840 },
+               { 0x06, 0xbe83 },
+               { 0x06, 0x50a0 },
+               { 0x06, 0x0101 },
+               { 0x06, 0x071b },
+               { 0x06, 0x89cf },
+               { 0x06, 0xd208 },
+               { 0x06, 0xebdb },
+               { 0x06, 0x19b2 },
+               { 0x06, 0xfbff },
+               { 0x06, 0xfefd },
+               { 0x06, 0x04f8 },
+               { 0x06, 0xe0f8 },
+               { 0x06, 0x48e1 },
+               { 0x06, 0xf849 },
+               { 0x06, 0x6808 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x48e5 },
+               { 0x06, 0xf849 },
+               { 0x06, 0x58f7 },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x48e5 },
+               { 0x06, 0xf849 },
+               { 0x06, 0xfc04 },
+               { 0x06, 0x4d20 },
+               { 0x06, 0x0002 },
+               { 0x06, 0x4e22 },
+               { 0x06, 0x0002 },
+               { 0x06, 0x4ddf },
+               { 0x06, 0xff01 },
+               { 0x06, 0x4edd },
+               { 0x06, 0xff01 },
+               { 0x05, 0x83d4 },
+               { 0x06, 0x8000 },
+               { 0x05, 0x83d8 },
+               { 0x06, 0x8051 },
+               { 0x02, 0x6010 },
+               { 0x03, 0xdc00 },
+               { 0x05, 0xfff6 },
+               { 0x06, 0x00fc },
                { 0x1f, 0x0000 },
-               { 0x14, 0x0060 },
+
                { 0x1f, 0x0000 },
-               { 0x0d, 0xf8a0 },
+               { 0x0d, 0xf880 },
+               { 0x1f, 0x0000 }
+       };
+
+       rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
+
+       mdio_write(ioaddr, 0x1f, 0x0002);
+       mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
+       mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
+
+       rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+
+       if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+               struct phy_reg phy_reg_init[] = {
+                       { 0x1f, 0x0002 },
+                       { 0x05, 0x669a },
+                       { 0x1f, 0x0005 },
+                       { 0x05, 0x8330 },
+                       { 0x06, 0x669a },
+                       { 0x1f, 0x0002 }
+               };
+               int val;
+
+               rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+               val = mdio_read(ioaddr, 0x0d);
+
+               if ((val & 0x00ff) != 0x006c) {
+                       u32 set[] = {
+                               0x0065, 0x0066, 0x0067, 0x0068,
+                               0x0069, 0x006a, 0x006b, 0x006c
+                       };
+                       int i;
+
+                       mdio_write(ioaddr, 0x1f, 0x0002);
+
+                       val &= 0xff00;
+                       for (i = 0; i < ARRAY_SIZE(set); i++)
+                               mdio_write(ioaddr, 0x0d, val | set[i]);
+               }
+       } else {
+               struct phy_reg phy_reg_init[] = {
+                       { 0x1f, 0x0002 },
+                       { 0x05, 0x6662 },
+                       { 0x1f, 0x0005 },
+                       { 0x05, 0x8330 },
+                       { 0x06, 0x6662 }
+               };
+
+               rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+       }
+
+       mdio_write(ioaddr, 0x1f, 0x0002);
+       mdio_patch(ioaddr, 0x0d, 0x0300);
+       mdio_patch(ioaddr, 0x0f, 0x0010);
+
+       mdio_write(ioaddr, 0x1f, 0x0002);
+       mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
+       mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
+
+       rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
+}
+
+static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
+{
+       static struct phy_reg phy_reg_init_0[] = {
+               { 0x1f, 0x0001 },
+               { 0x06, 0x4064 },
+               { 0x07, 0x2863 },
+               { 0x08, 0x059c },
+               { 0x09, 0x26b4 },
+               { 0x0a, 0x6a19 },
+               { 0x0b, 0xdcc8 },
+               { 0x10, 0xf06d },
+               { 0x14, 0x7f68 },
+               { 0x18, 0x7fd9 },
+               { 0x1c, 0xf0ff },
+               { 0x1d, 0x3d9c },
+               { 0x1f, 0x0003 },
+               { 0x12, 0xf49f },
+               { 0x13, 0x070b },
+               { 0x1a, 0x05ad },
+               { 0x14, 0x94c0 },
+
+               { 0x1f, 0x0002 },
+               { 0x06, 0x5561 },
                { 0x1f, 0x0005 },
-               { 0x05, 0xffc2 }
+               { 0x05, 0x8332 },
+               { 0x06, 0x5561 }
+       };
+       static struct phy_reg phy_reg_init_1[] = {
+               { 0x1f, 0x0005 },
+               { 0x05, 0xffc2 },
+               { 0x1f, 0x0005 },
+               { 0x05, 0x8000 },
+               { 0x06, 0xf8f9 },
+               { 0x06, 0xfaee },
+               { 0x06, 0xf8ea },
+               { 0x06, 0x00ee },
+               { 0x06, 0xf8eb },
+               { 0x06, 0x00e2 },
+               { 0x06, 0xf87c },
+               { 0x06, 0xe3f8 },
+               { 0x06, 0x7da5 },
+               { 0x06, 0x1111 },
+               { 0x06, 0x12d2 },
+               { 0x06, 0x40d6 },
+               { 0x06, 0x4444 },
+               { 0x06, 0x0281 },
+               { 0x06, 0xc6d2 },
+               { 0x06, 0xa0d6 },
+               { 0x06, 0xaaaa },
+               { 0x06, 0x0281 },
+               { 0x06, 0xc6ae },
+               { 0x06, 0x0fa5 },
+               { 0x06, 0x4444 },
+               { 0x06, 0x02ae },
+               { 0x06, 0x4da5 },
+               { 0x06, 0xaaaa },
+               { 0x06, 0x02ae },
+               { 0x06, 0x47af },
+               { 0x06, 0x81c2 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e00 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4d0f },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4c0f },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4f00 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x5100 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4aff },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4bff },
+               { 0x06, 0xe083 },
+               { 0x06, 0x30e1 },
+               { 0x06, 0x8331 },
+               { 0x06, 0x58fe },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x8ae5 },
+               { 0x06, 0xf88b },
+               { 0x06, 0xe083 },
+               { 0x06, 0x32e1 },
+               { 0x06, 0x8333 },
+               { 0x06, 0x590f },
+               { 0x06, 0xe283 },
+               { 0x06, 0x4d0c },
+               { 0x06, 0x245a },
+               { 0x06, 0xf01e },
+               { 0x06, 0x12e4 },
+               { 0x06, 0xf88c },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x8daf },
+               { 0x06, 0x81c2 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4f10 },
+               { 0x06, 0xe483 },
+               { 0x06, 0x4fe0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7800 },
+               { 0x06, 0x9f0a },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4fa0 },
+               { 0x06, 0x10a5 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e01 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x059e },
+               { 0x06, 0x9ae0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7804 },
+               { 0x06, 0x9e10 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x039e },
+               { 0x06, 0x0fe0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7801 },
+               { 0x06, 0x9e05 },
+               { 0x06, 0xae0c },
+               { 0x06, 0xaf81 },
+               { 0x06, 0xa7af },
+               { 0x06, 0x8152 },
+               { 0x06, 0xaf81 },
+               { 0x06, 0x8baf },
+               { 0x06, 0x81c2 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4800 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4900 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x5110 },
+               { 0x06, 0xe483 },
+               { 0x06, 0x5158 },
+               { 0x06, 0x019f },
+               { 0x06, 0xead0 },
+               { 0x06, 0x00d1 },
+               { 0x06, 0x801f },
+               { 0x06, 0x66e2 },
+               { 0x06, 0xf8ea },
+               { 0x06, 0xe3f8 },
+               { 0x06, 0xeb5a },
+               { 0x06, 0xf81e },
+               { 0x06, 0x20e6 },
+               { 0x06, 0xf8ea },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0xebd3 },
+               { 0x06, 0x02b3 },
+               { 0x06, 0xfee2 },
+               { 0x06, 0xf87c },
+               { 0x06, 0xef32 },
+               { 0x06, 0x5b80 },
+               { 0x06, 0xe3f8 },
+               { 0x06, 0x7d9e },
+               { 0x06, 0x037d },
+               { 0x06, 0xffff },
+               { 0x06, 0x0d58 },
+               { 0x06, 0x1c55 },
+               { 0x06, 0x1a65 },
+               { 0x06, 0x11a1 },
+               { 0x06, 0x90d3 },
+               { 0x06, 0xe283 },
+               { 0x06, 0x48e3 },
+               { 0x06, 0x8349 },
+               { 0x06, 0x1b56 },
+               { 0x06, 0xab08 },
+               { 0x06, 0xef56 },
+               { 0x06, 0xe683 },
+               { 0x06, 0x48e7 },
+               { 0x06, 0x8349 },
+               { 0x06, 0x10d1 },
+               { 0x06, 0x801f },
+               { 0x06, 0x66a0 },
+               { 0x06, 0x04b9 },
+               { 0x06, 0xe283 },
+               { 0x06, 0x48e3 },
+               { 0x06, 0x8349 },
+               { 0x06, 0xef65 },
+               { 0x06, 0xe283 },
+               { 0x06, 0x4ae3 },
+               { 0x06, 0x834b },
+               { 0x06, 0x1b56 },
+               { 0x06, 0xaa0e },
+               { 0x06, 0xef56 },
+               { 0x06, 0xe683 },
+               { 0x06, 0x4ae7 },
+               { 0x06, 0x834b },
+               { 0x06, 0xe283 },
+               { 0x06, 0x4de6 },
+               { 0x06, 0x834c },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4da0 },
+               { 0x06, 0x000c },
+               { 0x06, 0xaf81 },
+               { 0x06, 0x8be0 },
+               { 0x06, 0x834d },
+               { 0x06, 0x10e4 },
+               { 0x06, 0x834d },
+               { 0x06, 0xae04 },
+               { 0x06, 0x80e4 },
+               { 0x06, 0x834d },
+               { 0x06, 0xe083 },
+               { 0x06, 0x4e78 },
+               { 0x06, 0x039e },
+               { 0x06, 0x0be0 },
+               { 0x06, 0x834e },
+               { 0x06, 0x7804 },
+               { 0x06, 0x9e04 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e02 },
+               { 0x06, 0xe083 },
+               { 0x06, 0x32e1 },
+               { 0x06, 0x8333 },
+               { 0x06, 0x590f },
+               { 0x06, 0xe283 },
+               { 0x06, 0x4d0c },
+               { 0x06, 0x245a },
+               { 0x06, 0xf01e },
+               { 0x06, 0x12e4 },
+               { 0x06, 0xf88c },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x8de0 },
+               { 0x06, 0x8330 },
+               { 0x06, 0xe183 },
+               { 0x06, 0x3168 },
+               { 0x06, 0x01e4 },
+               { 0x06, 0xf88a },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x8bae },
+               { 0x06, 0x37ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x03e0 },
+               { 0x06, 0x834c },
+               { 0x06, 0xe183 },
+               { 0x06, 0x4d1b },
+               { 0x06, 0x019e },
+               { 0x06, 0x04aa },
+               { 0x06, 0xa1ae },
+               { 0x06, 0xa8ee },
+               { 0x06, 0x834e },
+               { 0x06, 0x04ee },
+               { 0x06, 0x834f },
+               { 0x06, 0x00ae },
+               { 0x06, 0xabe0 },
+               { 0x06, 0x834f },
+               { 0x06, 0x7803 },
+               { 0x06, 0x9f14 },
+               { 0x06, 0xee83 },
+               { 0x06, 0x4e05 },
+               { 0x06, 0xd240 },
+               { 0x06, 0xd655 },
+               { 0x06, 0x5402 },
+               { 0x06, 0x81c6 },
+               { 0x06, 0xd2a0 },
+               { 0x06, 0xd6ba },
+               { 0x06, 0x0002 },
+               { 0x06, 0x81c6 },
+               { 0x06, 0xfefd },
+               { 0x06, 0xfc05 },
+               { 0x06, 0xf8e0 },
+               { 0x06, 0xf860 },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x6168 },
+               { 0x06, 0x02e4 },
+               { 0x06, 0xf860 },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x61e0 },
+               { 0x06, 0xf848 },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x4958 },
+               { 0x06, 0x0f1e },
+               { 0x06, 0x02e4 },
+               { 0x06, 0xf848 },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x49d0 },
+               { 0x06, 0x0002 },
+               { 0x06, 0x820a },
+               { 0x06, 0xbf83 },
+               { 0x06, 0x50ef },
+               { 0x06, 0x46dc },
+               { 0x06, 0x19dd },
+               { 0x06, 0xd001 },
+               { 0x06, 0x0282 },
+               { 0x06, 0x0a02 },
+               { 0x06, 0x8226 },
+               { 0x06, 0xe0f8 },
+               { 0x06, 0x60e1 },
+               { 0x06, 0xf861 },
+               { 0x06, 0x58fd },
+               { 0x06, 0xe4f8 },
+               { 0x06, 0x60e5 },
+               { 0x06, 0xf861 },
+               { 0x06, 0xfc04 },
+               { 0x06, 0xf9fa },
+               { 0x06, 0xfbc6 },
+               { 0x06, 0xbff8 },
+               { 0x06, 0x40be },
+               { 0x06, 0x8350 },
+               { 0x06, 0xa001 },
+               { 0x06, 0x0107 },
+               { 0x06, 0x1b89 },
+               { 0x06, 0xcfd2 },
+               { 0x06, 0x08eb },
+               { 0x06, 0xdb19 },
+               { 0x06, 0xb2fb },
+               { 0x06, 0xfffe },
+               { 0x06, 0xfd04 },
+               { 0x06, 0xf8e0 },
+               { 0x06, 0xf848 },
+               { 0x06, 0xe1f8 },
+               { 0x06, 0x4968 },
+               { 0x06, 0x08e4 },
+               { 0x06, 0xf848 },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x4958 },
+               { 0x06, 0xf7e4 },
+               { 0x06, 0xf848 },
+               { 0x06, 0xe5f8 },
+               { 0x06, 0x49fc },
+               { 0x06, 0x044d },
+               { 0x06, 0x2000 },
+               { 0x06, 0x024e },
+               { 0x06, 0x2200 },
+               { 0x06, 0x024d },
+               { 0x06, 0xdfff },
+               { 0x06, 0x014e },
+               { 0x06, 0xddff },
+               { 0x06, 0x0100 },
+               { 0x05, 0x83d8 },
+               { 0x06, 0x8000 },
+               { 0x03, 0xdc00 },
+               { 0x05, 0xfff6 },
+               { 0x06, 0x00fc },
+               { 0x1f, 0x0000 },
+
+               { 0x1f, 0x0000 },
+               { 0x0d, 0xf880 },
+               { 0x1f, 0x0000 }
        };
 
        rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
-       if (mdio_read(ioaddr, 0x06) == 0xc400) {
-               struct phy_reg phy_reg_init_1[] = {
+       if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+               struct phy_reg phy_reg_init[] = {
+                       { 0x1f, 0x0002 },
+                       { 0x05, 0x669a },
                        { 0x1f, 0x0005 },
-                       { 0x01, 0x0300 },
-                       { 0x1f, 0x0000 },
-                       { 0x11, 0x401c },
-                       { 0x16, 0x4100 },
+                       { 0x05, 0x8330 },
+                       { 0x06, 0x669a },
+
+                       { 0x1f, 0x0002 }
+               };
+               int val;
+
+               rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+               val = mdio_read(ioaddr, 0x0d);
+               if ((val & 0x00ff) != 0x006c) {
+                       u32 set[] = {
+                               0x0065, 0x0066, 0x0067, 0x0068,
+                               0x0069, 0x006a, 0x006b, 0x006c
+                       };
+                       int i;
+
+                       mdio_write(ioaddr, 0x1f, 0x0002);
+
+                       val &= 0xff00;
+                       for (i = 0; i < ARRAY_SIZE(set); i++)
+                               mdio_write(ioaddr, 0x0d, val | set[i]);
+               }
+       } else {
+               struct phy_reg phy_reg_init[] = {
+                       { 0x1f, 0x0002 },
+                       { 0x05, 0x2642 },
                        { 0x1f, 0x0005 },
-                       { 0x07, 0x0010 },
-                       { 0x05, 0x83dc },
-                       { 0x06, 0x087d },
-                       { 0x05, 0x8300 },
-                       { 0x06, 0x0101 },
-                       { 0x06, 0x05f8 },
-                       { 0x06, 0xf9fa },
-                       { 0x06, 0xfbef },
-                       { 0x06, 0x79e2 },
-                       { 0x06, 0x835f },
-                       { 0x06, 0xe0f8 },
-                       { 0x06, 0x9ae1 },
-                       { 0x06, 0xf89b },
-                       { 0x06, 0xef31 },
-                       { 0x06, 0x3b65 },
-                       { 0x06, 0xaa07 },
-                       { 0x06, 0x81e4 },
-                       { 0x06, 0xf89a },
-                       { 0x06, 0xe5f8 },
-                       { 0x06, 0x9baf },
-                       { 0x06, 0x06ae },
-                       { 0x05, 0x83dc },
-                       { 0x06, 0x8300 },
+                       { 0x05, 0x8330 },
+                       { 0x06, 0x2642 }
                };
 
-               rtl_phy_write(ioaddr, phy_reg_init_1,
-                             ARRAY_SIZE(phy_reg_init_1));
+               rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
        }
 
-       mdio_write(ioaddr, 0x1f, 0x0000);
+       mdio_write(ioaddr, 0x1f, 0x0002);
+       mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
+       mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
+
+       mdio_write(ioaddr, 0x1f, 0x0001);
+       mdio_write(ioaddr, 0x17, 0x0cc0);
+
+       mdio_write(ioaddr, 0x1f, 0x0002);
+       mdio_patch(ioaddr, 0x0f, 0x0017);
+
+       rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+}
+
+static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
+{
+       struct phy_reg phy_reg_init[] = {
+               { 0x1f, 0x0002 },
+               { 0x10, 0x0008 },
+               { 0x0d, 0x006c },
+
+               { 0x1f, 0x0000 },
+               { 0x0d, 0xf880 },
+
+               { 0x1f, 0x0001 },
+               { 0x17, 0x0cc0 },
+
+               { 0x1f, 0x0001 },
+               { 0x0b, 0xa4d8 },
+               { 0x09, 0x281c },
+               { 0x07, 0x2883 },
+               { 0x0a, 0x6b35 },
+               { 0x1d, 0x3da4 },
+               { 0x1c, 0xeffd },
+               { 0x14, 0x7f52 },
+               { 0x18, 0x7fc6 },
+               { 0x08, 0x0601 },
+               { 0x06, 0x4063 },
+               { 0x10, 0xf074 },
+               { 0x1f, 0x0003 },
+               { 0x13, 0x0789 },
+               { 0x12, 0xf4bd },
+               { 0x1a, 0x04fd },
+               { 0x14, 0x84b0 },
+               { 0x1f, 0x0000 },
+               { 0x00, 0x9200 },
+
+               { 0x1f, 0x0005 },
+               { 0x01, 0x0340 },
+               { 0x1f, 0x0001 },
+               { 0x04, 0x4000 },
+               { 0x03, 0x1d21 },
+               { 0x02, 0x0c32 },
+               { 0x01, 0x0200 },
+               { 0x00, 0x5554 },
+               { 0x04, 0x4800 },
+               { 0x04, 0x4000 },
+               { 0x04, 0xf000 },
+               { 0x03, 0xdf01 },
+               { 0x02, 0xdf20 },
+               { 0x01, 0x101a },
+               { 0x00, 0xa0ff },
+               { 0x04, 0xf800 },
+               { 0x04, 0xf000 },
+               { 0x1f, 0x0000 },
+
+               { 0x1f, 0x0007 },
+               { 0x1e, 0x0023 },
+               { 0x16, 0x0000 },
+               { 0x1f, 0x0000 }
+       };
+
+       rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
 static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
@@ -1792,7 +2664,13 @@ static void rtl_hw_phy_config(struct net_device *dev)
                rtl8168cp_2_hw_phy_config(ioaddr);
                break;
        case RTL_GIGA_MAC_VER_25:
-               rtl8168d_hw_phy_config(ioaddr);
+               rtl8168d_1_hw_phy_config(ioaddr);
+               break;
+       case RTL_GIGA_MAC_VER_26:
+               rtl8168d_2_hw_phy_config(ioaddr);
+               break;
+       case RTL_GIGA_MAC_VER_27:
+               rtl8168d_3_hw_phy_config(ioaddr);
                break;
 
        default:
@@ -2322,6 +3200,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        rtl8169_init_phy(dev, tp);
+
+       /*
+        * Pretend we are using VLANs; This bypasses a nasty bug where
+        * Interrupts stop flowing on high load on 8110SCd controllers.
+        */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_05)
+               RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan);
+
        device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
 
 out:
@@ -2863,6 +3749,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
        break;
 
        case RTL_GIGA_MAC_VER_25:
+       case RTL_GIGA_MAC_VER_26:
+       case RTL_GIGA_MAC_VER_27:
                rtl_hw_start_8168d(ioaddr, pdev);
        break;
 
index 01f9432..98bff5a 100644 (file)
@@ -444,7 +444,8 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
  * the appropriate LRO method
  */
 static void efx_rx_packet_lro(struct efx_channel *channel,
-                             struct efx_rx_buffer *rx_buf)
+                             struct efx_rx_buffer *rx_buf,
+                             bool checksummed)
 {
        struct napi_struct *napi = &channel->napi_str;
 
@@ -466,7 +467,8 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
                skb->len = rx_buf->len;
                skb->data_len = rx_buf->len;
                skb->truesize += rx_buf->len;
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               skb->ip_summed =
+                       checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
 
                napi_gro_frags(napi);
 
@@ -475,6 +477,7 @@ out:
                rx_buf->page = NULL;
        } else {
                EFX_BUG_ON_PARANOID(!rx_buf->skb);
+               EFX_BUG_ON_PARANOID(!checksummed);
 
                napi_gro_receive(napi, rx_buf->skb);
                rx_buf->skb = NULL;
@@ -570,7 +573,7 @@ void __efx_rx_packet(struct efx_channel *channel,
        }
 
        if (likely(checksummed || rx_buf->page)) {
-               efx_rx_packet_lro(channel, rx_buf);
+               efx_rx_packet_lro(channel, rx_buf, checksummed);
                goto done;
        }
 
index f49d080..528b912 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/phy.h>
 #include <linux/cache.h>
 #include <linux/io.h>
+#include <asm/cacheflush.h>
 
 #include "sh_eth.h"
 
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
new file mode 100644 (file)
index 0000000..35eaa52
--- /dev/null
@@ -0,0 +1,53 @@
+config STMMAC_ETH
+       tristate "STMicroelectronics 10/100/1000 Ethernet driver"
+       select MII
+       select PHYLIB
+       depends on NETDEVICES && CPU_SUBTYPE_ST40
+       help
+         This is the driver for the ST MAC 10/100/1000 on-chip Ethernet
+         controllers. ST Ethernet IPs are built around a Synopsys IP Core.
+
+if STMMAC_ETH
+
+config STMMAC_DA
+       bool "STMMAC DMA arbitration scheme"
+       default n
+       help
+         Selecting this option, rx has priority over Tx (only for Giga
+         Ethernet device).
+         By default, the DMA arbitration scheme is based on Round-robin
+         (rx:tx priority is 1:1).
+
+config STMMAC_DUAL_MAC
+       bool "STMMAC: dual mac support (EXPERIMENTAL)"
+       default n
+        depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
+       help
+         Some ST SoCs (for example the stx7141 and stx7200c2) have two
+         Ethernet Controllers. This option turns on the second Ethernet
+         device on this kind of platforms.
+
+config STMMAC_TIMER
+       bool "STMMAC Timer optimisation"
+       default n
+       help
+         Use an external timer for mitigating the number of network
+         interrupts.
+
+choice
+        prompt "Select Timer device"
+        depends on STMMAC_TIMER
+
+config STMMAC_TMU_TIMER
+        bool "TMU channel 2"
+        depends on CPU_SH4
+       help
+
+config STMMAC_RTC_TIMER
+        bool "Real time clock"
+        depends on RTC_CLASS
+       help
+
+endchoice
+
+endif
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
new file mode 100644 (file)
index 0000000..b2d7a55
--- /dev/null
@@ -0,0 +1,4 @@
+obj-$(CONFIG_STMMAC_ETH) += stmmac.o
+stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
+stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
+               mac100.o  gmac.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
new file mode 100644 (file)
index 0000000..e49e518
--- /dev/null
@@ -0,0 +1,330 @@
+/*******************************************************************************
+  STMMAC Common Header File
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "descs.h"
+#include <linux/io.h>
+
+/* *********************************************
+   DMA CRS Control and Status Register Mapping
+ * *********************************************/
+#define DMA_BUS_MODE           0x00001000      /* Bus Mode */
+#define DMA_XMT_POLL_DEMAND    0x00001004      /* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND    0x00001008      /* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR      0x0000100c      /* Receive List Base */
+#define DMA_TX_BASE_ADDR       0x00001010      /* Transmit List Base */
+#define DMA_STATUS             0x00001014      /* Status Register */
+#define DMA_CONTROL            0x00001018      /* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA           0x0000101c      /* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR   0x00001020      /* Missed Frame Counter */
+#define DMA_CUR_TX_BUF_ADDR    0x00001050      /* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR    0x00001054      /* Current Host Rx Buffer */
+
+/* ********************************
+   DMA Control register defines
+ * ********************************/
+#define DMA_CONTROL_ST         0x00002000      /* Start/Stop Transmission */
+#define DMA_CONTROL_SR         0x00000002      /* Start/Stop Receive */
+
+/* **************************************
+   DMA Interrupt Enable register defines
+ * **************************************/
+/**** NORMAL INTERRUPT ****/
+#define DMA_INTR_ENA_NIE 0x00010000    /* Normal Summary */
+#define DMA_INTR_ENA_TIE 0x00000001    /* Transmit Interrupt */
+#define DMA_INTR_ENA_TUE 0x00000004    /* Transmit Buffer Unavailable */
+#define DMA_INTR_ENA_RIE 0x00000040    /* Receive Interrupt */
+#define DMA_INTR_ENA_ERE 0x00004000    /* Early Receive */
+
+#define DMA_INTR_NORMAL        (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
+                       DMA_INTR_ENA_TIE)
+
+/**** ABNORMAL INTERRUPT ****/
+#define DMA_INTR_ENA_AIE 0x00008000    /* Abnormal Summary */
+#define DMA_INTR_ENA_FBE 0x00002000    /* Fatal Bus Error */
+#define DMA_INTR_ENA_ETE 0x00000400    /* Early Transmit */
+#define DMA_INTR_ENA_RWE 0x00000200    /* Receive Watchdog */
+#define DMA_INTR_ENA_RSE 0x00000100    /* Receive Stopped */
+#define DMA_INTR_ENA_RUE 0x00000080    /* Receive Buffer Unavailable */
+#define DMA_INTR_ENA_UNE 0x00000020    /* Tx Underflow */
+#define DMA_INTR_ENA_OVE 0x00000010    /* Receive Overflow */
+#define DMA_INTR_ENA_TJE 0x00000008    /* Transmit Jabber */
+#define DMA_INTR_ENA_TSE 0x00000002    /* Transmit Stopped */
+
+#define DMA_INTR_ABNORMAL      (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
+                               DMA_INTR_ENA_UNE)
+
+/* DMA default interrupt mask */
+#define DMA_INTR_DEFAULT_MASK  (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
+
+/* ****************************
+ *  DMA Status register defines
+ * ****************************/
+#define DMA_STATUS_GPI         0x10000000      /* PMT interrupt */
+#define DMA_STATUS_GMI         0x08000000      /* MMC interrupt */
+#define DMA_STATUS_GLI         0x04000000      /* GMAC Line interface int. */
+#define DMA_STATUS_GMI         0x08000000
+#define DMA_STATUS_GLI         0x04000000
+#define DMA_STATUS_EB_MASK     0x00380000      /* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT 0x00080000      /* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT 0x00100000      /* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK     0x00700000      /* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT    20
+#define DMA_STATUS_RS_MASK     0x000e0000      /* Receive Process State */
+#define DMA_STATUS_RS_SHIFT    17
+#define DMA_STATUS_NIS 0x00010000      /* Normal Interrupt Summary */
+#define DMA_STATUS_AIS 0x00008000      /* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI 0x00004000      /* Early Receive Interrupt */
+#define DMA_STATUS_FBI 0x00002000      /* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI 0x00000400      /* Early Transmit Interrupt */
+#define DMA_STATUS_RWT 0x00000200      /* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS 0x00000100      /* Receive Process Stopped */
+#define DMA_STATUS_RU  0x00000080      /* Receive Buffer Unavailable */
+#define DMA_STATUS_RI  0x00000040      /* Receive Interrupt */
+#define DMA_STATUS_UNF 0x00000020      /* Transmit Underflow */
+#define DMA_STATUS_OVF 0x00000010      /* Receive Overflow */
+#define DMA_STATUS_TJT 0x00000008      /* Transmit Jabber Timeout */
+#define DMA_STATUS_TU  0x00000004      /* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS 0x00000002      /* Transmit Process Stopped */
+#define DMA_STATUS_TI  0x00000001      /* Transmit Interrupt */
+
+/* Other defines */
+#define HASH_TABLE_SIZE 64
+#define PAUSE_TIME 0x200
+
+/* Flow Control defines */
+#define FLOW_OFF       0
+#define FLOW_RX                1
+#define FLOW_TX                2
+#define FLOW_AUTO      (FLOW_TX | FLOW_RX)
+
+/* DMA STORE-AND-FORWARD Operation Mode */
+#define SF_DMA_MODE 1
+
+#define HW_CSUM 1
+#define NO_HW_CSUM 0
+
+/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
+#define BUF_SIZE_16KiB 16384
+#define BUF_SIZE_8KiB 8192
+#define BUF_SIZE_4KiB 4096
+#define BUF_SIZE_2KiB 2048
+
+/* Power Down and WOL */
+#define PMT_NOT_SUPPORTED 0
+#define PMT_SUPPORTED 1
+
+/* Common MAC defines */
+#define MAC_CTRL_REG           0x00000000      /* MAC Control */
+#define MAC_ENABLE_TX          0x00000008      /* Transmitter Enable */
+#define MAC_RNABLE_RX          0x00000004      /* Receiver Enable */
+
+/* MAC Management Counters register */
+#define MMC_CONTROL            0x00000100      /* MMC Control */
+#define MMC_HIGH_INTR          0x00000104      /* MMC High Interrupt */
+#define MMC_LOW_INTR           0x00000108      /* MMC Low Interrupt */
+#define MMC_HIGH_INTR_MASK     0x0000010c      /* MMC High Interrupt Mask */
+#define MMC_LOW_INTR_MASK      0x00000110      /* MMC Low Interrupt Mask */
+
+#define MMC_CONTROL_MAX_FRM_MASK       0x0003ff8       /* Maximum Frame Size */
+#define MMC_CONTROL_MAX_FRM_SHIFT      3
+#define MMC_CONTROL_MAX_FRAME          0x7FF
+
+struct stmmac_extra_stats {
+       /* Transmit errors */
+       unsigned long tx_underflow ____cacheline_aligned;
+       unsigned long tx_carrier;
+       unsigned long tx_losscarrier;
+       unsigned long tx_heartbeat;
+       unsigned long tx_deferred;
+       unsigned long tx_vlan;
+       unsigned long tx_jabber;
+       unsigned long tx_frame_flushed;
+       unsigned long tx_payload_error;
+       unsigned long tx_ip_header_error;
+       /* Receive errors */
+       unsigned long rx_desc;
+       unsigned long rx_partial;
+       unsigned long rx_runt;
+       unsigned long rx_toolong;
+       unsigned long rx_collision;
+       unsigned long rx_crc;
+       unsigned long rx_lenght;
+       unsigned long rx_mii;
+       unsigned long rx_multicast;
+       unsigned long rx_gmac_overflow;
+       unsigned long rx_watchdog;
+       unsigned long da_rx_filter_fail;
+       unsigned long sa_rx_filter_fail;
+       unsigned long rx_missed_cntr;
+       unsigned long rx_overflow_cntr;
+       unsigned long rx_vlan;
+       /* Tx/Rx IRQ errors */
+       unsigned long tx_undeflow_irq;
+       unsigned long tx_process_stopped_irq;
+       unsigned long tx_jabber_irq;
+       unsigned long rx_overflow_irq;
+       unsigned long rx_buf_unav_irq;
+       unsigned long rx_process_stopped_irq;
+       unsigned long rx_watchdog_irq;
+       unsigned long tx_early_irq;
+       unsigned long fatal_bus_error_irq;
+       /* Extra info */
+       unsigned long threshold;
+       unsigned long tx_pkt_n;
+       unsigned long rx_pkt_n;
+       unsigned long poll_n;
+       unsigned long sched_timer_n;
+       unsigned long normal_irq_n;
+};
+
+/* GMAC core can compute the checksums in HW. */
+enum rx_frame_status {
+       good_frame = 0,
+       discard_frame = 1,
+       csum_none = 2,
+};
+
+static inline void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+                        unsigned int high, unsigned int low)
+{
+       unsigned long data;
+
+       data = (addr[5] << 8) | addr[4];
+       writel(data, ioaddr + high);
+       data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
+       writel(data, ioaddr + low);
+
+       return;
+}
+
+static inline void stmmac_get_mac_addr(unsigned long ioaddr,
+                               unsigned char *addr, unsigned int high,
+                               unsigned int low)
+{
+       unsigned int hi_addr, lo_addr;
+
+       /* Read the MAC address from the hardware */
+       hi_addr = readl(ioaddr + high);
+       lo_addr = readl(ioaddr + low);
+
+       /* Extract the MAC address from the high and low words */
+       addr[0] = lo_addr & 0xff;
+       addr[1] = (lo_addr >> 8) & 0xff;
+       addr[2] = (lo_addr >> 16) & 0xff;
+       addr[3] = (lo_addr >> 24) & 0xff;
+       addr[4] = hi_addr & 0xff;
+       addr[5] = (hi_addr >> 8) & 0xff;
+
+       return;
+}
+
+struct stmmac_ops {
+       /* MAC core initialization */
+       void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
+       /* DMA core initialization */
+       int (*dma_init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+       /* Dump MAC registers */
+       void (*dump_mac_regs) (unsigned long ioaddr);
+       /* Dump DMA registers */
+       void (*dump_dma_regs) (unsigned long ioaddr);
+       /* Set tx/rx threshold in the csr6 register
+        * An invalid value enables the store-and-forward mode */
+       void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
+       /* To track extra statistic (if supported) */
+       void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
+                                  unsigned long ioaddr);
+       /* RX descriptor ring initialization */
+       void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
+                               int disable_rx_ic);
+       /* TX descriptor ring initialization */
+       void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
+
+       /* Invoked by the xmit function to prepare the tx descriptor */
+       void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
+                                int csum_flag);
+       /* Set/get the owner of the descriptor */
+       void (*set_tx_owner) (struct dma_desc *p);
+       int (*get_tx_owner) (struct dma_desc *p);
+       /* Invoked by the xmit function to close the tx descriptor */
+       void (*close_tx_desc) (struct dma_desc *p);
+       /* Clean the tx descriptor as soon as the tx irq is received */
+       void (*release_tx_desc) (struct dma_desc *p);
+       /* Clear interrupt on tx frame completion. When this bit is
+        * set an interrupt happens as soon as the frame is transmitted */
+       void (*clear_tx_ic) (struct dma_desc *p);
+       /* Last tx segment reports the transmit status */
+       int (*get_tx_ls) (struct dma_desc *p);
+       /* Return the transmit status looking at the TDES1 */
+       int (*tx_status) (void *data, struct stmmac_extra_stats *x,
+                         struct dma_desc *p, unsigned long ioaddr);
+       /* Get the buffer size from the descriptor */
+       int (*get_tx_len) (struct dma_desc *p);
+       /* Handle extra events on specific interrupts hw dependent */
+       void (*host_irq_status) (unsigned long ioaddr);
+       int (*get_rx_owner) (struct dma_desc *p);
+       void (*set_rx_owner) (struct dma_desc *p);
+       /* Get the receive frame size */
+       int (*get_rx_frame_len) (struct dma_desc *p);
+       /* Return the reception status looking at the RDES1 */
+       int (*rx_status) (void *data, struct stmmac_extra_stats *x,
+                         struct dma_desc *p);
+       /* Multicast filter setting */
+       void (*set_filter) (struct net_device *dev);
+       /* Flow control setting */
+       void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
+                          unsigned int fc, unsigned int pause_time);
+       /* Set power management mode (e.g. magic frame) */
+       void (*pmt) (unsigned long ioaddr, unsigned long mode);
+       /* Set/Get Unicast MAC addresses */
+       void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+                            unsigned int reg_n);
+       void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+                            unsigned int reg_n);
+};
+
+struct mac_link {
+       int port;
+       int duplex;
+       int speed;
+};
+
+struct mii_regs {
+       unsigned int addr;      /* MII Address */
+       unsigned int data;      /* MII Data */
+};
+
+struct hw_cap {
+       unsigned int version;   /* Core Version register (GMAC) */
+       unsigned int pmt;       /* Power-Down mode (GMAC) */
+       struct mac_link link;
+       struct mii_regs mii;
+};
+
+struct mac_device_info {
+       struct hw_cap hw;
+       struct stmmac_ops *ops;
+};
+
+struct mac_device_info *gmac_setup(unsigned long addr);
+struct mac_device_info *mac100_setup(unsigned long addr);
diff --git a/drivers/net/stmmac/descs.h b/drivers/net/stmmac/descs.h
new file mode 100644 (file)
index 0000000..6d2a0b2
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+  Header File to describe the DMA descriptors
+  Use enhanced descriptors in case of GMAC Cores.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+struct dma_desc {
+       /* Receive descriptor */
+       union {
+               struct {
+                       /* RDES0 */
+                       u32 reserved1:1;
+                       u32 crc_error:1;
+                       u32 dribbling:1;
+                       u32 mii_error:1;
+                       u32 receive_watchdog:1;
+                       u32 frame_type:1;
+                       u32 collision:1;
+                       u32 frame_too_long:1;
+                       u32 last_descriptor:1;
+                       u32 first_descriptor:1;
+                       u32 multicast_frame:1;
+                       u32 run_frame:1;
+                       u32 length_error:1;
+                       u32 partial_frame_error:1;
+                       u32 descriptor_error:1;
+                       u32 error_summary:1;
+                       u32 frame_length:14;
+                       u32 filtering_fail:1;
+                       u32 own:1;
+                       /* RDES1 */
+                       u32 buffer1_size:11;
+                       u32 buffer2_size:11;
+                       u32 reserved2:2;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 reserved3:5;
+                       u32 disable_ic:1;
+               } rx;
+               struct {
+                       /* RDES0 */
+                       u32 payload_csum_error:1;
+                       u32 crc_error:1;
+                       u32 dribbling:1;
+                       u32 error_gmii:1;
+                       u32 receive_watchdog:1;
+                       u32 frame_type:1;
+                       u32 late_collision:1;
+                       u32 ipc_csum_error:1;
+                       u32 last_descriptor:1;
+                       u32 first_descriptor:1;
+                       u32 vlan_tag:1;
+                       u32 overflow_error:1;
+                       u32 length_error:1;
+                       u32 sa_filter_fail:1;
+                       u32 descriptor_error:1;
+                       u32 error_summary:1;
+                       u32 frame_length:14;
+                       u32 da_filter_fail:1;
+                       u32 own:1;
+                       /* RDES1 */
+                       u32 buffer1_size:13;
+                       u32 reserved1:1;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 buffer2_size:13;
+                       u32 reserved2:2;
+                       u32 disable_ic:1;
+               } erx;          /* -- enhanced -- */
+
+               /* Transmit descriptor */
+               struct {
+                       /* TDES0 */
+                       u32 deferred:1;
+                       u32 underflow_error:1;
+                       u32 excessive_deferral:1;
+                       u32 collision_count:4;
+                       u32 heartbeat_fail:1;
+                       u32 excessive_collisions:1;
+                       u32 late_collision:1;
+                       u32 no_carrier:1;
+                       u32 loss_carrier:1;
+                       u32 reserved1:3;
+                       u32 error_summary:1;
+                       u32 reserved2:15;
+                       u32 own:1;
+                       /* TDES1 */
+                       u32 buffer1_size:11;
+                       u32 buffer2_size:11;
+                       u32 reserved3:1;
+                       u32 disable_padding:1;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 crc_disable:1;
+                       u32 reserved4:2;
+                       u32 first_segment:1;
+                       u32 last_segment:1;
+                       u32 interrupt:1;
+               } tx;
+               struct {
+                       /* TDES0 */
+                       u32 deferred:1;
+                       u32 underflow_error:1;
+                       u32 excessive_deferral:1;
+                       u32 collision_count:4;
+                       u32 vlan_frame:1;
+                       u32 excessive_collisions:1;
+                       u32 late_collision:1;
+                       u32 no_carrier:1;
+                       u32 loss_carrier:1;
+                       u32 payload_error:1;
+                       u32 frame_flushed:1;
+                       u32 jabber_timeout:1;
+                       u32 error_summary:1;
+                       u32 ip_header_error:1;
+                       u32 time_stamp_status:1;
+                       u32 reserved1:2;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 checksum_insertion:2;
+                       u32 reserved2:1;
+                       u32 time_stamp_enable:1;
+                       u32 disable_padding:1;
+                       u32 crc_disable:1;
+                       u32 first_segment:1;
+                       u32 last_segment:1;
+                       u32 interrupt:1;
+                       u32 own:1;
+                       /* TDES1 */
+                       u32 buffer1_size:13;
+                       u32 reserved3:3;
+                       u32 buffer2_size:13;
+                       u32 reserved4:3;
+               } etx;          /* -- enhanced -- */
+       } des01;
+       unsigned int des2;
+       unsigned int des3;
+};
+
+/* Transmit checksum insertion control */
+enum tdes_csum_insertion {
+       cic_disabled = 0,       /* Checksum Insertion Control */
+       cic_only_ip = 1,        /* Only IP header */
+       cic_no_pseudoheader = 2,        /* IP header but pseudoheader
+                                        * is not calculated */
+       cic_full = 3,           /* IP header and pseudoheader */
+};
diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/gmac.c
new file mode 100644 (file)
index 0000000..b624bb5
--- /dev/null
@@ -0,0 +1,693 @@
+/*******************************************************************************
+  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
+  developing this code.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+#include "gmac.h"
+
+#undef GMAC_DEBUG
+/*#define GMAC_DEBUG*/
+#undef FRAME_FILTER_DEBUG
+/*#define FRAME_FILTER_DEBUG*/
+#ifdef GMAC_DEBUG
+#define DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DBG(fmt, args...)  do { } while (0)
+#endif
+
+static void gmac_dump_regs(unsigned long ioaddr)
+{
+       int i;
+       pr_info("\t----------------------------------------------\n"
+              "\t  GMAC registers (base addr = 0x%8x)\n"
+              "\t----------------------------------------------\n",
+              (unsigned int)ioaddr);
+
+       for (i = 0; i < 55; i++) {
+               int offset = i * 4;
+               pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
+                      offset, readl(ioaddr + offset));
+       }
+       return;
+}
+
+static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
+{
+       u32 value = readl(ioaddr + DMA_BUS_MODE);
+       /* DMA SW reset */
+       value |= DMA_BUS_MODE_SFT_RESET;
+       writel(value, ioaddr + DMA_BUS_MODE);
+       do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+       value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
+           ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+            (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+#ifdef CONFIG_STMMAC_DA
+       value |= DMA_BUS_MODE_DA;       /* Rx has priority over tx */
+#endif
+       writel(value, ioaddr + DMA_BUS_MODE);
+
+       /* Mask interrupts by writing to CSR7 */
+       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+       /* The base address of the RX/TX descriptor lists must be written into
+        * DMA CSR3 and CSR4, respectively. */
+       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+       return 0;
+}
+
+/* Transmit FIFO flush operation */
+static void gmac_flush_tx_fifo(unsigned long ioaddr)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+       writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
+
+       do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
+}
+
+static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode,
+                                   int rxmode)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+       if (txmode == SF_DMA_MODE) {
+               DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n");
+               /* Transmit COE type 2 cannot be done in cut-through mode. */
+               csr6 |= DMA_CONTROL_TSF;
+               /* Operating on second frame increase the performance
+                * especially when transmit store-and-forward is used.*/
+               csr6 |= DMA_CONTROL_OSF;
+       } else {
+               DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
+                             " (threshold = %d)\n", txmode);
+               csr6 &= ~DMA_CONTROL_TSF;
+               csr6 &= DMA_CONTROL_TC_TX_MASK;
+               /* Set the transmit threashold */
+               if (txmode <= 32)
+                       csr6 |= DMA_CONTROL_TTC_32;
+               else if (txmode <= 64)
+                       csr6 |= DMA_CONTROL_TTC_64;
+               else if (txmode <= 128)
+                       csr6 |= DMA_CONTROL_TTC_128;
+               else if (txmode <= 192)
+                       csr6 |= DMA_CONTROL_TTC_192;
+               else
+                       csr6 |= DMA_CONTROL_TTC_256;
+       }
+
+       if (rxmode == SF_DMA_MODE) {
+               DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
+               csr6 |= DMA_CONTROL_RSF;
+       } else {
+               DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
+                             " (threshold = %d)\n", rxmode);
+               csr6 &= ~DMA_CONTROL_RSF;
+               csr6 &= DMA_CONTROL_TC_RX_MASK;
+               if (rxmode <= 32)
+                       csr6 |= DMA_CONTROL_RTC_32;
+               else if (rxmode <= 64)
+                       csr6 |= DMA_CONTROL_RTC_64;
+               else if (rxmode <= 96)
+                       csr6 |= DMA_CONTROL_RTC_96;
+               else
+                       csr6 |= DMA_CONTROL_RTC_128;
+       }
+
+       writel(csr6, ioaddr + DMA_CONTROL);
+       return;
+}
+
+/* Not yet implemented --- no RMON module */
+static void gmac_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
+                                  unsigned long ioaddr)
+{
+       return;
+}
+
+static void gmac_dump_dma_regs(unsigned long ioaddr)
+{
+       int i;
+       pr_info(" DMA registers\n");
+       for (i = 0; i < 22; i++) {
+               if ((i < 9) || (i > 17)) {
+                       int offset = i * 4;
+                       pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
+                              (DMA_BUS_MODE + offset),
+                              readl(ioaddr + DMA_BUS_MODE + offset));
+               }
+       }
+       return;
+}
+
+static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
+                                   struct dma_desc *p, unsigned long ioaddr)
+{
+       int ret = 0;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.etx.error_summary)) {
+               DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
+               if (unlikely(p->des01.etx.jabber_timeout)) {
+                       DBG(KERN_ERR "\tjabber_timeout error\n");
+                       x->tx_jabber++;
+               }
+
+               if (unlikely(p->des01.etx.frame_flushed)) {
+                       DBG(KERN_ERR "\tframe_flushed error\n");
+                       x->tx_frame_flushed++;
+                       gmac_flush_tx_fifo(ioaddr);
+               }
+
+               if (unlikely(p->des01.etx.loss_carrier)) {
+                       DBG(KERN_ERR "\tloss_carrier error\n");
+                       x->tx_losscarrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.etx.no_carrier)) {
+                       DBG(KERN_ERR "\tno_carrier error\n");
+                       x->tx_carrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.etx.late_collision)) {
+                       DBG(KERN_ERR "\tlate_collision error\n");
+                       stats->collisions += p->des01.etx.collision_count;
+               }
+               if (unlikely(p->des01.etx.excessive_collisions)) {
+                       DBG(KERN_ERR "\texcessive_collisions\n");
+                       stats->collisions += p->des01.etx.collision_count;
+               }
+               if (unlikely(p->des01.etx.excessive_deferral)) {
+                       DBG(KERN_INFO "\texcessive tx_deferral\n");
+                       x->tx_deferred++;
+               }
+
+               if (unlikely(p->des01.etx.underflow_error)) {
+                       DBG(KERN_ERR "\tunderflow error\n");
+                       gmac_flush_tx_fifo(ioaddr);
+                       x->tx_underflow++;
+               }
+
+               if (unlikely(p->des01.etx.ip_header_error)) {
+                       DBG(KERN_ERR "\tTX IP header csum error\n");
+                       x->tx_ip_header_error++;
+               }
+
+               if (unlikely(p->des01.etx.payload_error)) {
+                       DBG(KERN_ERR "\tAddr/Payload csum error\n");
+                       x->tx_payload_error++;
+                       gmac_flush_tx_fifo(ioaddr);
+               }
+
+               ret = -1;
+       }
+
+       if (unlikely(p->des01.etx.deferred)) {
+               DBG(KERN_INFO "GMAC TX status: tx deferred\n");
+               x->tx_deferred++;
+       }
+#ifdef STMMAC_VLAN_TAG_USED
+       if (p->des01.etx.vlan_frame) {
+               DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+               x->tx_vlan++;
+       }
+#endif
+
+       return ret;
+}
+
+static int gmac_get_tx_len(struct dma_desc *p)
+{
+       return p->des01.etx.buffer1_size;
+}
+
+static int gmac_coe_rdes0(int ipc_err, int type, int payload_err)
+{
+       int ret = good_frame;
+       u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
+
+       /* bits 5 7 0 | Frame status
+        * ----------------------------------------------------------
+        *      0 0 0 | IEEE 802.3 Type frame (lenght < 1536 octects)
+        *      1 0 0 | IPv4/6 No CSUM errorS.
+        *      1 0 1 | IPv4/6 CSUM PAYLOAD error
+        *      1 1 0 | IPv4/6 CSUM IP HR error
+        *      1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
+        *      0 0 1 | IPv4/6 unsupported IP PAYLOAD
+        *      0 1 1 | COE bypassed.. no IPv4/6 frame
+        *      0 1 0 | Reserved.
+        */
+       if (status == 0x0) {
+               DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
+               ret = good_frame;
+       } else if (status == 0x4) {
+               DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
+               ret = good_frame;
+       } else if (status == 0x5) {
+               DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
+               ret = csum_none;
+       } else if (status == 0x6) {
+               DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
+               ret = csum_none;
+       } else if (status == 0x7) {
+               DBG(KERN_ERR
+                   "RX Des0 status: IPv4/6 Header and Payload Error.\n");
+               ret = csum_none;
+       } else if (status == 0x1) {
+               DBG(KERN_ERR
+                   "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
+               ret = discard_frame;
+       } else if (status == 0x3) {
+               DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+               ret = discard_frame;
+       }
+       return ret;
+}
+
+static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
+                                   struct dma_desc *p)
+{
+       int ret = good_frame;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.erx.error_summary)) {
+               DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
+               if (unlikely(p->des01.erx.descriptor_error)) {
+                       DBG(KERN_ERR "\tdescriptor error\n");
+                       x->rx_desc++;
+                       stats->rx_length_errors++;
+               }
+               if (unlikely(p->des01.erx.overflow_error)) {
+                       DBG(KERN_ERR "\toverflow error\n");
+                       x->rx_gmac_overflow++;
+               }
+
+               if (unlikely(p->des01.erx.ipc_csum_error))
+                       DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
+
+               if (unlikely(p->des01.erx.late_collision)) {
+                       DBG(KERN_ERR "\tlate_collision error\n");
+                       stats->collisions++;
+                       stats->collisions++;
+               }
+               if (unlikely(p->des01.erx.receive_watchdog)) {
+                       DBG(KERN_ERR "\treceive_watchdog error\n");
+                       x->rx_watchdog++;
+               }
+               if (unlikely(p->des01.erx.error_gmii)) {
+                       DBG(KERN_ERR "\tReceive Error\n");
+                       x->rx_mii++;
+               }
+               if (unlikely(p->des01.erx.crc_error)) {
+                       DBG(KERN_ERR "\tCRC error\n");
+                       x->rx_crc++;
+                       stats->rx_crc_errors++;
+               }
+               ret = discard_frame;
+       }
+
+       /* After a payload csum error, the ES bit is set.
+        * It doesn't match with the information reported into the databook.
+        * At any rate, we need to understand if the CSUM hw computation is ok
+        * and report this info to the upper layers. */
+       ret = gmac_coe_rdes0(p->des01.erx.ipc_csum_error,
+               p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
+
+       if (unlikely(p->des01.erx.dribbling)) {
+               DBG(KERN_ERR "GMAC RX: dribbling error\n");
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.sa_filter_fail)) {
+               DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
+               x->sa_rx_filter_fail++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.da_filter_fail)) {
+               DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
+               x->da_rx_filter_fail++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.length_error)) {
+               DBG(KERN_ERR "GMAC RX: length_error error\n");
+               x->rx_lenght++;
+               ret = discard_frame;
+       }
+#ifdef STMMAC_VLAN_TAG_USED
+       if (p->des01.erx.vlan_tag) {
+               DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
+               x->rx_vlan++;
+       }
+#endif
+       return ret;
+}
+
+static void gmac_irq_status(unsigned long ioaddr)
+{
+       u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
+
+       /* Not used events (e.g. MMC interrupts) are not handled. */
+       if ((intr_status & mmc_tx_irq))
+               DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_TX_INTR));
+       if (unlikely(intr_status & mmc_rx_irq))
+               DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_RX_INTR));
+       if (unlikely(intr_status & mmc_rx_csum_offload_irq))
+               DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+       if (unlikely(intr_status & pmt_irq)) {
+               DBG(KERN_DEBUG "GMAC: received Magic frame\n");
+               /* clear the PMT bits 5 and 6 by reading the PMT
+                * status register. */
+               readl(ioaddr + GMAC_PMT);
+       }
+
+       return;
+}
+
+static void gmac_core_init(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + GMAC_CONTROL);
+       value |= GMAC_CORE_INIT;
+       writel(value, ioaddr + GMAC_CONTROL);
+
+       /* STBus Bridge Configuration */
+       /*writel(0xc5608, ioaddr + 0x00007000);*/
+
+       /* Freeze MMC counters */
+       writel(0x8, ioaddr + GMAC_MMC_CTRL);
+       /* Mask GMAC interrupts */
+       writel(0x207, ioaddr + GMAC_INT_MASK);
+
+#ifdef STMMAC_VLAN_TAG_USED
+       /* Tag detection without filtering */
+       writel(0x0, ioaddr + GMAC_VLAN_TAG);
+#endif
+       return;
+}
+
+static void gmac_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+                               unsigned int reg_n)
+{
+       stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+                               GMAC_ADDR_LOW(reg_n));
+}
+
+static void gmac_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+                               unsigned int reg_n)
+{
+       stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+                               GMAC_ADDR_LOW(reg_n));
+}
+
+static void gmac_set_filter(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       unsigned int value = 0;
+
+       DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
+           __func__, dev->mc_count, dev->uc_count);
+
+       if (dev->flags & IFF_PROMISC)
+               value = GMAC_FRAME_FILTER_PR;
+       else if ((dev->mc_count > HASH_TABLE_SIZE)
+                  || (dev->flags & IFF_ALLMULTI)) {
+               value = GMAC_FRAME_FILTER_PM;   /* pass all multi */
+               writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
+               writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
+       } else if (dev->mc_count > 0) {
+               int i;
+               u32 mc_filter[2];
+               struct dev_mc_list *mclist;
+
+               /* Hash filter for multicast */
+               value = GMAC_FRAME_FILTER_HMC;
+
+               memset(mc_filter, 0, sizeof(mc_filter));
+               for (i = 0, mclist = dev->mc_list;
+                    mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+                       /* The upper 6 bits of the calculated CRC are used to
+                          index the contens of the hash table */
+                       int bit_nr =
+                           bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
+                       /* The most significant bit determines the register to
+                        * use (H/L) while the other 5 bits determine the bit
+                        * within the register. */
+                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+               }
+               writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
+               writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
+       }
+
+       /* Handle multiple unicast addresses (perfect filtering)*/
+       if (dev->uc_count > GMAC_MAX_UNICAST_ADDRESSES)
+               /* Switch to promiscuous mode is more than 16 addrs
+                  are required */
+               value |= GMAC_FRAME_FILTER_PR;
+       else {
+               int i;
+               struct dev_addr_list *uc_ptr = dev->uc_list;
+
+                       for (i = 0; i < dev->uc_count; i++) {
+                               gmac_set_umac_addr(ioaddr, uc_ptr->da_addr,
+                                               i + 1);
+
+                               DBG(KERN_INFO "\t%d "
+                               "- Unicast addr %02x:%02x:%02x:%02x:%02x:"
+                               "%02x\n", i + 1,
+                               uc_ptr->da_addr[0], uc_ptr->da_addr[1],
+                               uc_ptr->da_addr[2], uc_ptr->da_addr[3],
+                               uc_ptr->da_addr[4], uc_ptr->da_addr[5]);
+                               uc_ptr = uc_ptr->next;
+               }
+       }
+
+#ifdef FRAME_FILTER_DEBUG
+       /* Enable Receive all mode (to debug filtering_fail errors) */
+       value |= GMAC_FRAME_FILTER_RA;
+#endif
+       writel(value, ioaddr + GMAC_FRAME_FILTER);
+
+       DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
+           "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
+           readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
+
+       return;
+}
+
+static void gmac_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+                          unsigned int fc, unsigned int pause_time)
+{
+       unsigned int flow = 0;
+
+       DBG(KERN_DEBUG "GMAC Flow-Control:\n");
+       if (fc & FLOW_RX) {
+               DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
+               flow |= GMAC_FLOW_CTRL_RFE;
+       }
+       if (fc & FLOW_TX) {
+               DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
+               flow |= GMAC_FLOW_CTRL_TFE;
+       }
+
+       if (duplex) {
+               DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
+               flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
+       }
+
+       writel(flow, ioaddr + GMAC_FLOW_CTRL);
+       return;
+}
+
+static void gmac_pmt(unsigned long ioaddr, unsigned long mode)
+{
+       unsigned int pmt = 0;
+
+       if (mode == WAKE_MAGIC) {
+               DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
+               pmt |= power_down | magic_pkt_en;
+       } else if (mode == WAKE_UCAST) {
+               DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
+               pmt |= global_unicast;
+       }
+
+       writel(pmt, ioaddr + GMAC_PMT);
+       return;
+}
+
+static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+                               int disable_rx_ic)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.erx.own = 1;
+               p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
+               /* To support jumbo frames */
+               p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
+               if (i == ring_size - 1)
+                       p->des01.erx.end_ring = 1;
+               if (disable_rx_ic)
+                       p->des01.erx.disable_ic = 1;
+               p++;
+       }
+       return;
+}
+
+static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+       int i;
+
+       for (i = 0; i < ring_size; i++) {
+               p->des01.etx.own = 0;
+               if (i == ring_size - 1)
+                       p->des01.etx.end_ring = 1;
+               p++;
+       }
+
+       return;
+}
+
+static int gmac_get_tx_owner(struct dma_desc *p)
+{
+       return p->des01.etx.own;
+}
+
+static int gmac_get_rx_owner(struct dma_desc *p)
+{
+       return p->des01.erx.own;
+}
+
+static void gmac_set_tx_owner(struct dma_desc *p)
+{
+       p->des01.etx.own = 1;
+}
+
+static void gmac_set_rx_owner(struct dma_desc *p)
+{
+       p->des01.erx.own = 1;
+}
+
+static int gmac_get_tx_ls(struct dma_desc *p)
+{
+       return p->des01.etx.last_segment;
+}
+
+static void gmac_release_tx_desc(struct dma_desc *p)
+{
+       int ter = p->des01.etx.end_ring;
+
+       memset(p, 0, sizeof(struct dma_desc));
+       p->des01.etx.end_ring = ter;
+
+       return;
+}
+
+static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+                                int csum_flag)
+{
+       p->des01.etx.first_segment = is_fs;
+       if (unlikely(len > BUF_SIZE_4KiB)) {
+               p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
+               p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
+       } else {
+               p->des01.etx.buffer1_size = len;
+       }
+       if (likely(csum_flag))
+               p->des01.etx.checksum_insertion = cic_full;
+}
+
+static void gmac_clear_tx_ic(struct dma_desc *p)
+{
+       p->des01.etx.interrupt = 0;
+}
+
+static void gmac_close_tx_desc(struct dma_desc *p)
+{
+       p->des01.etx.last_segment = 1;
+       p->des01.etx.interrupt = 1;
+}
+
+static int gmac_get_rx_frame_len(struct dma_desc *p)
+{
+       return p->des01.erx.frame_length;
+}
+
+struct stmmac_ops gmac_driver = {
+       .core_init = gmac_core_init,
+       .dump_mac_regs = gmac_dump_regs,
+       .dma_init = gmac_dma_init,
+       .dump_dma_regs = gmac_dump_dma_regs,
+       .dma_mode = gmac_dma_operation_mode,
+       .dma_diagnostic_fr = gmac_dma_diagnostic_fr,
+       .tx_status = gmac_get_tx_frame_status,
+       .rx_status = gmac_get_rx_frame_status,
+       .get_tx_len = gmac_get_tx_len,
+       .set_filter = gmac_set_filter,
+       .flow_ctrl = gmac_flow_ctrl,
+       .pmt = gmac_pmt,
+       .init_rx_desc = gmac_init_rx_desc,
+       .init_tx_desc = gmac_init_tx_desc,
+       .get_tx_owner = gmac_get_tx_owner,
+       .get_rx_owner = gmac_get_rx_owner,
+       .release_tx_desc = gmac_release_tx_desc,
+       .prepare_tx_desc = gmac_prepare_tx_desc,
+       .clear_tx_ic = gmac_clear_tx_ic,
+       .close_tx_desc = gmac_close_tx_desc,
+       .get_tx_ls = gmac_get_tx_ls,
+       .set_tx_owner = gmac_set_tx_owner,
+       .set_rx_owner = gmac_set_rx_owner,
+       .get_rx_frame_len = gmac_get_rx_frame_len,
+       .host_irq_status = gmac_irq_status,
+       .set_umac_addr = gmac_set_umac_addr,
+       .get_umac_addr = gmac_get_umac_addr,
+};
+
+struct mac_device_info *gmac_setup(unsigned long ioaddr)
+{
+       struct mac_device_info *mac;
+       u32 uid = readl(ioaddr + GMAC_VERSION);
+
+       pr_info("\tGMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
+              ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
+
+       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+       mac->ops = &gmac_driver;
+       mac->hw.pmt = PMT_SUPPORTED;
+       mac->hw.link.port = GMAC_CONTROL_PS;
+       mac->hw.link.duplex = GMAC_CONTROL_DM;
+       mac->hw.link.speed = GMAC_CONTROL_FES;
+       mac->hw.mii.addr = GMAC_MII_ADDR;
+       mac->hw.mii.data = GMAC_MII_DATA;
+
+       return mac;
+}
diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/gmac.h
new file mode 100644 (file)
index 0000000..684a363
--- /dev/null
@@ -0,0 +1,204 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#define GMAC_CONTROL           0x00000000      /* Configuration */
+#define GMAC_FRAME_FILTER      0x00000004      /* Frame Filter */
+#define GMAC_HASH_HIGH         0x00000008      /* Multicast Hash Table High */
+#define GMAC_HASH_LOW          0x0000000c      /* Multicast Hash Table Low */
+#define GMAC_MII_ADDR          0x00000010      /* MII Address */
+#define GMAC_MII_DATA          0x00000014      /* MII Data */
+#define GMAC_FLOW_CTRL         0x00000018      /* Flow Control */
+#define GMAC_VLAN_TAG          0x0000001c      /* VLAN Tag */
+#define GMAC_VERSION           0x00000020      /* GMAC CORE Version */
+#define GMAC_WAKEUP_FILTER     0x00000028      /* Wake-up Frame Filter */
+
+#define GMAC_INT_STATUS                0x00000038      /* interrupt status register */
+enum gmac_irq_status {
+       time_stamp_irq = 0x0200,
+       mmc_rx_csum_offload_irq = 0x0080,
+       mmc_tx_irq = 0x0040,
+       mmc_rx_irq = 0x0020,
+       mmc_irq = 0x0010,
+       pmt_irq = 0x0008,
+       pcs_ane_irq = 0x0004,
+       pcs_link_irq = 0x0002,
+       rgmii_irq = 0x0001,
+};
+#define GMAC_INT_MASK          0x0000003c      /* interrupt mask register */
+
+/* PMT Control and Status */
+#define GMAC_PMT               0x0000002c
+enum power_event {
+       pointer_reset = 0x80000000,
+       global_unicast = 0x00000200,
+       wake_up_rx_frame = 0x00000040,
+       magic_frame = 0x00000020,
+       wake_up_frame_en = 0x00000004,
+       magic_pkt_en = 0x00000002,
+       power_down = 0x00000001,
+};
+
+/* GMAC HW ADDR regs */
+#define GMAC_ADDR_HIGH(reg)            (0x00000040+(reg * 8))
+#define GMAC_ADDR_LOW(reg)             (0x00000044+(reg * 8))
+#define GMAC_MAX_UNICAST_ADDRESSES     16
+
+#define GMAC_AN_CTRL   0x000000c0      /* AN control */
+#define GMAC_AN_STATUS 0x000000c4      /* AN status */
+#define GMAC_ANE_ADV   0x000000c8      /* Auto-Neg. Advertisement */
+#define GMAC_ANE_LINK  0x000000cc      /* Auto-Neg. link partener ability */
+#define GMAC_ANE_EXP   0x000000d0      /* ANE expansion */
+#define GMAC_TBI       0x000000d4      /* TBI extend status */
+#define GMAC_GMII_STATUS 0x000000d8    /* S/R-GMII status */
+
+/* GMAC Configuration defines */
+#define GMAC_CONTROL_TC        0x01000000      /* Transmit Conf. in RGMII/SGMII */
+#define GMAC_CONTROL_WD        0x00800000      /* Disable Watchdog on receive */
+#define GMAC_CONTROL_JD        0x00400000      /* Jabber disable */
+#define GMAC_CONTROL_BE        0x00200000      /* Frame Burst Enable */
+#define GMAC_CONTROL_JE        0x00100000      /* Jumbo frame */
+enum inter_frame_gap {
+       GMAC_CONTROL_IFG_88 = 0x00040000,
+       GMAC_CONTROL_IFG_80 = 0x00020000,
+       GMAC_CONTROL_IFG_40 = 0x000e0000,
+};
+#define GMAC_CONTROL_DCRS      0x00010000 /* Disable carrier sense during tx */
+#define GMAC_CONTROL_PS                0x00008000 /* Port Select 0:GMI 1:MII */
+#define GMAC_CONTROL_FES       0x00004000 /* Speed 0:10 1:100 */
+#define GMAC_CONTROL_DO                0x00002000 /* Disable Rx Own */
+#define GMAC_CONTROL_LM                0x00001000 /* Loop-back mode */
+#define GMAC_CONTROL_DM                0x00000800 /* Duplex Mode */
+#define GMAC_CONTROL_IPC       0x00000400 /* Checksum Offload */
+#define GMAC_CONTROL_DR                0x00000200 /* Disable Retry */
+#define GMAC_CONTROL_LUD       0x00000100 /* Link up/down */
+#define GMAC_CONTROL_ACS       0x00000080 /* Automatic Pad Stripping */
+#define GMAC_CONTROL_DC                0x00000010 /* Deferral Check */
+#define GMAC_CONTROL_TE                0x00000008 /* Transmitter Enable */
+#define GMAC_CONTROL_RE                0x00000004 /* Receiver Enable */
+
+#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
+                       GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
+
+/* GMAC Frame Filter defines */
+#define GMAC_FRAME_FILTER_PR   0x00000001      /* Promiscuous Mode */
+#define GMAC_FRAME_FILTER_HUC  0x00000002      /* Hash Unicast */
+#define GMAC_FRAME_FILTER_HMC  0x00000004      /* Hash Multicast */
+#define GMAC_FRAME_FILTER_DAIF 0x00000008      /* DA Inverse Filtering */
+#define GMAC_FRAME_FILTER_PM   0x00000010      /* Pass all multicast */
+#define GMAC_FRAME_FILTER_DBF  0x00000020      /* Disable Broadcast frames */
+#define GMAC_FRAME_FILTER_SAIF 0x00000100      /* Inverse Filtering */
+#define GMAC_FRAME_FILTER_SAF  0x00000200      /* Source Address Filter */
+#define GMAC_FRAME_FILTER_HPF  0x00000400      /* Hash or perfect Filter */
+#define GMAC_FRAME_FILTER_RA   0x80000000      /* Receive all mode */
+/* GMII ADDR  defines */
+#define GMAC_MII_ADDR_WRITE    0x00000002      /* MII Write */
+#define GMAC_MII_ADDR_BUSY     0x00000001      /* MII Busy */
+/* GMAC FLOW CTRL defines */
+#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000      /* Pause Time Mask */
+#define GMAC_FLOW_CTRL_PT_SHIFT        16
+#define GMAC_FLOW_CTRL_RFE     0x00000004      /* Rx Flow Control Enable */
+#define GMAC_FLOW_CTRL_TFE     0x00000002      /* Tx Flow Control Enable */
+#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001      /* Flow Control Busy ... */
+
+/*--- DMA BLOCK defines ---*/
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
+#define DMA_BUS_MODE_DA                0x00000002      /* Arbitration scheme */
+#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
+/* Programmable burst length (passed thorugh platform)*/
+#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+
+enum rx_tx_priority_ratio {
+       double_ratio = 0x00004000,      /*2:1 */
+       triple_ratio = 0x00008000,      /*3:1 */
+       quadruple_ratio = 0x0000c000,   /*4:1 */
+};
+
+#define DMA_BUS_MODE_FB                0x00010000      /* Fixed burst */
+#define DMA_BUS_MODE_RPBL_MASK 0x003e0000      /* Rx-Programmable Burst Len */
+#define DMA_BUS_MODE_RPBL_SHIFT        17
+#define DMA_BUS_MODE_USP       0x00800000
+#define DMA_BUS_MODE_4PBL      0x01000000
+#define DMA_BUS_MODE_AAL       0x02000000
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_HOST_TX_DESC         0x00001048    /* Current Host Tx descriptor */
+#define DMA_HOST_RX_DESC         0x0000104c    /* Current Host Rx descriptor */
+/*  DMA Bus Mode register defines */
+#define DMA_BUS_PR_RATIO_MASK    0x0000c000    /* Rx/Tx priority ratio */
+#define DMA_BUS_PR_RATIO_SHIFT   14
+#define DMA_BUS_FB               0x00010000    /* Fixed Burst */
+
+/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
+#define DMA_CONTROL_DT         0x04000000 /* Disable Drop TCP/IP csum error */
+#define DMA_CONTROL_RSF                0x02000000 /* Receive Store and Forward */
+#define DMA_CONTROL_DFF                0x01000000 /* Disaable flushing */
+/* Theshold for Activating the FC */
+enum rfa {
+       act_full_minus_1 = 0x00800000,
+       act_full_minus_2 = 0x00800200,
+       act_full_minus_3 = 0x00800400,
+       act_full_minus_4 = 0x00800600,
+};
+/* Theshold for Deactivating the FC */
+enum rfd {
+       deac_full_minus_1 = 0x00400000,
+       deac_full_minus_2 = 0x00400800,
+       deac_full_minus_3 = 0x00401000,
+       deac_full_minus_4 = 0x00401800,
+};
+#define DMA_CONTROL_TSF                0x00200000 /* Transmit  Store and Forward */
+#define DMA_CONTROL_FTF                0x00100000 /* Flush transmit FIFO */
+
+enum ttc_control {
+       DMA_CONTROL_TTC_64 = 0x00000000,
+       DMA_CONTROL_TTC_128 = 0x00004000,
+       DMA_CONTROL_TTC_192 = 0x00008000,
+       DMA_CONTROL_TTC_256 = 0x0000c000,
+       DMA_CONTROL_TTC_40 = 0x00010000,
+       DMA_CONTROL_TTC_32 = 0x00014000,
+       DMA_CONTROL_TTC_24 = 0x00018000,
+       DMA_CONTROL_TTC_16 = 0x0001c000,
+};
+#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
+
+#define DMA_CONTROL_EFC                0x00000100
+#define DMA_CONTROL_FEF                0x00000080
+#define DMA_CONTROL_FUF                0x00000040
+
+enum rtc_control {
+       DMA_CONTROL_RTC_64 = 0x00000000,
+       DMA_CONTROL_RTC_32 = 0x00000008,
+       DMA_CONTROL_RTC_96 = 0x00000010,
+       DMA_CONTROL_RTC_128 = 0x00000018,
+};
+#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
+
+#define DMA_CONTROL_OSF        0x00000004      /* Operate on second frame */
+
+/* MMC registers offset */
+#define GMAC_MMC_CTRL      0x100
+#define GMAC_MMC_RX_INTR   0x104
+#define GMAC_MMC_TX_INTR   0x108
+#define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
diff --git a/drivers/net/stmmac/mac100.c b/drivers/net/stmmac/mac100.c
new file mode 100644 (file)
index 0000000..625171b
--- /dev/null
@@ -0,0 +1,517 @@
+/*******************************************************************************
+  This is the driver for the MAC 10/100 on-chip Ethernet controller
+  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
+
+  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
+  this code.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "common.h"
+#include "mac100.h"
+
+#undef MAC100_DEBUG
+/*#define MAC100_DEBUG*/
+#ifdef MAC100_DEBUG
+#define DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DBG(fmt, args...)  do { } while (0)
+#endif
+
+static void mac100_core_init(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CONTROL);
+
+       writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
+
+#ifdef STMMAC_VLAN_TAG_USED
+       writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
+#endif
+       return;
+}
+
+static void mac100_dump_mac_regs(unsigned long ioaddr)
+{
+       pr_info("\t----------------------------------------------\n"
+              "\t  MAC100 CSR (base addr = 0x%8x)\n"
+              "\t----------------------------------------------\n",
+              (unsigned int)ioaddr);
+       pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
+              readl(ioaddr + MAC_CONTROL));
+       pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
+              readl(ioaddr + MAC_ADDR_HIGH));
+       pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
+              readl(ioaddr + MAC_ADDR_LOW));
+       pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
+                       MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
+       pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
+                       MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
+       pr_info("\tflow control (offset 0x%x): 0x%08x\n",
+               MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
+       pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
+              readl(ioaddr + MAC_VLAN1));
+       pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
+              readl(ioaddr + MAC_VLAN2));
+       pr_info("\n\tMAC management counter registers\n");
+       pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
+              MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
+       pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
+              MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
+       pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
+              MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
+       pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
+              MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
+       pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
+              MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
+       return;
+}
+
+static int mac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+                          u32 dma_rx)
+{
+       u32 value = readl(ioaddr + DMA_BUS_MODE);
+       /* DMA SW reset */
+       value |= DMA_BUS_MODE_SFT_RESET;
+       writel(value, ioaddr + DMA_BUS_MODE);
+       do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
+
+       /* Enable Application Access by writing to DMA CSR0 */
+       writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
+              ioaddr + DMA_BUS_MODE);
+
+       /* Mask interrupts by writing to CSR7 */
+       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+       /* The base address of the RX/TX descriptor lists must be written into
+        * DMA CSR3 and CSR4, respectively. */
+       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+       return 0;
+}
+
+/* Store and Forward capability is not used at all..
+ * The transmit threshold can be programmed by
+ * setting the TTC bits in the DMA control register.*/
+static void mac100_dma_operation_mode(unsigned long ioaddr, int txmode,
+                                     int rxmode)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+       if (txmode <= 32)
+               csr6 |= DMA_CONTROL_TTC_32;
+       else if (txmode <= 64)
+               csr6 |= DMA_CONTROL_TTC_64;
+       else
+               csr6 |= DMA_CONTROL_TTC_128;
+
+       writel(csr6, ioaddr + DMA_CONTROL);
+
+       return;
+}
+
+static void mac100_dump_dma_regs(unsigned long ioaddr)
+{
+       int i;
+
+       DBG(KERN_DEBUG "MAC100 DMA CSR \n");
+       for (i = 0; i < 9; i++)
+               pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
+                      (DMA_BUS_MODE + i * 4),
+                      readl(ioaddr + DMA_BUS_MODE + i * 4));
+       DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
+           DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
+       DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
+           DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
+       return;
+}
+
+/* DMA controller has two counters to track the number of
+   the receive missed frames. */
+static void mac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
+                                    unsigned long ioaddr)
+{
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+       u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
+
+       if (unlikely(csr8)) {
+               if (csr8 & DMA_MISSED_FRAME_OVE) {
+                       stats->rx_over_errors += 0x800;
+                       x->rx_overflow_cntr += 0x800;
+               } else {
+                       unsigned int ove_cntr;
+                       ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
+                       stats->rx_over_errors += ove_cntr;
+                       x->rx_overflow_cntr += ove_cntr;
+               }
+
+               if (csr8 & DMA_MISSED_FRAME_OVE_M) {
+                       stats->rx_missed_errors += 0xffff;
+                       x->rx_missed_cntr += 0xffff;
+               } else {
+                       unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
+                       stats->rx_missed_errors += miss_f;
+                       x->rx_missed_cntr += miss_f;
+               }
+       }
+       return;
+}
+
+static int mac100_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
+                                     struct dma_desc *p, unsigned long ioaddr)
+{
+       int ret = 0;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.tx.error_summary)) {
+               if (unlikely(p->des01.tx.underflow_error)) {
+                       x->tx_underflow++;
+                       stats->tx_fifo_errors++;
+               }
+               if (unlikely(p->des01.tx.no_carrier)) {
+                       x->tx_carrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.tx.loss_carrier)) {
+                       x->tx_losscarrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely((p->des01.tx.excessive_deferral) ||
+                            (p->des01.tx.excessive_collisions) ||
+                            (p->des01.tx.late_collision)))
+                       stats->collisions += p->des01.tx.collision_count;
+               ret = -1;
+       }
+       if (unlikely(p->des01.tx.heartbeat_fail)) {
+               x->tx_heartbeat++;
+               stats->tx_heartbeat_errors++;
+               ret = -1;
+       }
+       if (unlikely(p->des01.tx.deferred))
+               x->tx_deferred++;
+
+       return ret;
+}
+
+static int mac100_get_tx_len(struct dma_desc *p)
+{
+       return p->des01.tx.buffer1_size;
+}
+
+/* This function verifies if each incoming frame has some errors
+ * and, if required, updates the multicast statistics.
+ * In case of success, it returns csum_none becasue the device
+ * is not able to compute the csum in HW. */
+static int mac100_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
+                                     struct dma_desc *p)
+{
+       int ret = csum_none;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.rx.last_descriptor == 0)) {
+               pr_warning("mac100 Error: Oversized Ethernet "
+                          "frame spanned multiple buffers\n");
+               stats->rx_length_errors++;
+               return discard_frame;
+       }
+
+       if (unlikely(p->des01.rx.error_summary)) {
+               if (unlikely(p->des01.rx.descriptor_error))
+                       x->rx_desc++;
+               if (unlikely(p->des01.rx.partial_frame_error))
+                       x->rx_partial++;
+               if (unlikely(p->des01.rx.run_frame))
+                       x->rx_runt++;
+               if (unlikely(p->des01.rx.frame_too_long))
+                       x->rx_toolong++;
+               if (unlikely(p->des01.rx.collision)) {
+                       x->rx_collision++;
+                       stats->collisions++;
+               }
+               if (unlikely(p->des01.rx.crc_error)) {
+                       x->rx_crc++;
+                       stats->rx_crc_errors++;
+               }
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.rx.dribbling))
+               ret = discard_frame;
+
+       if (unlikely(p->des01.rx.length_error)) {
+               x->rx_lenght++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.rx.mii_error)) {
+               x->rx_mii++;
+               ret = discard_frame;
+       }
+       if (p->des01.rx.multicast_frame) {
+               x->rx_multicast++;
+               stats->multicast++;
+       }
+       return ret;
+}
+
+static void mac100_irq_status(unsigned long ioaddr)
+{
+       return;
+}
+
+static void mac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+                         unsigned int reg_n)
+{
+       stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void mac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+                         unsigned int reg_n)
+{
+       stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void mac100_set_filter(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       u32 value = readl(ioaddr + MAC_CONTROL);
+
+       if (dev->flags & IFF_PROMISC) {
+               value |= MAC_CONTROL_PR;
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
+                          MAC_CONTROL_HP);
+       } else if ((dev->mc_count > HASH_TABLE_SIZE)
+                  || (dev->flags & IFF_ALLMULTI)) {
+               value |= MAC_CONTROL_PM;
+               value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
+               writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
+               writel(0xffffffff, ioaddr + MAC_HASH_LOW);
+       } else if (dev->mc_count == 0) {        /* no multicast */
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
+                          MAC_CONTROL_HO | MAC_CONTROL_HP);
+       } else {
+               int i;
+               u32 mc_filter[2];
+               struct dev_mc_list *mclist;
+
+               /* Perfect filter mode for physical address and Hash
+                  filter for multicast */
+               value |= MAC_CONTROL_HP;
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF
+                          | MAC_CONTROL_HO);
+
+               memset(mc_filter, 0, sizeof(mc_filter));
+               for (i = 0, mclist = dev->mc_list;
+                    mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+                       /* The upper 6 bits of the calculated CRC are used to
+                        * index the contens of the hash table */
+                       int bit_nr =
+                           ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+                       /* The most significant bit determines the register to
+                        * use (H/L) while the other 5 bits determine the bit
+                        * within the register. */
+                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+               }
+               writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
+               writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
+       }
+
+       writel(value, ioaddr + MAC_CONTROL);
+
+       DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
+           "HI 0x%08x, LO 0x%08x\n",
+           __func__, readl(ioaddr + MAC_CONTROL),
+           readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
+       return;
+}
+
+static void mac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+                            unsigned int fc, unsigned int pause_time)
+{
+       unsigned int flow = MAC_FLOW_CTRL_ENABLE;
+
+       if (duplex)
+               flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
+       writel(flow, ioaddr + MAC_FLOW_CTRL);
+
+       return;
+}
+
+/* No PMT module supported in our SoC  for the Ethernet Controller. */
+static void mac100_pmt(unsigned long ioaddr, unsigned long mode)
+{
+       return;
+}
+
+static void mac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+                               int disable_rx_ic)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.rx.own = 1;
+               p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
+               if (i == ring_size - 1)
+                       p->des01.rx.end_ring = 1;
+               if (disable_rx_ic)
+                       p->des01.rx.disable_ic = 1;
+               p++;
+       }
+       return;
+}
+
+static void mac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.tx.own = 0;
+               if (i == ring_size - 1)
+                       p->des01.tx.end_ring = 1;
+               p++;
+       }
+       return;
+}
+
+static int mac100_get_tx_owner(struct dma_desc *p)
+{
+       return p->des01.tx.own;
+}
+
+static int mac100_get_rx_owner(struct dma_desc *p)
+{
+       return p->des01.rx.own;
+}
+
+static void mac100_set_tx_owner(struct dma_desc *p)
+{
+       p->des01.tx.own = 1;
+}
+
+static void mac100_set_rx_owner(struct dma_desc *p)
+{
+       p->des01.rx.own = 1;
+}
+
+static int mac100_get_tx_ls(struct dma_desc *p)
+{
+       return p->des01.tx.last_segment;
+}
+
+static void mac100_release_tx_desc(struct dma_desc *p)
+{
+       int ter = p->des01.tx.end_ring;
+
+       /* clean field used within the xmit */
+       p->des01.tx.first_segment = 0;
+       p->des01.tx.last_segment = 0;
+       p->des01.tx.buffer1_size = 0;
+
+       /* clean status reported */
+       p->des01.tx.error_summary = 0;
+       p->des01.tx.underflow_error = 0;
+       p->des01.tx.no_carrier = 0;
+       p->des01.tx.loss_carrier = 0;
+       p->des01.tx.excessive_deferral = 0;
+       p->des01.tx.excessive_collisions = 0;
+       p->des01.tx.late_collision = 0;
+       p->des01.tx.heartbeat_fail = 0;
+       p->des01.tx.deferred = 0;
+
+       /* set termination field */
+       p->des01.tx.end_ring = ter;
+
+       return;
+}
+
+static void mac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+                                  int csum_flag)
+{
+       p->des01.tx.first_segment = is_fs;
+       p->des01.tx.buffer1_size = len;
+}
+
+static void mac100_clear_tx_ic(struct dma_desc *p)
+{
+       p->des01.tx.interrupt = 0;
+}
+
+static void mac100_close_tx_desc(struct dma_desc *p)
+{
+       p->des01.tx.last_segment = 1;
+       p->des01.tx.interrupt = 1;
+}
+
+static int mac100_get_rx_frame_len(struct dma_desc *p)
+{
+       return p->des01.rx.frame_length;
+}
+
+struct stmmac_ops mac100_driver = {
+       .core_init = mac100_core_init,
+       .dump_mac_regs = mac100_dump_mac_regs,
+       .dma_init = mac100_dma_init,
+       .dump_dma_regs = mac100_dump_dma_regs,
+       .dma_mode = mac100_dma_operation_mode,
+       .dma_diagnostic_fr = mac100_dma_diagnostic_fr,
+       .tx_status = mac100_get_tx_frame_status,
+       .rx_status = mac100_get_rx_frame_status,
+       .get_tx_len = mac100_get_tx_len,
+       .set_filter = mac100_set_filter,
+       .flow_ctrl = mac100_flow_ctrl,
+       .pmt = mac100_pmt,
+       .init_rx_desc = mac100_init_rx_desc,
+       .init_tx_desc = mac100_init_tx_desc,
+       .get_tx_owner = mac100_get_tx_owner,
+       .get_rx_owner = mac100_get_rx_owner,
+       .release_tx_desc = mac100_release_tx_desc,
+       .prepare_tx_desc = mac100_prepare_tx_desc,
+       .clear_tx_ic = mac100_clear_tx_ic,
+       .close_tx_desc = mac100_close_tx_desc,
+       .get_tx_ls = mac100_get_tx_ls,
+       .set_tx_owner = mac100_set_tx_owner,
+       .set_rx_owner = mac100_set_rx_owner,
+       .get_rx_frame_len = mac100_get_rx_frame_len,
+       .host_irq_status = mac100_irq_status,
+       .set_umac_addr = mac100_set_umac_addr,
+       .get_umac_addr = mac100_get_umac_addr,
+};
+
+struct mac_device_info *mac100_setup(unsigned long ioaddr)
+{
+       struct mac_device_info *mac;
+
+       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+
+       pr_info("\tMAC 10/100\n");
+
+       mac->ops = &mac100_driver;
+       mac->hw.pmt = PMT_NOT_SUPPORTED;
+       mac->hw.link.port = MAC_CONTROL_PS;
+       mac->hw.link.duplex = MAC_CONTROL_F;
+       mac->hw.link.speed = 0;
+       mac->hw.mii.addr = MAC_MII_ADDR;
+       mac->hw.mii.data = MAC_MII_DATA;
+
+       return mac;
+}
diff --git a/drivers/net/stmmac/mac100.h b/drivers/net/stmmac/mac100.h
new file mode 100644 (file)
index 0000000..0f8f110
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************
+  MAC 10/100 Header File
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+/*----------------------------------------------------------------------------
+ *                             MAC BLOCK defines
+ *---------------------------------------------------------------------------*/
+/* MAC CSR offset */
+#define MAC_CONTROL    0x00000000      /* MAC Control */
+#define MAC_ADDR_HIGH  0x00000004      /* MAC Address High */
+#define MAC_ADDR_LOW   0x00000008      /* MAC Address Low */
+#define MAC_HASH_HIGH  0x0000000c      /* Multicast Hash Table High */
+#define MAC_HASH_LOW   0x00000010      /* Multicast Hash Table Low */
+#define MAC_MII_ADDR   0x00000014      /* MII Address */
+#define MAC_MII_DATA   0x00000018      /* MII Data */
+#define MAC_FLOW_CTRL  0x0000001c      /* Flow Control */
+#define MAC_VLAN1      0x00000020      /* VLAN1 Tag */
+#define MAC_VLAN2      0x00000024      /* VLAN2 Tag */
+
+/* MAC CTRL defines */
+#define MAC_CONTROL_RA 0x80000000      /* Receive All Mode */
+#define MAC_CONTROL_BLE        0x40000000      /* Endian Mode */
+#define MAC_CONTROL_HBD        0x10000000      /* Heartbeat Disable */
+#define MAC_CONTROL_PS 0x08000000      /* Port Select */
+#define MAC_CONTROL_DRO        0x00800000      /* Disable Receive Own */
+#define MAC_CONTROL_EXT_LOOPBACK 0x00400000    /* Reserved (ext loopback?) */
+#define MAC_CONTROL_OM 0x00200000      /* Loopback Operating Mode */
+#define MAC_CONTROL_F  0x00100000      /* Full Duplex Mode */
+#define MAC_CONTROL_PM 0x00080000      /* Pass All Multicast */
+#define MAC_CONTROL_PR 0x00040000      /* Promiscuous Mode */
+#define MAC_CONTROL_IF 0x00020000      /* Inverse Filtering */
+#define MAC_CONTROL_PB 0x00010000      /* Pass Bad Frames */
+#define MAC_CONTROL_HO 0x00008000      /* Hash Only Filtering Mode */
+#define MAC_CONTROL_HP 0x00002000      /* Hash/Perfect Filtering Mode */
+#define MAC_CONTROL_LCC        0x00001000      /* Late Collision Control */
+#define MAC_CONTROL_DBF        0x00000800      /* Disable Broadcast Frames */
+#define MAC_CONTROL_DRTY       0x00000400      /* Disable Retry */
+#define MAC_CONTROL_ASTP       0x00000100      /* Automatic Pad Stripping */
+#define MAC_CONTROL_BOLMT_10   0x00000000      /* Back Off Limit 10 */
+#define MAC_CONTROL_BOLMT_8    0x00000040      /* Back Off Limit 8 */
+#define MAC_CONTROL_BOLMT_4    0x00000080      /* Back Off Limit 4 */
+#define MAC_CONTROL_BOLMT_1    0x000000c0      /* Back Off Limit 1 */
+#define MAC_CONTROL_DC         0x00000020      /* Deferral Check */
+#define MAC_CONTROL_TE         0x00000008      /* Transmitter Enable */
+#define MAC_CONTROL_RE         0x00000004      /* Receiver Enable */
+
+#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
+
+/* MAC FLOW CTRL defines */
+#define MAC_FLOW_CTRL_PT_MASK  0xffff0000      /* Pause Time Mask */
+#define MAC_FLOW_CTRL_PT_SHIFT 16
+#define MAC_FLOW_CTRL_PASS     0x00000004      /* Pass Control Frames */
+#define MAC_FLOW_CTRL_ENABLE   0x00000002      /* Flow Control Enable */
+#define MAC_FLOW_CTRL_PAUSE    0x00000001      /* Flow Control Busy ... */
+
+/* MII ADDR  defines */
+#define MAC_MII_ADDR_WRITE     0x00000002      /* MII Write */
+#define MAC_MII_ADDR_BUSY      0x00000001      /* MII Busy */
+
+/*----------------------------------------------------------------------------
+ *                             DMA BLOCK defines
+ *---------------------------------------------------------------------------*/
+
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_DBO       0x00100000      /* Descriptor Byte Ordering */
+#define DMA_BUS_MODE_BLE       0x00000080      /* Big Endian/Little Endian */
+#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
+#define DMA_BUS_MODE_BAR_BUS   0x00000002      /* Bar-Bus Arbitration */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
+#define DMA_BUS_MODE_DEFAULT   0x00000000
+
+/* DMA Control register defines */
+#define DMA_CONTROL_SF         0x00200000      /* Store And Forward */
+
+/* Transmit Threshold Control */
+enum ttc_control {
+       DMA_CONTROL_TTC_DEFAULT = 0x00000000,   /* Threshold is 32 DWORDS */
+       DMA_CONTROL_TTC_64 = 0x00004000,        /* Threshold is 64 DWORDS */
+       DMA_CONTROL_TTC_128 = 0x00008000,       /* Threshold is 128 DWORDS */
+       DMA_CONTROL_TTC_256 = 0x0000c000,       /* Threshold is 256 DWORDS */
+       DMA_CONTROL_TTC_18 = 0x00400000,        /* Threshold is 18 DWORDS */
+       DMA_CONTROL_TTC_24 = 0x00404000,        /* Threshold is 24 DWORDS */
+       DMA_CONTROL_TTC_32 = 0x00408000,        /* Threshold is 32 DWORDS */
+       DMA_CONTROL_TTC_40 = 0x0040c000,        /* Threshold is 40 DWORDS */
+       DMA_CONTROL_SE = 0x00000008,    /* Stop On Empty */
+       DMA_CONTROL_OSF = 0x00000004,   /* Operate On 2nd Frame */
+};
+
+/* STMAC110 DMA Missed Frame Counter register defines */
+#define DMA_MISSED_FRAME_OVE   0x10000000      /* FIFO Overflow Overflow */
+#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000   /* Overflow Frame Counter */
+#define DMA_MISSED_FRAME_OVE_M 0x00010000      /* Missed Frame Overflow */
+#define DMA_MISSED_FRAME_M_CNTR        0x0000ffff      /* Missed Frame Couinter */
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
new file mode 100644 (file)
index 0000000..6d2eae3
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#define DRV_MODULE_VERSION     "Oct_09"
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define STMMAC_VLAN_TAG_USED
+#include <linux/if_vlan.h>
+#endif
+
+#include "common.h"
+#ifdef CONFIG_STMMAC_TIMER
+#include "stmmac_timer.h"
+#endif
+
+struct stmmac_priv {
+       /* Frequently used values are kept adjacent for cache effect */
+       struct dma_desc *dma_tx ____cacheline_aligned;
+       dma_addr_t dma_tx_phy;
+       struct sk_buff **tx_skbuff;
+       unsigned int cur_tx;
+       unsigned int dirty_tx;
+       unsigned int dma_tx_size;
+       int tx_coe;
+       int tx_coalesce;
+
+       struct dma_desc *dma_rx ;
+       unsigned int cur_rx;
+       unsigned int dirty_rx;
+       struct sk_buff **rx_skbuff;
+       dma_addr_t *rx_skbuff_dma;
+       struct sk_buff_head rx_recycle;
+
+       struct net_device *dev;
+       int is_gmac;
+       dma_addr_t dma_rx_phy;
+       unsigned int dma_rx_size;
+       int rx_csum;
+       unsigned int dma_buf_sz;
+       struct device *device;
+       struct mac_device_info *mac_type;
+
+       struct stmmac_extra_stats xstats;
+       struct napi_struct napi;
+
+       phy_interface_t phy_interface;
+       int pbl;
+       int bus_id;
+       int phy_addr;
+       int phy_mask;
+       int (*phy_reset) (void *priv);
+       void (*fix_mac_speed) (void *priv, unsigned int speed);
+       void *bsp_priv;
+
+       int phy_irq;
+       struct phy_device *phydev;
+       int oldlink;
+       int speed;
+       int oldduplex;
+       unsigned int flow_ctrl;
+       unsigned int pause;
+       struct mii_bus *mii;
+
+       u32 msg_enable;
+       spinlock_t lock;
+       int wolopts;
+       int wolenabled;
+       int shutdown;
+#ifdef CONFIG_STMMAC_TIMER
+       struct stmmac_timer *tm;
+#endif
+#ifdef STMMAC_VLAN_TAG_USED
+       struct vlan_group *vlgrp;
+#endif
+};
+
+extern int stmmac_mdio_unregister(struct net_device *ndev);
+extern int stmmac_mdio_register(struct net_device *ndev);
+extern void stmmac_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
new file mode 100644 (file)
index 0000000..694ebe6
--- /dev/null
@@ -0,0 +1,395 @@
+/*******************************************************************************
+  STMMAC Ethtool support
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+
+#define REG_SPACE_SIZE 0x1054
+#define MAC100_ETHTOOL_NAME    "st_mac100"
+#define GMAC_ETHTOOL_NAME      "st_gmac"
+
+struct stmmac_stats {
+       char stat_string[ETH_GSTRING_LEN];
+       int sizeof_stat;
+       int stat_offset;
+};
+
+#define STMMAC_STAT(m) \
+       { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m),       \
+       offsetof(struct stmmac_priv, xstats.m)}
+
+static const struct  stmmac_stats stmmac_gstrings_stats[] = {
+       STMMAC_STAT(tx_underflow),
+       STMMAC_STAT(tx_carrier),
+       STMMAC_STAT(tx_losscarrier),
+       STMMAC_STAT(tx_heartbeat),
+       STMMAC_STAT(tx_deferred),
+       STMMAC_STAT(tx_vlan),
+       STMMAC_STAT(rx_vlan),
+       STMMAC_STAT(tx_jabber),
+       STMMAC_STAT(tx_frame_flushed),
+       STMMAC_STAT(tx_payload_error),
+       STMMAC_STAT(tx_ip_header_error),
+       STMMAC_STAT(rx_desc),
+       STMMAC_STAT(rx_partial),
+       STMMAC_STAT(rx_runt),
+       STMMAC_STAT(rx_toolong),
+       STMMAC_STAT(rx_collision),
+       STMMAC_STAT(rx_crc),
+       STMMAC_STAT(rx_lenght),
+       STMMAC_STAT(rx_mii),
+       STMMAC_STAT(rx_multicast),
+       STMMAC_STAT(rx_gmac_overflow),
+       STMMAC_STAT(rx_watchdog),
+       STMMAC_STAT(da_rx_filter_fail),
+       STMMAC_STAT(sa_rx_filter_fail),
+       STMMAC_STAT(rx_missed_cntr),
+       STMMAC_STAT(rx_overflow_cntr),
+       STMMAC_STAT(tx_undeflow_irq),
+       STMMAC_STAT(tx_process_stopped_irq),
+       STMMAC_STAT(tx_jabber_irq),
+       STMMAC_STAT(rx_overflow_irq),
+       STMMAC_STAT(rx_buf_unav_irq),
+       STMMAC_STAT(rx_process_stopped_irq),
+       STMMAC_STAT(rx_watchdog_irq),
+       STMMAC_STAT(tx_early_irq),
+       STMMAC_STAT(fatal_bus_error_irq),
+       STMMAC_STAT(threshold),
+       STMMAC_STAT(tx_pkt_n),
+       STMMAC_STAT(rx_pkt_n),
+       STMMAC_STAT(poll_n),
+       STMMAC_STAT(sched_timer_n),
+       STMMAC_STAT(normal_irq_n),
+};
+#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
+
+void stmmac_ethtool_getdrvinfo(struct net_device *dev,
+                              struct ethtool_drvinfo *info)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (!priv->is_gmac)
+               strcpy(info->driver, MAC100_ETHTOOL_NAME);
+       else
+               strcpy(info->driver, GMAC_ETHTOOL_NAME);
+
+       strcpy(info->version, DRV_MODULE_VERSION);
+       info->fw_version[0] = '\0';
+       info->n_stats = STMMAC_STATS_LEN;
+       return;
+}
+
+int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phy = priv->phydev;
+       int rc;
+       if (phy == NULL) {
+               pr_err("%s: %s: PHY is not registered\n",
+                      __func__, dev->name);
+               return -ENODEV;
+       }
+       if (!netif_running(dev)) {
+               pr_err("%s: interface is disabled: we cannot track "
+               "link speed / duplex setting\n", dev->name);
+               return -EBUSY;
+       }
+       cmd->transceiver = XCVR_INTERNAL;
+       spin_lock_irq(&priv->lock);
+       rc = phy_ethtool_gset(phy, cmd);
+       spin_unlock_irq(&priv->lock);
+       return rc;
+}
+
+int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phy = priv->phydev;
+       int rc;
+
+       spin_lock(&priv->lock);
+       rc = phy_ethtool_sset(phy, cmd);
+       spin_unlock(&priv->lock);
+
+       return rc;
+}
+
+u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       return priv->msg_enable;
+}
+
+void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       priv->msg_enable = level;
+
+}
+
+int stmmac_check_if_running(struct net_device *dev)
+{
+       if (!netif_running(dev))
+               return -EBUSY;
+       return 0;
+}
+
+int stmmac_ethtool_get_regs_len(struct net_device *dev)
+{
+       return REG_SPACE_SIZE;
+}
+
+void stmmac_ethtool_gregs(struct net_device *dev,
+                         struct ethtool_regs *regs, void *space)
+{
+       int i;
+       u32 *reg_space = (u32 *) space;
+
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       memset(reg_space, 0x0, REG_SPACE_SIZE);
+
+       if (!priv->is_gmac) {
+               /* MAC registers */
+               for (i = 0; i < 12; i++)
+                       reg_space[i] = readl(dev->base_addr + (i * 4));
+               /* DMA registers */
+               for (i = 0; i < 9; i++)
+                       reg_space[i + 12] =
+                           readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+               reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR);
+               reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR);
+       } else {
+               /* MAC registers */
+               for (i = 0; i < 55; i++)
+                       reg_space[i] = readl(dev->base_addr + (i * 4));
+               /* DMA registers */
+               for (i = 0; i < 22; i++)
+                       reg_space[i + 55] =
+                           readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+       }
+
+       return;
+}
+
+int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
+{
+       if (data)
+               netdev->features |= NETIF_F_HW_CSUM;
+       else
+               netdev->features &= ~NETIF_F_HW_CSUM;
+
+       return 0;
+}
+
+u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       return priv->rx_csum;
+}
+
+static void
+stmmac_get_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+
+       spin_lock(&priv->lock);
+
+       pause->rx_pause = 0;
+       pause->tx_pause = 0;
+       pause->autoneg = priv->phydev->autoneg;
+
+       if (priv->flow_ctrl & FLOW_RX)
+               pause->rx_pause = 1;
+       if (priv->flow_ctrl & FLOW_TX)
+               pause->tx_pause = 1;
+
+       spin_unlock(&priv->lock);
+       return;
+}
+
+static int
+stmmac_set_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+       struct phy_device *phy = priv->phydev;
+       int new_pause = FLOW_OFF;
+       int ret = 0;
+
+       spin_lock(&priv->lock);
+
+       if (pause->rx_pause)
+               new_pause |= FLOW_RX;
+       if (pause->tx_pause)
+               new_pause |= FLOW_TX;
+
+       priv->flow_ctrl = new_pause;
+
+       if (phy->autoneg) {
+               if (netif_running(netdev)) {
+                       struct ethtool_cmd cmd;
+                       /* auto-negotiation automatically restarted */
+                       cmd.cmd = ETHTOOL_NWAY_RST;
+                       cmd.supported = phy->supported;
+                       cmd.advertising = phy->advertising;
+                       cmd.autoneg = phy->autoneg;
+                       cmd.speed = phy->speed;
+                       cmd.duplex = phy->duplex;
+                       cmd.phy_address = phy->addr;
+                       ret = phy_ethtool_sset(phy, &cmd);
+               }
+       } else {
+               unsigned long ioaddr = netdev->base_addr;
+               priv->mac_type->ops->flow_ctrl(ioaddr, phy->duplex,
+                                              priv->flow_ctrl, priv->pause);
+       }
+       spin_unlock(&priv->lock);
+       return ret;
+}
+
+static void stmmac_get_ethtool_stats(struct net_device *dev,
+                                struct ethtool_stats *dummy, u64 *data)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       int i;
+
+       /* Update HW stats if supported */
+       priv->mac_type->ops->dma_diagnostic_fr(&dev->stats, &priv->xstats,
+                                              ioaddr);
+
+       for (i = 0; i < STMMAC_STATS_LEN; i++) {
+               char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
+               data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
+               sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
+       }
+
+       return;
+}
+
+static int stmmac_get_sset_count(struct net_device *netdev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return STMMAC_STATS_LEN;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+       int i;
+       u8 *p = data;
+
+       switch (stringset) {
+       case ETH_SS_STATS:
+               for (i = 0; i < STMMAC_STATS_LEN; i++) {
+                       memcpy(p, stmmac_gstrings_stats[i].stat_string,
+                               ETH_GSTRING_LEN);
+                       p += ETH_GSTRING_LEN;
+               }
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+       return;
+}
+
+/* Currently only support WOL through Magic packet. */
+static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       spin_lock_irq(&priv->lock);
+       if (priv->wolenabled == PMT_SUPPORTED) {
+               wol->supported = WAKE_MAGIC;
+               wol->wolopts = priv->wolopts;
+       }
+       spin_unlock_irq(&priv->lock);
+}
+
+static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       u32 support = WAKE_MAGIC;
+
+       if (priv->wolenabled == PMT_NOT_SUPPORTED)
+               return -EINVAL;
+
+       if (wol->wolopts & ~support)
+               return -EINVAL;
+
+       if (wol->wolopts == 0)
+               device_set_wakeup_enable(priv->device, 0);
+       else
+               device_set_wakeup_enable(priv->device, 1);
+
+       spin_lock_irq(&priv->lock);
+       priv->wolopts = wol->wolopts;
+       spin_unlock_irq(&priv->lock);
+
+       return 0;
+}
+
+static struct ethtool_ops stmmac_ethtool_ops = {
+       .begin = stmmac_check_if_running,
+       .get_drvinfo = stmmac_ethtool_getdrvinfo,
+       .get_settings = stmmac_ethtool_getsettings,
+       .set_settings = stmmac_ethtool_setsettings,
+       .get_msglevel = stmmac_ethtool_getmsglevel,
+       .set_msglevel = stmmac_ethtool_setmsglevel,
+       .get_regs = stmmac_ethtool_gregs,
+       .get_regs_len = stmmac_ethtool_get_regs_len,
+       .get_link = ethtool_op_get_link,
+       .get_rx_csum = stmmac_ethtool_get_rx_csum,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = stmmac_ethtool_set_tx_csum,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = ethtool_op_set_sg,
+       .get_pauseparam = stmmac_get_pauseparam,
+       .set_pauseparam = stmmac_set_pauseparam,
+       .get_ethtool_stats = stmmac_get_ethtool_stats,
+       .get_strings = stmmac_get_strings,
+       .get_wol = stmmac_get_wol,
+       .set_wol = stmmac_set_wol,
+       .get_sset_count = stmmac_get_sset_count,
+#ifdef NETIF_F_TSO
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = ethtool_op_set_tso,
+#endif
+};
+
+void stmmac_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
+}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
new file mode 100644 (file)
index 0000000..c2f14dc
--- /dev/null
@@ -0,0 +1,2204 @@
+/*******************************************************************************
+  This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
+  ST Ethernet IPs are built around a Synopsys IP Core.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+  Documentation available at:
+       http://www.stlinux.com
+  Support available at:
+       https://bugzilla.stlinux.com/
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/if_vlan.h>
+#include <linux/dma-mapping.h>
+#include <linux/stm/soc.h>
+#include "stmmac.h"
+
+#define STMMAC_RESOURCE_NAME   "stmmaceth"
+#define PHY_RESOURCE_NAME      "stmmacphy"
+
+#undef STMMAC_DEBUG
+/*#define STMMAC_DEBUG*/
+#ifdef STMMAC_DEBUG
+#define DBG(nlevel, klevel, fmt, args...) \
+               ((void)(netif_msg_##nlevel(priv) && \
+               printk(KERN_##klevel fmt, ## args)))
+#else
+#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
+#endif
+
+#undef STMMAC_RX_DEBUG
+/*#define STMMAC_RX_DEBUG*/
+#ifdef STMMAC_RX_DEBUG
+#define RX_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define RX_DBG(fmt, args...)  do { } while (0)
+#endif
+
+#undef STMMAC_XMIT_DEBUG
+/*#define STMMAC_XMIT_DEBUG*/
+#ifdef STMMAC_TX_DEBUG
+#define TX_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define TX_DBG(fmt, args...)  do { } while (0)
+#endif
+
+#define STMMAC_ALIGN(x)        L1_CACHE_ALIGN(x)
+#define JUMBO_LEN      9000
+
+/* Module parameters */
+#define TX_TIMEO 5000 /* default 5 seconds */
+static int watchdog = TX_TIMEO;
+module_param(watchdog, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
+
+static int debug = -1;         /* -1: default, 0: no output, 16:  all */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
+
+static int phyaddr = -1;
+module_param(phyaddr, int, S_IRUGO);
+MODULE_PARM_DESC(phyaddr, "Physical device address");
+
+#define DMA_TX_SIZE 256
+static int dma_txsize = DMA_TX_SIZE;
+module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
+
+#define DMA_RX_SIZE 256
+static int dma_rxsize = DMA_RX_SIZE;
+module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
+
+static int flow_ctrl = FLOW_OFF;
+module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
+
+static int pause = PAUSE_TIME;
+module_param(pause, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pause, "Flow Control Pause Time");
+
+#define TC_DEFAULT 64
+static int tc = TC_DEFAULT;
+module_param(tc, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tc, "DMA threshold control value");
+
+#define RX_NO_COALESCE 1       /* Always interrupt on completion */
+#define TX_NO_COALESCE -1      /* No moderation by default */
+
+/* Pay attention to tune this parameter; take care of both
+ * hardware capability and network stabitily/performance impact.
+ * Many tests showed that ~4ms latency seems to be good enough. */
+#ifdef CONFIG_STMMAC_TIMER
+#define DEFAULT_PERIODIC_RATE  256
+static int tmrate = DEFAULT_PERIODIC_RATE;
+module_param(tmrate, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
+#endif
+
+#define DMA_BUFFER_SIZE        BUF_SIZE_2KiB
+static int buf_sz = DMA_BUFFER_SIZE;
+module_param(buf_sz, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(buf_sz, "DMA buffer size");
+
+/* In case of Giga ETH, we can enable/disable the COE for the
+ * transmit HW checksum computation.
+ * Note that, if tx csum is off in HW, SG will be still supported. */
+static int tx_coe = HW_CSUM;
+module_param(tx_coe, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]");
+
+static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+                                     NETIF_MSG_LINK | NETIF_MSG_IFUP |
+                                     NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
+static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
+
+/**
+ * stmmac_verify_args - verify the driver parameters.
+ * Description: it verifies if some wrong parameter is passed to the driver.
+ * Note that wrong parameters are replaced with the default values.
+ */
+static void stmmac_verify_args(void)
+{
+       if (unlikely(watchdog < 0))
+               watchdog = TX_TIMEO;
+       if (unlikely(dma_rxsize < 0))
+               dma_rxsize = DMA_RX_SIZE;
+       if (unlikely(dma_txsize < 0))
+               dma_txsize = DMA_TX_SIZE;
+       if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
+               buf_sz = DMA_BUFFER_SIZE;
+       if (unlikely(flow_ctrl > 1))
+               flow_ctrl = FLOW_AUTO;
+       else if (likely(flow_ctrl < 0))
+               flow_ctrl = FLOW_OFF;
+       if (unlikely((pause < 0) || (pause > 0xffff)))
+               pause = PAUSE_TIME;
+
+       return;
+}
+
+#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
+static void print_pkt(unsigned char *buf, int len)
+{
+       int j;
+       pr_info("len = %d byte, buf addr: 0x%p", len, buf);
+       for (j = 0; j < len; j++) {
+               if ((j % 16) == 0)
+                       pr_info("\n %03x:", j);
+               pr_info(" %02x", buf[j]);
+       }
+       pr_info("\n");
+       return;
+}
+#endif
+
+/* minimum number of free TX descriptors required to wake up TX process */
+#define STMMAC_TX_THRESH(x)    (x->dma_tx_size/4)
+
+static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
+{
+       return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
+}
+
+/**
+ * stmmac_adjust_link
+ * @dev: net device structure
+ * Description: it adjusts the link parameters.
+ */
+static void stmmac_adjust_link(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+       unsigned long ioaddr = dev->base_addr;
+       unsigned long flags;
+       int new_state = 0;
+       unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
+
+       if (phydev == NULL)
+               return;
+
+       DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
+           phydev->addr, phydev->link);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (phydev->link) {
+               u32 ctrl = readl(ioaddr + MAC_CTRL_REG);
+
+               /* Now we make sure that we can be in full duplex mode.
+                * If not, we operate in half-duplex mode. */
+               if (phydev->duplex != priv->oldduplex) {
+                       new_state = 1;
+                       if (!(phydev->duplex))
+                               ctrl &= ~priv->mac_type->hw.link.duplex;
+                       else
+                               ctrl |= priv->mac_type->hw.link.duplex;
+                       priv->oldduplex = phydev->duplex;
+               }
+               /* Flow Control operation */
+               if (phydev->pause)
+                       priv->mac_type->ops->flow_ctrl(ioaddr, phydev->duplex,
+                                                      fc, pause_time);
+
+               if (phydev->speed != priv->speed) {
+                       new_state = 1;
+                       switch (phydev->speed) {
+                       case 1000:
+                               if (likely(priv->is_gmac))
+                                       ctrl &= ~priv->mac_type->hw.link.port;
+                               break;
+                       case 100:
+                       case 10:
+                               if (priv->is_gmac) {
+                                       ctrl |= priv->mac_type->hw.link.port;
+                                       if (phydev->speed == SPEED_100) {
+                                               ctrl |=
+                                                   priv->mac_type->hw.link.
+                                                   speed;
+                                       } else {
+                                               ctrl &=
+                                                   ~(priv->mac_type->hw.
+                                                     link.speed);
+                                       }
+                               } else {
+                                       ctrl &= ~priv->mac_type->hw.link.port;
+                               }
+                               priv->fix_mac_speed(priv->bsp_priv,
+                                                   phydev->speed);
+                               break;
+                       default:
+                               if (netif_msg_link(priv))
+                                       pr_warning("%s: Speed (%d) is not 10"
+                                      " or 100!\n", dev->name, phydev->speed);
+                               break;
+                       }
+
+                       priv->speed = phydev->speed;
+               }
+
+               writel(ctrl, ioaddr + MAC_CTRL_REG);
+
+               if (!priv->oldlink) {
+                       new_state = 1;
+                       priv->oldlink = 1;
+               }
+       } else if (priv->oldlink) {
+               new_state = 1;
+               priv->oldlink = 0;
+               priv->speed = 0;
+               priv->oldduplex = -1;
+       }
+
+       if (new_state && netif_msg_link(priv))
+               phy_print_status(phydev);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
+}
+
+/**
+ * stmmac_init_phy - PHY initialization
+ * @dev: net device structure
+ * Description: it initializes the driver's PHY state, and attaches the PHY
+ * to the mac driver.
+ *  Return value:
+ *  0 on success
+ */
+static int stmmac_init_phy(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev;
+       char phy_id[BUS_ID_SIZE];       /* PHY to connect */
+       char bus_id[BUS_ID_SIZE];
+
+       priv->oldlink = 0;
+       priv->speed = 0;
+       priv->oldduplex = -1;
+
+       if (priv->phy_addr == -1) {
+               /* We don't have a PHY, so do nothing */
+               return 0;
+       }
+
+       snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, bus_id, priv->phy_addr);
+       pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id);
+
+       phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
+                       priv->phy_interface);
+
+       if (IS_ERR(phydev)) {
+               pr_err("%s: Could not attach to PHY\n", dev->name);
+               return PTR_ERR(phydev);
+       }
+
+       /*
+        * Broken HW is sometimes missing the pull-up resistor on the
+        * MDIO line, which results in reads to non-existent devices returning
+        * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
+        * device as well.
+        * Note: phydev->phy_id is the result of reading the UID PHY registers.
+        */
+       if (phydev->phy_id == 0) {
+               phy_disconnect(phydev);
+               return -ENODEV;
+       }
+       pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
+              " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
+
+       priv->phydev = phydev;
+
+       return 0;
+}
+
+static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+       value |= MAC_RNABLE_RX;
+       /* Set the RE (receive enable bit into the MAC CTRL register).  */
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+       value |= MAC_ENABLE_TX;
+       /* Set the TE (transmit enable bit into the MAC CTRL register).  */
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_disable_rx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+       value &= ~MAC_RNABLE_RX;
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_mac_disable_tx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+       value &= ~MAC_ENABLE_TX;
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+/**
+ * display_ring
+ * @p: pointer to the ring.
+ * @size: size of the ring.
+ * Description: display all the descriptors within the ring.
+ */
+static void display_ring(struct dma_desc *p, int size)
+{
+       struct tmp_s {
+               u64 a;
+               unsigned int b;
+               unsigned int c;
+       };
+       int i;
+       for (i = 0; i < size; i++) {
+               struct tmp_s *x = (struct tmp_s *)(p + i);
+               pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
+                      i, (unsigned int)virt_to_phys(&p[i]),
+                      (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
+                      x->b, x->c);
+               pr_info("\n");
+       }
+}
+
+/**
+ * init_dma_desc_rings - init the RX/TX descriptor rings
+ * @dev: net device structure
+ * Description:  this function initializes the DMA RX/TX descriptors
+ * and allocates the socket buffers.
+ */
+static void init_dma_desc_rings(struct net_device *dev)
+{
+       int i;
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct sk_buff *skb;
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int rxsize = priv->dma_rx_size;
+       unsigned int bfsize = priv->dma_buf_sz;
+       int buff2_needed = 0;
+       int dis_ic = 0;
+
+#ifdef CONFIG_STMMAC_TIMER
+       /* Using Timers disable interrupts on completion for the reception */
+       dis_ic = 1;
+#endif
+       /* Set the Buffer size according to the MTU;
+        * indeed, in case of jumbo we need to bump-up the buffer sizes.
+        */
+       if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
+               bfsize = BUF_SIZE_16KiB;
+       else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
+               bfsize = BUF_SIZE_8KiB;
+       else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
+               bfsize = BUF_SIZE_4KiB;
+       else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
+               bfsize = BUF_SIZE_2KiB;
+       else
+               bfsize = DMA_BUFFER_SIZE;
+
+       /* If the MTU exceeds 8k so use the second buffer in the chain */
+       if (bfsize >= BUF_SIZE_8KiB)
+               buff2_needed = 1;
+
+       DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
+           txsize, rxsize, bfsize);
+
+       priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
+       priv->rx_skbuff =
+           kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
+       priv->dma_rx =
+           (struct dma_desc *)dma_alloc_coherent(priv->device,
+                                                 rxsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_rx_phy,
+                                                 GFP_KERNEL);
+       priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
+                                      GFP_KERNEL);
+       priv->dma_tx =
+           (struct dma_desc *)dma_alloc_coherent(priv->device,
+                                                 txsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_tx_phy,
+                                                 GFP_KERNEL);
+
+       if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
+               pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
+               return;
+       }
+
+       DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
+           "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
+           dev->name, priv->dma_rx, priv->dma_tx,
+           (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
+
+       /* RX INITIALIZATION */
+       DBG(probe, INFO, "stmmac: SKB addresses:\n"
+                        "skb\t\tskb data\tdma data\n");
+
+       for (i = 0; i < rxsize; i++) {
+               struct dma_desc *p = priv->dma_rx + i;
+
+               skb = netdev_alloc_skb_ip_align(dev, bfsize);
+               if (unlikely(skb == NULL)) {
+                       pr_err("%s: Rx init fails; skb is NULL\n", __func__);
+                       break;
+               }
+               priv->rx_skbuff[i] = skb;
+               priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
+                                               bfsize, DMA_FROM_DEVICE);
+
+               p->des2 = priv->rx_skbuff_dma[i];
+               if (unlikely(buff2_needed))
+                       p->des3 = p->des2 + BUF_SIZE_8KiB;
+               DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
+                       priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
+       }
+       priv->cur_rx = 0;
+       priv->dirty_rx = (unsigned int)(i - rxsize);
+       priv->dma_buf_sz = bfsize;
+       buf_sz = bfsize;
+
+       /* TX INITIALIZATION */
+       for (i = 0; i < txsize; i++) {
+               priv->tx_skbuff[i] = NULL;
+               priv->dma_tx[i].des2 = 0;
+       }
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+
+       /* Clear the Rx/Tx descriptors */
+       priv->mac_type->ops->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
+       priv->mac_type->ops->init_tx_desc(priv->dma_tx, txsize);
+
+       if (netif_msg_hw(priv)) {
+               pr_info("RX descriptor ring:\n");
+               display_ring(priv->dma_rx, rxsize);
+               pr_info("TX descriptor ring:\n");
+               display_ring(priv->dma_tx, txsize);
+       }
+       return;
+}
+
+static void dma_free_rx_skbufs(struct stmmac_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->dma_rx_size; i++) {
+               if (priv->rx_skbuff[i]) {
+                       dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
+                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
+                       dev_kfree_skb_any(priv->rx_skbuff[i]);
+               }
+               priv->rx_skbuff[i] = NULL;
+       }
+       return;
+}
+
+static void dma_free_tx_skbufs(struct stmmac_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->dma_tx_size; i++) {
+               if (priv->tx_skbuff[i] != NULL) {
+                       struct dma_desc *p = priv->dma_tx + i;
+                       if (p->des2)
+                               dma_unmap_single(priv->device, p->des2,
+                                priv->mac_type->ops->get_tx_len(p),
+                                DMA_TO_DEVICE);
+                       dev_kfree_skb_any(priv->tx_skbuff[i]);
+                       priv->tx_skbuff[i] = NULL;
+               }
+       }
+       return;
+}
+
+static void free_dma_desc_resources(struct stmmac_priv *priv)
+{
+       /* Release the DMA TX/RX socket buffers */
+       dma_free_rx_skbufs(priv);
+       dma_free_tx_skbufs(priv);
+
+       /* Free the region of consistent memory previously allocated for
+        * the DMA */
+       dma_free_coherent(priv->device,
+                         priv->dma_tx_size * sizeof(struct dma_desc),
+                         priv->dma_tx, priv->dma_tx_phy);
+       dma_free_coherent(priv->device,
+                         priv->dma_rx_size * sizeof(struct dma_desc),
+                         priv->dma_rx, priv->dma_rx_phy);
+       kfree(priv->rx_skbuff_dma);
+       kfree(priv->rx_skbuff);
+       kfree(priv->tx_skbuff);
+
+       return;
+}
+
+/**
+ * stmmac_dma_start_tx
+ * @ioaddr: device I/O address
+ * Description:  this function starts the DMA tx process.
+ */
+static void stmmac_dma_start_tx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value |= DMA_CONTROL_ST;
+       writel(value, ioaddr + DMA_CONTROL);
+       return;
+}
+
+static void stmmac_dma_stop_tx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value &= ~DMA_CONTROL_ST;
+       writel(value, ioaddr + DMA_CONTROL);
+       return;
+}
+
+/**
+ * stmmac_dma_start_rx
+ * @ioaddr: device I/O address
+ * Description:  this function starts the DMA rx process.
+ */
+static void stmmac_dma_start_rx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value |= DMA_CONTROL_SR;
+       writel(value, ioaddr + DMA_CONTROL);
+
+       return;
+}
+
+static void stmmac_dma_stop_rx(unsigned long ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value &= ~DMA_CONTROL_SR;
+       writel(value, ioaddr + DMA_CONTROL);
+
+       return;
+}
+
+/**
+ *  stmmac_dma_operation_mode - HW DMA operation mode
+ *  @priv : pointer to the private device structure.
+ *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
+ *  or Store-And-Forward capability. It also verifies the COE for the
+ *  transmission in case of Giga ETH.
+ */
+static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
+{
+       if (!priv->is_gmac) {
+               /* MAC 10/100 */
+               priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc, 0);
+               priv->tx_coe = NO_HW_CSUM;
+       } else {
+               if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
+                       priv->mac_type->ops->dma_mode(priv->dev->base_addr,
+                                                     SF_DMA_MODE, SF_DMA_MODE);
+                       tc = SF_DMA_MODE;
+                       priv->tx_coe = HW_CSUM;
+               } else {
+                       /* Checksum computation is performed in software. */
+                       priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc,
+                                                     SF_DMA_MODE);
+                       priv->tx_coe = NO_HW_CSUM;
+               }
+       }
+       tx_coe = priv->tx_coe;
+
+       return;
+}
+
+#ifdef STMMAC_DEBUG
+/**
+ * show_tx_process_state
+ * @status: tx descriptor status field
+ * Description: it shows the Transmit Process State for CSR5[22:20]
+ */
+static void show_tx_process_state(unsigned int status)
+{
+       unsigned int state;
+       state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
+
+       switch (state) {
+       case 0:
+               pr_info("- TX (Stopped): Reset or Stop command\n");
+               break;
+       case 1:
+               pr_info("- TX (Running):Fetching the Tx desc\n");
+               break;
+       case 2:
+               pr_info("- TX (Running): Waiting for end of tx\n");
+               break;
+       case 3:
+               pr_info("- TX (Running): Reading the data "
+                      "and queuing the data into the Tx buf\n");
+               break;
+       case 6:
+               pr_info("- TX (Suspended): Tx Buff Underflow "
+                      "or an unavailable Transmit descriptor\n");
+               break;
+       case 7:
+               pr_info("- TX (Running): Closing Tx descriptor\n");
+               break;
+       default:
+               break;
+       }
+       return;
+}
+
+/**
+ * show_rx_process_state
+ * @status: rx descriptor status field
+ * Description: it shows the  Receive Process State for CSR5[19:17]
+ */
+static void show_rx_process_state(unsigned int status)
+{
+       unsigned int state;
+       state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
+
+       switch (state) {
+       case 0:
+               pr_info("- RX (Stopped): Reset or Stop command\n");
+               break;
+       case 1:
+               pr_info("- RX (Running): Fetching the Rx desc\n");
+               break;
+       case 2:
+               pr_info("- RX (Running):Checking for end of pkt\n");
+               break;
+       case 3:
+               pr_info("- RX (Running): Waiting for Rx pkt\n");
+               break;
+       case 4:
+               pr_info("- RX (Suspended): Unavailable Rx buf\n");
+               break;
+       case 5:
+               pr_info("- RX (Running): Closing Rx descriptor\n");
+               break;
+       case 6:
+               pr_info("- RX(Running): Flushing the current frame"
+                      " from the Rx buf\n");
+               break;
+       case 7:
+               pr_info("- RX (Running): Queuing the Rx frame"
+                      " from the Rx buf into memory\n");
+               break;
+       default:
+               break;
+       }
+       return;
+}
+#endif
+
+/**
+ * stmmac_tx:
+ * @priv: private driver structure
+ * Description: it reclaims resources after transmission completes.
+ */
+static void stmmac_tx(struct stmmac_priv *priv)
+{
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned long ioaddr = priv->dev->base_addr;
+
+       while (priv->dirty_tx != priv->cur_tx) {
+               int last;
+               unsigned int entry = priv->dirty_tx % txsize;
+               struct sk_buff *skb = priv->tx_skbuff[entry];
+               struct dma_desc *p = priv->dma_tx + entry;
+
+               /* Check if the descriptor is owned by the DMA. */
+               if (priv->mac_type->ops->get_tx_owner(p))
+                       break;
+
+               /* Verify tx error by looking at the last segment */
+               last = priv->mac_type->ops->get_tx_ls(p);
+               if (likely(last)) {
+                       int tx_error =
+                           priv->mac_type->ops->tx_status(&priv->dev->stats,
+                                                          &priv->xstats,
+                                                          p, ioaddr);
+                       if (likely(tx_error == 0)) {
+                               priv->dev->stats.tx_packets++;
+                               priv->xstats.tx_pkt_n++;
+                       } else
+                               priv->dev->stats.tx_errors++;
+               }
+               TX_DBG("%s: curr %d, dirty %d\n", __func__,
+                       priv->cur_tx, priv->dirty_tx);
+
+               if (likely(p->des2))
+                       dma_unmap_single(priv->device, p->des2,
+                                        priv->mac_type->ops->get_tx_len(p),
+                                        DMA_TO_DEVICE);
+               if (unlikely(p->des3))
+                       p->des3 = 0;
+
+               if (likely(skb != NULL)) {
+                       /*
+                        * If there's room in the queue (limit it to size)
+                        * we add this skb back into the pool,
+                        * if it's the right size.
+                        */
+                       if ((skb_queue_len(&priv->rx_recycle) <
+                               priv->dma_rx_size) &&
+                               skb_recycle_check(skb, priv->dma_buf_sz))
+                               __skb_queue_head(&priv->rx_recycle, skb);
+                       else
+                               dev_kfree_skb(skb);
+
+                       priv->tx_skbuff[entry] = NULL;
+               }
+
+               priv->mac_type->ops->release_tx_desc(p);
+
+               entry = (++priv->dirty_tx) % txsize;
+       }
+       if (unlikely(netif_queue_stopped(priv->dev) &&
+                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
+               netif_tx_lock(priv->dev);
+               if (netif_queue_stopped(priv->dev) &&
+                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
+                       TX_DBG("%s: restart transmit\n", __func__);
+                       netif_wake_queue(priv->dev);
+               }
+               netif_tx_unlock(priv->dev);
+       }
+       return;
+}
+
+static inline void stmmac_enable_irq(struct stmmac_priv *priv)
+{
+#ifndef CONFIG_STMMAC_TIMER
+       writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
+#else
+       priv->tm->timer_start(tmrate);
+#endif
+}
+
+static inline void stmmac_disable_irq(struct stmmac_priv *priv)
+{
+#ifndef CONFIG_STMMAC_TIMER
+       writel(0, priv->dev->base_addr + DMA_INTR_ENA);
+#else
+       priv->tm->timer_stop();
+#endif
+}
+
+static int stmmac_has_work(struct stmmac_priv *priv)
+{
+       unsigned int has_work = 0;
+       int rxret, tx_work = 0;
+
+       rxret = priv->mac_type->ops->get_rx_owner(priv->dma_rx +
+               (priv->cur_rx % priv->dma_rx_size));
+
+       if (priv->dirty_tx != priv->cur_tx)
+               tx_work = 1;
+
+       if (likely(!rxret || tx_work))
+               has_work = 1;
+
+       return has_work;
+}
+
+static inline void _stmmac_schedule(struct stmmac_priv *priv)
+{
+       if (likely(stmmac_has_work(priv))) {
+               stmmac_disable_irq(priv);
+               napi_schedule(&priv->napi);
+       }
+}
+
+#ifdef CONFIG_STMMAC_TIMER
+void stmmac_schedule(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       priv->xstats.sched_timer_n++;
+
+       _stmmac_schedule(priv);
+
+       return;
+}
+
+static void stmmac_no_timer_started(unsigned int x)
+{;
+};
+
+static void stmmac_no_timer_stopped(void)
+{;
+};
+#endif
+
+/**
+ * stmmac_tx_err:
+ * @priv: pointer to the private device structure
+ * Description: it cleans the descriptors and restarts the transmission
+ * in case of errors.
+ */
+static void stmmac_tx_err(struct stmmac_priv *priv)
+{
+       netif_stop_queue(priv->dev);
+
+       stmmac_dma_stop_tx(priv->dev->base_addr);
+       dma_free_tx_skbufs(priv);
+       priv->mac_type->ops->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+       stmmac_dma_start_tx(priv->dev->base_addr);
+
+       priv->dev->stats.tx_errors++;
+       netif_wake_queue(priv->dev);
+
+       return;
+}
+
+/**
+ * stmmac_dma_interrupt - Interrupt handler for the driver
+ * @dev: net device structure
+ * Description: Interrupt handler for the driver (DMA).
+ */
+static void stmmac_dma_interrupt(struct net_device *dev)
+{
+       unsigned long ioaddr = dev->base_addr;
+       struct stmmac_priv *priv = netdev_priv(dev);
+       /* read the status register (CSR5) */
+       u32 intr_status = readl(ioaddr + DMA_STATUS);
+
+       DBG(intr, INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
+
+#ifdef STMMAC_DEBUG
+       /* It displays the DMA transmit process state (CSR5 register) */
+       if (netif_msg_tx_done(priv))
+               show_tx_process_state(intr_status);
+       if (netif_msg_rx_status(priv))
+               show_rx_process_state(intr_status);
+#endif
+       /* ABNORMAL interrupts */
+       if (unlikely(intr_status & DMA_STATUS_AIS)) {
+               DBG(intr, INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
+               if (unlikely(intr_status & DMA_STATUS_UNF)) {
+                       DBG(intr, INFO, "transmit underflow\n");
+                       if (unlikely(tc != SF_DMA_MODE)
+                           && (tc <= 256)) {
+                               /* Try to bump up the threshold */
+                               tc += 64;
+                               priv->mac_type->ops->dma_mode(ioaddr, tc,
+                                             SF_DMA_MODE);
+                               priv->xstats.threshold = tc;
+                       }
+                       stmmac_tx_err(priv);
+                       priv->xstats.tx_undeflow_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_TJT)) {
+                       DBG(intr, INFO, "transmit jabber\n");
+                       priv->xstats.tx_jabber_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_OVF)) {
+                       DBG(intr, INFO, "recv overflow\n");
+                       priv->xstats.rx_overflow_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RU)) {
+                       DBG(intr, INFO, "receive buffer unavailable\n");
+                       priv->xstats.rx_buf_unav_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RPS)) {
+                       DBG(intr, INFO, "receive process stopped\n");
+                       priv->xstats.rx_process_stopped_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RWT)) {
+                       DBG(intr, INFO, "receive watchdog\n");
+                       priv->xstats.rx_watchdog_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_ETI)) {
+                       DBG(intr, INFO, "transmit early interrupt\n");
+                       priv->xstats.tx_early_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_TPS)) {
+                       DBG(intr, INFO, "transmit process stopped\n");
+                       priv->xstats.tx_process_stopped_irq++;
+                       stmmac_tx_err(priv);
+               }
+               if (unlikely(intr_status & DMA_STATUS_FBI)) {
+                       DBG(intr, INFO, "fatal bus error\n");
+                       priv->xstats.fatal_bus_error_irq++;
+                       stmmac_tx_err(priv);
+               }
+       }
+
+       /* TX/RX NORMAL interrupts */
+       if (intr_status & DMA_STATUS_NIS) {
+               priv->xstats.normal_irq_n++;
+               if (likely((intr_status & DMA_STATUS_RI) ||
+                        (intr_status & (DMA_STATUS_TI))))
+                               _stmmac_schedule(priv);
+       }
+
+       /* Optional hardware blocks, interrupts should be disabled */
+       if (unlikely(intr_status &
+                    (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
+               pr_info("%s: unexpected status %08x\n", __func__, intr_status);
+
+       /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
+       writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
+
+       DBG(intr, INFO, "\n\n");
+
+       return;
+}
+
+/**
+ *  stmmac_open - open entry point of the driver
+ *  @dev : pointer to the device structure.
+ *  Description:
+ *  This function is the open entry point of the driver.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_open(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+       int ret;
+
+       /* Check that the MAC address is valid.  If its not, refuse
+        * to bring the device up. The user must specify an
+        * address using the following linux command:
+        *      ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx  */
+       if (!is_valid_ether_addr(dev->dev_addr)) {
+               random_ether_addr(dev->dev_addr);
+               pr_warning("%s: generated random MAC address %pM\n", dev->name,
+                       dev->dev_addr);
+       }
+
+       stmmac_verify_args();
+
+       ret = stmmac_init_phy(dev);
+       if (unlikely(ret)) {
+               pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
+               return ret;
+       }
+
+       /* Request the IRQ lines */
+       ret = request_irq(dev->irq, &stmmac_interrupt,
+                         IRQF_SHARED, dev->name, dev);
+       if (unlikely(ret < 0)) {
+               pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
+                      __func__, dev->irq, ret);
+               return ret;
+       }
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
+       if (unlikely(priv->tm == NULL)) {
+               pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
+               return -ENOMEM;
+       }
+       priv->tm->freq = tmrate;
+
+       /* Test if the HW timer can be actually used.
+        * In case of failure continue with no timer. */
+       if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
+               pr_warning("stmmaceth: cannot attach the HW timer\n");
+               tmrate = 0;
+               priv->tm->freq = 0;
+               priv->tm->timer_start = stmmac_no_timer_started;
+               priv->tm->timer_stop = stmmac_no_timer_stopped;
+       }
+#endif
+
+       /* Create and initialize the TX/RX descriptors chains. */
+       priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
+       priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
+       priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
+       init_dma_desc_rings(dev);
+
+       /* DMA initialization and SW reset */
+       if (unlikely(priv->mac_type->ops->dma_init(ioaddr,
+               priv->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) {
+
+               pr_err("%s: DMA initialization failed\n", __func__);
+               return -1;
+       }
+
+       /* Copy the MAC addr into the HW  */
+       priv->mac_type->ops->set_umac_addr(ioaddr, dev->dev_addr, 0);
+       /* Initialize the MAC Core */
+       priv->mac_type->ops->core_init(ioaddr);
+
+       priv->shutdown = 0;
+
+       /* Initialise the MMC (if present) to disable all interrupts. */
+       writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK);
+       writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK);
+
+       /* Enable the MAC Rx/Tx */
+       stmmac_mac_enable_rx(ioaddr);
+       stmmac_mac_enable_tx(ioaddr);
+
+       /* Set the HW DMA mode and the COE */
+       stmmac_dma_operation_mode(priv);
+
+       /* Extra statistics */
+       memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+       priv->xstats.threshold = tc;
+
+       /* Start the ball rolling... */
+       DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
+       stmmac_dma_start_tx(ioaddr);
+       stmmac_dma_start_rx(ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm->timer_start(tmrate);
+#endif
+       /* Dump DMA/MAC registers */
+       if (netif_msg_hw(priv)) {
+               priv->mac_type->ops->dump_mac_regs(ioaddr);
+               priv->mac_type->ops->dump_dma_regs(ioaddr);
+       }
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
+       napi_enable(&priv->napi);
+       skb_queue_head_init(&priv->rx_recycle);
+       netif_start_queue(dev);
+       return 0;
+}
+
+/**
+ *  stmmac_release - close entry point of the driver
+ *  @dev : device pointer.
+ *  Description:
+ *  This is the stop entry point of the driver.
+ */
+static int stmmac_release(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       /* Stop and disconnect the PHY */
+       if (priv->phydev) {
+               phy_stop(priv->phydev);
+               phy_disconnect(priv->phydev);
+               priv->phydev = NULL;
+       }
+
+       netif_stop_queue(dev);
+
+#ifdef CONFIG_STMMAC_TIMER
+       /* Stop and release the timer */
+       stmmac_close_ext_timer();
+       if (priv->tm != NULL)
+               kfree(priv->tm);
+#endif
+       napi_disable(&priv->napi);
+       skb_queue_purge(&priv->rx_recycle);
+
+       /* Free the IRQ lines */
+       free_irq(dev->irq, dev);
+
+       /* Stop TX/RX DMA and clear the descriptors */
+       stmmac_dma_stop_tx(dev->base_addr);
+       stmmac_dma_stop_rx(dev->base_addr);
+
+       /* Release and free the Rx/Tx resources */
+       free_dma_desc_resources(priv);
+
+       /* Disable the MAC core */
+       stmmac_mac_disable_tx(dev->base_addr);
+       stmmac_mac_disable_rx(dev->base_addr);
+
+       netif_carrier_off(dev);
+
+       return 0;
+}
+
+/*
+ * To perform emulated hardware segmentation on skb.
+ */
+static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
+{
+       struct sk_buff *segs, *curr_skb;
+       int gso_segs = skb_shinfo(skb)->gso_segs;
+
+       /* Estimate the number of fragments in the worst case */
+       if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
+               netif_stop_queue(priv->dev);
+               TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
+                      __func__);
+               if (stmmac_tx_avail(priv) < gso_segs)
+                       return NETDEV_TX_BUSY;
+
+               netif_wake_queue(priv->dev);
+       }
+       TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
+              skb, skb->len);
+
+       segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
+       if (unlikely(IS_ERR(segs)))
+               goto sw_tso_end;
+
+       do {
+               curr_skb = segs;
+               segs = segs->next;
+               TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
+                      "*next %p\n", curr_skb->len, curr_skb, segs);
+               curr_skb->next = NULL;
+               stmmac_xmit(curr_skb, priv->dev);
+       } while (segs);
+
+sw_tso_end:
+       dev_kfree_skb(skb);
+
+       return NETDEV_TX_OK;
+}
+
+static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
+                                              struct net_device *dev,
+                                              int csum_insertion)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned int nopaged_len = skb_headlen(skb);
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int entry = priv->cur_tx % txsize;
+       struct dma_desc *desc = priv->dma_tx + entry;
+
+       if (nopaged_len > BUF_SIZE_8KiB) {
+
+               int buf2_size = nopaged_len - BUF_SIZE_8KiB;
+
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                           BUF_SIZE_8KiB, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->mac_type->ops->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
+                                                    csum_insertion);
+
+               entry = (++priv->cur_tx) % txsize;
+               desc = priv->dma_tx + entry;
+
+               desc->des2 = dma_map_single(priv->device,
+                                       skb->data + BUF_SIZE_8KiB,
+                                       buf2_size, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->mac_type->ops->prepare_tx_desc(desc, 0,
+                                                    buf2_size, csum_insertion);
+               priv->mac_type->ops->set_tx_owner(desc);
+               priv->tx_skbuff[entry] = NULL;
+       } else {
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                       nopaged_len, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
+                                                    csum_insertion);
+       }
+       return entry;
+}
+
+/**
+ *  stmmac_xmit:
+ *  @skb : the socket buffer
+ *  @dev : device pointer
+ *  Description : Tx entry point of the driver.
+ */
+static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int entry;
+       int i, csum_insertion = 0;
+       int nfrags = skb_shinfo(skb)->nr_frags;
+       struct dma_desc *desc, *first;
+
+       if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
+               if (!netif_queue_stopped(dev)) {
+                       netif_stop_queue(dev);
+                       /* This is a hard error, log it. */
+                       pr_err("%s: BUG! Tx Ring full when queue awake\n",
+                               __func__);
+               }
+               return NETDEV_TX_BUSY;
+       }
+
+       entry = priv->cur_tx % txsize;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if ((skb->len > ETH_FRAME_LEN) || nfrags)
+               pr_info("stmmac xmit:\n"
+                      "\tskb addr %p - len: %d - nopaged_len: %d\n"
+                      "\tn_frags: %d - ip_summed: %d - %s gso\n",
+                      skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
+                      !skb_is_gso(skb) ? "isn't" : "is");
+#endif
+
+       if (unlikely(skb_is_gso(skb)))
+               return stmmac_sw_tso(priv, skb);
+
+       if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
+               if (likely(priv->tx_coe == NO_HW_CSUM))
+                       skb_checksum_help(skb);
+               else
+                       csum_insertion = 1;
+       }
+
+       desc = priv->dma_tx + entry;
+       first = desc;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
+               pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
+                      "\t\tn_frags: %d, ip_summed: %d\n",
+                      skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
+#endif
+       priv->tx_skbuff[entry] = skb;
+       if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
+               entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
+               desc = priv->dma_tx + entry;
+       } else {
+               unsigned int nopaged_len = skb_headlen(skb);
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                       nopaged_len, DMA_TO_DEVICE);
+               priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
+                                                    csum_insertion);
+       }
+
+       for (i = 0; i < nfrags; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               int len = frag->size;
+
+               entry = (++priv->cur_tx) % txsize;
+               desc = priv->dma_tx + entry;
+
+               TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
+               desc->des2 = dma_map_page(priv->device, frag->page,
+                                         frag->page_offset,
+                                         len, DMA_TO_DEVICE);
+               priv->tx_skbuff[entry] = NULL;
+               priv->mac_type->ops->prepare_tx_desc(desc, 0, len,
+                                                    csum_insertion);
+               priv->mac_type->ops->set_tx_owner(desc);
+       }
+
+       /* Interrupt on completition only for the latest segment */
+       priv->mac_type->ops->close_tx_desc(desc);
+#ifdef CONFIG_STMMAC_TIMER
+       /* Clean IC while using timers */
+       priv->mac_type->ops->clear_tx_ic(desc);
+#endif
+       /* To avoid raise condition */
+       priv->mac_type->ops->set_tx_owner(first);
+
+       priv->cur_tx++;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if (netif_msg_pktdata(priv)) {
+               pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
+                      "first=%p, nfrags=%d\n",
+                      (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
+                      entry, first, nfrags);
+               display_ring(priv->dma_tx, txsize);
+               pr_info(">>> frame to be transmitted: ");
+               print_pkt(skb->data, skb->len);
+       }
+#endif
+       if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
+               TX_DBG("%s: stop transmitted packets\n", __func__);
+               netif_stop_queue(dev);
+       }
+
+       dev->stats.tx_bytes += skb->len;
+
+       /* CSR1 enables the transmit DMA to check for new descriptor */
+       writel(1, dev->base_addr + DMA_XMT_POLL_DEMAND);
+
+       return NETDEV_TX_OK;
+}
+
+static inline void stmmac_rx_refill(struct stmmac_priv *priv)
+{
+       unsigned int rxsize = priv->dma_rx_size;
+       int bfsize = priv->dma_buf_sz;
+       struct dma_desc *p = priv->dma_rx;
+
+       for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
+               unsigned int entry = priv->dirty_rx % rxsize;
+               if (likely(priv->rx_skbuff[entry] == NULL)) {
+                       struct sk_buff *skb;
+
+                       skb = __skb_dequeue(&priv->rx_recycle);
+                       if (skb == NULL)
+                               skb = netdev_alloc_skb_ip_align(priv->dev,
+                                                               bfsize);
+
+                       if (unlikely(skb == NULL))
+                               break;
+
+                       priv->rx_skbuff[entry] = skb;
+                       priv->rx_skbuff_dma[entry] =
+                           dma_map_single(priv->device, skb->data, bfsize,
+                                          DMA_FROM_DEVICE);
+
+                       (p + entry)->des2 = priv->rx_skbuff_dma[entry];
+                       if (unlikely(priv->is_gmac)) {
+                               if (bfsize >= BUF_SIZE_8KiB)
+                                       (p + entry)->des3 =
+                                           (p + entry)->des2 + BUF_SIZE_8KiB;
+                       }
+                       RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
+               }
+               priv->mac_type->ops->set_rx_owner(p + entry);
+       }
+       return;
+}
+
+static int stmmac_rx(struct stmmac_priv *priv, int limit)
+{
+       unsigned int rxsize = priv->dma_rx_size;
+       unsigned int entry = priv->cur_rx % rxsize;
+       unsigned int next_entry;
+       unsigned int count = 0;
+       struct dma_desc *p = priv->dma_rx + entry;
+       struct dma_desc *p_next;
+
+#ifdef STMMAC_RX_DEBUG
+       if (netif_msg_hw(priv)) {
+               pr_debug(">>> stmmac_rx: descriptor ring:\n");
+               display_ring(priv->dma_rx, rxsize);
+       }
+#endif
+       count = 0;
+       while (!priv->mac_type->ops->get_rx_owner(p)) {
+               int status;
+
+               if (count >= limit)
+                       break;
+
+               count++;
+
+               next_entry = (++priv->cur_rx) % rxsize;
+               p_next = priv->dma_rx + next_entry;
+               prefetch(p_next);
+
+               /* read the status of the incoming frame */
+               status = (priv->mac_type->ops->rx_status(&priv->dev->stats,
+                                                        &priv->xstats, p));
+               if (unlikely(status == discard_frame))
+                       priv->dev->stats.rx_errors++;
+               else {
+                       struct sk_buff *skb;
+                       /* Length should omit the CRC */
+                       int frame_len =
+                           priv->mac_type->ops->get_rx_frame_len(p) - 4;
+
+#ifdef STMMAC_RX_DEBUG
+                       if (frame_len > ETH_FRAME_LEN)
+                               pr_debug("\tRX frame size %d, COE status: %d\n",
+                                       frame_len, status);
+
+                       if (netif_msg_hw(priv))
+                               pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
+                                       p, entry, p->des2);
+#endif
+                       skb = priv->rx_skbuff[entry];
+                       if (unlikely(!skb)) {
+                               pr_err("%s: Inconsistent Rx descriptor chain\n",
+                                       priv->dev->name);
+                               priv->dev->stats.rx_dropped++;
+                               break;
+                       }
+                       prefetch(skb->data - NET_IP_ALIGN);
+                       priv->rx_skbuff[entry] = NULL;
+
+                       skb_put(skb, frame_len);
+                       dma_unmap_single(priv->device,
+                                        priv->rx_skbuff_dma[entry],
+                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
+#ifdef STMMAC_RX_DEBUG
+                       if (netif_msg_pktdata(priv)) {
+                               pr_info(" frame received (%dbytes)", frame_len);
+                               print_pkt(skb->data, frame_len);
+                       }
+#endif
+                       skb->protocol = eth_type_trans(skb, priv->dev);
+
+                       if (unlikely(status == csum_none)) {
+                               /* always for the old mac 10/100 */
+                               skb->ip_summed = CHECKSUM_NONE;
+                               netif_receive_skb(skb);
+                       } else {
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+                               napi_gro_receive(&priv->napi, skb);
+                       }
+
+                       priv->dev->stats.rx_packets++;
+                       priv->dev->stats.rx_bytes += frame_len;
+                       priv->dev->last_rx = jiffies;
+               }
+               entry = next_entry;
+               p = p_next;     /* use prefetched values */
+       }
+
+       stmmac_rx_refill(priv);
+
+       priv->xstats.rx_pkt_n += count;
+
+       return count;
+}
+
+/**
+ *  stmmac_poll - stmmac poll method (NAPI)
+ *  @napi : pointer to the napi structure.
+ *  @budget : maximum number of packets that the current CPU can receive from
+ *           all interfaces.
+ *  Description :
+ *   This function implements the the reception process.
+ *   Also it runs the TX completion thread
+ */
+static int stmmac_poll(struct napi_struct *napi, int budget)
+{
+       struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
+       int work_done = 0;
+
+       priv->xstats.poll_n++;
+       stmmac_tx(priv);
+       work_done = stmmac_rx(priv, budget);
+
+       if (work_done < budget) {
+               napi_complete(napi);
+               stmmac_enable_irq(priv);
+       }
+       return work_done;
+}
+
+/**
+ *  stmmac_tx_timeout
+ *  @dev : Pointer to net device structure
+ *  Description: this function is called when a packet transmission fails to
+ *   complete within a reasonable tmrate. The driver will mark the error in the
+ *   netdev structure and arrange for the device to be reset to a sane state
+ *   in order to transmit a new packet.
+ */
+static void stmmac_tx_timeout(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       /* Clear Tx resources and restart transmitting again */
+       stmmac_tx_err(priv);
+       return;
+}
+
+/* Configuration changes (passed on by ifconfig) */
+static int stmmac_config(struct net_device *dev, struct ifmap *map)
+{
+       if (dev->flags & IFF_UP)        /* can't act on a running interface */
+               return -EBUSY;
+
+       /* Don't allow changing the I/O address */
+       if (map->base_addr != dev->base_addr) {
+               pr_warning("%s: can't change I/O address\n", dev->name);
+               return -EOPNOTSUPP;
+       }
+
+       /* Don't allow changing the IRQ */
+       if (map->irq != dev->irq) {
+               pr_warning("%s: can't change IRQ number %d\n",
+                      dev->name, dev->irq);
+               return -EOPNOTSUPP;
+       }
+
+       /* ignore other fields */
+       return 0;
+}
+
+/**
+ *  stmmac_multicast_list - entry point for multicast addressing
+ *  @dev : pointer to the device structure
+ *  Description:
+ *  This function is a driver entry point which gets called by the kernel
+ *  whenever multicast addresses must be enabled/disabled.
+ *  Return value:
+ *  void.
+ */
+static void stmmac_multicast_list(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       spin_lock(&priv->lock);
+       priv->mac_type->ops->set_filter(dev);
+       spin_unlock(&priv->lock);
+       return;
+}
+
+/**
+ *  stmmac_change_mtu - entry point to change MTU size for the device.
+ *  @dev : device pointer.
+ *  @new_mtu : the new MTU size for the device.
+ *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
+ *  to drive packet transmission. Ethernet has an MTU of 1500 octets
+ *  (ETH_DATA_LEN). This value can be changed with ifconfig.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int max_mtu;
+
+       if (netif_running(dev)) {
+               pr_err("%s: must be stopped to change its MTU\n", dev->name);
+               return -EBUSY;
+       }
+
+       if (priv->is_gmac)
+               max_mtu = JUMBO_LEN;
+       else
+               max_mtu = ETH_DATA_LEN;
+
+       if ((new_mtu < 46) || (new_mtu > max_mtu)) {
+               pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
+               return -EINVAL;
+       }
+
+       dev->mtu = new_mtu;
+
+       return 0;
+}
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = (struct net_device *)dev_id;
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (unlikely(!dev)) {
+               pr_err("%s: invalid dev pointer\n", __func__);
+               return IRQ_NONE;
+       }
+
+       if (priv->is_gmac) {
+               unsigned long ioaddr = dev->base_addr;
+               /* To handle GMAC own interrupts */
+               priv->mac_type->ops->host_irq_status(ioaddr);
+       }
+       stmmac_dma_interrupt(dev);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* Polling receive - used by NETCONSOLE and other diagnostic tools
+ * to allow network I/O with interrupts disabled. */
+static void stmmac_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       stmmac_interrupt(dev->irq, dev);
+       enable_irq(dev->irq);
+}
+#endif
+
+/**
+ *  stmmac_ioctl - Entry point for the Ioctl
+ *  @dev: Device pointer.
+ *  @rq: An IOCTL specefic structure, that can contain a pointer to
+ *  a proprietary structure used to pass information to the driver.
+ *  @cmd: IOCTL command
+ *  Description:
+ *  Currently there are no special functionality supported in IOCTL, just the
+ *  phy_mii_ioctl(...) can be invoked.
+ */
+static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int ret = -EOPNOTSUPP;
+
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               if (!priv->phydev)
+                       return -EINVAL;
+
+               spin_lock(&priv->lock);
+               ret = phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+               spin_unlock(&priv->lock);
+       default:
+               break;
+       }
+       return ret;
+}
+
+#ifdef STMMAC_VLAN_TAG_USED
+static void stmmac_vlan_rx_register(struct net_device *dev,
+                                   struct vlan_group *grp)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp);
+
+       spin_lock(&priv->lock);
+       priv->vlgrp = grp;
+       spin_unlock(&priv->lock);
+
+       return;
+}
+#endif
+
+static const struct net_device_ops stmmac_netdev_ops = {
+       .ndo_open = stmmac_open,
+       .ndo_start_xmit = stmmac_xmit,
+       .ndo_stop = stmmac_release,
+       .ndo_change_mtu = stmmac_change_mtu,
+       .ndo_set_multicast_list = stmmac_multicast_list,
+       .ndo_tx_timeout = stmmac_tx_timeout,
+       .ndo_do_ioctl = stmmac_ioctl,
+       .ndo_set_config = stmmac_config,
+#ifdef STMMAC_VLAN_TAG_USED
+       .ndo_vlan_rx_register = stmmac_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = stmmac_poll_controller,
+#endif
+       .ndo_set_mac_address = eth_mac_addr,
+};
+
+/**
+ * stmmac_probe - Initialization of the adapter .
+ * @dev : device pointer
+ * Description: The function initializes the network device structure for
+ * the STMMAC driver. It also calls the low level routines
+ * in order to init the HW (i.e. the DMA engine)
+ */
+static int stmmac_probe(struct net_device *dev)
+{
+       int ret = 0;
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       ether_setup(dev);
+
+       dev->netdev_ops = &stmmac_netdev_ops;
+       stmmac_set_ethtool_ops(dev);
+
+       dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA);
+       dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+#ifdef STMMAC_VLAN_TAG_USED
+       /* Both mac100 and gmac support receive VLAN tag detection */
+       dev->features |= NETIF_F_HW_VLAN_RX;
+#endif
+       priv->msg_enable = netif_msg_init(debug, default_msg_level);
+
+       if (priv->is_gmac)
+               priv->rx_csum = 1;
+
+       if (flow_ctrl)
+               priv->flow_ctrl = FLOW_AUTO;    /* RX/TX pause on */
+
+       priv->pause = pause;
+       netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
+
+       /* Get the MAC address */
+       priv->mac_type->ops->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
+
+       if (!is_valid_ether_addr(dev->dev_addr))
+               pr_warning("\tno valid MAC address;"
+                       "please, use ifconfig or nwhwconfig!\n");
+
+       ret = register_netdev(dev);
+       if (ret) {
+               pr_err("%s: ERROR %i registering the device\n",
+                      __func__, ret);
+               return -ENODEV;
+       }
+
+       DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
+           dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
+           (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
+
+       spin_lock_init(&priv->lock);
+
+       return ret;
+}
+
+/**
+ * stmmac_mac_device_setup
+ * @dev : device pointer
+ * Description: select and initialise the mac device (mac100 or Gmac).
+ */
+static int stmmac_mac_device_setup(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+
+       struct mac_device_info *device;
+
+       if (priv->is_gmac)
+               device = gmac_setup(ioaddr);
+       else
+               device = mac100_setup(ioaddr);
+
+       if (!device)
+               return -ENOMEM;
+
+       priv->mac_type = device;
+
+       priv->wolenabled = priv->mac_type->hw.pmt;      /* PMT supported */
+       if (priv->wolenabled == PMT_SUPPORTED)
+               priv->wolopts = WAKE_MAGIC;             /* Magic Frame */
+
+       return 0;
+}
+
+static int stmmacphy_dvr_probe(struct platform_device *pdev)
+{
+       struct plat_stmmacphy_data *plat_dat;
+       plat_dat = (struct plat_stmmacphy_data *)((pdev->dev).platform_data);
+
+       pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n",
+              plat_dat->bus_id);
+
+       return 0;
+}
+
+static int stmmacphy_dvr_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct platform_driver stmmacphy_driver = {
+       .driver = {
+                  .name = PHY_RESOURCE_NAME,
+                  },
+       .probe = stmmacphy_dvr_probe,
+       .remove = stmmacphy_dvr_remove,
+};
+
+/**
+ * stmmac_associate_phy
+ * @dev: pointer to device structure
+ * @data: points to the private structure.
+ * Description: Scans through all the PHYs we have registered and checks if
+ * any are associated with our MAC.  If so, then just fill in
+ * the blanks in our local context structure
+ */
+static int stmmac_associate_phy(struct device *dev, void *data)
+{
+       struct stmmac_priv *priv = (struct stmmac_priv *)data;
+       struct plat_stmmacphy_data *plat_dat;
+
+       plat_dat = (struct plat_stmmacphy_data *)(dev->platform_data);
+
+       DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__,
+               plat_dat->bus_id);
+
+       /* Check that this phy is for the MAC being initialised */
+       if (priv->bus_id != plat_dat->bus_id)
+               return 0;
+
+       /* OK, this PHY is connected to the MAC.
+          Go ahead and get the parameters */
+       DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__);
+       priv->phy_irq =
+           platform_get_irq_byname(to_platform_device(dev), "phyirq");
+       DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__,
+           plat_dat->bus_id, priv->phy_irq);
+
+       /* Override with kernel parameters if supplied XXX CRS XXX
+        * this needs to have multiple instances */
+       if ((phyaddr >= 0) && (phyaddr <= 31))
+               plat_dat->phy_addr = phyaddr;
+
+       priv->phy_addr = plat_dat->phy_addr;
+       priv->phy_mask = plat_dat->phy_mask;
+       priv->phy_interface = plat_dat->interface;
+       priv->phy_reset = plat_dat->phy_reset;
+
+       DBG(probe, DEBUG, "%s: exiting\n", __func__);
+       return 1;       /* forces exit of driver_for_each_device() */
+}
+
+/**
+ * stmmac_dvr_probe
+ * @pdev: platform device pointer
+ * Description: the driver is initialized through platform_device.
+ */
+static int stmmac_dvr_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct resource *res;
+       unsigned int *addr = NULL;
+       struct net_device *ndev = NULL;
+       struct stmmac_priv *priv;
+       struct plat_stmmacenet_data *plat_dat;
+
+       pr_info("STMMAC driver:\n\tplatform registration... ");
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto out;
+       }
+       pr_info("done!\n");
+
+       if (!request_mem_region(res->start, (res->end - res->start),
+                               pdev->name)) {
+               pr_err("%s: ERROR: memory allocation failed"
+                      "cannot get the I/O addr 0x%x\n",
+                      __func__, (unsigned int)res->start);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       addr = ioremap(res->start, (res->end - res->start));
+       if (!addr) {
+               pr_err("%s: ERROR: memory mapping failed \n", __func__);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ndev = alloc_etherdev(sizeof(struct stmmac_priv));
+       if (!ndev) {
+               pr_err("%s: ERROR: allocating the device\n", __func__);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+
+       /* Get the MAC information */
+       ndev->irq = platform_get_irq_byname(pdev, "macirq");
+       if (ndev->irq == -ENXIO) {
+               pr_err("%s: ERROR: MAC IRQ configuration "
+                      "information not found\n", __func__);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       priv = netdev_priv(ndev);
+       priv->device = &(pdev->dev);
+       priv->dev = ndev;
+       plat_dat = (struct plat_stmmacenet_data *)((pdev->dev).platform_data);
+       priv->bus_id = plat_dat->bus_id;
+       priv->pbl = plat_dat->pbl;      /* TLI */
+       priv->is_gmac = plat_dat->has_gmac;     /* GMAC is on board */
+
+       platform_set_drvdata(pdev, ndev);
+
+       /* Set the I/O base addr */
+       ndev->base_addr = (unsigned long)addr;
+
+       /* MAC HW revice detection */
+       ret = stmmac_mac_device_setup(ndev);
+       if (ret < 0)
+               goto out;
+
+       /* Network Device Registration */
+       ret = stmmac_probe(ndev);
+       if (ret < 0)
+               goto out;
+
+       /* associate a PHY - it is provided by another platform bus */
+       if (!driver_for_each_device
+           (&(stmmacphy_driver.driver), NULL, (void *)priv,
+            stmmac_associate_phy)) {
+               pr_err("No PHY device is associated with this MAC!\n");
+               ret = -ENODEV;
+               goto out;
+       }
+
+       priv->fix_mac_speed = plat_dat->fix_mac_speed;
+       priv->bsp_priv = plat_dat->bsp_priv;
+
+       pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
+              "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name,
+              pdev->id, ndev->irq, (unsigned int)addr);
+
+       /* MDIO bus Registration */
+       pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
+       ret = stmmac_mdio_register(ndev);
+       if (ret < 0)
+               goto out;
+       pr_debug("registered!\n");
+
+out:
+       if (ret < 0) {
+               platform_set_drvdata(pdev, NULL);
+               release_mem_region(res->start, (res->end - res->start));
+               if (addr != NULL)
+                       iounmap(addr);
+       }
+
+       return ret;
+}
+
+/**
+ * stmmac_dvr_remove
+ * @pdev: platform device pointer
+ * Description: this function resets the TX/RX processes, disables the MAC RX/TX
+ * changes the link status, releases the DMA descriptor rings,
+ * unregisters the MDIO bus and unmaps the allocated memory.
+ */
+static int stmmac_dvr_remove(struct platform_device *pdev)
+{
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct resource *res;
+
+       pr_info("%s:\n\tremoving driver", __func__);
+
+       stmmac_dma_stop_rx(ndev->base_addr);
+       stmmac_dma_stop_tx(ndev->base_addr);
+
+       stmmac_mac_disable_rx(ndev->base_addr);
+       stmmac_mac_disable_tx(ndev->base_addr);
+
+       netif_carrier_off(ndev);
+
+       stmmac_mdio_unregister(ndev);
+
+       platform_set_drvdata(pdev, NULL);
+       unregister_netdev(ndev);
+
+       iounmap((void *)ndev->base_addr);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, (res->end - res->start));
+
+       free_netdev(ndev);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int dis_ic = 0;
+
+       if (!dev || !netif_running(dev))
+               return 0;
+
+       spin_lock(&priv->lock);
+
+       if (state.event == PM_EVENT_SUSPEND) {
+               netif_device_detach(dev);
+               netif_stop_queue(dev);
+               if (priv->phydev)
+                       phy_stop(priv->phydev);
+
+#ifdef CONFIG_STMMAC_TIMER
+               priv->tm->timer_stop();
+               dis_ic = 1;
+#endif
+               napi_disable(&priv->napi);
+
+               /* Stop TX/RX DMA */
+               stmmac_dma_stop_tx(dev->base_addr);
+               stmmac_dma_stop_rx(dev->base_addr);
+               /* Clear the Rx/Tx descriptors */
+               priv->mac_type->ops->init_rx_desc(priv->dma_rx,
+                                                 priv->dma_rx_size, dis_ic);
+               priv->mac_type->ops->init_tx_desc(priv->dma_tx,
+                                                 priv->dma_tx_size);
+
+               stmmac_mac_disable_tx(dev->base_addr);
+
+               if (device_may_wakeup(&(pdev->dev))) {
+                       /* Enable Power down mode by programming the PMT regs */
+                       if (priv->wolenabled == PMT_SUPPORTED)
+                               priv->mac_type->ops->pmt(dev->base_addr,
+                                                        priv->wolopts);
+               } else {
+                       stmmac_mac_disable_rx(dev->base_addr);
+               }
+       } else {
+               priv->shutdown = 1;
+               /* Although this can appear slightly redundant it actually
+                * makes fast the standby operation and guarantees the driver
+                * working if hibernation is on media. */
+               stmmac_release(dev);
+       }
+
+       spin_unlock(&priv->lock);
+       return 0;
+}
+
+static int stmmac_resume(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned long ioaddr = dev->base_addr;
+
+       if (!netif_running(dev))
+               return 0;
+
+       spin_lock(&priv->lock);
+
+       if (priv->shutdown) {
+               /* Re-open the interface and re-init the MAC/DMA
+                  and the rings. */
+               stmmac_open(dev);
+               goto out_resume;
+       }
+
+       /* Power Down bit, into the PM register, is cleared
+        * automatically as soon as a magic packet or a Wake-up frame
+        * is received. Anyway, it's better to manually clear
+        * this bit because it can generate problems while resuming
+        * from another devices (e.g. serial console). */
+       if (device_may_wakeup(&(pdev->dev)))
+               if (priv->wolenabled == PMT_SUPPORTED)
+                       priv->mac_type->ops->pmt(dev->base_addr, 0);
+
+       netif_device_attach(dev);
+
+       /* Enable the MAC and DMA */
+       stmmac_mac_enable_rx(ioaddr);
+       stmmac_mac_enable_tx(ioaddr);
+       stmmac_dma_start_tx(ioaddr);
+       stmmac_dma_start_rx(ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm->timer_start(tmrate);
+#endif
+       napi_enable(&priv->napi);
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
+       netif_start_queue(dev);
+
+out_resume:
+       spin_unlock(&priv->lock);
+       return 0;
+}
+#endif
+
+static struct platform_driver stmmac_driver = {
+       .driver = {
+                  .name = STMMAC_RESOURCE_NAME,
+                  },
+       .probe = stmmac_dvr_probe,
+       .remove = stmmac_dvr_remove,
+#ifdef CONFIG_PM
+       .suspend = stmmac_suspend,
+       .resume = stmmac_resume,
+#endif
+
+};
+
+/**
+ * stmmac_init_module - Entry point for the driver
+ * Description: This function is the entry point for the driver.
+ */
+static int __init stmmac_init_module(void)
+{
+       int ret;
+
+       if (platform_driver_register(&stmmacphy_driver)) {
+               pr_err("No PHY devices registered!\n");
+               return -ENODEV;
+       }
+
+       ret = platform_driver_register(&stmmac_driver);
+       return ret;
+}
+
+/**
+ * stmmac_cleanup_module - Cleanup routine for the driver
+ * Description: This function is the cleanup routine for the driver.
+ */
+static void __exit stmmac_cleanup_module(void)
+{
+       platform_driver_unregister(&stmmacphy_driver);
+       platform_driver_unregister(&stmmac_driver);
+}
+
+#ifndef MODULE
+static int __init stmmac_cmdline_opt(char *str)
+{
+       char *opt;
+
+       if (!str || !*str)
+               return -EINVAL;
+       while ((opt = strsep(&str, ",")) != NULL) {
+               if (!strncmp(opt, "debug:", 6))
+                       strict_strtoul(opt + 6, 0, (unsigned long *)&debug);
+               else if (!strncmp(opt, "phyaddr:", 8))
+                       strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr);
+               else if (!strncmp(opt, "dma_txsize:", 11))
+                       strict_strtoul(opt + 11, 0,
+                                      (unsigned long *)&dma_txsize);
+               else if (!strncmp(opt, "dma_rxsize:", 11))
+                       strict_strtoul(opt + 11, 0,
+                                      (unsigned long *)&dma_rxsize);
+               else if (!strncmp(opt, "buf_sz:", 7))
+                       strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz);
+               else if (!strncmp(opt, "tc:", 3))
+                       strict_strtoul(opt + 3, 0, (unsigned long *)&tc);
+               else if (!strncmp(opt, "tx_coe:", 7))
+                       strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe);
+               else if (!strncmp(opt, "watchdog:", 9))
+                       strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog);
+               else if (!strncmp(opt, "flow_ctrl:", 10))
+                       strict_strtoul(opt + 10, 0,
+                                      (unsigned long *)&flow_ctrl);
+               else if (!strncmp(opt, "pause:", 6))
+                       strict_strtoul(opt + 6, 0, (unsigned long *)&pause);
+#ifdef CONFIG_STMMAC_TIMER
+               else if (!strncmp(opt, "tmrate:", 7))
+                       strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate);
+#endif
+       }
+       return 0;
+}
+
+__setup("stmmaceth=", stmmac_cmdline_opt);
+#endif
+
+module_init(stmmac_init_module);
+module_exit(stmmac_cleanup_module);
+
+MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
+MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
new file mode 100644 (file)
index 0000000..8498552
--- /dev/null
@@ -0,0 +1,217 @@
+/*******************************************************************************
+  STMMAC Ethernet Driver -- MDIO bus implementation
+  Provides Bus interface for MII registers
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Carl Shaw <carl.shaw@st.com>
+  Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include "stmmac.h"
+
+#define MII_BUSY 0x00000001
+#define MII_WRITE 0x00000002
+
+/**
+ * stmmac_mdio_read
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * Description: it reads data from the MII register from within the phy device.
+ * For the 7111 GMAC, we must set the bit 0 in the MII address register while
+ * accessing the PHY registers.
+ * Fortunately, it seems this has no drawback for the 7109 MAC.
+ */
+static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned long ioaddr = ndev->base_addr;
+       unsigned int mii_address = priv->mac_type->hw.mii.addr;
+       unsigned int mii_data = priv->mac_type->hw.mii.data;
+
+       int data;
+       u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
+                       ((phyreg << 6) & (0x000007C0)));
+       regValue |= MII_BUSY;   /* in case of GMAC */
+
+       do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+       writel(regValue, ioaddr + mii_address);
+       do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       /* Read the data from the MII data register */
+       data = (int)readl(ioaddr + mii_data);
+
+       return data;
+}
+
+/**
+ * stmmac_mdio_write
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * @phydata: phy data
+ * Description: it writes the data into the MII register from within the device.
+ */
+static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
+                            u16 phydata)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned long ioaddr = ndev->base_addr;
+       unsigned int mii_address = priv->mac_type->hw.mii.addr;
+       unsigned int mii_data = priv->mac_type->hw.mii.data;
+
+       u16 value =
+           (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
+           | MII_WRITE;
+
+       value |= MII_BUSY;
+
+       /* Wait until any existing MII operation is complete */
+       do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       /* Set the MII address register to write */
+       writel(phydata, ioaddr + mii_data);
+       writel(value, ioaddr + mii_address);
+
+       /* Wait until any existing MII operation is complete */
+       do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       return 0;
+}
+
+/**
+ * stmmac_mdio_reset
+ * @bus: points to the mii_bus structure
+ * Description: reset the MII bus
+ */
+static int stmmac_mdio_reset(struct mii_bus *bus)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned long ioaddr = ndev->base_addr;
+       unsigned int mii_address = priv->mac_type->hw.mii.addr;
+
+       if (priv->phy_reset) {
+               pr_debug("stmmac_mdio_reset: calling phy_reset\n");
+               priv->phy_reset(priv->bsp_priv);
+       }
+
+       /* This is a workaround for problems with the STE101P PHY.
+        * It doesn't complete its reset until at least one clock cycle
+        * on MDC, so perform a dummy mdio read.
+        */
+       writel(0, ioaddr + mii_address);
+
+       return 0;
+}
+
+/**
+ * stmmac_mdio_register
+ * @ndev: net device structure
+ * Description: it registers the MII bus
+ */
+int stmmac_mdio_register(struct net_device *ndev)
+{
+       int err = 0;
+       struct mii_bus *new_bus;
+       int *irqlist;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       int addr, found;
+
+       new_bus = mdiobus_alloc();
+       if (new_bus == NULL)
+               return -ENOMEM;
+
+       irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+       if (irqlist == NULL) {
+               err = -ENOMEM;
+               goto irqlist_alloc_fail;
+       }
+
+       /* Assign IRQ to phy at address phy_addr */
+       if (priv->phy_addr != -1)
+               irqlist[priv->phy_addr] = priv->phy_irq;
+
+       new_bus->name = "STMMAC MII Bus";
+       new_bus->read = &stmmac_mdio_read;
+       new_bus->write = &stmmac_mdio_write;
+       new_bus->reset = &stmmac_mdio_reset;
+       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
+       new_bus->priv = ndev;
+       new_bus->irq = irqlist;
+       new_bus->phy_mask = priv->phy_mask;
+       new_bus->parent = priv->device;
+       err = mdiobus_register(new_bus);
+       if (err != 0) {
+               pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
+               goto bus_register_fail;
+       }
+
+       priv->mii = new_bus;
+
+       found = 0;
+       for (addr = 0; addr < 32; addr++) {
+               struct phy_device *phydev = new_bus->phy_map[addr];
+               if (phydev) {
+                       if (priv->phy_addr == -1) {
+                               priv->phy_addr = addr;
+                               phydev->irq = priv->phy_irq;
+                               irqlist[addr] = priv->phy_irq;
+                       }
+                       pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n",
+                              ndev->name, phydev->phy_id, addr,
+                              phydev->irq, dev_name(&phydev->dev),
+                              (addr == priv->phy_addr) ? " active" : "");
+                       found = 1;
+               }
+       }
+
+       if (!found)
+               pr_warning("%s: No PHY found\n", ndev->name);
+
+       return 0;
+bus_register_fail:
+       kfree(irqlist);
+irqlist_alloc_fail:
+       kfree(new_bus);
+       return err;
+}
+
+/**
+ * stmmac_mdio_unregister
+ * @ndev: net device structure
+ * Description: it unregisters the MII bus
+ */
+int stmmac_mdio_unregister(struct net_device *ndev)
+{
+       struct stmmac_priv *priv = netdev_priv(ndev);
+
+       mdiobus_unregister(priv->mii);
+       priv->mii->priv = NULL;
+       kfree(priv->mii);
+
+       return 0;
+}
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
new file mode 100644 (file)
index 0000000..b838c65
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************
+  STMMAC external timer support.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/etherdevice.h>
+#include "stmmac_timer.h"
+
+static void stmmac_timer_handler(void *data)
+{
+       struct net_device *dev = (struct net_device *)data;
+
+       stmmac_schedule(dev);
+
+       return;
+}
+
+#define STMMAC_TIMER_MSG(timer, freq) \
+printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
+
+#if defined(CONFIG_STMMAC_RTC_TIMER)
+#include <linux/rtc.h>
+static struct rtc_device *stmmac_rtc;
+static rtc_task_t stmmac_task;
+
+static void stmmac_rtc_start(unsigned int new_freq)
+{
+       rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
+       return;
+}
+
+static void stmmac_rtc_stop(void)
+{
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+       return;
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+       stmmac_task.private_data = dev;
+       stmmac_task.func = stmmac_timer_handler;
+
+       stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+       if (stmmac_rtc == NULL) {
+               pr_error("open rtc device failed\n");
+               return -ENODEV;
+       }
+
+       rtc_irq_register(stmmac_rtc, &stmmac_task);
+
+       /* Periodic mode is not supported */
+       if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
+               pr_error("set periodic failed\n");
+               rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+               rtc_class_close(stmmac_rtc);
+               return -1;
+       }
+
+       STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
+
+       tm->timer_start = stmmac_rtc_start;
+       tm->timer_stop = stmmac_rtc_stop;
+
+       return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+       rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+       rtc_class_close(stmmac_rtc);
+       return 0;
+}
+
+#elif defined(CONFIG_STMMAC_TMU_TIMER)
+#include <linux/clk.h>
+#define TMU_CHANNEL "tmu2_clk"
+static struct clk *timer_clock;
+
+static void stmmac_tmu_start(unsigned int new_freq)
+{
+       clk_set_rate(timer_clock, new_freq);
+       clk_enable(timer_clock);
+       return;
+}
+
+static void stmmac_tmu_stop(void)
+{
+       clk_disable(timer_clock);
+       return;
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+       timer_clock = clk_get(NULL, TMU_CHANNEL);
+
+       if (timer_clock == NULL)
+               return -1;
+
+       if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
+               timer_clock = NULL;
+               return -1;
+       }
+
+       STMMAC_TIMER_MSG("TMU2", tm->freq);
+       tm->timer_start = stmmac_tmu_start;
+       tm->timer_stop = stmmac_tmu_stop;
+
+       return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+       clk_disable(timer_clock);
+       tmu2_unregister_user();
+       clk_put(timer_clock);
+       return 0;
+}
+#endif
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
new file mode 100644 (file)
index 0000000..f795cae
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+  STMMAC external timer Header File.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+struct stmmac_timer {
+       void (*timer_start) (unsigned int new_freq);
+       void (*timer_stop) (void);
+       unsigned int freq;
+};
+
+/* Open the HW timer device and return 0 in case of success */
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
+/* Stop the timer and release it */
+int stmmac_close_ext_timer(void);
+/* Function used for scheduling task within the stmmac */
+void stmmac_schedule(struct net_device *dev);
+
+#if defined(CONFIG_STMMAC_TMU_TIMER)
+extern int tmu2_register_user(void *fnt, void *data);
+extern void tmu2_unregister_user(void);
+#endif
index 72470f7..a2b30a1 100644 (file)
@@ -649,6 +649,10 @@ static const struct usb_device_id products[] = {
        USB_DEVICE(0x0fe6, 0x8101),     /* DM9601 USB to Fast Ethernet Adapter */
        .driver_info = (unsigned long)&dm9601_info,
         },
+       {
+        USB_DEVICE(0x0a46, 0x9000),    /* DM9000E */
+        .driver_info = (unsigned long)&dm9601_info,
+        },
        {},                     // END
 };
 
index 6fdaba8..ed4a508 100644 (file)
@@ -62,8 +62,11 @@ static char *devid=NULL;
 static struct usb_eth_dev usb_dev_id[] = {
 #define        PEGASUS_DEV(pn, vid, pid, flags)        \
        {.name = pn, .vendor = vid, .device = pid, .private = flags},
+#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
+       PEGASUS_DEV(pn, vid, pid, flags)
 #include "pegasus.h"
 #undef PEGASUS_DEV
+#undef PEGASUS_DEV_CLASS
        {NULL, 0, 0, 0},
        {NULL, 0, 0, 0}
 };
@@ -71,8 +74,18 @@ static struct usb_eth_dev usb_dev_id[] = {
 static struct usb_device_id pegasus_ids[] = {
 #define        PEGASUS_DEV(pn, vid, pid, flags) \
        {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
+/*
+ * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
+ * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
+ * ignore adaptors belonging to the "Wireless" class 0xE0. For this one
+ * case anyway, seeing as the pegasus is for "Wired" adaptors.
+ */
+#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
+       {.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
+       .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
 #include "pegasus.h"
 #undef PEGASUS_DEV
+#undef PEGASUS_DEV_CLASS
        {},
        {}
 };
index f968c83..5d02f02 100644 (file)
@@ -202,7 +202,11 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
                DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
+/*
+ * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
+ * with the same product IDs by checking the device class too.
+ */
+PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
                DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
                DEFAULT_GPIO_RESET )
index 0caa800..f56dec6 100644 (file)
@@ -362,12 +362,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
                        retval = -EINVAL;
                        goto halt_fail_and_release;
                }
-               dev->hard_mtu = tmp;
-               net->mtu = dev->hard_mtu - net->hard_header_len;
                dev_warn(&intf->dev,
                         "dev can't take %u byte packets (max %u), "
                         "adjusting MTU to %u\n",
-                        dev->hard_mtu, tmp, net->mtu);
+                        dev->hard_mtu, tmp, tmp - net->hard_header_len);
+               dev->hard_mtu = tmp;
+               net->mtu = dev->hard_mtu - net->hard_header_len;
        }
 
        /* REVISIT:  peripheral "alignment" request is ignored ... */
index 8d00976..05630f2 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_net.h>
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
@@ -454,7 +453,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
                vi->dev->stats.tx_bytes += skb->len;
                vi->dev->stats.tx_packets++;
                tot_sgs += skb_vnet_hdr(skb)->num_sg;
-               kfree_skb(skb);
+               dev_kfree_skb_any(skb);
        }
        return tot_sgs;
 }
@@ -517,8 +516,7 @@ again:
        /* Free up any pending old buffers before queueing new ones. */
        free_old_xmit_skbs(vi);
 
-       /* Put new one in send queue and do transmit */
-       __skb_queue_head(&vi->send, skb);
+       /* Try to transmit */
        capacity = xmit_skb(vi, skb);
 
        /* This can happen with OOM and indirect buffers. */
@@ -532,8 +530,17 @@ again:
                }
                return NETDEV_TX_BUSY;
        }
-
        vi->svq->vq_ops->kick(vi->svq);
+
+       /*
+        * Put new one in send queue.  You'd expect we'd need this before
+        * xmit_skb calls add_buf(), since the callback can be triggered
+        * immediately after that.  But since the callback just triggers
+        * another call back here, normal network xmit locking prevents the
+        * race.
+        */
+       __skb_queue_head(&vi->send, skb);
+
        /* Don't wait up for transmitted skbs to be freed. */
        skb_orphan(skb);
        nf_reset(skb);
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
new file mode 100644 (file)
index 0000000..880f509
--- /dev/null
@@ -0,0 +1,35 @@
+################################################################################
+#
+# Linux driver for VMware's vmxnet3 ethernet NIC.
+#
+# Copyright (C) 2007-2009, VMware, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+# NON INFRINGEMENT.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+#
+#
+################################################################################
+
+#
+# Makefile for the VMware vmxnet3 ethernet NIC driver
+#
+
+obj-$(CONFIG_VMXNET3) += vmxnet3.o
+
+vmxnet3-objs := vmxnet3_drv.o vmxnet3_ethtool.o
diff --git a/drivers/net/vmxnet3/upt1_defs.h b/drivers/net/vmxnet3/upt1_defs.h
new file mode 100644 (file)
index 0000000..37108fb
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _UPT1_DEFS_H
+#define _UPT1_DEFS_H
+
+struct UPT1_TxStats {
+       u64                     TSOPktsTxOK;  /* TSO pkts post-segmentation */
+       u64                     TSOBytesTxOK;
+       u64                     ucastPktsTxOK;
+       u64                     ucastBytesTxOK;
+       u64                     mcastPktsTxOK;
+       u64                     mcastBytesTxOK;
+       u64                     bcastPktsTxOK;
+       u64                     bcastBytesTxOK;
+       u64                     pktsTxError;
+       u64                     pktsTxDiscard;
+};
+
+struct UPT1_RxStats {
+       u64                     LROPktsRxOK;    /* LRO pkts */
+       u64                     LROBytesRxOK;   /* bytes from LRO pkts */
+       /* the following counters are for pkts from the wire, i.e., pre-LRO */
+       u64                     ucastPktsRxOK;
+       u64                     ucastBytesRxOK;
+       u64                     mcastPktsRxOK;
+       u64                     mcastBytesRxOK;
+       u64                     bcastPktsRxOK;
+       u64                     bcastBytesRxOK;
+       u64                     pktsRxOutOfBuf;
+       u64                     pktsRxError;
+};
+
+/* interrupt moderation level */
+enum {
+       UPT1_IML_NONE           = 0, /* no interrupt moderation */
+       UPT1_IML_HIGHEST        = 7, /* least intr generated */
+       UPT1_IML_ADAPTIVE       = 8, /* adpative intr moderation */
+};
+/* values for UPT1_RSSConf.hashFunc */
+enum {
+       UPT1_RSS_HASH_TYPE_NONE      = 0x0,
+       UPT1_RSS_HASH_TYPE_IPV4      = 0x01,
+       UPT1_RSS_HASH_TYPE_TCP_IPV4  = 0x02,
+       UPT1_RSS_HASH_TYPE_IPV6      = 0x04,
+       UPT1_RSS_HASH_TYPE_TCP_IPV6  = 0x08,
+};
+
+enum {
+       UPT1_RSS_HASH_FUNC_NONE      = 0x0,
+       UPT1_RSS_HASH_FUNC_TOEPLITZ  = 0x01,
+};
+
+#define UPT1_RSS_MAX_KEY_SIZE        40
+#define UPT1_RSS_MAX_IND_TABLE_SIZE  128
+
+struct UPT1_RSSConf {
+       u16                     hashType;
+       u16                     hashFunc;
+       u16                     hashKeySize;
+       u16                     indTableSize;
+       u8                      hashKey[UPT1_RSS_MAX_KEY_SIZE];
+       u8                      indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
+};
+
+/* features */
+enum {
+       UPT1_F_RXCSUM           = 0x0001,   /* rx csum verification */
+       UPT1_F_RSS              = 0x0002,
+       UPT1_F_RXVLAN           = 0x0004,   /* VLAN tag stripping */
+       UPT1_F_LRO              = 0x0008,
+};
+#endif
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
new file mode 100644 (file)
index 0000000..dc8ee44
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _VMXNET3_DEFS_H_
+#define _VMXNET3_DEFS_H_
+
+#include "upt1_defs.h"
+
+/* all registers are 32 bit wide */
+/* BAR 1 */
+enum {
+       VMXNET3_REG_VRRS        = 0x0,  /* Vmxnet3 Revision Report Selection */
+       VMXNET3_REG_UVRS        = 0x8,  /* UPT Version Report Selection */
+       VMXNET3_REG_DSAL        = 0x10, /* Driver Shared Address Low */
+       VMXNET3_REG_DSAH        = 0x18, /* Driver Shared Address High */
+       VMXNET3_REG_CMD         = 0x20, /* Command */
+       VMXNET3_REG_MACL        = 0x28, /* MAC Address Low */
+       VMXNET3_REG_MACH        = 0x30, /* MAC Address High */
+       VMXNET3_REG_ICR         = 0x38, /* Interrupt Cause Register */
+       VMXNET3_REG_ECR         = 0x40  /* Event Cause Register */
+};
+
+/* BAR 0 */
+enum {
+       VMXNET3_REG_IMR         = 0x0,   /* Interrupt Mask Register */
+       VMXNET3_REG_TXPROD      = 0x600, /* Tx Producer Index */
+       VMXNET3_REG_RXPROD      = 0x800, /* Rx Producer Index for ring 1 */
+       VMXNET3_REG_RXPROD2     = 0xA00  /* Rx Producer Index for ring 2 */
+};
+
+#define VMXNET3_PT_REG_SIZE     4096   /* BAR 0 */
+#define VMXNET3_VD_REG_SIZE     4096   /* BAR 1 */
+
+#define VMXNET3_REG_ALIGN       8      /* All registers are 8-byte aligned. */
+#define VMXNET3_REG_ALIGN_MASK  0x7
+
+/* I/O Mapped access to registers */
+#define VMXNET3_IO_TYPE_PT              0
+#define VMXNET3_IO_TYPE_VD              1
+#define VMXNET3_IO_ADDR(type, reg)      (((type) << 24) | ((reg) & 0xFFFFFF))
+#define VMXNET3_IO_TYPE(addr)           ((addr) >> 24)
+#define VMXNET3_IO_REG(addr)            ((addr) & 0xFFFFFF)
+
+enum {
+       VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
+       VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET,
+       VMXNET3_CMD_QUIESCE_DEV,
+       VMXNET3_CMD_RESET_DEV,
+       VMXNET3_CMD_UPDATE_RX_MODE,
+       VMXNET3_CMD_UPDATE_MAC_FILTERS,
+       VMXNET3_CMD_UPDATE_VLAN_FILTERS,
+       VMXNET3_CMD_UPDATE_RSSIDT,
+       VMXNET3_CMD_UPDATE_IML,
+       VMXNET3_CMD_UPDATE_PMCFG,
+       VMXNET3_CMD_UPDATE_FEATURE,
+       VMXNET3_CMD_LOAD_PLUGIN,
+
+       VMXNET3_CMD_FIRST_GET = 0xF00D0000,
+       VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
+       VMXNET3_CMD_GET_STATS,
+       VMXNET3_CMD_GET_LINK,
+       VMXNET3_CMD_GET_PERM_MAC_LO,
+       VMXNET3_CMD_GET_PERM_MAC_HI,
+       VMXNET3_CMD_GET_DID_LO,
+       VMXNET3_CMD_GET_DID_HI,
+       VMXNET3_CMD_GET_DEV_EXTRA_INFO,
+       VMXNET3_CMD_GET_CONF_INTR
+};
+
+struct Vmxnet3_TxDesc {
+       u64             addr;
+
+       u32             len:14;
+       u32             gen:1;      /* generation bit */
+       u32             rsvd:1;
+       u32             dtype:1;    /* descriptor type */
+       u32             ext1:1;
+       u32             msscof:14;  /* MSS, checksum offset, flags */
+
+       u32             hlen:10;    /* header len */
+       u32             om:2;       /* offload mode */
+       u32             eop:1;      /* End Of Packet */
+       u32             cq:1;       /* completion request */
+       u32             ext2:1;
+       u32             ti:1;       /* VLAN Tag Insertion */
+       u32             tci:16;     /* Tag to Insert */
+};
+
+/* TxDesc.OM values */
+#define VMXNET3_OM_NONE                0
+#define VMXNET3_OM_CSUM                2
+#define VMXNET3_OM_TSO         3
+
+/* fields in TxDesc we access w/o using bit fields */
+#define VMXNET3_TXD_EOP_SHIFT  12
+#define VMXNET3_TXD_CQ_SHIFT   13
+#define VMXNET3_TXD_GEN_SHIFT  14
+
+#define VMXNET3_TXD_CQ         (1 << VMXNET3_TXD_CQ_SHIFT)
+#define VMXNET3_TXD_EOP                (1 << VMXNET3_TXD_EOP_SHIFT)
+#define VMXNET3_TXD_GEN                (1 << VMXNET3_TXD_GEN_SHIFT)
+
+#define VMXNET3_HDR_COPY_SIZE   128
+
+
+struct Vmxnet3_TxDataDesc {
+       u8              data[VMXNET3_HDR_COPY_SIZE];
+};
+
+
+struct Vmxnet3_TxCompDesc {
+       u32             txdIdx:12;    /* Index of the EOP TxDesc */
+       u32             ext1:20;
+
+       u32             ext2;
+       u32             ext3;
+
+       u32             rsvd:24;
+       u32             type:7;       /* completion type */
+       u32             gen:1;        /* generation bit */
+};
+
+
+struct Vmxnet3_RxDesc {
+       u64             addr;
+
+       u32             len:14;
+       u32             btype:1;      /* Buffer Type */
+       u32             dtype:1;      /* Descriptor type */
+       u32             rsvd:15;
+       u32             gen:1;        /* Generation bit */
+
+       u32             ext1;
+};
+
+/* values of RXD.BTYPE */
+#define VMXNET3_RXD_BTYPE_HEAD   0    /* head only */
+#define VMXNET3_RXD_BTYPE_BODY   1    /* body only */
+
+/* fields in RxDesc we access w/o using bit fields */
+#define VMXNET3_RXD_BTYPE_SHIFT  14
+#define VMXNET3_RXD_GEN_SHIFT    31
+
+
+struct Vmxnet3_RxCompDesc {
+       u32             rxdIdx:12;    /* Index of the RxDesc */
+       u32             ext1:2;
+       u32             eop:1;        /* End of Packet */
+       u32             sop:1;        /* Start of Packet */
+       u32             rqID:10;      /* rx queue/ring ID */
+       u32             rssType:4;    /* RSS hash type used */
+       u32             cnc:1;        /* Checksum Not Calculated */
+       u32             ext2:1;
+
+       u32             rssHash;      /* RSS hash value */
+
+       u32             len:14;       /* data length */
+       u32             err:1;        /* Error */
+       u32             ts:1;         /* Tag is stripped */
+       u32             tci:16;       /* Tag stripped */
+
+       u32             csum:16;
+       u32             tuc:1;        /* TCP/UDP Checksum Correct */
+       u32             udp:1;        /* UDP packet */
+       u32             tcp:1;        /* TCP packet */
+       u32             ipc:1;        /* IP Checksum Correct */
+       u32             v6:1;         /* IPv6 */
+       u32             v4:1;         /* IPv4 */
+       u32             frg:1;        /* IP Fragment */
+       u32             fcs:1;        /* Frame CRC correct */
+       u32             type:7;       /* completion type */
+       u32             gen:1;        /* generation bit */
+};
+
+/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
+#define VMXNET3_RCD_TUC_SHIFT  16
+#define VMXNET3_RCD_IPC_SHIFT  19
+
+/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
+#define VMXNET3_RCD_TYPE_SHIFT 56
+#define VMXNET3_RCD_GEN_SHIFT  63
+
+/* csum OK for TCP/UDP pkts over IP */
+#define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
+                            1 << VMXNET3_RCD_IPC_SHIFT)
+
+/* value of RxCompDesc.rssType */
+enum {
+       VMXNET3_RCD_RSS_TYPE_NONE     = 0,
+       VMXNET3_RCD_RSS_TYPE_IPV4     = 1,
+       VMXNET3_RCD_RSS_TYPE_TCPIPV4  = 2,
+       VMXNET3_RCD_RSS_TYPE_IPV6     = 3,
+       VMXNET3_RCD_RSS_TYPE_TCPIPV6  = 4,
+};
+
+
+/* a union for accessing all cmd/completion descriptors */
+union Vmxnet3_GenericDesc {
+       u64                             qword[2];
+       u32                             dword[4];
+       u16                             word[8];
+       struct Vmxnet3_TxDesc           txd;
+       struct Vmxnet3_RxDesc           rxd;
+       struct Vmxnet3_TxCompDesc       tcd;
+       struct Vmxnet3_RxCompDesc       rcd;
+};
+
+#define VMXNET3_INIT_GEN       1
+
+/* Max size of a single tx buffer */
+#define VMXNET3_MAX_TX_BUF_SIZE  (1 << 14)
+
+/* # of tx desc needed for a tx buffer size */
+#define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
+                                 VMXNET3_MAX_TX_BUF_SIZE)
+
+/* max # of tx descs for a non-tso pkt */
+#define VMXNET3_MAX_TXD_PER_PKT 16
+
+/* Max size of a single rx buffer */
+#define VMXNET3_MAX_RX_BUF_SIZE  ((1 << 14) - 1)
+/* Minimum size of a type 0 buffer */
+#define VMXNET3_MIN_T0_BUF_SIZE  128
+#define VMXNET3_MAX_CSUM_OFFSET  1024
+
+/* Ring base address alignment */
+#define VMXNET3_RING_BA_ALIGN   512
+#define VMXNET3_RING_BA_MASK    (VMXNET3_RING_BA_ALIGN - 1)
+
+/* Ring size must be a multiple of 32 */
+#define VMXNET3_RING_SIZE_ALIGN 32
+#define VMXNET3_RING_SIZE_MASK  (VMXNET3_RING_SIZE_ALIGN - 1)
+
+/* Max ring size */
+#define VMXNET3_TX_RING_MAX_SIZE   4096
+#define VMXNET3_TC_RING_MAX_SIZE   4096
+#define VMXNET3_RX_RING_MAX_SIZE   4096
+#define VMXNET3_RC_RING_MAX_SIZE   8192
+
+/* a list of reasons for queue stop */
+
+enum {
+ VMXNET3_ERR_NOEOP        = 0x80000000,  /* cannot find the EOP desc of a pkt */
+ VMXNET3_ERR_TXD_REUSE    = 0x80000001,  /* reuse TxDesc before tx completion */
+ VMXNET3_ERR_BIG_PKT      = 0x80000002,  /* too many TxDesc for a pkt */
+ VMXNET3_ERR_DESC_NOT_SPT = 0x80000003,  /* descriptor type not supported */
+ VMXNET3_ERR_SMALL_BUF    = 0x80000004,  /* type 0 buffer too small */
+ VMXNET3_ERR_STRESS       = 0x80000005,  /* stress option firing in vmkernel */
+ VMXNET3_ERR_SWITCH       = 0x80000006,  /* mode switch failure */
+ VMXNET3_ERR_TXD_INVALID  = 0x80000007,  /* invalid TxDesc */
+};
+
+/* completion descriptor types */
+#define VMXNET3_CDTYPE_TXCOMP      0    /* Tx Completion Descriptor */
+#define VMXNET3_CDTYPE_RXCOMP      3    /* Rx Completion Descriptor */
+
+enum {
+       VMXNET3_GOS_BITS_UNK    = 0,   /* unknown */
+       VMXNET3_GOS_BITS_32     = 1,
+       VMXNET3_GOS_BITS_64     = 2,
+};
+
+#define VMXNET3_GOS_TYPE_LINUX 1
+
+
+struct Vmxnet3_GOSInfo {
+       u32                             gosBits:2;      /* 32-bit or 64-bit? */
+       u32                             gosType:4;   /* which guest */
+       u32                             gosVer:16;   /* gos version */
+       u32                             gosMisc:10;  /* other info about gos */
+};
+
+
+struct Vmxnet3_DriverInfo {
+       u32                             version;
+       struct Vmxnet3_GOSInfo          gos;
+       u32                             vmxnet3RevSpt;
+       u32                             uptVerSpt;
+};
+
+
+#define VMXNET3_REV1_MAGIC  0xbabefee1
+
+/*
+ * QueueDescPA must be 128 bytes aligned. It points to an array of
+ * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
+ * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
+ * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
+ */
+#define VMXNET3_QUEUE_DESC_ALIGN  128
+
+
+struct Vmxnet3_MiscConf {
+       struct Vmxnet3_DriverInfo driverInfo;
+       u64             uptFeatures;
+       u64             ddPA;         /* driver data PA */
+       u64             queueDescPA;  /* queue descriptor table PA */
+       u32             ddLen;        /* driver data len */
+       u32             queueDescLen; /* queue desc. table len in bytes */
+       u32             mtu;
+       u16             maxNumRxSG;
+       u8              numTxQueues;
+       u8              numRxQueues;
+       u32             reserved[4];
+};
+
+
+struct Vmxnet3_TxQueueConf {
+       u64             txRingBasePA;
+       u64             dataRingBasePA;
+       u64             compRingBasePA;
+       u64             ddPA;         /* driver data */
+       u64             reserved;
+       u32             txRingSize;   /* # of tx desc */
+       u32             dataRingSize; /* # of data desc */
+       u32             compRingSize; /* # of comp desc */
+       u32             ddLen;        /* size of driver data */
+       u8              intrIdx;
+       u8              _pad[7];
+};
+
+
+struct Vmxnet3_RxQueueConf {
+       u64             rxRingBasePA[2];
+       u64             compRingBasePA;
+       u64             ddPA;            /* driver data */
+       u64             reserved;
+       u32             rxRingSize[2];   /* # of rx desc */
+       u32             compRingSize;    /* # of rx comp desc */
+       u32             ddLen;           /* size of driver data */
+       u8              intrIdx;
+       u8              _pad[7];
+};
+
+
+enum vmxnet3_intr_mask_mode {
+       VMXNET3_IMM_AUTO   = 0,
+       VMXNET3_IMM_ACTIVE = 1,
+       VMXNET3_IMM_LAZY   = 2
+};
+
+enum vmxnet3_intr_type {
+       VMXNET3_IT_AUTO = 0,
+       VMXNET3_IT_INTX = 1,
+       VMXNET3_IT_MSI  = 2,
+       VMXNET3_IT_MSIX = 3
+};
+
+#define VMXNET3_MAX_TX_QUEUES  8
+#define VMXNET3_MAX_RX_QUEUES  16
+/* addition 1 for events */
+#define VMXNET3_MAX_INTRS      25
+
+
+struct Vmxnet3_IntrConf {
+       bool            autoMask;
+       u8              numIntrs;      /* # of interrupts */
+       u8              eventIntrIdx;
+       u8              modLevels[VMXNET3_MAX_INTRS];   /* moderation level for
+                                                        * each intr */
+       u32             reserved[3];
+};
+
+/* one bit per VLAN ID, the size is in the units of u32        */
+#define VMXNET3_VFT_SIZE  (4096 / (sizeof(u32) * 8))
+
+
+struct Vmxnet3_QueueStatus {
+       bool            stopped;
+       u8              _pad[3];
+       u32             error;
+};
+
+
+struct Vmxnet3_TxQueueCtrl {
+       u32             txNumDeferred;
+       u32             txThreshold;
+       u64             reserved;
+};
+
+
+struct Vmxnet3_RxQueueCtrl {
+       bool            updateRxProd;
+       u8              _pad[7];
+       u64             reserved;
+};
+
+enum {
+       VMXNET3_RXM_UCAST     = 0x01,  /* unicast only */
+       VMXNET3_RXM_MCAST     = 0x02,  /* multicast passing the filters */
+       VMXNET3_RXM_BCAST     = 0x04,  /* broadcast only */
+       VMXNET3_RXM_ALL_MULTI = 0x08,  /* all multicast */
+       VMXNET3_RXM_PROMISC   = 0x10  /* promiscuous */
+};
+
+struct Vmxnet3_RxFilterConf {
+       u32             rxMode;       /* VMXNET3_RXM_xxx */
+       u16             mfTableLen;   /* size of the multicast filter table */
+       u16             _pad1;
+       u64             mfTablePA;    /* PA of the multicast filters table */
+       u32             vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
+};
+
+
+#define VMXNET3_PM_MAX_FILTERS        6
+#define VMXNET3_PM_MAX_PATTERN_SIZE   128
+#define VMXNET3_PM_MAX_MASK_SIZE      (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
+
+#define VMXNET3_PM_WAKEUP_MAGIC       0x01  /* wake up on magic pkts */
+#define VMXNET3_PM_WAKEUP_FILTER      0x02  /* wake up on pkts matching
+                                            * filters */
+
+
+struct Vmxnet3_PM_PktFilter {
+       u8              maskSize;
+       u8              patternSize;
+       u8              mask[VMXNET3_PM_MAX_MASK_SIZE];
+       u8              pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
+       u8              pad[6];
+};
+
+
+struct Vmxnet3_PMConf {
+       u16             wakeUpEvents;  /* VMXNET3_PM_WAKEUP_xxx */
+       u8              numFilters;
+       u8              pad[5];
+       struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
+};
+
+
+struct Vmxnet3_VariableLenConfDesc {
+       u32             confVer;
+       u32             confLen;
+       u64             confPA;
+};
+
+
+struct Vmxnet3_TxQueueDesc {
+       struct Vmxnet3_TxQueueCtrl              ctrl;
+       struct Vmxnet3_TxQueueConf              conf;
+
+       /* Driver read after a GET command */
+       struct Vmxnet3_QueueStatus              status;
+       struct UPT1_TxStats                     stats;
+       u8                                      _pad[88]; /* 128 aligned */
+};
+
+
+struct Vmxnet3_RxQueueDesc {
+       struct Vmxnet3_RxQueueCtrl              ctrl;
+       struct Vmxnet3_RxQueueConf              conf;
+       /* Driver read after a GET commad */
+       struct Vmxnet3_QueueStatus              status;
+       struct UPT1_RxStats                     stats;
+       u8                                    __pad[88]; /* 128 aligned */
+};
+
+
+struct Vmxnet3_DSDevRead {
+       /* read-only region for device, read by dev in response to a SET cmd */
+       struct Vmxnet3_MiscConf                 misc;
+       struct Vmxnet3_IntrConf                 intrConf;
+       struct Vmxnet3_RxFilterConf             rxFilterConf;
+       struct Vmxnet3_VariableLenConfDesc      rssConfDesc;
+       struct Vmxnet3_VariableLenConfDesc      pmConfDesc;
+       struct Vmxnet3_VariableLenConfDesc      pluginConfDesc;
+};
+
+/* All structures in DriverShared are padded to multiples of 8 bytes */
+struct Vmxnet3_DriverShared {
+       u32                             magic;
+       /* make devRead start at 64bit boundaries */
+       u32                                     pad;
+       struct Vmxnet3_DSDevRead                devRead;
+       u32                                     ecr;
+       u32                                     reserved[5];
+};
+
+
+#define VMXNET3_ECR_RQERR       (1 << 0)
+#define VMXNET3_ECR_TQERR       (1 << 1)
+#define VMXNET3_ECR_LINK        (1 << 2)
+#define VMXNET3_ECR_DIC         (1 << 3)
+#define VMXNET3_ECR_DEBUG       (1 << 4)
+
+/* flip the gen bit of a ring */
+#define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
+
+/* only use this if moving the idx won't affect the gen bit */
+#define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
+       do {\
+               (idx)++;\
+               if (unlikely((idx) == (ring_size))) {\
+                       (idx) = 0;\
+               } \
+       } while (0)
+
+#define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
+       (vfTable[vid >> 5] |= (1 << (vid & 31)))
+#define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
+       (vfTable[vid >> 5] &= ~(1 << (vid & 31)))
+
+#define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
+       ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
+
+#define VMXNET3_MAX_MTU     9000
+#define VMXNET3_MIN_MTU     60
+
+#define VMXNET3_LINK_UP         (10000 << 16 | 1)    /* 10 Gbps, up */
+#define VMXNET3_LINK_DOWN       0
+
+#endif /* _VMXNET3_DEFS_H_ */
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
new file mode 100644 (file)
index 0000000..004353a
--- /dev/null
@@ -0,0 +1,2574 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#include "vmxnet3_int.h"
+
+char vmxnet3_driver_name[] = "vmxnet3";
+#define VMXNET3_DRIVER_DESC "VMware vmxnet3 virtual NIC driver"
+
+
+/*
+ * PCI Device ID Table
+ * Last entry must be all 0s
+ */
+static const struct pci_device_id vmxnet3_pciid_table[] = {
+       {PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_VMXNET3)},
+       {0}
+};
+
+MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table);
+
+static atomic_t devices_found;
+
+
+/*
+ *    Enable/Disable the given intr
+ */
+static void
+vmxnet3_enable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
+{
+       VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 0);
+}
+
+
+static void
+vmxnet3_disable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
+{
+       VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 1);
+}
+
+
+/*
+ *    Enable/Disable all intrs used by the device
+ */
+static void
+vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->intr.num_intrs; i++)
+               vmxnet3_enable_intr(adapter, i);
+}
+
+
+static void
+vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->intr.num_intrs; i++)
+               vmxnet3_disable_intr(adapter, i);
+}
+
+
+static void
+vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events)
+{
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_ECR, events);
+}
+
+
+static bool
+vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+       return netif_queue_stopped(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+       tq->stopped = false;
+       netif_start_queue(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+       tq->stopped = false;
+       netif_wake_queue(adapter->netdev);
+}
+
+
+static void
+vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
+{
+       tq->stopped = true;
+       tq->num_stop++;
+       netif_stop_queue(adapter->netdev);
+}
+
+
+/*
+ * Check the link state. This may start or stop the tx queue.
+ */
+static void
+vmxnet3_check_link(struct vmxnet3_adapter *adapter)
+{
+       u32 ret;
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
+       ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       adapter->link_speed = ret >> 16;
+       if (ret & 1) { /* Link is up. */
+               printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",
+                      adapter->netdev->name, adapter->link_speed);
+               if (!netif_carrier_ok(adapter->netdev))
+                       netif_carrier_on(adapter->netdev);
+
+               vmxnet3_tq_start(&adapter->tx_queue, adapter);
+       } else {
+               printk(KERN_INFO "%s: NIC Link is Down\n",
+                      adapter->netdev->name);
+               if (netif_carrier_ok(adapter->netdev))
+                       netif_carrier_off(adapter->netdev);
+
+               vmxnet3_tq_stop(&adapter->tx_queue, adapter);
+       }
+}
+
+
+static void
+vmxnet3_process_events(struct vmxnet3_adapter *adapter)
+{
+       u32 events = adapter->shared->ecr;
+       if (!events)
+               return;
+
+       vmxnet3_ack_events(adapter, events);
+
+       /* Check if link state has changed */
+       if (events & VMXNET3_ECR_LINK)
+               vmxnet3_check_link(adapter);
+
+       /* Check if there is an error on xmit/recv queues */
+       if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) {
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                      VMXNET3_CMD_GET_QUEUE_STATUS);
+
+               if (adapter->tqd_start->status.stopped) {
+                       printk(KERN_ERR "%s: tq error 0x%x\n",
+                              adapter->netdev->name,
+                              adapter->tqd_start->status.error);
+               }
+               if (adapter->rqd_start->status.stopped) {
+                       printk(KERN_ERR "%s: rq error 0x%x\n",
+                              adapter->netdev->name,
+                              adapter->rqd_start->status.error);
+               }
+
+               schedule_work(&adapter->work);
+       }
+}
+
+
+static void
+vmxnet3_unmap_tx_buf(struct vmxnet3_tx_buf_info *tbi,
+                    struct pci_dev *pdev)
+{
+       if (tbi->map_type == VMXNET3_MAP_SINGLE)
+               pci_unmap_single(pdev, tbi->dma_addr, tbi->len,
+                                PCI_DMA_TODEVICE);
+       else if (tbi->map_type == VMXNET3_MAP_PAGE)
+               pci_unmap_page(pdev, tbi->dma_addr, tbi->len,
+                              PCI_DMA_TODEVICE);
+       else
+               BUG_ON(tbi->map_type != VMXNET3_MAP_NONE);
+
+       tbi->map_type = VMXNET3_MAP_NONE; /* to help debugging */
+}
+
+
+static int
+vmxnet3_unmap_pkt(u32 eop_idx, struct vmxnet3_tx_queue *tq,
+                 struct pci_dev *pdev, struct vmxnet3_adapter *adapter)
+{
+       struct sk_buff *skb;
+       int entries = 0;
+
+       /* no out of order completion */
+       BUG_ON(tq->buf_info[eop_idx].sop_idx != tq->tx_ring.next2comp);
+       BUG_ON(tq->tx_ring.base[eop_idx].txd.eop != 1);
+
+       skb = tq->buf_info[eop_idx].skb;
+       BUG_ON(skb == NULL);
+       tq->buf_info[eop_idx].skb = NULL;
+
+       VMXNET3_INC_RING_IDX_ONLY(eop_idx, tq->tx_ring.size);
+
+       while (tq->tx_ring.next2comp != eop_idx) {
+               vmxnet3_unmap_tx_buf(tq->buf_info + tq->tx_ring.next2comp,
+                                    pdev);
+
+               /* update next2comp w/o tx_lock. Since we are marking more,
+                * instead of less, tx ring entries avail, the worst case is
+                * that the tx routine incorrectly re-queues a pkt due to
+                * insufficient tx ring entries.
+                */
+               vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
+               entries++;
+       }
+
+       dev_kfree_skb_any(skb);
+       return entries;
+}
+
+
+static int
+vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq,
+                       struct vmxnet3_adapter *adapter)
+{
+       int completed = 0;
+       union Vmxnet3_GenericDesc *gdesc;
+
+       gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
+       while (gdesc->tcd.gen == tq->comp_ring.gen) {
+               completed += vmxnet3_unmap_pkt(gdesc->tcd.txdIdx, tq,
+                                              adapter->pdev, adapter);
+
+               vmxnet3_comp_ring_adv_next2proc(&tq->comp_ring);
+               gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
+       }
+
+       if (completed) {
+               spin_lock(&tq->tx_lock);
+               if (unlikely(vmxnet3_tq_stopped(tq, adapter) &&
+                            vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) >
+                            VMXNET3_WAKE_QUEUE_THRESHOLD(tq) &&
+                            netif_carrier_ok(adapter->netdev))) {
+                       vmxnet3_tq_wake(tq, adapter);
+               }
+               spin_unlock(&tq->tx_lock);
+       }
+       return completed;
+}
+
+
+static void
+vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq,
+                  struct vmxnet3_adapter *adapter)
+{
+       int i;
+
+       while (tq->tx_ring.next2comp != tq->tx_ring.next2fill) {
+               struct vmxnet3_tx_buf_info *tbi;
+               union Vmxnet3_GenericDesc *gdesc;
+
+               tbi = tq->buf_info + tq->tx_ring.next2comp;
+               gdesc = tq->tx_ring.base + tq->tx_ring.next2comp;
+
+               vmxnet3_unmap_tx_buf(tbi, adapter->pdev);
+               if (tbi->skb) {
+                       dev_kfree_skb_any(tbi->skb);
+                       tbi->skb = NULL;
+               }
+               vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
+       }
+
+       /* sanity check, verify all buffers are indeed unmapped and freed */
+       for (i = 0; i < tq->tx_ring.size; i++) {
+               BUG_ON(tq->buf_info[i].skb != NULL ||
+                      tq->buf_info[i].map_type != VMXNET3_MAP_NONE);
+       }
+
+       tq->tx_ring.gen = VMXNET3_INIT_GEN;
+       tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
+
+       tq->comp_ring.gen = VMXNET3_INIT_GEN;
+       tq->comp_ring.next2proc = 0;
+}
+
+
+void
+vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
+                  struct vmxnet3_adapter *adapter)
+{
+       if (tq->tx_ring.base) {
+               pci_free_consistent(adapter->pdev, tq->tx_ring.size *
+                                   sizeof(struct Vmxnet3_TxDesc),
+                                   tq->tx_ring.base, tq->tx_ring.basePA);
+               tq->tx_ring.base = NULL;
+       }
+       if (tq->data_ring.base) {
+               pci_free_consistent(adapter->pdev, tq->data_ring.size *
+                                   sizeof(struct Vmxnet3_TxDataDesc),
+                                   tq->data_ring.base, tq->data_ring.basePA);
+               tq->data_ring.base = NULL;
+       }
+       if (tq->comp_ring.base) {
+               pci_free_consistent(adapter->pdev, tq->comp_ring.size *
+                                   sizeof(struct Vmxnet3_TxCompDesc),
+                                   tq->comp_ring.base, tq->comp_ring.basePA);
+               tq->comp_ring.base = NULL;
+       }
+       kfree(tq->buf_info);
+       tq->buf_info = NULL;
+}
+
+
+static void
+vmxnet3_tq_init(struct vmxnet3_tx_queue *tq,
+               struct vmxnet3_adapter *adapter)
+{
+       int i;
+
+       /* reset the tx ring contents to 0 and reset the tx ring states */
+       memset(tq->tx_ring.base, 0, tq->tx_ring.size *
+              sizeof(struct Vmxnet3_TxDesc));
+       tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
+       tq->tx_ring.gen = VMXNET3_INIT_GEN;
+
+       memset(tq->data_ring.base, 0, tq->data_ring.size *
+              sizeof(struct Vmxnet3_TxDataDesc));
+
+       /* reset the tx comp ring contents to 0 and reset comp ring states */
+       memset(tq->comp_ring.base, 0, tq->comp_ring.size *
+              sizeof(struct Vmxnet3_TxCompDesc));
+       tq->comp_ring.next2proc = 0;
+       tq->comp_ring.gen = VMXNET3_INIT_GEN;
+
+       /* reset the bookkeeping data */
+       memset(tq->buf_info, 0, sizeof(tq->buf_info[0]) * tq->tx_ring.size);
+       for (i = 0; i < tq->tx_ring.size; i++)
+               tq->buf_info[i].map_type = VMXNET3_MAP_NONE;
+
+       /* stats are not reset */
+}
+
+
+static int
+vmxnet3_tq_create(struct vmxnet3_tx_queue *tq,
+                 struct vmxnet3_adapter *adapter)
+{
+       BUG_ON(tq->tx_ring.base || tq->data_ring.base ||
+              tq->comp_ring.base || tq->buf_info);
+
+       tq->tx_ring.base = pci_alloc_consistent(adapter->pdev, tq->tx_ring.size
+                          * sizeof(struct Vmxnet3_TxDesc),
+                          &tq->tx_ring.basePA);
+       if (!tq->tx_ring.base) {
+               printk(KERN_ERR "%s: failed to allocate tx ring\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+
+       tq->data_ring.base = pci_alloc_consistent(adapter->pdev,
+                            tq->data_ring.size *
+                            sizeof(struct Vmxnet3_TxDataDesc),
+                            &tq->data_ring.basePA);
+       if (!tq->data_ring.base) {
+               printk(KERN_ERR "%s: failed to allocate data ring\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+
+       tq->comp_ring.base = pci_alloc_consistent(adapter->pdev,
+                            tq->comp_ring.size *
+                            sizeof(struct Vmxnet3_TxCompDesc),
+                            &tq->comp_ring.basePA);
+       if (!tq->comp_ring.base) {
+               printk(KERN_ERR "%s: failed to allocate tx comp ring\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+
+       tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]),
+                              GFP_KERNEL);
+       if (!tq->buf_info) {
+               printk(KERN_ERR "%s: failed to allocate tx bufinfo\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+
+       return 0;
+
+err:
+       vmxnet3_tq_destroy(tq, adapter);
+       return -ENOMEM;
+}
+
+
+/*
+ *    starting from ring->next2fill, allocate rx buffers for the given ring
+ *    of the rx queue and update the rx desc. stop after @num_to_alloc buffers
+ *    are allocated or allocation fails
+ */
+
+static int
+vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
+                       int num_to_alloc, struct vmxnet3_adapter *adapter)
+{
+       int num_allocated = 0;
+       struct vmxnet3_rx_buf_info *rbi_base = rq->buf_info[ring_idx];
+       struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
+       u32 val;
+
+       while (num_allocated < num_to_alloc) {
+               struct vmxnet3_rx_buf_info *rbi;
+               union Vmxnet3_GenericDesc *gd;
+
+               rbi = rbi_base + ring->next2fill;
+               gd = ring->base + ring->next2fill;
+
+               if (rbi->buf_type == VMXNET3_RX_BUF_SKB) {
+                       if (rbi->skb == NULL) {
+                               rbi->skb = dev_alloc_skb(rbi->len +
+                                                        NET_IP_ALIGN);
+                               if (unlikely(rbi->skb == NULL)) {
+                                       rq->stats.rx_buf_alloc_failure++;
+                                       break;
+                               }
+                               rbi->skb->dev = adapter->netdev;
+
+                               skb_reserve(rbi->skb, NET_IP_ALIGN);
+                               rbi->dma_addr = pci_map_single(adapter->pdev,
+                                               rbi->skb->data, rbi->len,
+                                               PCI_DMA_FROMDEVICE);
+                       } else {
+                               /* rx buffer skipped by the device */
+                       }
+                       val = VMXNET3_RXD_BTYPE_HEAD << VMXNET3_RXD_BTYPE_SHIFT;
+               } else {
+                       BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE ||
+                              rbi->len  != PAGE_SIZE);
+
+                       if (rbi->page == NULL) {
+                               rbi->page = alloc_page(GFP_ATOMIC);
+                               if (unlikely(rbi->page == NULL)) {
+                                       rq->stats.rx_buf_alloc_failure++;
+                                       break;
+                               }
+                               rbi->dma_addr = pci_map_page(adapter->pdev,
+                                               rbi->page, 0, PAGE_SIZE,
+                                               PCI_DMA_FROMDEVICE);
+                       } else {
+                               /* rx buffers skipped by the device */
+                       }
+                       val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
+               }
+
+               BUG_ON(rbi->dma_addr == 0);
+               gd->rxd.addr = rbi->dma_addr;
+               gd->dword[2] = (ring->gen << VMXNET3_RXD_GEN_SHIFT) | val |
+                               rbi->len;
+
+               num_allocated++;
+               vmxnet3_cmd_ring_adv_next2fill(ring);
+       }
+       rq->uncommitted[ring_idx] += num_allocated;
+
+       dev_dbg(&adapter->netdev->dev,
+               "alloc_rx_buf: %d allocated, next2fill %u, next2comp "
+               "%u, uncommited %u\n", num_allocated, ring->next2fill,
+               ring->next2comp, rq->uncommitted[ring_idx]);
+
+       /* so that the device can distinguish a full ring and an empty ring */
+       BUG_ON(num_allocated != 0 && ring->next2fill == ring->next2comp);
+
+       return num_allocated;
+}
+
+
+static void
+vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd,
+                   struct vmxnet3_rx_buf_info *rbi)
+{
+       struct skb_frag_struct *frag = skb_shinfo(skb)->frags +
+               skb_shinfo(skb)->nr_frags;
+
+       BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
+
+       frag->page = rbi->page;
+       frag->page_offset = 0;
+       frag->size = rcd->len;
+       skb->data_len += frag->size;
+       skb_shinfo(skb)->nr_frags++;
+}
+
+
+static void
+vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
+               struct vmxnet3_tx_queue *tq, struct pci_dev *pdev,
+               struct vmxnet3_adapter *adapter)
+{
+       u32 dw2, len;
+       unsigned long buf_offset;
+       int i;
+       union Vmxnet3_GenericDesc *gdesc;
+       struct vmxnet3_tx_buf_info *tbi = NULL;
+
+       BUG_ON(ctx->copy_size > skb_headlen(skb));
+
+       /* use the previous gen bit for the SOP desc */
+       dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
+
+       ctx->sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill;
+       gdesc = ctx->sop_txd; /* both loops below can be skipped */
+
+       /* no need to map the buffer if headers are copied */
+       if (ctx->copy_size) {
+               ctx->sop_txd->txd.addr = tq->data_ring.basePA +
+                                       tq->tx_ring.next2fill *
+                                       sizeof(struct Vmxnet3_TxDataDesc);
+               ctx->sop_txd->dword[2] = dw2 | ctx->copy_size;
+               ctx->sop_txd->dword[3] = 0;
+
+               tbi = tq->buf_info + tq->tx_ring.next2fill;
+               tbi->map_type = VMXNET3_MAP_NONE;
+
+               dev_dbg(&adapter->netdev->dev,
+                       "txd[%u]: 0x%Lx 0x%x 0x%x\n",
+                       tq->tx_ring.next2fill, ctx->sop_txd->txd.addr,
+                       ctx->sop_txd->dword[2], ctx->sop_txd->dword[3]);
+               vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+
+               /* use the right gen for non-SOP desc */
+               dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+       }
+
+       /* linear part can use multiple tx desc if it's big */
+       len = skb_headlen(skb) - ctx->copy_size;
+       buf_offset = ctx->copy_size;
+       while (len) {
+               u32 buf_size;
+
+               buf_size = len > VMXNET3_MAX_TX_BUF_SIZE ?
+                          VMXNET3_MAX_TX_BUF_SIZE : len;
+
+               tbi = tq->buf_info + tq->tx_ring.next2fill;
+               tbi->map_type = VMXNET3_MAP_SINGLE;
+               tbi->dma_addr = pci_map_single(adapter->pdev,
+                               skb->data + buf_offset, buf_size,
+                               PCI_DMA_TODEVICE);
+
+               tbi->len = buf_size; /* this automatically convert 2^14 to 0 */
+
+               gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
+               BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
+
+               gdesc->txd.addr = tbi->dma_addr;
+               gdesc->dword[2] = dw2 | buf_size;
+               gdesc->dword[3] = 0;
+
+               dev_dbg(&adapter->netdev->dev,
+                       "txd[%u]: 0x%Lx 0x%x 0x%x\n",
+                       tq->tx_ring.next2fill, gdesc->txd.addr,
+                       gdesc->dword[2], gdesc->dword[3]);
+               vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+               dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+
+               len -= buf_size;
+               buf_offset += buf_size;
+       }
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+               tbi = tq->buf_info + tq->tx_ring.next2fill;
+               tbi->map_type = VMXNET3_MAP_PAGE;
+               tbi->dma_addr = pci_map_page(adapter->pdev, frag->page,
+                                            frag->page_offset, frag->size,
+                                            PCI_DMA_TODEVICE);
+
+               tbi->len = frag->size;
+
+               gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
+               BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
+
+               gdesc->txd.addr = tbi->dma_addr;
+               gdesc->dword[2] = dw2 | frag->size;
+               gdesc->dword[3] = 0;
+
+               dev_dbg(&adapter->netdev->dev,
+                       "txd[%u]: 0x%llu %u %u\n",
+                       tq->tx_ring.next2fill, gdesc->txd.addr,
+                       gdesc->dword[2], gdesc->dword[3]);
+               vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
+               dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+       }
+
+       ctx->eop_txd = gdesc;
+
+       /* set the last buf_info for the pkt */
+       tbi->skb = skb;
+       tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base;
+}
+
+
+/*
+ *    parse and copy relevant protocol headers:
+ *      For a tso pkt, relevant headers are L2/3/4 including options
+ *      For a pkt requesting csum offloading, they are L2/3 and may include L4
+ *      if it's a TCP/UDP pkt
+ *
+ * Returns:
+ *    -1:  error happens during parsing
+ *     0:  protocol headers parsed, but too big to be copied
+ *     1:  protocol headers parsed and copied
+ *
+ * Other effects:
+ *    1. related *ctx fields are updated.
+ *    2. ctx->copy_size is # of bytes copied
+ *    3. the portion copied is guaranteed to be in the linear part
+ *
+ */
+static int
+vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+                          struct vmxnet3_tx_ctx *ctx,
+                          struct vmxnet3_adapter *adapter)
+{
+       struct Vmxnet3_TxDataDesc *tdd;
+
+       if (ctx->mss) {
+               ctx->eth_ip_hdr_size = skb_transport_offset(skb);
+               ctx->l4_hdr_size = ((struct tcphdr *)
+                                  skb_transport_header(skb))->doff * 4;
+               ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
+       } else {
+               unsigned int pull_size;
+
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                       ctx->eth_ip_hdr_size = skb_transport_offset(skb);
+
+                       if (ctx->ipv4) {
+                               struct iphdr *iph = (struct iphdr *)
+                                                   skb_network_header(skb);
+                               if (iph->protocol == IPPROTO_TCP) {
+                                       pull_size = ctx->eth_ip_hdr_size +
+                                                   sizeof(struct tcphdr);
+
+                                       if (unlikely(!pskb_may_pull(skb,
+                                                               pull_size))) {
+                                               goto err;
+                                       }
+                                       ctx->l4_hdr_size = ((struct tcphdr *)
+                                          skb_transport_header(skb))->doff * 4;
+                               } else if (iph->protocol == IPPROTO_UDP) {
+                                       ctx->l4_hdr_size =
+                                                       sizeof(struct udphdr);
+                               } else {
+                                       ctx->l4_hdr_size = 0;
+                               }
+                       } else {
+                               /* for simplicity, don't copy L4 headers */
+                               ctx->l4_hdr_size = 0;
+                       }
+                       ctx->copy_size = ctx->eth_ip_hdr_size +
+                                        ctx->l4_hdr_size;
+               } else {
+                       ctx->eth_ip_hdr_size = 0;
+                       ctx->l4_hdr_size = 0;
+                       /* copy as much as allowed */
+                       ctx->copy_size = min((unsigned int)VMXNET3_HDR_COPY_SIZE
+                                            , skb_headlen(skb));
+               }
+
+               /* make sure headers are accessible directly */
+               if (unlikely(!pskb_may_pull(skb, ctx->copy_size)))
+                       goto err;
+       }
+
+       if (unlikely(ctx->copy_size > VMXNET3_HDR_COPY_SIZE)) {
+               tq->stats.oversized_hdr++;
+               ctx->copy_size = 0;
+               return 0;
+       }
+
+       tdd = tq->data_ring.base + tq->tx_ring.next2fill;
+
+       memcpy(tdd->data, skb->data, ctx->copy_size);
+       dev_dbg(&adapter->netdev->dev,
+               "copy %u bytes to dataRing[%u]\n",
+               ctx->copy_size, tq->tx_ring.next2fill);
+       return 1;
+
+err:
+       return -1;
+}
+
+
+static void
+vmxnet3_prepare_tso(struct sk_buff *skb,
+                   struct vmxnet3_tx_ctx *ctx)
+{
+       struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb);
+       if (ctx->ipv4) {
+               struct iphdr *iph = (struct iphdr *)skb_network_header(skb);
+               iph->check = 0;
+               tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
+                                                IPPROTO_TCP, 0);
+       } else {
+               struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb);
+               tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
+                                              IPPROTO_TCP, 0);
+       }
+}
+
+
+/*
+ * Transmits a pkt thru a given tq
+ * Returns:
+ *    NETDEV_TX_OK:      descriptors are setup successfully
+ *    NETDEV_TX_OK:      error occured, the pkt is dropped
+ *    NETDEV_TX_BUSY:    tx ring is full, queue is stopped
+ *
+ * Side-effects:
+ *    1. tx ring may be changed
+ *    2. tq stats may be updated accordingly
+ *    3. shared->txNumDeferred may be updated
+ */
+
+static int
+vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+               struct vmxnet3_adapter *adapter, struct net_device *netdev)
+{
+       int ret;
+       u32 count;
+       unsigned long flags;
+       struct vmxnet3_tx_ctx ctx;
+       union Vmxnet3_GenericDesc *gdesc;
+
+       /* conservatively estimate # of descriptors to use */
+       count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
+               skb_shinfo(skb)->nr_frags + 1;
+
+       ctx.ipv4 = (skb->protocol == __constant_ntohs(ETH_P_IP));
+
+       ctx.mss = skb_shinfo(skb)->gso_size;
+       if (ctx.mss) {
+               if (skb_header_cloned(skb)) {
+                       if (unlikely(pskb_expand_head(skb, 0, 0,
+                                                     GFP_ATOMIC) != 0)) {
+                               tq->stats.drop_tso++;
+                               goto drop_pkt;
+                       }
+                       tq->stats.copy_skb_header++;
+               }
+               vmxnet3_prepare_tso(skb, &ctx);
+       } else {
+               if (unlikely(count > VMXNET3_MAX_TXD_PER_PKT)) {
+
+                       /* non-tso pkts must not use more than
+                        * VMXNET3_MAX_TXD_PER_PKT entries
+                        */
+                       if (skb_linearize(skb) != 0) {
+                               tq->stats.drop_too_many_frags++;
+                               goto drop_pkt;
+                       }
+                       tq->stats.linearized++;
+
+                       /* recalculate the # of descriptors to use */
+                       count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1;
+               }
+       }
+
+       ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter);
+       if (ret >= 0) {
+               BUG_ON(ret <= 0 && ctx.copy_size != 0);
+               /* hdrs parsed, check against other limits */
+               if (ctx.mss) {
+                       if (unlikely(ctx.eth_ip_hdr_size + ctx.l4_hdr_size >
+                                    VMXNET3_MAX_TX_BUF_SIZE)) {
+                               goto hdr_too_big;
+                       }
+               } else {
+                       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                               if (unlikely(ctx.eth_ip_hdr_size +
+                                            skb->csum_offset >
+                                            VMXNET3_MAX_CSUM_OFFSET)) {
+                                       goto hdr_too_big;
+                               }
+                       }
+               }
+       } else {
+               tq->stats.drop_hdr_inspect_err++;
+               goto drop_pkt;
+       }
+
+       spin_lock_irqsave(&tq->tx_lock, flags);
+
+       if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) {
+               tq->stats.tx_ring_full++;
+               dev_dbg(&adapter->netdev->dev,
+                       "tx queue stopped on %s, next2comp %u"
+                       " next2fill %u\n", adapter->netdev->name,
+                       tq->tx_ring.next2comp, tq->tx_ring.next2fill);
+
+               vmxnet3_tq_stop(tq, adapter);
+               spin_unlock_irqrestore(&tq->tx_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       /* fill tx descs related to addr & len */
+       vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter);
+
+       /* setup the EOP desc */
+       ctx.eop_txd->dword[3] = VMXNET3_TXD_CQ | VMXNET3_TXD_EOP;
+
+       /* setup the SOP desc */
+       gdesc = ctx.sop_txd;
+       if (ctx.mss) {
+               gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
+               gdesc->txd.om = VMXNET3_OM_TSO;
+               gdesc->txd.msscof = ctx.mss;
+               tq->shared->txNumDeferred += (skb->len - gdesc->txd.hlen +
+                                            ctx.mss - 1) / ctx.mss;
+       } else {
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                       gdesc->txd.hlen = ctx.eth_ip_hdr_size;
+                       gdesc->txd.om = VMXNET3_OM_CSUM;
+                       gdesc->txd.msscof = ctx.eth_ip_hdr_size +
+                                           skb->csum_offset;
+               } else {
+                       gdesc->txd.om = 0;
+                       gdesc->txd.msscof = 0;
+               }
+               tq->shared->txNumDeferred++;
+       }
+
+       if (vlan_tx_tag_present(skb)) {
+               gdesc->txd.ti = 1;
+               gdesc->txd.tci = vlan_tx_tag_get(skb);
+       }
+
+       wmb();
+
+       /* finally flips the GEN bit of the SOP desc */
+       gdesc->dword[2] ^= VMXNET3_TXD_GEN;
+       dev_dbg(&adapter->netdev->dev,
+               "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n",
+               (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd -
+               tq->tx_ring.base), gdesc->txd.addr, gdesc->dword[2],
+               gdesc->dword[3]);
+
+       spin_unlock_irqrestore(&tq->tx_lock, flags);
+
+       if (tq->shared->txNumDeferred >= tq->shared->txThreshold) {
+               tq->shared->txNumDeferred = 0;
+               VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
+                                      tq->tx_ring.next2fill);
+       }
+       netdev->trans_start = jiffies;
+
+       return NETDEV_TX_OK;
+
+hdr_too_big:
+       tq->stats.drop_oversized_hdr++;
+drop_pkt:
+       tq->stats.drop_total++;
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
+}
+
+
+static netdev_tx_t
+vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       struct vmxnet3_tx_queue *tq = &adapter->tx_queue;
+
+       return vmxnet3_tq_xmit(skb, tq, adapter, netdev);
+}
+
+
+static void
+vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+               struct sk_buff *skb,
+               union Vmxnet3_GenericDesc *gdesc)
+{
+       if (!gdesc->rcd.cnc && adapter->rxcsum) {
+               /* typical case: TCP/UDP over IP and both csums are correct */
+               if ((gdesc->dword[3] & VMXNET3_RCD_CSUM_OK) ==
+                                                       VMXNET3_RCD_CSUM_OK) {
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
+                       BUG_ON(!(gdesc->rcd.v4  || gdesc->rcd.v6));
+                       BUG_ON(gdesc->rcd.frg);
+               } else {
+                       if (gdesc->rcd.csum) {
+                               skb->csum = htons(gdesc->rcd.csum);
+                               skb->ip_summed = CHECKSUM_PARTIAL;
+                       } else {
+                               skb->ip_summed = CHECKSUM_NONE;
+                       }
+               }
+       } else {
+               skb->ip_summed = CHECKSUM_NONE;
+       }
+}
+
+
+static void
+vmxnet3_rx_error(struct vmxnet3_rx_queue *rq, struct Vmxnet3_RxCompDesc *rcd,
+                struct vmxnet3_rx_ctx *ctx,  struct vmxnet3_adapter *adapter)
+{
+       rq->stats.drop_err++;
+       if (!rcd->fcs)
+               rq->stats.drop_fcs++;
+
+       rq->stats.drop_total++;
+
+       /*
+        * We do not unmap and chain the rx buffer to the skb.
+        * We basically pretend this buffer is not used and will be recycled
+        * by vmxnet3_rq_alloc_rx_buf()
+        */
+
+       /*
+        * ctx->skb may be NULL if this is the first and the only one
+        * desc for the pkt
+        */
+       if (ctx->skb)
+               dev_kfree_skb_irq(ctx->skb);
+
+       ctx->skb = NULL;
+}
+
+
+static int
+vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+                      struct vmxnet3_adapter *adapter, int quota)
+{
+       static u32 rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
+       u32 num_rxd = 0;
+       struct Vmxnet3_RxCompDesc *rcd;
+       struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
+
+       rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+       while (rcd->gen == rq->comp_ring.gen) {
+               struct vmxnet3_rx_buf_info *rbi;
+               struct sk_buff *skb;
+               int num_to_alloc;
+               struct Vmxnet3_RxDesc *rxd;
+               u32 idx, ring_idx;
+
+               if (num_rxd >= quota) {
+                       /* we may stop even before we see the EOP desc of
+                        * the current pkt
+                        */
+                       break;
+               }
+               num_rxd++;
+
+               idx = rcd->rxdIdx;
+               ring_idx = rcd->rqID == rq->qid ? 0 : 1;
+
+               rxd = &rq->rx_ring[ring_idx].base[idx].rxd;
+               rbi = rq->buf_info[ring_idx] + idx;
+
+               BUG_ON(rxd->addr != rbi->dma_addr || rxd->len != rbi->len);
+
+               if (unlikely(rcd->eop && rcd->err)) {
+                       vmxnet3_rx_error(rq, rcd, ctx, adapter);
+                       goto rcd_done;
+               }
+
+               if (rcd->sop) { /* first buf of the pkt */
+                       BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD ||
+                              rcd->rqID != rq->qid);
+
+                       BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB);
+                       BUG_ON(ctx->skb != NULL || rbi->skb == NULL);
+
+                       if (unlikely(rcd->len == 0)) {
+                               /* Pretend the rx buffer is skipped. */
+                               BUG_ON(!(rcd->sop && rcd->eop));
+                               dev_dbg(&adapter->netdev->dev,
+                                       "rxRing[%u][%u] 0 length\n",
+                                       ring_idx, idx);
+                               goto rcd_done;
+                       }
+
+                       ctx->skb = rbi->skb;
+                       rbi->skb = NULL;
+
+                       pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len,
+                                        PCI_DMA_FROMDEVICE);
+
+                       skb_put(ctx->skb, rcd->len);
+               } else {
+                       BUG_ON(ctx->skb == NULL);
+                       /* non SOP buffer must be type 1 in most cases */
+                       if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
+                               BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
+
+                               if (rcd->len) {
+                                       pci_unmap_page(adapter->pdev,
+                                                      rbi->dma_addr, rbi->len,
+                                                      PCI_DMA_FROMDEVICE);
+
+                                       vmxnet3_append_frag(ctx->skb, rcd, rbi);
+                                       rbi->page = NULL;
+                               }
+                       } else {
+                               /*
+                                * The only time a non-SOP buffer is type 0 is
+                                * when it's EOP and error flag is raised, which
+                                * has already been handled.
+                                */
+                               BUG_ON(true);
+                       }
+               }
+
+               skb = ctx->skb;
+               if (rcd->eop) {
+                       skb->len += skb->data_len;
+                       skb->truesize += skb->data_len;
+
+                       vmxnet3_rx_csum(adapter, skb,
+                                       (union Vmxnet3_GenericDesc *)rcd);
+                       skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+                       if (unlikely(adapter->vlan_grp && rcd->ts)) {
+                               vlan_hwaccel_receive_skb(skb,
+                                               adapter->vlan_grp, rcd->tci);
+                       } else {
+                               netif_receive_skb(skb);
+                       }
+
+                       adapter->netdev->last_rx = jiffies;
+                       ctx->skb = NULL;
+               }
+
+rcd_done:
+               /* device may skip some rx descs */
+               rq->rx_ring[ring_idx].next2comp = idx;
+               VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp,
+                                         rq->rx_ring[ring_idx].size);
+
+               /* refill rx buffers frequently to avoid starving the h/w */
+               num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring +
+                                                          ring_idx);
+               if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq,
+                                                       ring_idx, adapter))) {
+                       vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc,
+                                               adapter);
+
+                       /* if needed, update the register */
+                       if (unlikely(rq->shared->updateRxProd)) {
+                               VMXNET3_WRITE_BAR0_REG(adapter,
+                                       rxprod_reg[ring_idx] + rq->qid * 8,
+                                       rq->rx_ring[ring_idx].next2fill);
+                               rq->uncommitted[ring_idx] = 0;
+                       }
+               }
+
+               vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
+               rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
+       }
+
+       return num_rxd;
+}
+
+
+static void
+vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
+                  struct vmxnet3_adapter *adapter)
+{
+       u32 i, ring_idx;
+       struct Vmxnet3_RxDesc *rxd;
+
+       for (ring_idx = 0; ring_idx < 2; ring_idx++) {
+               for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
+                       rxd = &rq->rx_ring[ring_idx].base[i].rxd;
+
+                       if (rxd->btype == VMXNET3_RXD_BTYPE_HEAD &&
+                                       rq->buf_info[ring_idx][i].skb) {
+                               pci_unmap_single(adapter->pdev, rxd->addr,
+                                                rxd->len, PCI_DMA_FROMDEVICE);
+                               dev_kfree_skb(rq->buf_info[ring_idx][i].skb);
+                               rq->buf_info[ring_idx][i].skb = NULL;
+                       } else if (rxd->btype == VMXNET3_RXD_BTYPE_BODY &&
+                                       rq->buf_info[ring_idx][i].page) {
+                               pci_unmap_page(adapter->pdev, rxd->addr,
+                                              rxd->len, PCI_DMA_FROMDEVICE);
+                               put_page(rq->buf_info[ring_idx][i].page);
+                               rq->buf_info[ring_idx][i].page = NULL;
+                       }
+               }
+
+               rq->rx_ring[ring_idx].gen = VMXNET3_INIT_GEN;
+               rq->rx_ring[ring_idx].next2fill =
+                                       rq->rx_ring[ring_idx].next2comp = 0;
+               rq->uncommitted[ring_idx] = 0;
+       }
+
+       rq->comp_ring.gen = VMXNET3_INIT_GEN;
+       rq->comp_ring.next2proc = 0;
+}
+
+
+void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+                       struct vmxnet3_adapter *adapter)
+{
+       int i;
+       int j;
+
+       /* all rx buffers must have already been freed */
+       for (i = 0; i < 2; i++) {
+               if (rq->buf_info[i]) {
+                       for (j = 0; j < rq->rx_ring[i].size; j++)
+                               BUG_ON(rq->buf_info[i][j].page != NULL);
+               }
+       }
+
+
+       kfree(rq->buf_info[0]);
+
+       for (i = 0; i < 2; i++) {
+               if (rq->rx_ring[i].base) {
+                       pci_free_consistent(adapter->pdev, rq->rx_ring[i].size
+                                           * sizeof(struct Vmxnet3_RxDesc),
+                                           rq->rx_ring[i].base,
+                                           rq->rx_ring[i].basePA);
+                       rq->rx_ring[i].base = NULL;
+               }
+               rq->buf_info[i] = NULL;
+       }
+
+       if (rq->comp_ring.base) {
+               pci_free_consistent(adapter->pdev, rq->comp_ring.size *
+                                   sizeof(struct Vmxnet3_RxCompDesc),
+                                   rq->comp_ring.base, rq->comp_ring.basePA);
+               rq->comp_ring.base = NULL;
+       }
+}
+
+
+static int
+vmxnet3_rq_init(struct vmxnet3_rx_queue *rq,
+               struct vmxnet3_adapter  *adapter)
+{
+       int i;
+
+       /* initialize buf_info */
+       for (i = 0; i < rq->rx_ring[0].size; i++) {
+
+               /* 1st buf for a pkt is skbuff */
+               if (i % adapter->rx_buf_per_pkt == 0) {
+                       rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_SKB;
+                       rq->buf_info[0][i].len = adapter->skb_buf_size;
+               } else { /* subsequent bufs for a pkt is frag */
+                       rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_PAGE;
+                       rq->buf_info[0][i].len = PAGE_SIZE;
+               }
+       }
+       for (i = 0; i < rq->rx_ring[1].size; i++) {
+               rq->buf_info[1][i].buf_type = VMXNET3_RX_BUF_PAGE;
+               rq->buf_info[1][i].len = PAGE_SIZE;
+       }
+
+       /* reset internal state and allocate buffers for both rings */
+       for (i = 0; i < 2; i++) {
+               rq->rx_ring[i].next2fill = rq->rx_ring[i].next2comp = 0;
+               rq->uncommitted[i] = 0;
+
+               memset(rq->rx_ring[i].base, 0, rq->rx_ring[i].size *
+                      sizeof(struct Vmxnet3_RxDesc));
+               rq->rx_ring[i].gen = VMXNET3_INIT_GEN;
+       }
+       if (vmxnet3_rq_alloc_rx_buf(rq, 0, rq->rx_ring[0].size - 1,
+                                   adapter) == 0) {
+               /* at least has 1 rx buffer for the 1st ring */
+               return -ENOMEM;
+       }
+       vmxnet3_rq_alloc_rx_buf(rq, 1, rq->rx_ring[1].size - 1, adapter);
+
+       /* reset the comp ring */
+       rq->comp_ring.next2proc = 0;
+       memset(rq->comp_ring.base, 0, rq->comp_ring.size *
+              sizeof(struct Vmxnet3_RxCompDesc));
+       rq->comp_ring.gen = VMXNET3_INIT_GEN;
+
+       /* reset rxctx */
+       rq->rx_ctx.skb = NULL;
+
+       /* stats are not reset */
+       return 0;
+}
+
+
+static int
+vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
+{
+       int i;
+       size_t sz;
+       struct vmxnet3_rx_buf_info *bi;
+
+       for (i = 0; i < 2; i++) {
+
+               sz = rq->rx_ring[i].size * sizeof(struct Vmxnet3_RxDesc);
+               rq->rx_ring[i].base = pci_alloc_consistent(adapter->pdev, sz,
+                                                       &rq->rx_ring[i].basePA);
+               if (!rq->rx_ring[i].base) {
+                       printk(KERN_ERR "%s: failed to allocate rx ring %d\n",
+                              adapter->netdev->name, i);
+                       goto err;
+               }
+       }
+
+       sz = rq->comp_ring.size * sizeof(struct Vmxnet3_RxCompDesc);
+       rq->comp_ring.base = pci_alloc_consistent(adapter->pdev, sz,
+                                                 &rq->comp_ring.basePA);
+       if (!rq->comp_ring.base) {
+               printk(KERN_ERR "%s: failed to allocate rx comp ring\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+
+       sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
+                                                  rq->rx_ring[1].size);
+       bi = kmalloc(sz, GFP_KERNEL);
+       if (!bi) {
+               printk(KERN_ERR "%s: failed to allocate rx bufinfo\n",
+                      adapter->netdev->name);
+               goto err;
+       }
+       memset(bi, 0, sz);
+       rq->buf_info[0] = bi;
+       rq->buf_info[1] = bi + rq->rx_ring[0].size;
+
+       return 0;
+
+err:
+       vmxnet3_rq_destroy(rq, adapter);
+       return -ENOMEM;
+}
+
+
+static int
+vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget)
+{
+       if (unlikely(adapter->shared->ecr))
+               vmxnet3_process_events(adapter);
+
+       vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter);
+       return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget);
+}
+
+
+static int
+vmxnet3_poll(struct napi_struct *napi, int budget)
+{
+       struct vmxnet3_adapter *adapter = container_of(napi,
+                                         struct vmxnet3_adapter, napi);
+       int rxd_done;
+
+       rxd_done = vmxnet3_do_poll(adapter, budget);
+
+       if (rxd_done < budget) {
+               napi_complete(napi);
+               vmxnet3_enable_intr(adapter, 0);
+       }
+       return rxd_done;
+}
+
+
+/* Interrupt handler for vmxnet3  */
+static irqreturn_t
+vmxnet3_intr(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct vmxnet3_adapter *adapter = netdev_priv(dev);
+
+       if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) {
+               u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
+               if (unlikely(icr == 0))
+                       /* not ours */
+                       return IRQ_NONE;
+       }
+
+
+       /* disable intr if needed */
+       if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
+               vmxnet3_disable_intr(adapter, 0);
+
+       napi_schedule(&adapter->napi);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+
+/* netpoll callback. */
+static void
+vmxnet3_netpoll(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       int irq;
+
+#ifdef CONFIG_PCI_MSI
+       if (adapter->intr.type == VMXNET3_IT_MSIX)
+               irq = adapter->intr.msix_entries[0].vector;
+       else
+#endif
+               irq = adapter->pdev->irq;
+
+       disable_irq(irq);
+       vmxnet3_intr(irq, netdev);
+       enable_irq(irq);
+}
+#endif
+
+static int
+vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
+{
+       int err;
+
+#ifdef CONFIG_PCI_MSI
+       if (adapter->intr.type == VMXNET3_IT_MSIX) {
+               /* we only use 1 MSI-X vector */
+               err = request_irq(adapter->intr.msix_entries[0].vector,
+                                 vmxnet3_intr, 0, adapter->netdev->name,
+                                 adapter->netdev);
+       } else
+#endif
+       if (adapter->intr.type == VMXNET3_IT_MSI) {
+               err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0,
+                                 adapter->netdev->name, adapter->netdev);
+       } else {
+               err = request_irq(adapter->pdev->irq, vmxnet3_intr,
+                                 IRQF_SHARED, adapter->netdev->name,
+                                 adapter->netdev);
+       }
+
+       if (err)
+               printk(KERN_ERR "Failed to request irq %s (intr type:%d), error"
+                      ":%d\n", adapter->netdev->name, adapter->intr.type, err);
+
+
+       if (!err) {
+               int i;
+               /* init our intr settings */
+               for (i = 0; i < adapter->intr.num_intrs; i++)
+                       adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE;
+
+               /* next setup intr index for all intr sources */
+               adapter->tx_queue.comp_ring.intr_idx = 0;
+               adapter->rx_queue.comp_ring.intr_idx = 0;
+               adapter->intr.event_intr_idx = 0;
+
+               printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors "
+                      "allocated\n", adapter->netdev->name, adapter->intr.type,
+                      adapter->intr.mask_mode, adapter->intr.num_intrs);
+       }
+
+       return err;
+}
+
+
+static void
+vmxnet3_free_irqs(struct vmxnet3_adapter *adapter)
+{
+       BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO ||
+              adapter->intr.num_intrs <= 0);
+
+       switch (adapter->intr.type) {
+#ifdef CONFIG_PCI_MSI
+       case VMXNET3_IT_MSIX:
+       {
+               int i;
+
+               for (i = 0; i < adapter->intr.num_intrs; i++)
+                       free_irq(adapter->intr.msix_entries[i].vector,
+                                adapter->netdev);
+               break;
+       }
+#endif
+       case VMXNET3_IT_MSI:
+               free_irq(adapter->pdev->irq, adapter->netdev);
+               break;
+       case VMXNET3_IT_INTX:
+               free_irq(adapter->pdev->irq, adapter->netdev);
+               break;
+       default:
+               BUG_ON(true);
+       }
+}
+
+
+static void
+vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       struct Vmxnet3_DriverShared *shared = adapter->shared;
+       u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+       if (grp) {
+               /* add vlan rx stripping. */
+               if (adapter->netdev->features & NETIF_F_HW_VLAN_RX) {
+                       int i;
+                       struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+                       adapter->vlan_grp = grp;
+
+                       /* update FEATURES to device */
+                       devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                              VMXNET3_CMD_UPDATE_FEATURE);
+                       /*
+                        *  Clear entire vfTable; then enable untagged pkts.
+                        *  Note: setting one entry in vfTable to non-zero turns
+                        *  on VLAN rx filtering.
+                        */
+                       for (i = 0; i < VMXNET3_VFT_SIZE; i++)
+                               vfTable[i] = 0;
+
+                       VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
+                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+               } else {
+                       printk(KERN_ERR "%s: vlan_rx_register when device has "
+                              "no NETIF_F_HW_VLAN_RX\n", netdev->name);
+               }
+       } else {
+               /* remove vlan rx stripping. */
+               struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+               adapter->vlan_grp = NULL;
+
+               if (devRead->misc.uptFeatures & UPT1_F_RXVLAN) {
+                       int i;
+
+                       for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
+                               /* clear entire vfTable; this also disables
+                                * VLAN rx filtering
+                                */
+                               vfTable[i] = 0;
+                       }
+                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+
+                       /* update FEATURES to device */
+                       devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
+                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                              VMXNET3_CMD_UPDATE_FEATURE);
+               }
+       }
+}
+
+
+static void
+vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter)
+{
+       if (adapter->vlan_grp) {
+               u16 vid;
+               u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+               bool activeVlan = false;
+
+               for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+                       if (vlan_group_get_device(adapter->vlan_grp, vid)) {
+                               VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+                               activeVlan = true;
+                       }
+               }
+               if (activeVlan) {
+                       /* continue to allow untagged pkts */
+                       VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
+               }
+       }
+}
+
+
+static void
+vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+       VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
+
+static void
+vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+
+       VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
+
+static u8 *
+vmxnet3_copy_mc(struct net_device *netdev)
+{
+       u8 *buf = NULL;
+       u32 sz = netdev->mc_count * ETH_ALEN;
+
+       /* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */
+       if (sz <= 0xffff) {
+               /* We may be called with BH disabled */
+               buf = kmalloc(sz, GFP_ATOMIC);
+               if (buf) {
+                       int i;
+                       struct dev_mc_list *mc = netdev->mc_list;
+
+                       for (i = 0; i < netdev->mc_count; i++) {
+                               BUG_ON(!mc);
+                               memcpy(buf + i * ETH_ALEN, mc->dmi_addr,
+                                      ETH_ALEN);
+                               mc = mc->next;
+                       }
+               }
+       }
+       return buf;
+}
+
+
+static void
+vmxnet3_set_mc(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       struct Vmxnet3_RxFilterConf *rxConf =
+                                       &adapter->shared->devRead.rxFilterConf;
+       u8 *new_table = NULL;
+       u32 new_mode = VMXNET3_RXM_UCAST;
+
+       if (netdev->flags & IFF_PROMISC)
+               new_mode |= VMXNET3_RXM_PROMISC;
+
+       if (netdev->flags & IFF_BROADCAST)
+               new_mode |= VMXNET3_RXM_BCAST;
+
+       if (netdev->flags & IFF_ALLMULTI)
+               new_mode |= VMXNET3_RXM_ALL_MULTI;
+       else
+               if (netdev->mc_count > 0) {
+                       new_table = vmxnet3_copy_mc(netdev);
+                       if (new_table) {
+                               new_mode |= VMXNET3_RXM_MCAST;
+                               rxConf->mfTableLen = netdev->mc_count *
+                                                    ETH_ALEN;
+                               rxConf->mfTablePA = virt_to_phys(new_table);
+                       } else {
+                               printk(KERN_INFO "%s: failed to copy mcast list"
+                                      ", setting ALL_MULTI\n", netdev->name);
+                               new_mode |= VMXNET3_RXM_ALL_MULTI;
+                       }
+               }
+
+
+       if (!(new_mode & VMXNET3_RXM_MCAST)) {
+               rxConf->mfTableLen = 0;
+               rxConf->mfTablePA = 0;
+       }
+
+       if (new_mode != rxConf->rxMode) {
+               rxConf->rxMode = new_mode;
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                      VMXNET3_CMD_UPDATE_RX_MODE);
+       }
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_UPDATE_MAC_FILTERS);
+
+       kfree(new_table);
+}
+
+
+/*
+ *   Set up driver_shared based on settings in adapter.
+ */
+
+static void
+vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
+{
+       struct Vmxnet3_DriverShared *shared = adapter->shared;
+       struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
+       struct Vmxnet3_TxQueueConf *tqc;
+       struct Vmxnet3_RxQueueConf *rqc;
+       int i;
+
+       memset(shared, 0, sizeof(*shared));
+
+       /* driver settings */
+       shared->magic = VMXNET3_REV1_MAGIC;
+       devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
+       devRead->misc.driverInfo.gos.gosBits = (sizeof(void *) == 4 ?
+                               VMXNET3_GOS_BITS_32 : VMXNET3_GOS_BITS_64);
+       devRead->misc.driverInfo.gos.gosType = VMXNET3_GOS_TYPE_LINUX;
+       devRead->misc.driverInfo.vmxnet3RevSpt = 1;
+       devRead->misc.driverInfo.uptVerSpt = 1;
+
+       devRead->misc.ddPA = virt_to_phys(adapter);
+       devRead->misc.ddLen = sizeof(struct vmxnet3_adapter);
+
+       /* set up feature flags */
+       if (adapter->rxcsum)
+               devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
+
+       if (adapter->lro) {
+               devRead->misc.uptFeatures |= UPT1_F_LRO;
+               devRead->misc.maxNumRxSG = 1 + MAX_SKB_FRAGS;
+       }
+       if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX)
+                       && adapter->vlan_grp) {
+               devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+       }
+
+       devRead->misc.mtu = adapter->netdev->mtu;
+       devRead->misc.queueDescPA = adapter->queue_desc_pa;
+       devRead->misc.queueDescLen = sizeof(struct Vmxnet3_TxQueueDesc) +
+                                    sizeof(struct Vmxnet3_RxQueueDesc);
+
+       /* tx queue settings */
+       BUG_ON(adapter->tx_queue.tx_ring.base == NULL);
+
+       devRead->misc.numTxQueues = 1;
+       tqc = &adapter->tqd_start->conf;
+       tqc->txRingBasePA   = adapter->tx_queue.tx_ring.basePA;
+       tqc->dataRingBasePA = adapter->tx_queue.data_ring.basePA;
+       tqc->compRingBasePA = adapter->tx_queue.comp_ring.basePA;
+       tqc->ddPA           = virt_to_phys(adapter->tx_queue.buf_info);
+       tqc->txRingSize     = adapter->tx_queue.tx_ring.size;
+       tqc->dataRingSize   = adapter->tx_queue.data_ring.size;
+       tqc->compRingSize   = adapter->tx_queue.comp_ring.size;
+       tqc->ddLen          = sizeof(struct vmxnet3_tx_buf_info) *
+                             tqc->txRingSize;
+       tqc->intrIdx        = adapter->tx_queue.comp_ring.intr_idx;
+
+       /* rx queue settings */
+       devRead->misc.numRxQueues = 1;
+       rqc = &adapter->rqd_start->conf;
+       rqc->rxRingBasePA[0] = adapter->rx_queue.rx_ring[0].basePA;
+       rqc->rxRingBasePA[1] = adapter->rx_queue.rx_ring[1].basePA;
+       rqc->compRingBasePA  = adapter->rx_queue.comp_ring.basePA;
+       rqc->ddPA            = virt_to_phys(adapter->rx_queue.buf_info);
+       rqc->rxRingSize[0]   = adapter->rx_queue.rx_ring[0].size;
+       rqc->rxRingSize[1]   = adapter->rx_queue.rx_ring[1].size;
+       rqc->compRingSize    = adapter->rx_queue.comp_ring.size;
+       rqc->ddLen           = sizeof(struct vmxnet3_rx_buf_info) *
+                              (rqc->rxRingSize[0] + rqc->rxRingSize[1]);
+       rqc->intrIdx         = adapter->rx_queue.comp_ring.intr_idx;
+
+       /* intr settings */
+       devRead->intrConf.autoMask = adapter->intr.mask_mode ==
+                                    VMXNET3_IMM_AUTO;
+       devRead->intrConf.numIntrs = adapter->intr.num_intrs;
+       for (i = 0; i < adapter->intr.num_intrs; i++)
+               devRead->intrConf.modLevels[i] = adapter->intr.mod_levels[i];
+
+       devRead->intrConf.eventIntrIdx = adapter->intr.event_intr_idx;
+
+       /* rx filter settings */
+       devRead->rxFilterConf.rxMode = 0;
+       vmxnet3_restore_vlan(adapter);
+       /* the rest are already zeroed */
+}
+
+
+int
+vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
+{
+       int err;
+       u32 ret;
+
+       dev_dbg(&adapter->netdev->dev,
+               "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes"
+               " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size,
+               adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size,
+               adapter->rx_queue.rx_ring[0].size,
+               adapter->rx_queue.rx_ring[1].size);
+
+       vmxnet3_tq_init(&adapter->tx_queue, adapter);
+       err = vmxnet3_rq_init(&adapter->rx_queue, adapter);
+       if (err) {
+               printk(KERN_ERR "Failed to init rx queue for %s: error %d\n",
+                      adapter->netdev->name, err);
+               goto rq_err;
+       }
+
+       err = vmxnet3_request_irqs(adapter);
+       if (err) {
+               printk(KERN_ERR "Failed to setup irq for %s: error %d\n",
+                      adapter->netdev->name, err);
+               goto irq_err;
+       }
+
+       vmxnet3_setup_driver_shared(adapter);
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL,
+                              VMXNET3_GET_ADDR_LO(adapter->shared_pa));
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH,
+                              VMXNET3_GET_ADDR_HI(adapter->shared_pa));
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_ACTIVATE_DEV);
+       ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+
+       if (ret != 0) {
+               printk(KERN_ERR "Failed to activate dev %s: error %u\n",
+                      adapter->netdev->name, ret);
+               err = -EINVAL;
+               goto activate_err;
+       }
+       VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD,
+                              adapter->rx_queue.rx_ring[0].next2fill);
+       VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2,
+                              adapter->rx_queue.rx_ring[1].next2fill);
+
+       /* Apply the rx filter settins last. */
+       vmxnet3_set_mc(adapter->netdev);
+
+       /*
+        * Check link state when first activating device. It will start the
+        * tx queue if the link is up.
+        */
+       vmxnet3_check_link(adapter);
+
+       napi_enable(&adapter->napi);
+       vmxnet3_enable_all_intrs(adapter);
+       clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
+       return 0;
+
+activate_err:
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL, 0);
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH, 0);
+       vmxnet3_free_irqs(adapter);
+irq_err:
+rq_err:
+       /* free up buffers we allocated */
+       vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+       return err;
+}
+
+
+void
+vmxnet3_reset_dev(struct vmxnet3_adapter *adapter)
+{
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
+}
+
+
+int
+vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
+{
+       if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))
+               return 0;
+
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_QUIESCE_DEV);
+       vmxnet3_disable_all_intrs(adapter);
+
+       napi_disable(&adapter->napi);
+       netif_tx_disable(adapter->netdev);
+       adapter->link_speed = 0;
+       netif_carrier_off(adapter->netdev);
+
+       vmxnet3_tq_cleanup(&adapter->tx_queue, adapter);
+       vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
+       vmxnet3_free_irqs(adapter);
+       return 0;
+}
+
+
+static void
+vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
+{
+       u32 tmp;
+
+       tmp = *(u32 *)mac;
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACL, tmp);
+
+       tmp = (mac[5] << 8) | mac[4];
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACH, tmp);
+}
+
+
+static int
+vmxnet3_set_mac_addr(struct net_device *netdev, void *p)
+{
+       struct sockaddr *addr = p;
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       vmxnet3_write_mac_addr(adapter, addr->sa_data);
+
+       return 0;
+}
+
+
+/* ==================== initialization and cleanup routines ============ */
+
+static int
+vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
+{
+       int err;
+       unsigned long mmio_start, mmio_len;
+       struct pci_dev *pdev = adapter->pdev;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR "Failed to enable adapter %s: error %d\n",
+                      pci_name(pdev), err);
+               return err;
+       }
+
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
+               if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
+                       printk(KERN_ERR "pci_set_consistent_dma_mask failed "
+                              "for adapter %s\n", pci_name(pdev));
+                       err = -EIO;
+                       goto err_set_mask;
+               }
+               *dma64 = true;
+       } else {
+               if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
+                       printk(KERN_ERR "pci_set_dma_mask failed for adapter "
+                              "%s\n",  pci_name(pdev));
+                       err = -EIO;
+                       goto err_set_mask;
+               }
+               *dma64 = false;
+       }
+
+       err = pci_request_selected_regions(pdev, (1 << 2) - 1,
+                                          vmxnet3_driver_name);
+       if (err) {
+               printk(KERN_ERR "Failed to request region for adapter %s: "
+                      "error %d\n", pci_name(pdev), err);
+               goto err_set_mask;
+       }
+
+       pci_set_master(pdev);
+
+       mmio_start = pci_resource_start(pdev, 0);
+       mmio_len = pci_resource_len(pdev, 0);
+       adapter->hw_addr0 = ioremap(mmio_start, mmio_len);
+       if (!adapter->hw_addr0) {
+               printk(KERN_ERR "Failed to map bar0 for adapter %s\n",
+                      pci_name(pdev));
+               err = -EIO;
+               goto err_ioremap;
+       }
+
+       mmio_start = pci_resource_start(pdev, 1);
+       mmio_len = pci_resource_len(pdev, 1);
+       adapter->hw_addr1 = ioremap(mmio_start, mmio_len);
+       if (!adapter->hw_addr1) {
+               printk(KERN_ERR "Failed to map bar1 for adapter %s\n",
+                      pci_name(pdev));
+               err = -EIO;
+               goto err_bar1;
+       }
+       return 0;
+
+err_bar1:
+       iounmap(adapter->hw_addr0);
+err_ioremap:
+       pci_release_selected_regions(pdev, (1 << 2) - 1);
+err_set_mask:
+       pci_disable_device(pdev);
+       return err;
+}
+
+
+static void
+vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter)
+{
+       BUG_ON(!adapter->pdev);
+
+       iounmap(adapter->hw_addr0);
+       iounmap(adapter->hw_addr1);
+       pci_release_selected_regions(adapter->pdev, (1 << 2) - 1);
+       pci_disable_device(adapter->pdev);
+}
+
+
+static void
+vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
+{
+       size_t sz;
+
+       if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
+                                   VMXNET3_MAX_ETH_HDR_SIZE) {
+               adapter->skb_buf_size = adapter->netdev->mtu +
+                                       VMXNET3_MAX_ETH_HDR_SIZE;
+               if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
+                       adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE;
+
+               adapter->rx_buf_per_pkt = 1;
+       } else {
+               adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE;
+               sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE +
+                                           VMXNET3_MAX_ETH_HDR_SIZE;
+               adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE;
+       }
+
+       /*
+        * for simplicity, force the ring0 size to be a multiple of
+        * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
+        */
+       sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
+       adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size +
+                                            sz - 1) / sz * sz;
+       adapter->rx_queue.rx_ring[0].size = min_t(u32,
+                                           adapter->rx_queue.rx_ring[0].size,
+                                           VMXNET3_RX_RING_MAX_SIZE / sz * sz);
+}
+
+
+int
+vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
+                     u32 rx_ring_size, u32 rx_ring2_size)
+{
+       int err;
+
+       adapter->tx_queue.tx_ring.size   = tx_ring_size;
+       adapter->tx_queue.data_ring.size = tx_ring_size;
+       adapter->tx_queue.comp_ring.size = tx_ring_size;
+       adapter->tx_queue.shared = &adapter->tqd_start->ctrl;
+       adapter->tx_queue.stopped = true;
+       err = vmxnet3_tq_create(&adapter->tx_queue, adapter);
+       if (err)
+               return err;
+
+       adapter->rx_queue.rx_ring[0].size = rx_ring_size;
+       adapter->rx_queue.rx_ring[1].size = rx_ring2_size;
+       vmxnet3_adjust_rx_ring_size(adapter);
+       adapter->rx_queue.comp_ring.size  = adapter->rx_queue.rx_ring[0].size +
+                                           adapter->rx_queue.rx_ring[1].size;
+       adapter->rx_queue.qid  = 0;
+       adapter->rx_queue.qid2 = 1;
+       adapter->rx_queue.shared = &adapter->rqd_start->ctrl;
+       err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
+       if (err)
+               vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+
+       return err;
+}
+
+static int
+vmxnet3_open(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter;
+       int err;
+
+       adapter = netdev_priv(netdev);
+
+       spin_lock_init(&adapter->tx_queue.tx_lock);
+
+       err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE,
+                                   VMXNET3_DEF_RX_RING_SIZE,
+                                   VMXNET3_DEF_RX_RING_SIZE);
+       if (err)
+               goto queue_err;
+
+       err = vmxnet3_activate_dev(adapter);
+       if (err)
+               goto activate_err;
+
+       return 0;
+
+activate_err:
+       vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+       vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+queue_err:
+       return err;
+}
+
+
+static int
+vmxnet3_close(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       /*
+        * Reset_work may be in the middle of resetting the device, wait for its
+        * completion.
+        */
+       while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+               msleep(1);
+
+       vmxnet3_quiesce_dev(adapter);
+
+       vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+       vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+
+       clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+
+
+       return 0;
+}
+
+
+void
+vmxnet3_force_close(struct vmxnet3_adapter *adapter)
+{
+       /*
+        * we must clear VMXNET3_STATE_BIT_RESETTING, otherwise
+        * vmxnet3_close() will deadlock.
+        */
+       BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state));
+
+       /* we need to enable NAPI, otherwise dev_close will deadlock */
+       napi_enable(&adapter->napi);
+       dev_close(adapter->netdev);
+}
+
+
+static int
+vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       int err = 0;
+
+       if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
+               return -EINVAL;
+
+       if (new_mtu > 1500 && !adapter->jumbo_frame)
+               return -EINVAL;
+
+       netdev->mtu = new_mtu;
+
+       /*
+        * Reset_work may be in the middle of resetting the device, wait for its
+        * completion.
+        */
+       while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (netif_running(netdev)) {
+               vmxnet3_quiesce_dev(adapter);
+               vmxnet3_reset_dev(adapter);
+
+               /* we need to re-create the rx queue based on the new mtu */
+               vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+               vmxnet3_adjust_rx_ring_size(adapter);
+               adapter->rx_queue.comp_ring.size  =
+                                       adapter->rx_queue.rx_ring[0].size +
+                                       adapter->rx_queue.rx_ring[1].size;
+               err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
+               if (err) {
+                       printk(KERN_ERR "%s: failed to re-create rx queue,"
+                               " error %d. Closing it.\n", netdev->name, err);
+                       goto out;
+               }
+
+               err = vmxnet3_activate_dev(adapter);
+               if (err) {
+                       printk(KERN_ERR "%s: failed to re-activate, error %d. "
+                               "Closing it\n", netdev->name, err);
+                       goto out;
+               }
+       }
+
+out:
+       clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+       if (err)
+               vmxnet3_force_close(adapter);
+
+       return err;
+}
+
+
+static void
+vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       netdev->features = NETIF_F_SG |
+               NETIF_F_HW_CSUM |
+               NETIF_F_HW_VLAN_TX |
+               NETIF_F_HW_VLAN_RX |
+               NETIF_F_HW_VLAN_FILTER |
+               NETIF_F_TSO |
+               NETIF_F_TSO6 |
+               NETIF_F_LRO;
+
+       printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
+
+       adapter->rxcsum = true;
+       adapter->jumbo_frame = true;
+       adapter->lro = true;
+
+       if (dma64) {
+               netdev->features |= NETIF_F_HIGHDMA;
+               printk(" highDMA");
+       }
+
+       netdev->vlan_features = netdev->features;
+       printk("\n");
+}
+
+
+static void
+vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
+{
+       u32 tmp;
+
+       tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACL);
+       *(u32 *)mac = tmp;
+
+       tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACH);
+       mac[4] = tmp & 0xff;
+       mac[5] = (tmp >> 8) & 0xff;
+}
+
+
+static void
+vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
+{
+       u32 cfg;
+
+       /* intr settings */
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_GET_CONF_INTR);
+       cfg = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       adapter->intr.type = cfg & 0x3;
+       adapter->intr.mask_mode = (cfg >> 2) & 0x3;
+
+       if (adapter->intr.type == VMXNET3_IT_AUTO) {
+               int err;
+
+#ifdef CONFIG_PCI_MSI
+               adapter->intr.msix_entries[0].entry = 0;
+               err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
+                                     VMXNET3_LINUX_MAX_MSIX_VECT);
+               if (!err) {
+                       adapter->intr.num_intrs = 1;
+                       adapter->intr.type = VMXNET3_IT_MSIX;
+                       return;
+               }
+#endif
+
+               err = pci_enable_msi(adapter->pdev);
+               if (!err) {
+                       adapter->intr.num_intrs = 1;
+                       adapter->intr.type = VMXNET3_IT_MSI;
+                       return;
+               }
+       }
+
+       adapter->intr.type = VMXNET3_IT_INTX;
+
+       /* INT-X related setting */
+       adapter->intr.num_intrs = 1;
+}
+
+
+static void
+vmxnet3_free_intr_resources(struct vmxnet3_adapter *adapter)
+{
+       if (adapter->intr.type == VMXNET3_IT_MSIX)
+               pci_disable_msix(adapter->pdev);
+       else if (adapter->intr.type == VMXNET3_IT_MSI)
+               pci_disable_msi(adapter->pdev);
+       else
+               BUG_ON(adapter->intr.type != VMXNET3_IT_INTX);
+}
+
+
+static void
+vmxnet3_tx_timeout(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       adapter->tx_timeout_count++;
+
+       printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name);
+       schedule_work(&adapter->work);
+}
+
+
+static void
+vmxnet3_reset_work(struct work_struct *data)
+{
+       struct vmxnet3_adapter *adapter;
+
+       adapter = container_of(data, struct vmxnet3_adapter, work);
+
+       /* if another thread is resetting the device, no need to proceed */
+       if (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+               return;
+
+       /* if the device is closed, we must leave it alone */
+       if (netif_running(adapter->netdev)) {
+               printk(KERN_INFO "%s: resetting\n", adapter->netdev->name);
+               vmxnet3_quiesce_dev(adapter);
+               vmxnet3_reset_dev(adapter);
+               vmxnet3_activate_dev(adapter);
+       } else {
+               printk(KERN_INFO "%s: already closed\n", adapter->netdev->name);
+       }
+
+       clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+}
+
+
+static int __devinit
+vmxnet3_probe_device(struct pci_dev *pdev,
+                    const struct pci_device_id *id)
+{
+       static const struct net_device_ops vmxnet3_netdev_ops = {
+               .ndo_open = vmxnet3_open,
+               .ndo_stop = vmxnet3_close,
+               .ndo_start_xmit = vmxnet3_xmit_frame,
+               .ndo_set_mac_address = vmxnet3_set_mac_addr,
+               .ndo_change_mtu = vmxnet3_change_mtu,
+               .ndo_get_stats = vmxnet3_get_stats,
+               .ndo_tx_timeout = vmxnet3_tx_timeout,
+               .ndo_set_multicast_list = vmxnet3_set_mc,
+               .ndo_vlan_rx_register = vmxnet3_vlan_rx_register,
+               .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
+               .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+               .ndo_poll_controller = vmxnet3_netpoll,
+#endif
+       };
+       int err;
+       bool dma64 = false; /* stupid gcc */
+       u32 ver;
+       struct net_device *netdev;
+       struct vmxnet3_adapter *adapter;
+       u8 mac[ETH_ALEN];
+
+       netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter));
+       if (!netdev) {
+               printk(KERN_ERR "Failed to alloc ethernet device for adapter "
+                       "%s\n", pci_name(pdev));
+               return -ENOMEM;
+       }
+
+       pci_set_drvdata(pdev, netdev);
+       adapter = netdev_priv(netdev);
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+
+       adapter->shared = pci_alloc_consistent(adapter->pdev,
+                         sizeof(struct Vmxnet3_DriverShared),
+                         &adapter->shared_pa);
+       if (!adapter->shared) {
+               printk(KERN_ERR "Failed to allocate memory for %s\n",
+                       pci_name(pdev));
+               err = -ENOMEM;
+               goto err_alloc_shared;
+       }
+
+       adapter->tqd_start = pci_alloc_consistent(adapter->pdev,
+                            sizeof(struct Vmxnet3_TxQueueDesc) +
+                            sizeof(struct Vmxnet3_RxQueueDesc),
+                            &adapter->queue_desc_pa);
+
+       if (!adapter->tqd_start) {
+               printk(KERN_ERR "Failed to allocate memory for %s\n",
+                       pci_name(pdev));
+               err = -ENOMEM;
+               goto err_alloc_queue_desc;
+       }
+       adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start
+                                                           + 1);
+
+       adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
+       if (adapter->pm_conf == NULL) {
+               printk(KERN_ERR "Failed to allocate memory for %s\n",
+                       pci_name(pdev));
+               err = -ENOMEM;
+               goto err_alloc_pm;
+       }
+
+       err = vmxnet3_alloc_pci_resources(adapter, &dma64);
+       if (err < 0)
+               goto err_alloc_pci;
+
+       ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
+       if (ver & 1) {
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_VRRS, 1);
+       } else {
+               printk(KERN_ERR "Incompatible h/w version (0x%x) for adapter"
+                      " %s\n", ver, pci_name(pdev));
+               err = -EBUSY;
+               goto err_ver;
+       }
+
+       ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_UVRS);
+       if (ver & 1) {
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_UVRS, 1);
+       } else {
+               printk(KERN_ERR "Incompatible upt version (0x%x) for "
+                      "adapter %s\n", ver, pci_name(pdev));
+               err = -EBUSY;
+               goto err_ver;
+       }
+
+       vmxnet3_declare_features(adapter, dma64);
+
+       adapter->dev_number = atomic_read(&devices_found);
+       vmxnet3_alloc_intr_resources(adapter);
+
+       vmxnet3_read_mac_addr(adapter, mac);
+       memcpy(netdev->dev_addr,  mac, netdev->addr_len);
+
+       netdev->netdev_ops = &vmxnet3_netdev_ops;
+       netdev->watchdog_timeo = 5 * HZ;
+       vmxnet3_set_ethtool_ops(netdev);
+
+       INIT_WORK(&adapter->work, vmxnet3_reset_work);
+
+       netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64);
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+       err = register_netdev(netdev);
+
+       if (err) {
+               printk(KERN_ERR "Failed to register adapter %s\n",
+                       pci_name(pdev));
+               goto err_register;
+       }
+
+       set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
+       atomic_inc(&devices_found);
+       return 0;
+
+err_register:
+       vmxnet3_free_intr_resources(adapter);
+err_ver:
+       vmxnet3_free_pci_resources(adapter);
+err_alloc_pci:
+       kfree(adapter->pm_conf);
+err_alloc_pm:
+       pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
+                           sizeof(struct Vmxnet3_RxQueueDesc),
+                           adapter->tqd_start, adapter->queue_desc_pa);
+err_alloc_queue_desc:
+       pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
+                           adapter->shared, adapter->shared_pa);
+err_alloc_shared:
+       pci_set_drvdata(pdev, NULL);
+       free_netdev(netdev);
+       return err;
+}
+
+
+static void __devexit
+vmxnet3_remove_device(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       flush_scheduled_work();
+
+       unregister_netdev(netdev);
+
+       vmxnet3_free_intr_resources(adapter);
+       vmxnet3_free_pci_resources(adapter);
+       kfree(adapter->pm_conf);
+       pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
+                           sizeof(struct Vmxnet3_RxQueueDesc),
+                           adapter->tqd_start, adapter->queue_desc_pa);
+       pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
+                           adapter->shared, adapter->shared_pa);
+       free_netdev(netdev);
+}
+
+
+#ifdef CONFIG_PM
+
+static int
+vmxnet3_suspend(struct device *device)
+{
+       struct pci_dev *pdev = to_pci_dev(device);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       struct Vmxnet3_PMConf *pmConf;
+       struct ethhdr *ehdr;
+       struct arphdr *ahdr;
+       u8 *arpreq;
+       struct in_device *in_dev;
+       struct in_ifaddr *ifa;
+       int i = 0;
+
+       if (!netif_running(netdev))
+               return 0;
+
+       vmxnet3_disable_all_intrs(adapter);
+       vmxnet3_free_irqs(adapter);
+       vmxnet3_free_intr_resources(adapter);
+
+       netif_device_detach(netdev);
+       netif_stop_queue(netdev);
+
+       /* Create wake-up filters. */
+       pmConf = adapter->pm_conf;
+       memset(pmConf, 0, sizeof(*pmConf));
+
+       if (adapter->wol & WAKE_UCAST) {
+               pmConf->filters[i].patternSize = ETH_ALEN;
+               pmConf->filters[i].maskSize = 1;
+               memcpy(pmConf->filters[i].pattern, netdev->dev_addr, ETH_ALEN);
+               pmConf->filters[i].mask[0] = 0x3F; /* LSB ETH_ALEN bits */
+
+               pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+               i++;
+       }
+
+       if (adapter->wol & WAKE_ARP) {
+               in_dev = in_dev_get(netdev);
+               if (!in_dev)
+                       goto skip_arp;
+
+               ifa = (struct in_ifaddr *)in_dev->ifa_list;
+               if (!ifa)
+                       goto skip_arp;
+
+               pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/
+                       sizeof(struct arphdr) +         /* ARP header */
+                       2 * ETH_ALEN +          /* 2 Ethernet addresses*/
+                       2 * sizeof(u32);        /*2 IPv4 addresses */
+               pmConf->filters[i].maskSize =
+                       (pmConf->filters[i].patternSize - 1) / 8 + 1;
+
+               /* ETH_P_ARP in Ethernet header. */
+               ehdr = (struct ethhdr *)pmConf->filters[i].pattern;
+               ehdr->h_proto = htons(ETH_P_ARP);
+
+               /* ARPOP_REQUEST in ARP header. */
+               ahdr = (struct arphdr *)&pmConf->filters[i].pattern[ETH_HLEN];
+               ahdr->ar_op = htons(ARPOP_REQUEST);
+               arpreq = (u8 *)(ahdr + 1);
+
+               /* The Unicast IPv4 address in 'tip' field. */
+               arpreq += 2 * ETH_ALEN + sizeof(u32);
+               *(u32 *)arpreq = ifa->ifa_address;
+
+               /* The mask for the relevant bits. */
+               pmConf->filters[i].mask[0] = 0x00;
+               pmConf->filters[i].mask[1] = 0x30; /* ETH_P_ARP */
+               pmConf->filters[i].mask[2] = 0x30; /* ARPOP_REQUEST */
+               pmConf->filters[i].mask[3] = 0x00;
+               pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */
+               pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
+               in_dev_put(in_dev);
+
+               pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
+               i++;
+       }
+
+skip_arp:
+       if (adapter->wol & WAKE_MAGIC)
+               pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_MAGIC;
+
+       pmConf->numFilters = i;
+
+       adapter->shared->devRead.pmConfDesc.confVer = 1;
+       adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
+       adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_UPDATE_PMCFG);
+
+       pci_save_state(pdev);
+       pci_enable_wake(pdev, pci_choose_state(pdev, PMSG_SUSPEND),
+                       adapter->wol);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, PMSG_SUSPEND));
+
+       return 0;
+}
+
+
+static int
+vmxnet3_resume(struct device *device)
+{
+       int err;
+       struct pci_dev *pdev = to_pci_dev(device);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       struct Vmxnet3_PMConf *pmConf;
+
+       if (!netif_running(netdev))
+               return 0;
+
+       /* Destroy wake-up filters. */
+       pmConf = adapter->pm_conf;
+       memset(pmConf, 0, sizeof(*pmConf));
+
+       adapter->shared->devRead.pmConfDesc.confVer = 1;
+       adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
+       adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
+
+       netif_device_attach(netdev);
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       err = pci_enable_device_mem(pdev);
+       if (err != 0)
+               return err;
+
+       pci_enable_wake(pdev, PCI_D0, 0);
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                              VMXNET3_CMD_UPDATE_PMCFG);
+       vmxnet3_alloc_intr_resources(adapter);
+       vmxnet3_request_irqs(adapter);
+       vmxnet3_enable_all_intrs(adapter);
+
+       return 0;
+}
+
+static struct dev_pm_ops vmxnet3_pm_ops = {
+       .suspend = vmxnet3_suspend,
+       .resume = vmxnet3_resume,
+};
+#endif
+
+static struct pci_driver vmxnet3_driver = {
+       .name           = vmxnet3_driver_name,
+       .id_table       = vmxnet3_pciid_table,
+       .probe          = vmxnet3_probe_device,
+       .remove         = __devexit_p(vmxnet3_remove_device),
+#ifdef CONFIG_PM
+       .driver.pm      = &vmxnet3_pm_ops,
+#endif
+};
+
+
+static int __init
+vmxnet3_init_module(void)
+{
+       printk(KERN_INFO "%s - version %s\n", VMXNET3_DRIVER_DESC,
+               VMXNET3_DRIVER_VERSION_REPORT);
+       return pci_register_driver(&vmxnet3_driver);
+}
+
+module_init(vmxnet3_init_module);
+
+
+static void
+vmxnet3_exit_module(void)
+{
+       pci_unregister_driver(&vmxnet3_driver);
+}
+
+module_exit(vmxnet3_exit_module);
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION(VMXNET3_DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(VMXNET3_DRIVER_VERSION_STRING);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
new file mode 100644 (file)
index 0000000..c2c15e4
--- /dev/null
@@ -0,0 +1,566 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+
+#include "vmxnet3_int.h"
+
+struct vmxnet3_stat_desc {
+       char desc[ETH_GSTRING_LEN];
+       int  offset;
+};
+
+
+static u32
+vmxnet3_get_rx_csum(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       return adapter->rxcsum;
+}
+
+
+static int
+vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       if (adapter->rxcsum != val) {
+               adapter->rxcsum = val;
+               if (netif_running(netdev)) {
+                       if (val)
+                               adapter->shared->devRead.misc.uptFeatures |=
+                                                               UPT1_F_RXCSUM;
+                       else
+                               adapter->shared->devRead.misc.uptFeatures &=
+                                                               ~UPT1_F_RXCSUM;
+
+                       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                              VMXNET3_CMD_UPDATE_FEATURE);
+               }
+       }
+       return 0;
+}
+
+
+/* per tq stats maintained by the device */
+static const struct vmxnet3_stat_desc
+vmxnet3_tq_dev_stats[] = {
+       /* description,         offset */
+       { "TSO pkts tx",        offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
+       { "TSO bytes tx",       offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
+       { "ucast pkts tx",      offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
+       { "ucast bytes tx",     offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
+       { "mcast pkts tx",      offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
+       { "mcast bytes tx",     offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
+       { "bcast pkts tx",      offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
+       { "bcast bytes tx",     offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
+       { "pkts tx err",        offsetof(struct UPT1_TxStats, pktsTxError) },
+       { "pkts tx discard",    offsetof(struct UPT1_TxStats, pktsTxDiscard) },
+};
+
+/* per tq stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_tq_driver_stats[] = {
+       /* description,         offset */
+       {"drv dropped tx total", offsetof(struct vmxnet3_tq_driver_stats,
+                                       drop_total) },
+       { "   too many frags",  offsetof(struct vmxnet3_tq_driver_stats,
+                                       drop_too_many_frags) },
+       { "   giant hdr",       offsetof(struct vmxnet3_tq_driver_stats,
+                                       drop_oversized_hdr) },
+       { "   hdr err",         offsetof(struct vmxnet3_tq_driver_stats,
+                                       drop_hdr_inspect_err) },
+       { "   tso",             offsetof(struct vmxnet3_tq_driver_stats,
+                                       drop_tso) },
+       { "ring full",          offsetof(struct vmxnet3_tq_driver_stats,
+                                       tx_ring_full) },
+       { "pkts linearized",    offsetof(struct vmxnet3_tq_driver_stats,
+                                       linearized) },
+       { "hdr cloned",         offsetof(struct vmxnet3_tq_driver_stats,
+                                       copy_skb_header) },
+       { "giant hdr",          offsetof(struct vmxnet3_tq_driver_stats,
+                                       oversized_hdr) },
+};
+
+/* per rq stats maintained by the device */
+static const struct vmxnet3_stat_desc
+vmxnet3_rq_dev_stats[] = {
+       { "LRO pkts rx",        offsetof(struct UPT1_RxStats, LROPktsRxOK) },
+       { "LRO byte rx",        offsetof(struct UPT1_RxStats, LROBytesRxOK) },
+       { "ucast pkts rx",      offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
+       { "ucast bytes rx",     offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
+       { "mcast pkts rx",      offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
+       { "mcast bytes rx",     offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
+       { "bcast pkts rx",      offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
+       { "bcast bytes rx",     offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
+       { "pkts rx out of buf", offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
+       { "pkts rx err",        offsetof(struct UPT1_RxStats, pktsRxError) },
+};
+
+/* per rq stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_rq_driver_stats[] = {
+       /* description,         offset */
+       { "drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
+                                          drop_total) },
+       { "   err",            offsetof(struct vmxnet3_rq_driver_stats,
+                                       drop_err) },
+       { "   fcs",            offsetof(struct vmxnet3_rq_driver_stats,
+                                       drop_fcs) },
+       { "rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
+                                       rx_buf_alloc_failure) },
+};
+
+/* gloabl stats maintained by the driver */
+static const struct vmxnet3_stat_desc
+vmxnet3_global_stats[] = {
+       /* description,         offset */
+       { "tx timeout count",   offsetof(struct vmxnet3_adapter,
+                                        tx_timeout_count) }
+};
+
+
+struct net_device_stats *
+vmxnet3_get_stats(struct net_device *netdev)
+{
+       struct vmxnet3_adapter *adapter;
+       struct vmxnet3_tq_driver_stats *drvTxStats;
+       struct vmxnet3_rq_driver_stats *drvRxStats;
+       struct UPT1_TxStats *devTxStats;
+       struct UPT1_RxStats *devRxStats;
+       struct net_device_stats *net_stats = &netdev->stats;
+
+       adapter = netdev_priv(netdev);
+
+       /* Collect the dev stats into the shared area */
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+
+       /* Assuming that we have a single queue device */
+       devTxStats = &adapter->tqd_start->stats;
+       devRxStats = &adapter->rqd_start->stats;
+
+       /* Get access to the driver stats per queue */
+       drvTxStats = &adapter->tx_queue.stats;
+       drvRxStats = &adapter->rx_queue.stats;
+
+       memset(net_stats, 0, sizeof(*net_stats));
+
+       net_stats->rx_packets = devRxStats->ucastPktsRxOK +
+                               devRxStats->mcastPktsRxOK +
+                               devRxStats->bcastPktsRxOK;
+
+       net_stats->tx_packets = devTxStats->ucastPktsTxOK +
+                               devTxStats->mcastPktsTxOK +
+                               devTxStats->bcastPktsTxOK;
+
+       net_stats->rx_bytes = devRxStats->ucastBytesRxOK +
+                             devRxStats->mcastBytesRxOK +
+                             devRxStats->bcastBytesRxOK;
+
+       net_stats->tx_bytes = devTxStats->ucastBytesTxOK +
+                             devTxStats->mcastBytesTxOK +
+                             devTxStats->bcastBytesTxOK;
+
+       net_stats->rx_errors = devRxStats->pktsRxError;
+       net_stats->tx_errors = devTxStats->pktsTxError;
+       net_stats->rx_dropped = drvRxStats->drop_total;
+       net_stats->tx_dropped = drvTxStats->drop_total;
+       net_stats->multicast =  devRxStats->mcastPktsRxOK;
+
+       return net_stats;
+}
+
+static int
+vmxnet3_get_sset_count(struct net_device *netdev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return ARRAY_SIZE(vmxnet3_tq_dev_stats) +
+                       ARRAY_SIZE(vmxnet3_tq_driver_stats) +
+                       ARRAY_SIZE(vmxnet3_rq_dev_stats) +
+                       ARRAY_SIZE(vmxnet3_rq_driver_stats) +
+                       ARRAY_SIZE(vmxnet3_global_stats);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+
+static int
+vmxnet3_get_regs_len(struct net_device *netdev)
+{
+       return 20 * sizeof(u32);
+}
+
+
+static void
+vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver));
+       drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
+
+       strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT,
+               sizeof(drvinfo->version));
+       drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0';
+
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0';
+
+       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+               ETHTOOL_BUSINFO_LEN);
+       drvinfo->n_stats = vmxnet3_get_sset_count(netdev, ETH_SS_STATS);
+       drvinfo->testinfo_len = 0;
+       drvinfo->eedump_len   = 0;
+       drvinfo->regdump_len  = vmxnet3_get_regs_len(netdev);
+}
+
+
+static void
+vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
+{
+       if (stringset == ETH_SS_STATS) {
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
+                       memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
+                              ETH_GSTRING_LEN);
+                       buf += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) {
+                       memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
+                              ETH_GSTRING_LEN);
+                       buf += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
+                       memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
+                              ETH_GSTRING_LEN);
+                       buf += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) {
+                       memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
+                              ETH_GSTRING_LEN);
+                       buf += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++) {
+                       memcpy(buf, vmxnet3_global_stats[i].desc,
+                               ETH_GSTRING_LEN);
+                       buf += ETH_GSTRING_LEN;
+               }
+       }
+}
+
+static u32
+vmxnet3_get_flags(struct net_device *netdev) {
+       return netdev->features;
+}
+
+static int
+vmxnet3_set_flags(struct net_device *netdev, u32 data) {
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
+       u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
+
+       if (lro_requested ^ lro_present) {
+               /* toggle the LRO feature*/
+               netdev->features ^= NETIF_F_LRO;
+
+               /* update harware LRO capability accordingly */
+               if (lro_requested)
+                       adapter->shared->devRead.misc.uptFeatures &= UPT1_F_LRO;
+               else
+                       adapter->shared->devRead.misc.uptFeatures &=
+                                                               ~UPT1_F_LRO;
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                      VMXNET3_CMD_UPDATE_FEATURE);
+       }
+       return 0;
+}
+
+static void
+vmxnet3_get_ethtool_stats(struct net_device *netdev,
+                         struct ethtool_stats *stats, u64  *buf)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u8 *base;
+       int i;
+
+       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
+
+       /* this does assume each counter is 64-bit wide */
+
+       base = (u8 *)&adapter->tqd_start->stats;
+       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
+               *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);
+
+       base = (u8 *)&adapter->tx_queue.stats;
+       for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
+               *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);
+
+       base = (u8 *)&adapter->rqd_start->stats;
+       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
+               *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);
+
+       base = (u8 *)&adapter->rx_queue.stats;
+       for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
+               *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);
+
+       base = (u8 *)adapter;
+       for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
+               *buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
+}
+
+
+static void
+vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u32 *buf = p;
+
+       memset(p, 0, vmxnet3_get_regs_len(netdev));
+
+       regs->version = 1;
+
+       /* Update vmxnet3_get_regs_len if we want to dump more registers */
+
+       /* make each ring use multiple of 16 bytes */
+       buf[0] = adapter->tx_queue.tx_ring.next2fill;
+       buf[1] = adapter->tx_queue.tx_ring.next2comp;
+       buf[2] = adapter->tx_queue.tx_ring.gen;
+       buf[3] = 0;
+
+       buf[4] = adapter->tx_queue.comp_ring.next2proc;
+       buf[5] = adapter->tx_queue.comp_ring.gen;
+       buf[6] = adapter->tx_queue.stopped;
+       buf[7] = 0;
+
+       buf[8] = adapter->rx_queue.rx_ring[0].next2fill;
+       buf[9] = adapter->rx_queue.rx_ring[0].next2comp;
+       buf[10] = adapter->rx_queue.rx_ring[0].gen;
+       buf[11] = 0;
+
+       buf[12] = adapter->rx_queue.rx_ring[1].next2fill;
+       buf[13] = adapter->rx_queue.rx_ring[1].next2comp;
+       buf[14] = adapter->rx_queue.rx_ring[1].gen;
+       buf[15] = 0;
+
+       buf[16] = adapter->rx_queue.comp_ring.next2proc;
+       buf[17] = adapter->rx_queue.comp_ring.gen;
+       buf[18] = 0;
+       buf[19] = 0;
+}
+
+
+static void
+vmxnet3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = WAKE_UCAST | WAKE_ARP | WAKE_MAGIC;
+       wol->wolopts = adapter->wol;
+}
+
+
+static int
+vmxnet3_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       if (wol->wolopts & (WAKE_PHY | WAKE_MCAST | WAKE_BCAST |
+                           WAKE_MAGICSECURE)) {
+               return -EOPNOTSUPP;
+       }
+
+       adapter->wol = wol->wolopts;
+
+       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       return 0;
+}
+
+
+static int
+vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       ecmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full |
+                         SUPPORTED_TP;
+       ecmd->advertising = ADVERTISED_TP;
+       ecmd->port = PORT_TP;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (adapter->link_speed) {
+               ecmd->speed = adapter->link_speed;
+               ecmd->duplex = DUPLEX_FULL;
+       } else {
+               ecmd->speed = -1;
+               ecmd->duplex = -1;
+       }
+       return 0;
+}
+
+
+static void
+vmxnet3_get_ringparam(struct net_device *netdev,
+                     struct ethtool_ringparam *param)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+       param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
+       param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
+       param->rx_mini_max_pending = 0;
+       param->rx_jumbo_max_pending = 0;
+
+       param->rx_pending = adapter->rx_queue.rx_ring[0].size;
+       param->tx_pending = adapter->tx_queue.tx_ring.size;
+       param->rx_mini_pending = 0;
+       param->rx_jumbo_pending = 0;
+}
+
+
+static int
+vmxnet3_set_ringparam(struct net_device *netdev,
+                     struct ethtool_ringparam *param)
+{
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+       u32 new_tx_ring_size, new_rx_ring_size;
+       u32 sz;
+       int err = 0;
+
+       if (param->tx_pending == 0 || param->tx_pending >
+                                               VMXNET3_TX_RING_MAX_SIZE)
+               return -EINVAL;
+
+       if (param->rx_pending == 0 || param->rx_pending >
+                                               VMXNET3_RX_RING_MAX_SIZE)
+               return -EINVAL;
+
+
+       /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
+       new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
+                                                       ~VMXNET3_RING_SIZE_MASK;
+       new_tx_ring_size = min_t(u32, new_tx_ring_size,
+                                VMXNET3_TX_RING_MAX_SIZE);
+       if (new_tx_ring_size > VMXNET3_TX_RING_MAX_SIZE || (new_tx_ring_size %
+                                               VMXNET3_RING_SIZE_ALIGN) != 0)
+               return -EINVAL;
+
+       /* ring0 has to be a multiple of
+        * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
+        */
+       sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
+       new_rx_ring_size = (param->rx_pending + sz - 1) / sz * sz;
+       new_rx_ring_size = min_t(u32, new_rx_ring_size,
+                                VMXNET3_RX_RING_MAX_SIZE / sz * sz);
+       if (new_rx_ring_size > VMXNET3_RX_RING_MAX_SIZE || (new_rx_ring_size %
+                                                          sz) != 0)
+               return -EINVAL;
+
+       if (new_tx_ring_size == adapter->tx_queue.tx_ring.size &&
+                       new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) {
+               return 0;
+       }
+
+       /*
+        * Reset_work may be in the middle of resetting the device, wait for its
+        * completion.
+        */
+       while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (netif_running(netdev)) {
+               vmxnet3_quiesce_dev(adapter);
+               vmxnet3_reset_dev(adapter);
+
+               /* recreate the rx queue and the tx queue based on the
+                * new sizes */
+               vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
+               vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
+
+               err = vmxnet3_create_queues(adapter, new_tx_ring_size,
+                       new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE);
+               if (err) {
+                       /* failed, most likely because of OOM, try default
+                        * size */
+                       printk(KERN_ERR "%s: failed to apply new sizes, try the"
+                               " default ones\n", netdev->name);
+                       err = vmxnet3_create_queues(adapter,
+                                                   VMXNET3_DEF_TX_RING_SIZE,
+                                                   VMXNET3_DEF_RX_RING_SIZE,
+                                                   VMXNET3_DEF_RX_RING_SIZE);
+                       if (err) {
+                               printk(KERN_ERR "%s: failed to create queues "
+                                       "with default sizes. Closing it\n",
+                                       netdev->name);
+                               goto out;
+                       }
+               }
+
+               err = vmxnet3_activate_dev(adapter);
+               if (err)
+                       printk(KERN_ERR "%s: failed to re-activate, error %d."
+                               " Closing it\n", netdev->name, err);
+       }
+
+out:
+       clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+       if (err)
+               vmxnet3_force_close(adapter);
+
+       return err;
+}
+
+
+static struct ethtool_ops vmxnet3_ethtool_ops = {
+       .get_settings      = vmxnet3_get_settings,
+       .get_drvinfo       = vmxnet3_get_drvinfo,
+       .get_regs_len      = vmxnet3_get_regs_len,
+       .get_regs          = vmxnet3_get_regs,
+       .get_wol           = vmxnet3_get_wol,
+       .set_wol           = vmxnet3_set_wol,
+       .get_link          = ethtool_op_get_link,
+       .get_rx_csum       = vmxnet3_get_rx_csum,
+       .set_rx_csum       = vmxnet3_set_rx_csum,
+       .get_tx_csum       = ethtool_op_get_tx_csum,
+       .set_tx_csum       = ethtool_op_set_tx_hw_csum,
+       .get_sg            = ethtool_op_get_sg,
+       .set_sg            = ethtool_op_set_sg,
+       .get_tso           = ethtool_op_get_tso,
+       .set_tso           = ethtool_op_set_tso,
+       .get_strings       = vmxnet3_get_strings,
+       .get_flags         = vmxnet3_get_flags,
+       .set_flags         = vmxnet3_set_flags,
+       .get_sset_count    = vmxnet3_get_sset_count,
+       .get_ethtool_stats = vmxnet3_get_ethtool_stats,
+       .get_ringparam     = vmxnet3_get_ringparam,
+       .set_ringparam     = vmxnet3_set_ringparam,
+};
+
+void vmxnet3_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops);
+}
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
new file mode 100644 (file)
index 0000000..3c0d70d
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * Linux driver for VMware's vmxnet3 ethernet NIC.
+ *
+ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ *
+ */
+
+#ifndef _VMXNET3_INT_H
+#define _VMXNET3_INT_H
+
+#include <linux/types.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <asm/dma.h>
+#include <asm/page.h>
+
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/in.h>
+#include <linux/etherdevice.h>
+#include <asm/checksum.h>
+#include <linux/if_vlan.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+#include "vmxnet3_defs.h"
+
+#ifdef DEBUG
+# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI(debug)"
+#else
+# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI"
+#endif
+
+
+/*
+ * Version numbers
+ */
+#define VMXNET3_DRIVER_VERSION_STRING   "1.0.5.0-k"
+
+/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
+#define VMXNET3_DRIVER_VERSION_NUM      0x01000500
+
+
+/*
+ * Capabilities
+ */
+
+enum {
+       VMNET_CAP_SG            = 0x0001, /* Can do scatter-gather transmits. */
+       VMNET_CAP_IP4_CSUM      = 0x0002, /* Can checksum only TCP/UDP over
+                                          * IPv4 */
+       VMNET_CAP_HW_CSUM       = 0x0004, /* Can checksum all packets. */
+       VMNET_CAP_HIGH_DMA      = 0x0008, /* Can DMA to high memory. */
+       VMNET_CAP_TOE           = 0x0010, /* Supports TCP/IP offload. */
+       VMNET_CAP_TSO           = 0x0020, /* Supports TCP Segmentation
+                                          * offload */
+       VMNET_CAP_SW_TSO        = 0x0040, /* Supports SW TCP Segmentation */
+       VMNET_CAP_VMXNET_APROM  = 0x0080, /* Vmxnet APROM support */
+       VMNET_CAP_HW_TX_VLAN    = 0x0100, /* Can we do VLAN tagging in HW */
+       VMNET_CAP_HW_RX_VLAN    = 0x0200, /* Can we do VLAN untagging in HW */
+       VMNET_CAP_SW_VLAN       = 0x0400, /* VLAN tagging/untagging in SW */
+       VMNET_CAP_WAKE_PCKT_RCV = 0x0800, /* Can wake on network packet recv? */
+       VMNET_CAP_ENABLE_INT_INLINE = 0x1000,  /* Enable Interrupt Inline */
+       VMNET_CAP_ENABLE_HEADER_COPY = 0x2000,  /* copy header for vmkernel */
+       VMNET_CAP_TX_CHAIN      = 0x4000, /* Guest can use multiple tx entries
+                                         * for a pkt */
+       VMNET_CAP_RX_CHAIN      = 0x8000, /* pkt can span multiple rx entries */
+       VMNET_CAP_LPD           = 0x10000, /* large pkt delivery */
+       VMNET_CAP_BPF           = 0x20000, /* BPF Support in VMXNET Virtual HW*/
+       VMNET_CAP_SG_SPAN_PAGES = 0x40000, /* Scatter-gather can span multiple*/
+                                          /* pages transmits */
+       VMNET_CAP_IP6_CSUM      = 0x80000, /* Can do IPv6 csum offload. */
+       VMNET_CAP_TSO6         = 0x100000, /* TSO seg. offload for IPv6 pkts. */
+       VMNET_CAP_TSO256k      = 0x200000, /* Can do TSO seg offload for */
+                                          /* pkts up to 256kB. */
+       VMNET_CAP_UPT          = 0x400000  /* Support UPT */
+};
+
+/*
+ * PCI vendor and device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE            0x15AD
+#define PCI_DEVICE_ID_VMWARE_VMXNET3    0x07B0
+#define MAX_ETHERNET_CARDS             10
+#define MAX_PCI_PASSTHRU_DEVICE                6
+
+struct vmxnet3_cmd_ring {
+       union Vmxnet3_GenericDesc *base;
+       u32             size;
+       u32             next2fill;
+       u32             next2comp;
+       u8              gen;
+       dma_addr_t      basePA;
+};
+
+static inline void
+vmxnet3_cmd_ring_adv_next2fill(struct vmxnet3_cmd_ring *ring)
+{
+       ring->next2fill++;
+       if (unlikely(ring->next2fill == ring->size)) {
+               ring->next2fill = 0;
+               VMXNET3_FLIP_RING_GEN(ring->gen);
+       }
+}
+
+static inline void
+vmxnet3_cmd_ring_adv_next2comp(struct vmxnet3_cmd_ring *ring)
+{
+       VMXNET3_INC_RING_IDX_ONLY(ring->next2comp, ring->size);
+}
+
+static inline int
+vmxnet3_cmd_ring_desc_avail(struct vmxnet3_cmd_ring *ring)
+{
+       return (ring->next2comp > ring->next2fill ? 0 : ring->size) +
+               ring->next2comp - ring->next2fill - 1;
+}
+
+struct vmxnet3_comp_ring {
+       union Vmxnet3_GenericDesc *base;
+       u32               size;
+       u32               next2proc;
+       u8                gen;
+       u8                intr_idx;
+       dma_addr_t           basePA;
+};
+
+static inline void
+vmxnet3_comp_ring_adv_next2proc(struct vmxnet3_comp_ring *ring)
+{
+       ring->next2proc++;
+       if (unlikely(ring->next2proc == ring->size)) {
+               ring->next2proc = 0;
+               VMXNET3_FLIP_RING_GEN(ring->gen);
+       }
+}
+
+struct vmxnet3_tx_data_ring {
+       struct Vmxnet3_TxDataDesc *base;
+       u32              size;
+       dma_addr_t          basePA;
+};
+
+enum vmxnet3_buf_map_type {
+       VMXNET3_MAP_INVALID = 0,
+       VMXNET3_MAP_NONE,
+       VMXNET3_MAP_SINGLE,
+       VMXNET3_MAP_PAGE,
+};
+
+struct vmxnet3_tx_buf_info {
+       u32      map_type;
+       u16      len;
+       u16      sop_idx;
+       dma_addr_t  dma_addr;
+       struct sk_buff *skb;
+};
+
+struct vmxnet3_tq_driver_stats {
+       u64 drop_total;     /* # of pkts dropped by the driver, the
+                               * counters below track droppings due to
+                               * different reasons
+                               */
+       u64 drop_too_many_frags;
+       u64 drop_oversized_hdr;
+       u64 drop_hdr_inspect_err;
+       u64 drop_tso;
+
+       u64 tx_ring_full;
+       u64 linearized;         /* # of pkts linearized */
+       u64 copy_skb_header;    /* # of times we have to copy skb header */
+       u64 oversized_hdr;
+};
+
+struct vmxnet3_tx_ctx {
+       bool   ipv4;
+       u16 mss;
+       u32 eth_ip_hdr_size; /* only valid for pkts requesting tso or csum
+                                * offloading
+                                */
+       u32 l4_hdr_size;     /* only valid if mss != 0 */
+       u32 copy_size;       /* # of bytes copied into the data ring */
+       union Vmxnet3_GenericDesc *sop_txd;
+       union Vmxnet3_GenericDesc *eop_txd;
+};
+
+struct vmxnet3_tx_queue {
+       spinlock_t                      tx_lock;
+       struct vmxnet3_cmd_ring         tx_ring;
+       struct vmxnet3_tx_buf_info     *buf_info;
+       struct vmxnet3_tx_data_ring     data_ring;
+       struct vmxnet3_comp_ring        comp_ring;
+       struct Vmxnet3_TxQueueCtrl            *shared;
+       struct vmxnet3_tq_driver_stats  stats;
+       bool                            stopped;
+       int                             num_stop;  /* # of times the queue is
+                                                   * stopped */
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+enum vmxnet3_rx_buf_type {
+       VMXNET3_RX_BUF_NONE = 0,
+       VMXNET3_RX_BUF_SKB = 1,
+       VMXNET3_RX_BUF_PAGE = 2
+};
+
+struct vmxnet3_rx_buf_info {
+       enum vmxnet3_rx_buf_type buf_type;
+       u16     len;
+       union {
+               struct sk_buff *skb;
+               struct page    *page;
+       };
+       dma_addr_t dma_addr;
+};
+
+struct vmxnet3_rx_ctx {
+       struct sk_buff *skb;
+       u32 sop_idx;
+};
+
+struct vmxnet3_rq_driver_stats {
+       u64 drop_total;
+       u64 drop_err;
+       u64 drop_fcs;
+       u64 rx_buf_alloc_failure;
+};
+
+struct vmxnet3_rx_queue {
+       struct vmxnet3_cmd_ring   rx_ring[2];
+       struct vmxnet3_comp_ring  comp_ring;
+       struct vmxnet3_rx_ctx     rx_ctx;
+       u32 qid;            /* rqID in RCD for buffer from 1st ring */
+       u32 qid2;           /* rqID in RCD for buffer from 2nd ring */
+       u32 uncommitted[2]; /* # of buffers allocated since last RXPROD
+                               * update */
+       struct vmxnet3_rx_buf_info     *buf_info[2];
+       struct Vmxnet3_RxQueueCtrl            *shared;
+       struct vmxnet3_rq_driver_stats  stats;
+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+
+#define VMXNET3_LINUX_MAX_MSIX_VECT     1
+
+struct vmxnet3_intr {
+       enum vmxnet3_intr_mask_mode  mask_mode;
+       enum vmxnet3_intr_type       type;      /* MSI-X, MSI, or INTx? */
+       u8  num_intrs;                  /* # of intr vectors */
+       u8  event_intr_idx;             /* idx of the intr vector for event */
+       u8  mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
+#ifdef CONFIG_PCI_MSI
+       struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
+#endif
+};
+
+#define VMXNET3_STATE_BIT_RESETTING   0
+#define VMXNET3_STATE_BIT_QUIESCED    1
+struct vmxnet3_adapter {
+       struct vmxnet3_tx_queue         tx_queue;
+       struct vmxnet3_rx_queue         rx_queue;
+       struct napi_struct              napi;
+       struct vlan_group              *vlan_grp;
+
+       struct vmxnet3_intr             intr;
+
+       struct Vmxnet3_DriverShared    *shared;
+       struct Vmxnet3_PMConf          *pm_conf;
+       struct Vmxnet3_TxQueueDesc     *tqd_start;     /* first tx queue desc */
+       struct Vmxnet3_RxQueueDesc     *rqd_start;     /* first rx queue desc */
+       struct net_device              *netdev;
+       struct pci_dev                 *pdev;
+
+       u8                              *hw_addr0; /* for BAR 0 */
+       u8                              *hw_addr1; /* for BAR 1 */
+
+       /* feature control */
+       bool                            rxcsum;
+       bool                            lro;
+       bool                            jumbo_frame;
+
+       /* rx buffer related */
+       unsigned                        skb_buf_size;
+       int             rx_buf_per_pkt;  /* only apply to the 1st ring */
+       dma_addr_t                      shared_pa;
+       dma_addr_t queue_desc_pa;
+
+       /* Wake-on-LAN */
+       u32     wol;
+
+       /* Link speed */
+       u32     link_speed; /* in mbps */
+
+       u64     tx_timeout_count;
+       struct work_struct work;
+
+       unsigned long  state;    /* VMXNET3_STATE_BIT_xxx */
+
+       int dev_number;
+};
+
+#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val)  \
+       writel((val), (adapter)->hw_addr0 + (reg))
+#define VMXNET3_READ_BAR0_REG(adapter, reg)        \
+       readl((adapter)->hw_addr0 + (reg))
+
+#define VMXNET3_WRITE_BAR1_REG(adapter, reg, val)  \
+       writel((val), (adapter)->hw_addr1 + (reg))
+#define VMXNET3_READ_BAR1_REG(adapter, reg)        \
+       readl((adapter)->hw_addr1 + (reg))
+
+#define VMXNET3_WAKE_QUEUE_THRESHOLD(tq)  (5)
+#define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
+       ((rq)->rx_ring[ring_idx].size >> 3)
+
+#define VMXNET3_GET_ADDR_LO(dma)   ((u32)(dma))
+#define VMXNET3_GET_ADDR_HI(dma)   ((u32)(((u64)(dma)) >> 32))
+
+/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
+#define VMXNET3_DEF_TX_RING_SIZE    512
+#define VMXNET3_DEF_RX_RING_SIZE    256
+
+#define VMXNET3_MAX_ETH_HDR_SIZE    22
+#define VMXNET3_MAX_SKB_BUF_SIZE    (3*1024)
+
+int
+vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
+
+int
+vmxnet3_activate_dev(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_force_close(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_reset_dev(struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
+                  struct vmxnet3_adapter *adapter);
+
+void
+vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+                  struct vmxnet3_adapter *adapter);
+
+int
+vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
+                     u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
+
+extern void vmxnet3_set_ethtool_ops(struct net_device *netdev);
+extern struct net_device_stats *vmxnet3_get_stats(struct net_device *netdev);
+
+extern char vmxnet3_driver_name[];
+#endif
index 9693b0f..0bd898c 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/capability.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
index cf5fd17..f1bff98 100644 (file)
@@ -58,8 +58,7 @@ struct cisco_state {
        spinlock_t lock;
        unsigned long last_poll;
        int up;
-       int request_sent;
-       u32 txseq; /* TX sequence number */
+       u32 txseq; /* TX sequence number, 0 = none */
        u32 rxseq; /* RX sequence number */
 };
 
@@ -163,6 +162,7 @@ static int cisco_rx(struct sk_buff *skb)
        struct cisco_packet *cisco_data;
        struct in_device *in_dev;
        __be32 addr, mask;
+       u32 ack;
 
        if (skb->len < sizeof(struct hdlc_header))
                goto rx_error;
@@ -223,8 +223,10 @@ static int cisco_rx(struct sk_buff *skb)
                case CISCO_KEEPALIVE_REQ:
                        spin_lock(&st->lock);
                        st->rxseq = ntohl(cisco_data->par1);
-                       if (st->request_sent &&
-                           ntohl(cisco_data->par2) == st->txseq) {
+                       ack = ntohl(cisco_data->par2);
+                       if (ack && (ack == st->txseq ||
+                                   /* our current REQ may be in transit */
+                                   ack == st->txseq - 1)) {
                                st->last_poll = jiffies;
                                if (!st->up) {
                                        u32 sec, min, hrs, days;
@@ -275,7 +277,6 @@ static void cisco_timer(unsigned long arg)
 
        cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq),
                             htonl(st->rxseq));
-       st->request_sent = 1;
        spin_unlock(&st->lock);
 
        st->timer.expires = jiffies + st->settings.interval * HZ;
@@ -293,9 +294,7 @@ static void cisco_start(struct net_device *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&st->lock, flags);
-       st->up = 0;
-       st->request_sent = 0;
-       st->txseq = st->rxseq = 0;
+       st->up = st->txseq = st->rxseq = 0;
        spin_unlock_irqrestore(&st->lock, flags);
 
        init_timer(&st->timer);
@@ -317,8 +316,7 @@ static void cisco_stop(struct net_device *dev)
 
        spin_lock_irqsave(&st->lock, flags);
        netif_dormant_on(dev);
-       st->up = 0;
-       st->request_sent = 0;
+       st->up = st->txseq = 0;
        spin_unlock_irqrestore(&st->lock, flags);
 }
 
index 83da596..58c6681 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/capability.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
index a52f29c..f1340fa 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/capability.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
index 4f6ab13..b07e4d3 100644 (file)
@@ -266,7 +266,7 @@ do {                                                                \
 #define ADM8211_SYNCTL_CS1     (1 << 28)
 #define ADM8211_SYNCTL_CAL     (1 << 27)
 #define ADM8211_SYNCTL_SELCAL  (1 << 26)
-#define ADM8211_SYNCTL_RFtype  ((1 << 24) || (1 << 23) || (1 << 22))
+#define ADM8211_SYNCTL_RFtype  ((1 << 24) | (1 << 23) | (1 << 22))
 #define ADM8211_SYNCTL_RFMD    (1 << 22)
 #define ADM8211_SYNCTL_GENERAL (0x7 << 22)
 /* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */
index 7116a1a..abf896a 100644 (file)
@@ -4790,9 +4790,8 @@ static int proc_stats_rid_open( struct inode *inode,
 static int get_dec_u16( char *buffer, int *start, int limit ) {
        u16 value;
        int valid = 0;
-       for( value = 0; buffer[*start] >= '0' &&
-                    buffer[*start] <= '9' &&
-                    *start < limit; (*start)++ ) {
+       for (value = 0; *start < limit && buffer[*start] >= '0' &&
+                       buffer[*start] <= '9'; (*start)++) {
                valid = 1;
                value *= 10;
                value += buffer[*start] - '0';
index fa1549a..6607162 100644 (file)
@@ -607,82 +607,7 @@ struct b43_qos_params {
        struct ieee80211_tx_queue_params p;
 };
 
-struct b43_wldev;
-
-/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
-struct b43_wl {
-       /* Pointer to the active wireless device on this chip */
-       struct b43_wldev *current_dev;
-       /* Pointer to the ieee80211 hardware data structure */
-       struct ieee80211_hw *hw;
-
-       /* Global driver mutex. Every operation must run with this mutex locked. */
-       struct mutex mutex;
-       /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
-        * handler, only. This basically is just the IRQ mask register. */
-       spinlock_t hardirq_lock;
-
-       /* The number of queues that were registered with the mac80211 subsystem
-        * initially. This is a backup copy of hw->queues in case hw->queues has
-        * to be dynamically lowered at runtime (Firmware does not support QoS).
-        * hw->queues has to be restored to the original value before unregistering
-        * from the mac80211 subsystem. */
-       u16 mac80211_initially_registered_queues;
-
-       /* We can only have one operating interface (802.11 core)
-        * at a time. General information about this interface follows.
-        */
-
-       struct ieee80211_vif *vif;
-       /* The MAC address of the operating interface. */
-       u8 mac_addr[ETH_ALEN];
-       /* Current BSSID */
-       u8 bssid[ETH_ALEN];
-       /* Interface type. (NL80211_IFTYPE_XXX) */
-       int if_type;
-       /* Is the card operating in AP, STA or IBSS mode? */
-       bool operating;
-       /* filter flags */
-       unsigned int filter_flags;
-       /* Stats about the wireless interface */
-       struct ieee80211_low_level_stats ieee_stats;
-
-#ifdef CONFIG_B43_HWRNG
-       struct hwrng rng;
-       bool rng_initialized;
-       char rng_name[30 + 1];
-#endif /* CONFIG_B43_HWRNG */
-
-       /* List of all wireless devices on this chip */
-       struct list_head devlist;
-       u8 nr_devs;
-
-       bool radiotap_enabled;
-       bool radio_enabled;
-
-       /* The beacon we are currently using (AP or IBSS mode). */
-       struct sk_buff *current_beacon;
-       bool beacon0_uploaded;
-       bool beacon1_uploaded;
-       bool beacon_templates_virgin; /* Never wrote the templates? */
-       struct work_struct beacon_update_trigger;
-
-       /* The current QOS parameters for the 4 queues. */
-       struct b43_qos_params qos_params[4];
-
-       /* Work for adjustment of the transmission power.
-        * This is scheduled when we determine that the actual TX output
-        * power doesn't match what we want. */
-       struct work_struct txpower_adjust_work;
-
-       /* Packet transmit work */
-       struct work_struct tx_work;
-       /* Queue of packets to be transmitted. */
-       struct sk_buff_head tx_queue;
-
-       /* The device LEDs. */
-       struct b43_leds leds;
-};
+struct b43_wl;
 
 /* The type of the firmware file. */
 enum b43_firmware_file_type {
@@ -824,6 +749,97 @@ struct b43_wldev {
 #endif
 };
 
+/*
+ * Include goes here to avoid a dependency problem.
+ * A better fix would be to integrate xmit.h into b43.h.
+ */
+#include "xmit.h"
+
+/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
+struct b43_wl {
+       /* Pointer to the active wireless device on this chip */
+       struct b43_wldev *current_dev;
+       /* Pointer to the ieee80211 hardware data structure */
+       struct ieee80211_hw *hw;
+
+       /* Global driver mutex. Every operation must run with this mutex locked. */
+       struct mutex mutex;
+       /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
+        * handler, only. This basically is just the IRQ mask register. */
+       spinlock_t hardirq_lock;
+
+       /* The number of queues that were registered with the mac80211 subsystem
+        * initially. This is a backup copy of hw->queues in case hw->queues has
+        * to be dynamically lowered at runtime (Firmware does not support QoS).
+        * hw->queues has to be restored to the original value before unregistering
+        * from the mac80211 subsystem. */
+       u16 mac80211_initially_registered_queues;
+
+       /* We can only have one operating interface (802.11 core)
+        * at a time. General information about this interface follows.
+        */
+
+       struct ieee80211_vif *vif;
+       /* The MAC address of the operating interface. */
+       u8 mac_addr[ETH_ALEN];
+       /* Current BSSID */
+       u8 bssid[ETH_ALEN];
+       /* Interface type. (NL80211_IFTYPE_XXX) */
+       int if_type;
+       /* Is the card operating in AP, STA or IBSS mode? */
+       bool operating;
+       /* filter flags */
+       unsigned int filter_flags;
+       /* Stats about the wireless interface */
+       struct ieee80211_low_level_stats ieee_stats;
+
+#ifdef CONFIG_B43_HWRNG
+       struct hwrng rng;
+       bool rng_initialized;
+       char rng_name[30 + 1];
+#endif /* CONFIG_B43_HWRNG */
+
+       /* List of all wireless devices on this chip */
+       struct list_head devlist;
+       u8 nr_devs;
+
+       bool radiotap_enabled;
+       bool radio_enabled;
+
+       /* The beacon we are currently using (AP or IBSS mode). */
+       struct sk_buff *current_beacon;
+       bool beacon0_uploaded;
+       bool beacon1_uploaded;
+       bool beacon_templates_virgin; /* Never wrote the templates? */
+       struct work_struct beacon_update_trigger;
+
+       /* The current QOS parameters for the 4 queues. */
+       struct b43_qos_params qos_params[4];
+
+       /* Work for adjustment of the transmission power.
+        * This is scheduled when we determine that the actual TX output
+        * power doesn't match what we want. */
+       struct work_struct txpower_adjust_work;
+
+       /* Packet transmit work */
+       struct work_struct tx_work;
+       /* Queue of packets to be transmitted. */
+       struct sk_buff_head tx_queue;
+
+       /* The device LEDs. */
+       struct b43_leds leds;
+
+#ifdef CONFIG_B43_PIO
+       /*
+        * RX/TX header/tail buffers used by the frame transmit functions.
+        */
+       struct b43_rxhdr_fw4 rxhdr;
+       struct b43_txhdr txhdr;
+       u8 rx_tail[4];
+       u8 tx_tail[4];
+#endif /* CONFIG_B43_PIO */
+};
+
 static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
 {
        return hw->priv;
index fbe3d4f..1e8dba4 100644 (file)
@@ -348,9 +348,9 @@ void b43_leds_register(struct b43_wldev *dev)
        }
 }
 
-void b43_leds_unregister(struct b43_wldev *dev)
+void b43_leds_unregister(struct b43_wl *wl)
 {
-       struct b43_leds *leds = &dev->wl->leds;
+       struct b43_leds *leds = &wl->leds;
 
        b43_unregister_led(&leds->led_tx);
        b43_unregister_led(&leds->led_rx);
index 9592e4c..32b66d5 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef B43_LEDS_H_
 #define B43_LEDS_H_
 
+struct b43_wl;
 struct b43_wldev;
 
 #ifdef CONFIG_B43_LEDS
@@ -60,7 +61,7 @@ enum b43_led_behaviour {
 };
 
 void b43_leds_register(struct b43_wldev *dev);
-void b43_leds_unregister(struct b43_wldev *dev);
+void b43_leds_unregister(struct b43_wl *wl);
 void b43_leds_init(struct b43_wldev *dev);
 void b43_leds_exit(struct b43_wldev *dev);
 void b43_leds_stop(struct b43_wldev *dev);
@@ -76,7 +77,7 @@ struct b43_leds {
 static inline void b43_leds_register(struct b43_wldev *dev)
 {
 }
-static inline void b43_leds_unregister(struct b43_wldev *dev)
+static inline void b43_leds_unregister(struct b43_wl *wl)
 {
 }
 static inline void b43_leds_init(struct b43_wldev *dev)
index 9b907a3..86f3582 100644 (file)
@@ -3874,6 +3874,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
 {
        struct b43_wl *wl = dev->wl;
        struct b43_wldev *orig_dev;
+       u32 mask;
 
 redo:
        if (!dev || b43_status(dev) < B43_STAT_STARTED)
@@ -3920,7 +3921,8 @@ redo:
                        goto redo;
                return dev;
        }
-       B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK));
+       mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+       B43_WARN_ON(mask != 0xFFFFFFFF && mask);
 
        /* Drain the TX queue */
        while (skb_queue_len(&wl->tx_queue))
@@ -4997,7 +4999,7 @@ static void b43_remove(struct ssb_device *dev)
 
        if (list_empty(&wl->devlist)) {
                b43_rng_exit(wl);
-               b43_leds_unregister(wldev);
+               b43_leds_unregister(wl);
                /* Last core on the chip unregistered.
                 * We can destroy common struct b43_wl.
                 */
index 5e87650..9b90444 100644 (file)
@@ -332,6 +332,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
                                unsigned int data_len)
 {
        struct b43_wldev *dev = q->dev;
+       struct b43_wl *wl = dev->wl;
        const u8 *data = _data;
 
        ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@@ -341,13 +342,12 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
                        q->mmio_base + B43_PIO_TXDATA,
                        sizeof(u16));
        if (data_len & 1) {
-               u8 tail[2] = { 0, };
-
                /* Write the last byte. */
                ctl &= ~B43_PIO_TXCTL_WRITEHI;
                b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-               tail[0] = data[data_len - 1];
-               ssb_block_write(dev->dev, tail, 2,
+               wl->tx_tail[0] = data[data_len - 1];
+               wl->tx_tail[1] = 0;
+               ssb_block_write(dev->dev, wl->tx_tail, 2,
                                q->mmio_base + B43_PIO_TXDATA,
                                sizeof(u16));
        }
@@ -382,6 +382,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
                                unsigned int data_len)
 {
        struct b43_wldev *dev = q->dev;
+       struct b43_wl *wl = dev->wl;
        const u8 *data = _data;
 
        ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@@ -392,29 +393,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
                        q->mmio_base + B43_PIO8_TXDATA,
                        sizeof(u32));
        if (data_len & 3) {
-               u8 tail[4] = { 0, };
-
+               wl->tx_tail[3] = 0;
                /* Write the last few bytes. */
                ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
                         B43_PIO8_TXCTL_24_31);
                switch (data_len & 3) {
                case 3:
                        ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
-                       tail[0] = data[data_len - 3];
-                       tail[1] = data[data_len - 2];
-                       tail[2] = data[data_len - 1];
+                       wl->tx_tail[0] = data[data_len - 3];
+                       wl->tx_tail[1] = data[data_len - 2];
+                       wl->tx_tail[2] = data[data_len - 1];
                        break;
                case 2:
                        ctl |= B43_PIO8_TXCTL_8_15;
-                       tail[0] = data[data_len - 2];
-                       tail[1] = data[data_len - 1];
+                       wl->tx_tail[0] = data[data_len - 2];
+                       wl->tx_tail[1] = data[data_len - 1];
+                       wl->tx_tail[2] = 0;
                        break;
                case 1:
-                       tail[0] = data[data_len - 1];
+                       wl->tx_tail[0] = data[data_len - 1];
+                       wl->tx_tail[1] = 0;
+                       wl->tx_tail[2] = 0;
                        break;
                }
                b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-               ssb_block_write(dev->dev, tail, 4,
+               ssb_block_write(dev->dev, wl->tx_tail, 4,
                                q->mmio_base + B43_PIO8_TXDATA,
                                sizeof(u32));
        }
@@ -446,8 +449,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
 static int pio_tx_frame(struct b43_pio_txqueue *q,
                        struct sk_buff *skb)
 {
+       struct b43_wldev *dev = q->dev;
+       struct b43_wl *wl = dev->wl;
        struct b43_pio_txpacket *pack;
-       struct b43_txhdr txhdr;
        u16 cookie;
        int err;
        unsigned int hdrlen;
@@ -458,8 +462,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
                          struct b43_pio_txpacket, list);
 
        cookie = generate_cookie(q, pack);
-       hdrlen = b43_txhdr_size(q->dev);
-       err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
+       hdrlen = b43_txhdr_size(dev);
+       err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
                                 info, cookie);
        if (err)
                return err;
@@ -467,15 +471,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
        if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
                /* Tell the firmware about the cookie of the last
                 * mcast frame, so it can clear the more-data bit in it. */
-               b43_shm_write16(q->dev, B43_SHM_SHARED,
+               b43_shm_write16(dev, B43_SHM_SHARED,
                                B43_SHM_SH_MCASTCOOKIE, cookie);
        }
 
        pack->skb = skb;
        if (q->rev >= 8)
-               pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+               pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
        else
-               pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+               pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
 
        /* Remove it from the list of available packet slots.
         * It will be put back when we receive the status report. */
@@ -615,14 +619,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
 static bool pio_rx_frame(struct b43_pio_rxqueue *q)
 {
        struct b43_wldev *dev = q->dev;
-       struct b43_rxhdr_fw4 rxhdr;
+       struct b43_wl *wl = dev->wl;
        u16 len;
        u32 macstat;
        unsigned int i, padding;
        struct sk_buff *skb;
        const char *err_msg = NULL;
 
-       memset(&rxhdr, 0, sizeof(rxhdr));
+       memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
 
        /* Check if we have data and wait for it to get ready. */
        if (q->rev >= 8) {
@@ -660,16 +664,16 @@ data_ready:
 
        /* Get the preamble (RX header) */
        if (q->rev >= 8) {
-               ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+               ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
                               q->mmio_base + B43_PIO8_RXDATA,
                               sizeof(u32));
        } else {
-               ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+               ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
                               q->mmio_base + B43_PIO_RXDATA,
                               sizeof(u16));
        }
        /* Sanity checks. */
-       len = le16_to_cpu(rxhdr.frame_len);
+       len = le16_to_cpu(wl->rxhdr.frame_len);
        if (unlikely(len > 0x700)) {
                err_msg = "len > 0x700";
                goto rx_error;
@@ -679,7 +683,7 @@ data_ready:
                goto rx_error;
        }
 
-       macstat = le32_to_cpu(rxhdr.mac_status);
+       macstat = le32_to_cpu(wl->rxhdr.mac_status);
        if (macstat & B43_RX_MAC_FCSERR) {
                if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
                        /* Drop frames with failed FCS. */
@@ -704,24 +708,22 @@ data_ready:
                               q->mmio_base + B43_PIO8_RXDATA,
                               sizeof(u32));
                if (len & 3) {
-                       u8 tail[4] = { 0, };
-
                        /* Read the last few bytes. */
-                       ssb_block_read(dev->dev, tail, 4,
+                       ssb_block_read(dev->dev, wl->rx_tail, 4,
                                       q->mmio_base + B43_PIO8_RXDATA,
                                       sizeof(u32));
                        switch (len & 3) {
                        case 3:
-                               skb->data[len + padding - 3] = tail[0];
-                               skb->data[len + padding - 2] = tail[1];
-                               skb->data[len + padding - 1] = tail[2];
+                               skb->data[len + padding - 3] = wl->rx_tail[0];
+                               skb->data[len + padding - 2] = wl->rx_tail[1];
+                               skb->data[len + padding - 1] = wl->rx_tail[2];
                                break;
                        case 2:
-                               skb->data[len + padding - 2] = tail[0];
-                               skb->data[len + padding - 1] = tail[1];
+                               skb->data[len + padding - 2] = wl->rx_tail[0];
+                               skb->data[len + padding - 1] = wl->rx_tail[1];
                                break;
                        case 1:
-                               skb->data[len + padding - 1] = tail[0];
+                               skb->data[len + padding - 1] = wl->rx_tail[0];
                                break;
                        }
                }
@@ -730,17 +732,15 @@ data_ready:
                               q->mmio_base + B43_PIO_RXDATA,
                               sizeof(u16));
                if (len & 1) {
-                       u8 tail[2] = { 0, };
-
                        /* Read the last byte. */
-                       ssb_block_read(dev->dev, tail, 2,
+                       ssb_block_read(dev->dev, wl->rx_tail, 2,
                                       q->mmio_base + B43_PIO_RXDATA,
                                       sizeof(u16));
-                       skb->data[len + padding - 1] = tail[0];
+                       skb->data[len + padding - 1] = wl->rx_tail[0];
                }
        }
 
-       b43_rx(q->dev, skb, &rxhdr);
+       b43_rx(q->dev, skb, &wl->rxhdr);
 
        return 1;
 
index 7a3218c..ffdce6f 100644 (file)
@@ -33,7 +33,8 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
                      & B43_MMIO_RADIO_HWENABLED_HI_MASK))
                        return 1;
        } else {
-               if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
+               if (b43_status(dev) >= B43_STAT_STARTED &&
+                   b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)
                    & B43_MMIO_RADIO_HWENABLED_LO_MASK)
                        return 1;
        }
index ac9f600..f4e9695 100644 (file)
@@ -27,7 +27,7 @@
 
 */
 
-#include "xmit.h"
+#include "b43.h"
 #include "phy_common.h"
 #include "dma.h"
 #include "pio.h"
@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
        }
 
        memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+
+       local_bh_disable();
        ieee80211_rx(dev->wl->hw, skb);
+       local_bh_enable();
 
 #if B43_DEBUG
        dev->rx_count++;
index a16bd41..cbb0585 100644 (file)
@@ -702,7 +702,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
                u8 sta_id = iwl_find_station(priv, hdr->addr1);
 
                if (sta_id == IWL_INVALID_STATION) {
-                       IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
+                       IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
                                       hdr->addr1);
                        sta_id = iwl_add_station(priv, hdr->addr1, false,
                                CMD_ASYNC, NULL);
index 6813617..f059b49 100644 (file)
@@ -611,7 +611,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
        if (rx_status.band == IEEE80211_BAND_5GHZ)
                rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
 
-       rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags &
+       rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) &
                                        RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
 
        /* set the preamble flag if appropriate */
index d6bc0e0..6e6f516 100644 (file)
@@ -318,7 +318,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
                        (s32)average_noise[i])) / 1500;
                /* bound gain by 2 bits value max, 3rd bit is sign */
                data->delta_gain_code[i] =
-                       min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+                       min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
                if (delta_g < 0)
                        /* set negative sign */
index 313d3e5..eaafae0 100644 (file)
@@ -3106,8 +3106,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  out_pci_disable_device:
        pci_disable_device(pdev);
  out_ieee80211_free_hw:
-       ieee80211_free_hw(priv->hw);
        iwl_free_traffic_mem(priv);
+       ieee80211_free_hw(priv->hw);
  out:
        return err;
 }
index 2c5c88f..4afaf77 100644 (file)
@@ -1154,7 +1154,7 @@ struct iwl_wep_cmd {
 #define RX_RES_PHY_FLAGS_MOD_CCK_MSK           cpu_to_le16(1 << 1)
 #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK    cpu_to_le16(1 << 2)
 #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK       cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK           cpu_to_le16(0xf0)
+#define RX_RES_PHY_FLAGS_ANTENNA_MSK           0xf0
 #define RX_RES_PHY_FLAGS_ANTENNA_POS           4
 
 #define RX_RES_STATUS_SEC_TYPE_MSK     (0x7 << 8)
index 3d2b93a..e14c995 100644 (file)
@@ -410,7 +410,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
                                        u16 *validblockaddr)
 {
        u16 next_link_addr = 0, link_value = 0, valid_addr;
-       int ret = 0;
        int usedblocks = 0;
 
        /* set addressing mode to absolute to traverse the link list */
@@ -430,29 +429,29 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
                 * check for more block on the link list
                 */
                valid_addr = next_link_addr;
-               next_link_addr = link_value;
+               next_link_addr = link_value * sizeof(u16);
                IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
                               usedblocks, next_link_addr);
                if (iwl_read_otp_word(priv, next_link_addr, &link_value))
                        return -EINVAL;
                if (!link_value) {
                        /*
-                        * reach the end of link list,
+                        * reach the end of link list, return success and
                         * set address point to the starting address
                         * of the image
                         */
-                       goto done;
+                       *validblockaddr = valid_addr;
+                       /* skip first 2 bytes (link list pointer) */
+                       *validblockaddr += 2;
+                       return 0;
                }
                /* more in the link list, continue */
                usedblocks++;
-       } while (usedblocks < priv->cfg->max_ll_items);
-       /* OTP full, use last block */
-       IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
-done:
-       *validblockaddr = valid_addr;
-       /* skip first 2 bytes (link list pointer) */
-       *validblockaddr += 2;
-       return ret;
+       } while (usedblocks <= priv->cfg->max_ll_items);
+
+       /* OTP has no valid blocks */
+       IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
+       return -EINVAL;
 }
 
 /**
index 6b68db7..80b9e45 100644 (file)
@@ -220,35 +220,35 @@ struct iwl_eeprom_enhanced_txpwr {
  * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
  */
 /* 2.4 GHz band: CCK */
-#define EEPROM_LB_CCK_20_COMMON       ((0xAA)\
+#define EEPROM_LB_CCK_20_COMMON       ((0xA8)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 8 bytes */
 /* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_LB_OFDM_COMMON       ((0xB2)\
+#define EEPROM_LB_OFDM_COMMON       ((0xB0)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
 /* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
-#define EEPROM_HB_OFDM_COMMON       ((0xCA)\
+#define EEPROM_HB_OFDM_COMMON       ((0xC8)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
 /* 2.4GHz band channels:
  *     1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
-#define EEPROM_LB_OFDM_20_BAND       ((0xE2)\
+#define EEPROM_LB_OFDM_20_BAND       ((0xE0)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 64 bytes */
 /* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
-#define EEPROM_LB_OFDM_HT40_BAND       ((0x122)\
+#define EEPROM_LB_OFDM_HT40_BAND       ((0x120)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 40 bytes */
 /* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
-#define EEPROM_HB_OFDM_20_BAND       ((0x14A)\
+#define EEPROM_HB_OFDM_20_BAND       ((0x148)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 48 bytes */
 /* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND       ((0x17A)\
+#define EEPROM_HB_OFDM_HT40_BAND       ((0x178)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
 /* 2.4 GHz band, channnel 13: Legacy, HT */
-#define EEPROM_LB_OFDM_20_CHANNEL_13       ((0x192)\
+#define EEPROM_LB_OFDM_20_CHANNEL_13       ((0x190)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
 /* 5.2 GHz band, channnel 140: Legacy, HT */
-#define EEPROM_HB_OFDM_20_CHANNEL_140       ((0x1A2)\
+#define EEPROM_HB_OFDM_20_CHANNEL_140       ((0x1A0)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
 /* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
-#define EEPROM_HB_OFDM_HT40_BAND_1       ((0x1B2)\
+#define EEPROM_HB_OFDM_HT40_BAND_1       ((0x1B0)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
 
 
index 8e1bb53..493626b 100644 (file)
@@ -1044,7 +1044,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
         * as a bitmask.
         */
        rx_status.antenna =
-               le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK)
+               (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
                >> RX_RES_PHY_FLAGS_ANTENNA_POS;
 
        /* set the preamble flag if appropriate */
index aa49230..d00a803 100644 (file)
@@ -4097,8 +4097,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        pci_set_drvdata(pdev, NULL);
        pci_disable_device(pdev);
  out_ieee80211_free_hw:
-       ieee80211_free_hw(priv->hw);
        iwl_free_traffic_mem(priv);
+       ieee80211_free_hw(priv->hw);
  out:
        return err;
 }
index c42d3fa..23f6843 100644 (file)
@@ -3,6 +3,7 @@
   * responses as well as events generated by firmware.
   */
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
 #include <asm/unaligned.h>
index cb8be8d..5b3672c 100644 (file)
@@ -134,7 +134,7 @@ static void spu_transaction_finish(struct if_spi_card *card)
 static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 {
        int err = 0;
-       u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
+       __le16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
        struct spi_message m;
        struct spi_transfer reg_trans;
        struct spi_transfer data_trans;
@@ -166,7 +166,7 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 
 static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
 {
-       u16 buff;
+       __le16 buff;
 
        buff = cpu_to_le16(val);
        return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
@@ -188,7 +188,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 {
        unsigned int delay;
        int err = 0;
-       u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
+       __le16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
        struct spi_message m;
        struct spi_transfer reg_trans;
        struct spi_transfer dummy_trans;
@@ -235,7 +235,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 /* Read 16 bits from an SPI register */
 static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
 {
-       u16 buf;
+       __le16 buf;
        int ret;
 
        ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
@@ -248,7 +248,7 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
  * The low 16 bits are read first. */
 static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
 {
-       u32 buf;
+       __le32 buf;
        int err;
 
        err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
index 88cd58e..1c88c2e 100644 (file)
@@ -2879,7 +2879,7 @@ static int write_essid(struct file *file, const char __user *buffer,
                       unsigned long count, void *data)
 {
        static char proc_essid[33];
-       int len = count;
+       unsigned int len = count;
 
        if (len > 32)
                len = 32;
index a084077..9fe770f 100644 (file)
@@ -1994,7 +1994,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
        rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
                           test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
-                              (skbdesc->entry->entry_idx + 1) : 0xff);
+                          txdesc->key_idx : 0xff);
        rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
                           skb->len - txdesc->l2pad);
        rt2x00_set_field32(&word, TXWI_W1_PACKETID,
index a0384b6..b423473 100644 (file)
@@ -169,7 +169,6 @@ static void znet_tx_timeout (struct net_device *dev);
 static int znet_request_resources (struct net_device *dev)
 {
        struct znet_private *znet = netdev_priv(dev);
-       unsigned long flags;
 
        if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
                goto failed;
@@ -187,13 +186,9 @@ static int znet_request_resources (struct net_device *dev)
  free_sia:
        release_region (znet->sia_base, znet->sia_size);
  free_tx_dma:
-       flags = claim_dma_lock();
        free_dma (znet->tx_dma);
-       release_dma_lock (flags);
  free_rx_dma:
-       flags = claim_dma_lock();
        free_dma (znet->rx_dma);
-       release_dma_lock (flags);
  free_irq:
        free_irq (dev->irq, dev);
  failed:
@@ -203,14 +198,11 @@ static int znet_request_resources (struct net_device *dev)
 static void znet_release_resources (struct net_device *dev)
 {
        struct znet_private *znet = netdev_priv(dev);
-       unsigned long flags;
 
        release_region (znet->sia_base, znet->sia_size);
        release_region (dev->base_addr, znet->io_size);
-       flags = claim_dma_lock();
        free_dma (znet->tx_dma);
        free_dma (znet->rx_dma);
-       release_dma_lock (flags);
        free_irq (dev->irq, dev);
 }
 
index bacaa53..4b22ba5 100644 (file)
@@ -97,6 +97,12 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 }
 EXPORT_SYMBOL(of_mdiobus_register);
 
+/* Helper function for of_phy_find_device */
+static int of_phy_match(struct device *dev, void *phy_np)
+{
+       return dev_archdata_get_node(&dev->archdata) == phy_np;
+}
+
 /**
  * of_phy_find_device - Give a PHY node, find the phy_device
  * @phy_np: Pointer to the phy's device tree node
@@ -106,15 +112,10 @@ EXPORT_SYMBOL(of_mdiobus_register);
 struct phy_device *of_phy_find_device(struct device_node *phy_np)
 {
        struct device *d;
-       int match(struct device *dev, void *phy_np)
-       {
-               return dev_archdata_get_node(&dev->archdata) == phy_np;
-       }
-
        if (!phy_np)
                return NULL;
 
-       d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
+       d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
        return d ? to_phy_device(d) : NULL;
 }
 EXPORT_SYMBOL(of_phy_find_device);
index 2b7ae36..5df60a6 100644 (file)
@@ -35,12 +35,23 @@ static size_t buffer_pos;
 /* atomic_t because wait_event checks it outside of buffer_mutex */
 static atomic_t buffer_ready = ATOMIC_INIT(0);
 
-/* Add an entry to the event buffer. When we
- * get near to the end we wake up the process
- * sleeping on the read() of the file.
+/*
+ * Add an entry to the event buffer. When we get near to the end we
+ * wake up the process sleeping on the read() of the file. To protect
+ * the event_buffer this function may only be called when buffer_mutex
+ * is set.
  */
 void add_event_entry(unsigned long value)
 {
+       /*
+        * This shouldn't happen since all workqueues or handlers are
+        * canceled or flushed before the event buffer is freed.
+        */
+       if (!event_buffer) {
+               WARN_ON_ONCE(1);
+               return;
+       }
+
        if (buffer_pos == buffer_size) {
                atomic_inc(&oprofile_stats.event_lost_overflow);
                return;
@@ -69,7 +80,6 @@ void wake_up_buffer_waiter(void)
 
 int alloc_event_buffer(void)
 {
-       int err = -ENOMEM;
        unsigned long flags;
 
        spin_lock_irqsave(&oprofilefs_lock, flags);
@@ -80,21 +90,22 @@ int alloc_event_buffer(void)
        if (buffer_watershed >= buffer_size)
                return -EINVAL;
 
+       buffer_pos = 0;
        event_buffer = vmalloc(sizeof(unsigned long) * buffer_size);
        if (!event_buffer)
-               goto out;
+               return -ENOMEM;
 
-       err = 0;
-out:
-       return err;
+       return 0;
 }
 
 
 void free_event_buffer(void)
 {
+       mutex_lock(&buffer_mutex);
        vfree(event_buffer);
-
+       buffer_pos = 0;
        event_buffer = NULL;
+       mutex_unlock(&buffer_mutex);
 }
 
 
@@ -167,6 +178,12 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
 
        mutex_lock(&buffer_mutex);
 
+       /* May happen if the buffer is freed during pending reads. */
+       if (!event_buffer) {
+               retval = -EINTR;
+               goto out;
+       }
+
        atomic_set(&buffer_ready, 0);
 
        retval = -EFAULT;
index 14bbaa1..22b02c6 100644 (file)
@@ -354,6 +354,7 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
        struct acpi_dmar_hardware_unit *drhd;
        struct acpi_dmar_reserved_memory *rmrr;
        struct acpi_dmar_atsr *atsr;
+       struct acpi_dmar_rhsa *rhsa;
 
        switch (header->type) {
        case ACPI_DMAR_TYPE_HARDWARE_UNIT:
@@ -375,6 +376,12 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
                atsr = container_of(header, struct acpi_dmar_atsr, header);
                printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags);
                break;
+       case ACPI_DMAR_HARDWARE_AFFINITY:
+               rhsa = container_of(header, struct acpi_dmar_rhsa, header);
+               printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n",
+                      (unsigned long long)rhsa->base_address,
+                      rhsa->proximity_domain);
+               break;
        }
 }
 
@@ -459,9 +466,13 @@ parse_dmar_table(void)
                        ret = dmar_parse_one_atsr(entry_header);
 #endif
                        break;
+               case ACPI_DMAR_HARDWARE_AFFINITY:
+                       /* We don't do anything with RHSA (yet?) */
+                       break;
                default:
                        printk(KERN_WARNING PREFIX
-                               "Unknown DMAR structure type\n");
+                               "Unknown DMAR structure type %d\n",
+                               entry_header->type);
                        ret = 0; /* for forward compatibility */
                        break;
                }
index 5383600..9c6a9fd 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/io.h>            /* for read? and write? functions */
 #include <linux/delay.h>       /* for delays */
 #include <linux/mutex.h>
+#include <linux/sched.h>       /* for signal_pending() */
 
 #define MY_NAME        "cpqphp"
 
index 855dd7c..b1e97e6 100644 (file)
@@ -48,6 +48,7 @@
 
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
 
 #define IOAPIC_RANGE_START     (0xfee00000)
 #define IOAPIC_RANGE_END       (0xfeefffff)
@@ -94,6 +95,7 @@ static inline unsigned long virt_to_dma_pfn(void *p)
 /* global iommu list, set NULL for ignored DMAR units */
 static struct intel_iommu **g_iommus;
 
+static void __init check_tylersburg_isoch(void);
 static int rwbf_quirk;
 
 /*
@@ -1934,6 +1936,9 @@ error:
 }
 
 static int iommu_identity_mapping;
+#define IDENTMAP_ALL           1
+#define IDENTMAP_GFX           2
+#define IDENTMAP_AZALIA                4
 
 static int iommu_domain_identity_map(struct dmar_domain *domain,
                                     unsigned long long start,
@@ -2151,8 +2156,14 @@ static int domain_add_dev_info(struct dmar_domain *domain,
 
 static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
 {
-       if (iommu_identity_mapping == 2)
-               return IS_GFX_DEVICE(pdev);
+       if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
+               return 1;
+
+       if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
+               return 1;
+
+       if (!(iommu_identity_mapping & IDENTMAP_ALL))
+               return 0;
 
        /*
         * We want to start off with all devices in the 1:1 domain, and
@@ -2332,11 +2343,14 @@ int __init init_dmars(void)
        }
 
        if (iommu_pass_through)
-               iommu_identity_mapping = 1;
+               iommu_identity_mapping |= IDENTMAP_ALL;
+
 #ifdef CONFIG_DMAR_BROKEN_GFX_WA
-       else
-               iommu_identity_mapping = 2;
+       iommu_identity_mapping |= IDENTMAP_GFX;
 #endif
+
+       check_tylersburg_isoch();
+
        /*
         * If pass through is not set or not enabled, setup context entries for
         * identity mappings for rmrr, gfx, and isa and may fall back to static
@@ -3670,3 +3684,61 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
+
+/* On Tylersburg chipsets, some BIOSes have been known to enable the
+   ISOCH DMAR unit for the Azalia sound device, but not give it any
+   TLB entries, which causes it to deadlock. Check for that.  We do
+   this in a function called from init_dmars(), instead of in a PCI
+   quirk, because we don't want to print the obnoxious "BIOS broken"
+   message if VT-d is actually disabled.
+*/
+static void __init check_tylersburg_isoch(void)
+{
+       struct pci_dev *pdev;
+       uint32_t vtisochctrl;
+
+       /* If there's no Azalia in the system anyway, forget it. */
+       pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
+       if (!pdev)
+               return;
+       pci_dev_put(pdev);
+
+       /* System Management Registers. Might be hidden, in which case
+          we can't do the sanity check. But that's OK, because the
+          known-broken BIOSes _don't_ actually hide it, so far. */
+       pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
+       if (!pdev)
+               return;
+
+       if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
+               pci_dev_put(pdev);
+               return;
+       }
+
+       pci_dev_put(pdev);
+
+       /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
+       if (vtisochctrl & 1)
+               return;
+
+       /* Drop all bits other than the number of TLB entries */
+       vtisochctrl &= 0x1c;
+
+       /* If we have the recommended number of TLB entries (16), fine. */
+       if (vtisochctrl == 0x10)
+               return;
+
+       /* Zero TLB entries? You get to ride the short bus to school. */
+       if (!vtisochctrl) {
+               WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
+                    "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+                    dmi_get_system_info(DMI_BIOS_VENDOR),
+                    dmi_get_system_info(DMI_BIOS_VERSION),
+                    dmi_get_system_info(DMI_PRODUCT_VERSION));
+               iommu_identity_mapping |= IDENTMAP_AZALIA;
+               return;
+       }
+       
+       printk(KERN_WARNING "DMAR: Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
+              vtisochctrl);
+}
index 6edecff..4e4c295 100644 (file)
@@ -513,7 +513,11 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
        else if (state == PCI_D2 || dev->current_state == PCI_D2)
                udelay(PCI_PM_D2_DELAY);
 
-       dev->current_state = state;
+       pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+       dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+       if (dev->current_state != state && printk_ratelimit())
+               dev_info(&dev->dev, "Refused to change power state, "
+                       "currently in D%d\n", dev->current_state);
 
        /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
         * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
@@ -2542,10 +2546,10 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 
 /**
  * pci_set_vga_state - set VGA decode state on device and parents if requested
- * @dev the PCI device
- * @decode - true = enable decoding, false = disable decoding
- * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
- * @change_bridge - traverse ancestors and change bridges
+ * @dev: the PCI device
+ * @decode: true = enable decoding, false = disable decoding
+ * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
+ * @change_bridge: traverse ancestors and change bridges
  */
 int pci_set_vga_state(struct pci_dev *dev, bool decode,
                      unsigned int command_bits, bool change_bridge)
@@ -2719,17 +2723,6 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
        return 1;
 }
 
-static int __devinit pci_init(void)
-{
-       struct pci_dev *dev = NULL;
-
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               pci_fixup_device(pci_fixup_final, dev);
-       }
-
-       return 0;
-}
-
 static int __init pci_setup(char *str)
 {
        while (str) {
@@ -2767,8 +2760,6 @@ static int __init pci_setup(char *str)
 }
 early_param("pci", pci_setup);
 
-device_initcall(pci_init);
-
 EXPORT_SYMBOL(pci_reenable_device);
 EXPORT_SYMBOL(pci_enable_device_io);
 EXPORT_SYMBOL(pci_enable_device_mem);
index d49ecc9..40c3cc5 100644 (file)
@@ -53,7 +53,7 @@ static struct pci_error_handlers aer_error_handlers = {
 
 static struct pcie_port_service_driver aerdriver = {
        .name           = "aer",
-       .port_type      = PCIE_ANY_PORT,
+       .port_type      = PCIE_RC_PORT,
        .service        = PCIE_PORT_SERVICE_AER,
 
        .probe          = aer_probe,
index 6df5c98..f635e47 100644 (file)
@@ -30,7 +30,6 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /* global data */
-static const char device_name[] = "pcieport-driver";
 
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
@@ -262,7 +261,7 @@ static struct pci_error_handlers pcie_portdrv_err_handler = {
 };
 
 static struct pci_driver pcie_portdriver = {
-       .name           = (char *)device_name,
+       .name           = "pcieport",
        .id_table       = &port_pci_ids[0],
 
        .probe          = pcie_portdrv_probe,
index 6099fac..245d2cd 100644 (file)
@@ -670,6 +670,25 @@ static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi);
 
+/*
+ * TI XIO2000a PCIe-PCI Bridge erroneously reports it supports fast back-to-back:
+ *     Disable fast back-to-back on the secondary bus segment
+ */
+static void __devinit quirk_xio2000a(struct pci_dev *dev)
+{
+       struct pci_dev *pdev;
+       u16 command;
+
+       dev_warn(&dev->dev, "TI XIO2000a quirk detected; "
+               "secondary bus fast back-to-back transfers disabled\n");
+       list_for_each_entry(pdev, &dev->subordinate->devices, bus_list) {
+               pci_read_config_word(pdev, PCI_COMMAND, &command);
+               if (command & PCI_COMMAND_FAST_BACK)
+                       pci_write_config_word(pdev, PCI_COMMAND, command & ~PCI_COMMAND_FAST_BACK);
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XIO2000A,
+                       quirk_xio2000a);
 
 #ifdef CONFIG_X86_IO_APIC 
 
@@ -990,7 +1009,7 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,        PCI_DEVICE_ID_INTEL_82454NX,
 
 static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
 {
-       /* set SBX00 SATA in IDE mode to AHCI mode */
+       /* set SBX00/Hudson-2 SATA in IDE mode to AHCI mode */
        u8 tmp;
 
        pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp);
@@ -1009,8 +1028,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SATA_IDE, quirk_amd_ide_mode);
-DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SB900_SATA_IDE, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
@@ -2572,6 +2591,19 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
        }
        pci_do_fixups(dev, start, end);
 }
+
+static int __init pci_apply_final_quirks(void)
+{
+       struct pci_dev *dev = NULL;
+
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               pci_fixup_device(pci_fixup_final, dev);
+       }
+
+       return 0;
+}
+
+fs_initcall_sync(pci_apply_final_quirks);
 #else
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
 #endif
index 706f82d..c54526b 100644 (file)
@@ -205,43 +205,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
        return ret;
 }
 
-#if 0
-int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
-{
-       struct pci_bus *bus = dev->bus;
-       struct resource *res = dev->resource + resno;
-       unsigned int type_mask;
-       int i, ret = -EBUSY;
-
-       type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
-
-       for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
-               struct resource *r = bus->resource[i];
-               if (!r)
-                       continue;
-
-               /* type_mask must match */
-               if ((res->flags ^ r->flags) & type_mask)
-                       continue;
-
-               ret = request_resource(r, res);
-
-               if (ret == 0)
-                       break;
-       }
-
-       if (ret) {
-               dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
-                       resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
-       } else if (resno < PCI_BRIDGE_RESOURCES) {
-               pci_update_resource(dev, resno);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(pci_assign_resource_fixed);
-#endif
-
 /* Sort resources by alignment */
 void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
 {
index 4a110b7..6c4a4fc 100644 (file)
@@ -1463,7 +1463,9 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
            return -ENOMEM;
     }
     tuple.DesiredTuple = code;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
+    tuple.Attributes = 0;
+    if (function == BIND_FN_ALL)
+           tuple.Attributes = TUPLE_RETURN_COMMON;
     ret = pccard_get_first_tuple(s, function, &tuple);
     if (ret != 0)
            goto done;
@@ -1490,7 +1492,7 @@ EXPORT_SYMBOL(pccard_read_tuple);
     
 ======================================================================*/
 
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info)
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
 {
     tuple_t *tuple;
     cisparse_t *p;
@@ -1515,30 +1517,30 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
     count = reserved = 0;
     tuple->DesiredTuple = RETURN_FIRST_TUPLE;
     tuple->Attributes = TUPLE_RETURN_COMMON;
-    ret = pccard_get_first_tuple(s, function, tuple);
+    ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
     if (ret != 0)
        goto done;
 
     /* First tuple should be DEVICE; we should really have either that
        or a CFTABLE_ENTRY of some sort */
     if ((tuple->TupleCode == CISTPL_DEVICE) ||
-       (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
-       (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
+       (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
+       (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
        dev_ok++;
 
     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
        tuple, for card identification.  Certain old D-Link and Linksys
        cards have only a broken VERS_2 tuple; hence the bogus test. */
-    if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
-       (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
-       (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
+    if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
+       (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
+       (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
        ident_ok++;
 
     if (!dev_ok && !ident_ok)
        goto done;
 
     for (count = 1; count < MAX_TUPLES; count++) {
-       ret = pccard_get_next_tuple(s, function, tuple);
+       ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
        if (ret != 0)
                break;
        if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
index 79615e6..1f4098f 100644 (file)
@@ -197,8 +197,7 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
                      cisdata_t code, void *parse);
 int pcmcia_replace_cis(struct pcmcia_socket *s,
                       const u8 *data, const size_t len);
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function,
-                       unsigned int *count);
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
 
 /* rsrc_mgr.c */
 int pcmcia_validate_mem(struct pcmcia_socket *s);
index 9f300d3..f5b7079 100644 (file)
@@ -547,7 +547,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
        if (!vers1)
                return -ENOMEM;
 
-       if (!pccard_read_tuple(p_dev->socket, p_dev->func,
+       if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
                               CISTPL_MANFID, &manf_id)) {
                p_dev->manf_id = manf_id.manf;
                p_dev->card_id = manf_id.card;
@@ -581,9 +581,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
                kfree(devgeo);
        }
 
-       if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1,
+       if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
                               vers1)) {
-               for (i=0; i < vers1->ns; i++) {
+               for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
                        char *tmp;
                        unsigned int length;
 
@@ -733,7 +733,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
                return -EAGAIN; /* try again, but later... */
        }
 
-       ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
+       ret = pccard_validate_cis(s, &no_chains);
        if (ret || !no_chains) {
                ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
                return -ENODEV;
index b906abe..a4aacb8 100644 (file)
@@ -1053,8 +1053,8 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
     u_char map, ioctl;
     
     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
-         "%#x-%#x)\n", sock, io->map, io->flags,
-         io->speed, io->start, io->stop);
+         "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
+         (unsigned long long)io->start, (unsigned long long)io->stop);
     map = io->map;
     if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
        (io->stop < io->start)) return -EINVAL;
index d1d89c4..7dfbee1 100644 (file)
@@ -537,8 +537,9 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
        u_char map;
 
        debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
-                 "%#lx-%#lx)\n", sock, io->map, io->flags,
-                 io->speed, io->start, io->stop);
+                 "%#llx-%#llx)\n", sock, io->map, io->flags,
+                 io->speed, (unsigned long long)io->start,
+                 (unsigned long long)io->stop);
        map = io->map;
 
        return 0;
@@ -554,8 +555,9 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
        pcc_socket_t *t = &socket[sock];
 
        debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
-                "%#lx, %#x)\n", sock, map, mem->flags,
-                mem->speed, mem->static_start, mem->card_start);
+                "%#llx, %#x)\n", sock, map, mem->flags,
+                mem->speed, (unsigned long long)mem->static_start,
+                mem->card_start);
 
        /*
         * sanity check
index a065583..c6524f9 100644 (file)
@@ -492,8 +492,9 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
        u_char map;
 
        debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
-                 "%#x-%#x)\n", sock, io->map, io->flags,
-                 io->speed, io->start, io->stop);
+                 "%#llx-%#llx)\n", sock, io->map, io->flags,
+                 io->speed, (unsigned long long)io->start,
+                 (unsigned long long)io->stop);
        map = io->map;
 
        return 0;
@@ -515,8 +516,9 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 #endif
 
        debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
-                "%#lx,  %#x)\n", sock, map, mem->flags,
-                mem->speed, mem->static_start, mem->card_start);
+                "%#llx,  %#x)\n", sock, map, mem->flags,
+                mem->speed, (unsigned long long)mem->static_start,
+                mem->card_start);
 
        /*
         * sanity check
index c69f2c4..403559b 100644 (file)
@@ -975,8 +975,9 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 #define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
 
        dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
-               "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
-               io->speed, io->start, io->stop);
+               "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
+               io->speed, (unsigned long long)io->start,
+               (unsigned long long)io->stop);
 
        if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
            || (io->stop > 0xffff) || (io->stop < io->start))
@@ -1055,8 +1056,9 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
        pcmconf8xx_t *pcmcia = s->pcmcia;
 
        dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
-               "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
-               mem->speed, mem->static_start, mem->card_start);
+               "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
+               mem->speed, (unsigned long long)mem->static_start,
+               mem->card_start);
 
        if ((mem->map >= PCMCIA_MEM_WIN_NO)
 //          || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
@@ -1107,8 +1109,9 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
        }
 
        dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
-               "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
-               mem->speed, mem->static_start, mem->card_start);
+               "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
+               mem->speed, (unsigned long long)mem->static_start,
+               mem->card_start);
 
        /* copy the struct and modify the copy */
 
index 32c4404..30cf71d 100644 (file)
@@ -881,7 +881,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
        mutex_lock(&s->skt_mutex);
        pcmcia_validate_mem(s);
        mutex_unlock(&s->skt_mutex);
-       ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
+       ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
        break;
     case DS_SUSPEND_CARD:
        ret = pcmcia_suspend_card(s);
index 1c39d34..70a3346 100644 (file)
@@ -641,6 +641,12 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
        if ((ret = pci_enable_device(dev)))
                goto err_out_free_mem;
 
+       if (!pci_resource_start(dev, 0)) {
+               printk(KERN_INFO "pd6729: refusing to load the driver "
+                                "as the io_base is 0.\n");
+               goto err_out_free_mem;
+       }
+
        printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
                "at 0x%llx on irq %d\n",
                (unsigned long long)pci_resource_start(dev, 0), dev->irq);
index 9ca22c7..7039f3c 100644 (file)
@@ -206,6 +206,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
     /* First, what does a floating port look like? */
     b = kzalloc(256, GFP_KERNEL);
     if (!b) {
+           printk("\n");
            dev_printk(KERN_ERR, &s->dev,
                   "do_io_probe: unable to kmalloc 256 bytes");
             return;
@@ -275,7 +276,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
        s->cis_mem.res = res;
        s->cis_virt = ioremap(res->start, s->map_size);
        if (s->cis_virt) {
-               ret = pccard_validate_cis(s, BIND_FN_ALL, count);
+               ret = pccard_validate_cis(s, count);
                /* invalidate mapping and CIS cache */
                iounmap(s->cis_virt);
                s->cis_virt = NULL;
index 163cf98..ef7e9e5 100644 (file)
@@ -336,8 +336,9 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
        struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
        unsigned short speed = map->speed;
 
-       debug(skt, 2, "map %u  speed %u start 0x%08x stop 0x%08x\n",
-               map->map, map->speed, map->start, map->stop);
+       debug(skt, 2, "map %u  speed %u start 0x%08llx stop 0x%08llx\n",
+               map->map, map->speed, (unsigned long long)map->start,
+               (unsigned long long)map->stop);
        debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
                (map->flags==0)?"<NONE>":"",
                (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
index ff9a3bb..78d5aab 100644 (file)
@@ -300,7 +300,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
 
                if (!(s->state & SOCKET_PRESENT))
                        return -ENODEV;
-               if (pccard_validate_cis(s, BIND_FN_ALL, &chains))
+               if (pccard_validate_cis(s, &chains))
                        return -EIO;
                if (!chains)
                        return -ENODATA;
index 582413f..6918849 100644 (file)
@@ -732,8 +732,8 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
     u_short base, len, ioctl;
     
     debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
-         "%#x-%#x)\n", psock, io->map, io->flags,
-         io->speed, io->start, io->stop);
+         "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
+         (unsigned long long)io->start, (unsigned long long)io->stop);
     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
        (io->stop < io->start)) return -EINVAL;
     tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
index 749e210..d379e74 100644 (file)
@@ -150,6 +150,8 @@ struct eeepc_hotk {
 /* The actual device the driver binds to */
 static struct eeepc_hotk *ehotk;
 
+static void eeepc_rfkill_hotplug(bool real);
+
 /* Platform device/driver */
 static int eeepc_hotk_thaw(struct device *device);
 static int eeepc_hotk_restore(struct device *device);
@@ -343,14 +345,23 @@ static bool eeepc_wlan_rfkill_blocked(void)
 static int eeepc_rfkill_set(void *data, bool blocked)
 {
        unsigned long asl = (unsigned long)data;
-       return set_acpi(asl, !blocked);
+       int ret;
+
+       if (asl != CM_ASL_WLAN)
+               return set_acpi(asl, !blocked);
+
+       /* hack to avoid panic with rt2860sta */
+       if (blocked)
+               eeepc_rfkill_hotplug(false);
+       ret = set_acpi(asl, !blocked);
+       return ret;
 }
 
 static const struct rfkill_ops eeepc_rfkill_ops = {
        .set_block = eeepc_rfkill_set,
 };
 
-static void __init eeepc_enable_camera(void)
+static void __devinit eeepc_enable_camera(void)
 {
        /*
         * If the following call to set_acpi() fails, it's because there's no
@@ -643,13 +654,13 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
        return 0;
 }
 
-static void eeepc_rfkill_hotplug(void)
+static void eeepc_rfkill_hotplug(bool real)
 {
        struct pci_dev *dev;
        struct pci_bus *bus;
-       bool blocked = eeepc_wlan_rfkill_blocked();
+       bool blocked = real ? eeepc_wlan_rfkill_blocked() : true;
 
-       if (ehotk->wlan_rfkill)
+       if (real && ehotk->wlan_rfkill)
                rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
 
        mutex_lock(&ehotk->hotplug_lock);
@@ -692,7 +703,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
        if (event != ACPI_NOTIFY_BUS_CHECK)
                return;
 
-       eeepc_rfkill_hotplug();
+       eeepc_rfkill_hotplug(true);
 }
 
 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
@@ -850,7 +861,7 @@ static int eeepc_hotk_restore(struct device *device)
 {
        /* Refresh both wlan rfkill state and pci hotplug */
        if (ehotk->wlan_rfkill)
-               eeepc_rfkill_hotplug();
+               eeepc_rfkill_hotplug(true);
 
        if (ehotk->bluetooth_rfkill)
                rfkill_set_sw_state(ehotk->bluetooth_rfkill,
@@ -993,7 +1004,7 @@ static void eeepc_rfkill_exit(void)
         * Refresh pci hotplug in case the rfkill state was changed after
         * eeepc_unregister_rfkill_notifier()
         */
-       eeepc_rfkill_hotplug();
+       eeepc_rfkill_hotplug(true);
        if (ehotk->hotplug_slot)
                pci_hp_deregister(ehotk->hotplug_slot);
 
@@ -1109,7 +1120,7 @@ static int eeepc_rfkill_init(struct device *dev)
         * Refresh pci hotplug in case the rfkill state was changed during
         * setup.
         */
-       eeepc_rfkill_hotplug();
+       eeepc_rfkill_hotplug(true);
 
 exit:
        if (result && result != -ENODEV)
@@ -1189,7 +1200,7 @@ static int eeepc_input_init(struct device *dev)
        return 0;
 }
 
-static int eeepc_hotk_add(struct acpi_device *device)
+static int __devinit eeepc_hotk_add(struct acpi_device *device)
 {
        struct device *dev;
        int result;
index f35aee5..bcd4ba8 100644 (file)
@@ -944,7 +944,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
        struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device);
        struct input_dev *input = fujitsu_hotkey->input;
 
-#ifdef CONFIG_LEDS_CLASS
+#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
        if (fujitsu_hotkey->logolamp_registered)
                led_classdev_unregister(&logolamp_led);
 
index 53b8c25..aaccc8e 100644 (file)
@@ -2533,6 +2533,7 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
 {
        struct dasd_ccw_req *cqr;
        struct ccw1 *ccw;
+       unsigned long *idaw;
 
        cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
 
@@ -2546,9 +2547,17 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
 
        ccw = cqr->cpaddr;
        ccw->cmd_code = CCW_CMD_RDC;
-       ccw->cda = (__u32)(addr_t)rdc_buffer;
-       ccw->count = rdc_buffer_size;
+       if (idal_is_needed(rdc_buffer, rdc_buffer_size)) {
+               idaw = (unsigned long *) (cqr->data);
+               ccw->cda = (__u32)(addr_t) idaw;
+               ccw->flags = CCW_FLAG_IDA;
+               idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size);
+       } else {
+               ccw->cda = (__u32)(addr_t) rdc_buffer;
+               ccw->flags = 0;
+       }
 
+       ccw->count = rdc_buffer_size;
        cqr->startdev = device;
        cqr->memdev = device;
        cqr->expires = 10*HZ;
index 0be7c15..417b97c 100644 (file)
@@ -3216,6 +3216,7 @@ int dasd_eckd_restore_device(struct dasd_device *device)
        struct dasd_eckd_characteristics temp_rdc_data;
        int is_known, rc;
        struct dasd_uid temp_uid;
+       unsigned long flags;
 
        private = (struct dasd_eckd_private *) device->private;
 
@@ -3228,7 +3229,8 @@ int dasd_eckd_restore_device(struct dasd_device *device)
        rc = dasd_eckd_generate_uid(device, &private->uid);
        dasd_get_uid(device->cdev, &temp_uid);
        if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
-               dev_err(&device->cdev->dev, "The UID of the DASD has changed\n");
+               dev_err(&device->cdev->dev, "The UID of the DASD has "
+                       "changed\n");
        if (rc)
                goto out_err;
        dasd_set_uid(device->cdev, &private->uid);
@@ -3256,9 +3258,9 @@ int dasd_eckd_restore_device(struct dasd_device *device)
                          "device: %s", rc, dev_name(&device->cdev->dev));
                goto out_err;
        }
-       spin_lock(get_ccwdev_lock(device->cdev));
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
        memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data));
-       spin_unlock(get_ccwdev_lock(device->cdev));
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 
        /* add device to alias management */
        dasd_alias_add_device(device);
index daaec18..b44462a 100644 (file)
@@ -26,7 +26,6 @@ static struct sclp_async_sccb *sccb;
 static int sclp_async_send_wait(char *message);
 static struct ctl_table_header *callhome_sysctl_header;
 static DEFINE_SPINLOCK(sclp_async_lock);
-static char nodename[64];
 #define SCLP_NORMAL_WRITE      0x00
 
 struct async_evbuf {
@@ -52,9 +51,10 @@ static struct sclp_register sclp_async_register = {
 static int call_home_on_panic(struct notifier_block *self,
                              unsigned long event, void *data)
 {
-               strncat(data, nodename, strlen(nodename));
-               sclp_async_send_wait(data);
-               return NOTIFY_DONE;
+       strncat(data, init_utsname()->nodename,
+               sizeof(init_utsname()->nodename));
+       sclp_async_send_wait(data);
+       return NOTIFY_DONE;
 }
 
 static struct notifier_block call_home_panic_nb = {
@@ -62,21 +62,20 @@ static struct notifier_block call_home_panic_nb = {
        .priority = INT_MAX,
 };
 
-static int proc_handler_callhome(ctl_table *ctl, int write, struct file *filp,
+static int proc_handler_callhome(struct ctl_table *ctl, int write,
                                 void __user *buffer, size_t *count,
                                 loff_t *ppos)
 {
        unsigned long val;
        int len, rc;
-       char buf[2];
+       char buf[3];
 
-       if (!*count | (*ppos && !write)) {
+       if (!*count || (*ppos && !write)) {
                *count = 0;
                return 0;
        }
        if (!write) {
-               len =  sprintf(buf, "%d\n", callhome_enabled);
-               buf[len] = '\0';
+               len = snprintf(buf, sizeof(buf), "%d\n", callhome_enabled);
                rc = copy_to_user(buffer, buf, sizeof(buf));
                if (rc != 0)
                        return -EFAULT;
@@ -100,7 +99,7 @@ static struct ctl_table callhome_table[] = {
        {
                .procname       = "callhome",
                .mode           = 0644,
-               .proc_handler   = &proc_handler_callhome,
+               .proc_handler   = proc_handler_callhome,
        },
        { .ctl_name = 0 }
 };
@@ -171,39 +170,29 @@ static int __init sclp_async_init(void)
        rc = sclp_register(&sclp_async_register);
        if (rc)
                return rc;
-       callhome_sysctl_header = register_sysctl_table(kern_dir_table);
-       if (!callhome_sysctl_header) {
-               rc = -ENOMEM;
-               goto out_sclp;
-       }
-       if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK)) {
-               rc = -EOPNOTSUPP;
+       rc = -EOPNOTSUPP;
+       if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK))
                goto out_sclp;
-       }
        rc = -ENOMEM;
+       callhome_sysctl_header = register_sysctl_table(kern_dir_table);
+       if (!callhome_sysctl_header)
+               goto out_sclp;
        request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL);
-       if (!request)
-               goto out_sys;
        sccb = (struct sclp_async_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
-       if (!sccb)
+       if (!request || !sccb)
                goto out_mem;
-       rc =  atomic_notifier_chain_register(&panic_notifier_list,
-                                            &call_home_panic_nb);
-       if (rc)
-               goto out_mem;
-
-       strncpy(nodename, init_utsname()->nodename, 64);
-       return 0;
-
+       rc = atomic_notifier_chain_register(&panic_notifier_list,
+                                           &call_home_panic_nb);
+       if (!rc)
+               goto out;
 out_mem:
        kfree(request);
        free_page((unsigned long) sccb);
-out_sys:
        unregister_sysctl_table(callhome_sysctl_header);
 out_sclp:
        sclp_unregister(&sclp_async_register);
+out:
        return rc;
-
 }
 module_init(sclp_async_init);
 
index 178724f..b9d2a00 100644 (file)
@@ -705,21 +705,6 @@ out_driver:
 }
 __initcall(sclp_vt220_tty_init);
 
-#ifdef CONFIG_SCLP_VT220_CONSOLE
-
-static void
-sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
-{
-       __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
-}
-
-static struct tty_driver *
-sclp_vt220_con_device(struct console *c, int *index)
-{
-       *index = 0;
-       return sclp_vt220_driver;
-}
-
 static void __sclp_vt220_flush_buffer(void)
 {
        unsigned long flags;
@@ -776,6 +761,21 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
        }
 }
 
+#ifdef CONFIG_SCLP_VT220_CONSOLE
+
+static void
+sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
+{
+       __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
+}
+
+static struct tty_driver *
+sclp_vt220_con_device(struct console *c, int *index)
+{
+       *index = 0;
+       return sclp_vt220_driver;
+}
+
 static int
 sclp_vt220_notify(struct notifier_block *self,
                          unsigned long event, void *data)
index 64f57ef..0c0705b 100644 (file)
@@ -162,9 +162,10 @@ tapeblock_requeue(struct work_struct *work) {
        spin_lock_irq(&device->blk_data.request_queue_lock);
        while (
                !blk_queue_plugged(queue) &&
-               (req = blk_fetch_request(queue)) &&
+               blk_peek_request(queue) &&
                nr_queued < TAPEBLOCK_MIN_REQUEUE
        ) {
+               req = blk_fetch_request(queue);
                if (rq_data_dir(req) == WRITE) {
                        DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
                        spin_unlock_irq(&device->blk_data.request_queue_lock);
index 2ee093e..2490b74 100644 (file)
@@ -1250,8 +1250,7 @@ static int io_subchannel_probe(struct subchannel *sch)
        unsigned long flags;
        struct ccw_dev_id dev_id;
 
-       cdev = sch_get_cdev(sch);
-       if (cdev) {
+       if (cio_is_console(sch->schid)) {
                rc = sysfs_create_group(&sch->dev.kobj,
                                        &io_subchannel_attr_group);
                if (rc)
@@ -1260,13 +1259,13 @@ static int io_subchannel_probe(struct subchannel *sch)
                                      "0.%x.%04x (rc=%d)\n",
                                      sch->schid.ssid, sch->schid.sch_no, rc);
                /*
-                * This subchannel already has an associated ccw_device.
+                * The console subchannel already has an associated ccw_device.
                 * Throw the delayed uevent for the subchannel, register
-                * the ccw_device and exit. This happens for all early
-                * devices, e.g. the console.
+                * the ccw_device and exit.
                 */
                dev_set_uevent_suppress(&sch->dev, 0);
                kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
+               cdev = sch_get_cdev(sch);
                cdev->dev.groups = ccwdev_attr_groups;
                device_initialize(&cdev->dev);
                ccw_device_register(cdev);
index 102000d..3012355 100644 (file)
@@ -158,7 +158,12 @@ static int smsg_pm_restore_thaw(struct device *dev)
                smsg_path->flags = 0;
                rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG    ",
                                       NULL, NULL, NULL);
-               printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc);
+#ifdef CONFIG_PM_DEBUG
+               if (rc)
+                       printk(KERN_ERR
+                              "iucv_path_connect returned with rc %i\n", rc);
+#endif
+               cpcmd("SET SMSG IUCV", NULL, 0, NULL);
        }
        return 0;
 }
index 0f79f3a..2889e5f 100644 (file)
@@ -128,12 +128,13 @@ out_ccwdev:
 static void __init zfcp_init_device_setup(char *devstr)
 {
        char *token;
-       char *str;
+       char *str, *str_saved;
        char busid[ZFCP_BUS_ID_SIZE];
        u64 wwpn, lun;
 
        /* duplicate devstr and keep the original for sysfs presentation*/
-       str = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+       str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+       str = str_saved;
        if (!str)
                return;
 
@@ -152,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr)
        if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun))
                goto err_out;
 
-       kfree(str);
+       kfree(str_saved);
        zfcp_init_device_configure(busid, wwpn, lun);
        return;
 
- err_out:
-       kfree(str);
+err_out:
+       kfree(str_saved);
        pr_err("%s is not a valid SCSI device\n", devstr);
 }
 
index 73d366b..f73e218 100644 (file)
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
                if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
                        return zfcp_erp_open_ptp_port(act);
                if (!port->d_id) {
-                       zfcp_port_get(port);
-                       if (!queue_work(adapter->work_queue,
-                                       &port->gid_pn_work))
-                               zfcp_port_put(port);
+                       zfcp_fc_trigger_did_lookup(port);
                        return ZFCP_ERP_EXIT;
                }
                return zfcp_erp_port_strategy_open_port(act);
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
        case ZFCP_ERP_STEP_PORT_OPENING:
                /* D_ID might have changed during open */
                if (p_status & ZFCP_STATUS_COMMON_OPEN) {
-                       if (port->d_id)
-                               return ZFCP_ERP_SUCCEEDED;
-                       else {
-                               act->step = ZFCP_ERP_STEP_PORT_CLOSING;
-                               return ZFCP_ERP_CONTINUES;
+                       if (!port->d_id) {
+                               zfcp_fc_trigger_did_lookup(port);
+                               return ZFCP_ERP_EXIT;
                        }
+                       return ZFCP_ERP_SUCCEEDED;
                }
                if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) {
                        port->d_id = 0;
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
 static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
 {
        struct zfcp_port *port = erp_action->port;
+       int p_status = atomic_read(&port->status);
 
-       if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
+       if ((p_status & ZFCP_STATUS_COMMON_NOESC) &&
+           !(p_status & ZFCP_STATUS_COMMON_OPEN))
                goto close_init_done;
 
        switch (erp_action->step) {
        case ZFCP_ERP_STEP_UNINITIALIZED:
                zfcp_erp_port_strategy_clearstati(port);
-               if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
+               if (p_status & ZFCP_STATUS_COMMON_OPEN)
                        return zfcp_erp_port_strategy_close(erp_action);
                break;
 
        case ZFCP_ERP_STEP_PORT_CLOSING:
-               if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)
+               if (p_status & ZFCP_STATUS_COMMON_OPEN)
                        return ZFCP_ERP_FAILED;
                break;
        }
index 629edec..b3f28de 100644 (file)
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
 extern void _zfcp_fc_scan_ports_later(struct work_struct *);
 extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
 extern void zfcp_fc_port_did_lookup(struct work_struct *);
+extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
 extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
 extern void zfcp_fc_test_link(struct zfcp_port *);
 extern void zfcp_fc_link_test_work(struct work_struct *);
index 722f22d..df23bce 100644 (file)
@@ -360,6 +360,17 @@ out:
        zfcp_port_put(port);
 }
 
+/**
+ * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request
+ * @port: The zfcp_port to lookup the d_id for.
+ */
+void zfcp_fc_trigger_did_lookup(struct zfcp_port *port)
+{
+       zfcp_port_get(port);
+       if (!queue_work(port->adapter->work_queue, &port->gid_pn_work))
+               zfcp_port_put(port);
+}
+
 /**
  * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
  * @port: zfcp_port structure
index 38a7e4a..4e41baa 100644 (file)
@@ -1079,7 +1079,7 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
        /* common settings for ct/gs and els requests */
        req->qtcb->bottom.support.service_class = FSF_CLASS_3;
        req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
-       zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
+       zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ);
 
        return 0;
 }
@@ -1475,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
                if (req->qtcb->bottom.support.els1_length >=
                    FSF_PLOGI_MIN_LEN) {
-                       if (plogi->serv_param.wwpn != port->wwpn)
+                       if (plogi->serv_param.wwpn != port->wwpn) {
                                port->d_id = 0;
-                       else {
+                               dev_warn(&port->adapter->ccw_device->dev,
+                                        "A port opened with WWPN 0x%016Lx "
+                                        "returned data that identifies it as "
+                                        "WWPN 0x%016Lx\n",
+                                        (unsigned long long) port->wwpn,
+                                        (unsigned long long)
+                                         plogi->serv_param.wwpn);
+                       } else {
                                port->wwnn = plogi->serv_param.wwnn;
                                zfcp_fc_plogi_evaluate(port, plogi);
                        }
index 079a8cf..d310008 100644 (file)
@@ -224,6 +224,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
 
        zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
        zfcp_erp_wait(unit->port->adapter);
+       flush_work(&unit->scsi_work);
        zfcp_unit_put(unit);
 out:
        mutex_unlock(&zfcp_data.config_mutex);
index b6af63c..4967643 100644 (file)
@@ -1918,6 +1918,10 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
                }
                size = size>>16;
                size *= 4;
+               if (size > MAX_MESSAGE_SIZE) {
+                       rcode = -EINVAL;
+                       goto cleanup;
+               }
                /* Copy in the user's I2O command */
                if (copy_from_user (msg, user_msg, size)) {
                        rcode = -EFAULT;
index c447838..0547a7f 100644 (file)
@@ -317,6 +317,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
 out_device_destroy:
        scsi_device_set_state(sdev, SDEV_DEL);
        transport_destroy_device(&sdev->sdev_gendev);
+       put_device(&sdev->sdev_dev);
        put_device(&sdev->sdev_gendev);
 out:
        if (display_failure_msg)
@@ -957,6 +958,7 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev)
        if (sdev->host->hostt->slave_destroy)
                sdev->host->hostt->slave_destroy(sdev);
        transport_destroy_device(&sdev->sdev_gendev);
+       put_device(&sdev->sdev_dev);
        put_device(&sdev->sdev_gendev);
 }
 
index fde5453..5c7eb63 100644 (file)
@@ -864,10 +864,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
                goto clean_device;
        }
 
-       /* take a reference for the sdev_dev; this is
-        * released by the sdev_class .release */
-       get_device(&sdev->sdev_gendev);
-
        /* create queue files, which may be writable, depending on the host */
        if (sdev->host->hostt->change_queue_depth)
                error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
@@ -917,6 +913,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 
        device_del(&sdev->sdev_gendev);
        transport_destroy_device(&sdev->sdev_gendev);
+       put_device(&sdev->sdev_dev);
        put_device(&sdev->sdev_gendev);
 
        return error;
@@ -1065,7 +1062,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
                     sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
 
        device_initialize(&sdev->sdev_dev);
-       sdev->sdev_dev.parent = &sdev->sdev_gendev;
+       sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
        sdev->sdev_dev.class = &sdev_class;
        dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d",
                     sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
index e7108e7..42e8550 100644 (file)
@@ -1561,11 +1561,16 @@ enum pci_board_num_t {
        pbn_exar_XR17C152,
        pbn_exar_XR17C154,
        pbn_exar_XR17C158,
+       pbn_exar_ibm_saturn,
        pbn_pasemi_1682M,
        pbn_ni8430_2,
        pbn_ni8430_4,
        pbn_ni8430_8,
        pbn_ni8430_16,
+       pbn_ADDIDATA_PCIe_1_3906250,
+       pbn_ADDIDATA_PCIe_2_3906250,
+       pbn_ADDIDATA_PCIe_4_3906250,
+       pbn_ADDIDATA_PCIe_8_3906250,
 };
 
 /*
@@ -2146,6 +2151,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .base_baud      = 921600,
                .uart_offset    = 0x200,
        },
+       [pbn_exar_ibm_saturn] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .uart_offset    = 0x200,
+       },
+
        /*
         * PA Semi PWRficient PA6T-1682M on-chip UART
         */
@@ -2185,6 +2197,37 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .uart_offset    = 0x10,
                .first_offset   = 0x800,
        },
+       /*
+        * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com>
+        */
+       [pbn_ADDIDATA_PCIe_1_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_2_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_4_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 4,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+       [pbn_ADDIDATA_PCIe_8_3906250] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+               .base_baud      = 3906250,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
 };
 
 static const struct pci_device_id softmodem_blacklist[] = {
@@ -2649,6 +2692,9 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_SUBVENDOR_ID_CONNECT_TECH,
                PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
                pbn_b0_8_1843200_200 },
+       {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+               PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT,
+               0, 0, pbn_exar_ibm_saturn },
 
        {       PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -3556,6 +3602,38 @@ static struct pci_device_id serial_pci_tbl[] = {
                0,
                pbn_b0_8_115200 },
 
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7500,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_4_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7420,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_2_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7300,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_1_3906250 },
+
+       {       PCI_VENDOR_ID_ADDIDATA,
+               PCI_DEVICE_ID_ADDIDATA_APCIe7800,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
+               0,
+               0,
+               pbn_ADDIDATA_PCIe_8_3906250 },
+
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
                PCI_VENDOR_ID_IBM, 0x0299,
                0, 0, pbn_b0_bt_2_115200 },
index 3551c5c..9d948bc 100644 (file)
@@ -1531,7 +1531,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
        void *data;
        int ret;
 
-       BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
+       BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
        port = &atmel_ports[pdev->id];
        port->backup_imr = 0;
index d7bcd07..7ce9e9f 100644 (file)
@@ -705,7 +705,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
                return -EINVAL;
 
        if ((ser->irq != port->irq) ||
-           (ser->io_type != SERIAL_IO_MEM) ||
+           (ser->io_type != UPIO_MEM) ||
            (ser->baud_base != port->uartclk)  ||
            (ser->iomem_base != (void *)port->mapbase) ||
            (ser->hub6 != 0))
index 1689bda..dcc7244 100644 (file)
@@ -1270,6 +1270,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 
        BUG_ON(!kernel_locked());
 
+       if (!state)
+               return;
+
        uport = state->uart_port;
        port = &state->port;
 
@@ -1316,9 +1319,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
         */
        if (port->flags & ASYNC_INITIALIZED) {
                unsigned long flags;
-               spin_lock_irqsave(&port->lock, flags);
+               spin_lock_irqsave(&uport->lock, flags);
                uport->ops->stop_rx(uport);
-               spin_unlock_irqrestore(&port->lock, flags);
+               spin_unlock_irqrestore(&uport->lock, flags);
                /*
                 * Before we drop DTR, make sure the UART transmitter
                 * has completely drained; this is especially
index 958a3ff..ff5bbb9 100644 (file)
@@ -1826,7 +1826,7 @@ static struct amba_id pl022_ids[] = {
                 * ST Micro derivative, this has 32bit wide
                 * and 32 locations deep TX/RX FIFO
                 */
-               .id     = 0x00108022,
+               .id     = 0x01080022,
                .mask   = 0xffffffff,
                .data   = &vendor_st,
        },
index 7df3ba4..d21b346 100644 (file)
@@ -93,8 +93,6 @@ source "drivers/staging/dst/Kconfig"
 
 source "drivers/staging/pohmelfs/Kconfig"
 
-source "drivers/staging/stlc45xx/Kconfig"
-
 source "drivers/staging/b3dfg/Kconfig"
 
 source "drivers/staging/phison/Kconfig"
index 7475711..8cbf1ae 100644 (file)
@@ -29,7 +29,6 @@ obj-$(CONFIG_ANDROID)         += android/
 obj-$(CONFIG_ANDROID)          += dream/
 obj-$(CONFIG_DST)              += dst/
 obj-$(CONFIG_POHMELFS)         += pohmelfs/
-obj-$(CONFIG_STLC45XX)         += stlc45xx/
 obj-$(CONFIG_B3DFG)            += b3dfg/
 obj-$(CONFIG_IDE_PHISON)       += phison/
 obj-$(CONFIG_PLAN9AUTH)                += p9auth/
index 2471949..eb67563 100644 (file)
@@ -2,6 +2,7 @@ menu "Android"
 
 config ANDROID
        bool "Android Drivers"
+       depends on BROKEN
        default N
        ---help---
          Enable support for various drivers needed on the Android platform
index 94c5d27..cda26bb 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/sched.h>
 
 static unsigned int b3dfg_nbuf = 2;
 
index 2cda7ad..80e192d 100644 (file)
@@ -51,6 +51,7 @@ from http://www.comedi.org
 */
 
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include "../comedidev.h"
 
 #include "comedi_pci.h"
index e3ffb06..753ee05 100644 (file)
@@ -62,6 +62,7 @@
 /* #define DEBUG_STATUS_B */
 
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include "8255.h"
 #include "mite.h"
 #include "comedi_fc.h"
index 52b2eca..d544698 100644 (file)
@@ -70,6 +70,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
 /* #define DEBUG_FLAGS */
 
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include "../comedidev.h"
 
 #include "mite.h"
index 6294d38..2c3d65a 100644 (file)
@@ -223,7 +223,7 @@ typedef union _TXDMA_PR_NUM_DES_t {
 
 extern inline void add_10bit(u32 *v, int n)
 {
-       *v = INDEX10(*v + n);
+       *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP);
 }
 
 /*
index 8f2e91f..10e21db 100644 (file)
@@ -1177,12 +1177,20 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
 
 static inline u32 bump_fbr(u32 *fbr, u32 limit)
 {
-       u32 v = *fbr;
-       add_10bit(&v, 1);
-       if (v > limit)
-               v = (*fbr & ~ET_DMA10_MASK) ^ ET_DMA10_WRAP;
-       *fbr = v;
-       return v;
+        u32 v = *fbr;
+        v++;
+        /* This works for all cases where limit < 1024. The 1023 case
+           works because 1023++ is 1024 which means the if condition is not
+           taken but the carry of the bit into the wrap bit toggles the wrap
+           value correctly */
+        if ((v & ET_DMA10_MASK) > limit) {
+                v &= ~ET_DMA10_MASK;
+                v ^= ET_DMA10_WRAP;
+        }
+        /* For the 1023 case */
+        v &= (ET_DMA10_MASK|ET_DMA10_WRAP);
+        *fbr = v;
+        return v;
 }
 
 /**
index a839d8f..fa973d8 100644 (file)
@@ -26,6 +26,7 @@
 #define _CHANNEL_MGMT_H_
 
 #include <linux/list.h>
+#include <linux/timer.h>
 #include "RingBuffer.h"
 #include "VmbusChannelInterface.h"
 #include "VmbusPacketFormat.h"
@@ -54,7 +55,7 @@ enum vmbus_channel_message_type {
        ChannelMessageViewRangeRemove           = 18,
 #endif
        ChannelMessageCount
-} __attribute__((packed));
+};
 
 struct vmbus_channel_message_header {
        enum vmbus_channel_message_type MessageType;
index 1610b84..d384c0d 100644 (file)
@@ -1052,7 +1052,7 @@ static void NetVscOnReceive(struct hv_device *Device,
         */
        spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
        while (!list_empty(&netDevice->ReceivePacketList)) {
-               list_move_tail(&netDevice->ReceivePacketList, &listHead);
+               list_move_tail(netDevice->ReceivePacketList.next, &listHead);
                if (++count == vmxferpagePacket->RangeCount + 1)
                        break;
        }
@@ -1071,7 +1071,7 @@ static void NetVscOnReceive(struct hv_device *Device,
                /* Return it to the freelist */
                spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
                for (i = count; i != 0; i--) {
-                       list_move_tail(&listHead,
+                       list_move_tail(listHead.next,
                                       &netDevice->ReceivePacketList);
                }
                spin_unlock_irqrestore(&netDevice->receive_packet_list_lock,
@@ -1085,8 +1085,7 @@ static void NetVscOnReceive(struct hv_device *Device,
        }
 
        /* Remove the 1st packet to represent the xfer page packet itself */
-       xferpagePacket = list_entry(&listHead, struct xferpage_packet,
-                                   ListEntry);
+       xferpagePacket = (struct xferpage_packet*)listHead.next;
        list_del(&xferpagePacket->ListEntry);
 
        /* This is how much we can satisfy */
@@ -1102,8 +1101,7 @@ static void NetVscOnReceive(struct hv_device *Device,
 
        /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
        for (i = 0; i < (count - 1); i++) {
-               netvscPacket = list_entry(&listHead, struct hv_netvsc_packet,
-                                         ListEntry);
+               netvscPacket = (struct hv_netvsc_packet*)listHead.next;
                list_del(&netvscPacket->ListEntry);
 
                /* Initialize the netvsc packet */
index 4d390b2..dbfbde9 100644 (file)
@@ -1,11 +1,17 @@
 TODO:
        - fix remaining checkpatch warnings and errors
+       - use of /** when it is not a kerneldoc header
        - remove RingBuffer.c to us in-kernel ringbuffer functions instead.
        - audit the vmbus to verify it is working properly with the
          driver model
+       - convert vmbus driver interface function pointer tables
+          to constant, a.k.a vmbus_ops
        - see if the vmbus can be merged with the other virtual busses
          in the kernel
        - audit the network driver
+         - use existing net_device_stats struct in network device
+         - checking for carrier inside open is wrong, network device API
+            confusion??
        - audit the block driver
        - audit the scsi driver
 
index 8fe543b..3a4793a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
index 9504604..ce064e8 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef _OSD_H_
 #define _OSD_H_
 
+#include <linux/workqueue.h>
 
 /* Defines */
 #define ALIGN_UP(value, align) (((value) & (align-1)) ?                \
index 582318f..894eecf 100644 (file)
@@ -507,12 +507,12 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
 
        child_device_obj = &child_device_ctx->device_obj;
        child_device_obj->context = context;
-       memcpy(&child_device_obj->deviceType, &type, sizeof(struct hv_guid));
-       memcpy(&child_device_obj->deviceInstance, &instance,
+       memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid));
+       memcpy(&child_device_obj->deviceInstance, instance,
               sizeof(struct hv_guid));
 
-       memcpy(&child_device_ctx->class_id, &type, sizeof(struct hv_guid));
-       memcpy(&child_device_ctx->device_id, &instance, sizeof(struct hv_guid));
+       memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid));
+       memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid));
 
        DPRINT_EXIT(VMBUS_DRV);
 
@@ -537,18 +537,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
        DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
                   child_device_ctx);
 
-       /* Make sure we are not registered already */
-       if (strlen(dev_name(&child_device_ctx->device)) != 0) {
-               DPRINT_ERR(VMBUS_DRV,
-                          "child device (%p) already registered - busid %s",
-                          child_device_ctx,
-                          dev_name(&child_device_ctx->device));
-
-               ret = -1;
-               goto Cleanup;
-       }
-
-       /* Set the device bus id. Otherwise, device_register()will fail. */
+       /* Set the device name. Otherwise, device_register() will fail. */
        dev_set_name(&child_device_ctx->device, "vmbus_0_%d",
                     atomic_inc_return(&device_num));
 
@@ -573,7 +562,6 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
                DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
                            &child_device_ctx->device);
 
-Cleanup:
        DPRINT_EXIT(VMBUS_DRV);
 
        return ret;
@@ -623,8 +611,6 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj)
 static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
 {
        struct device_context *device_ctx = device_to_device_context(device);
-       int i = 0;
-       int len = 0;
        int ret;
 
        DPRINT_ENTER(VMBUS_DRV);
@@ -644,8 +630,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
                    device_ctx->class_id.data[14],
                    device_ctx->class_id.data[15]);
 
-       env->envp_idx = i;
-       env->buflen = len;
        ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
                             "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
                             "%02x%02x%02x%02x%02x%02x%02x%02x}",
@@ -691,8 +675,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
        if (ret)
                return ret;
 
-       env->envp[env->envp_idx] = NULL;
-
        DPRINT_EXIT(VMBUS_DRV);
 
        return 0;
index 1fa18f2..768f448 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
 #include <linux/cdev.h>
 #include "iio.h"
 #include "trigger_consumer.h"
index d549d08..f6cc262 100644 (file)
@@ -1,6 +1,6 @@
 config OTUS
        tristate "Atheros OTUS 802.11n USB wireless support"
-       depends on USB && WLAN_80211 && MAC80211
+       depends on USB && WLAN && MAC80211
        default N
        ---help---
          Enable support for Atheros 802.11n USB hardware:
index dd7d3fd..4ce399b 100644 (file)
@@ -2071,11 +2071,15 @@ static void panel_detach(struct parport *port)
                return;
        }
 
-       if (keypad_enabled && keypad_initialized)
+       if (keypad_enabled && keypad_initialized) {
                misc_deregister(&keypad_dev);
+               keypad_initialized = 0;
+       }
 
-       if (lcd_enabled && lcd_initialized)
+       if (lcd_enabled && lcd_initialized) {
                misc_deregister(&lcd_dev);
+               lcd_initialized = 0;
+       }
 
        parport_release(pprt);
        parport_unregister_device(pprt);
@@ -2211,13 +2215,16 @@ static void __exit panel_cleanup_module(void)
                del_timer(&scan_timer);
 
        if (pprt != NULL) {
-               if (keypad_enabled)
+               if (keypad_enabled) {
                        misc_deregister(&keypad_dev);
+                       keypad_initialized = 0;
+               }
 
                if (lcd_enabled) {
                        panel_lcd_print("\x0cLCD driver " PANEL_VERSION
                                        "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
                        misc_deregister(&lcd_dev);
+                       lcd_initialized = 0;
                }
 
                /* TODO: free all input signals */
index 0d111dd..2eb8e3d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/ioctl.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include "poch.h"
 
index 7f44e5e..efe38e2 100644 (file)
@@ -1,5 +1,5 @@
 config RT2860
        tristate "Ralink 2860 wireless support"
-       depends on PCI && X86 && WLAN_80211
+       depends on PCI && X86 && WLAN
        ---help---
          This is an experimental driver for the Ralink 2860 wireless chip.
index fb17355..857ff45 100644 (file)
@@ -363,6 +363,8 @@ int RtmpPCIMgmtKickOut(
        ULONG                   SwIdx = pAd->MgmtRing.TxCpuIdx;
 
        pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
+       if (!pTxD)
+               return 0;
 
        pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
        pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
index 9d589c2..019cc44 100644 (file)
@@ -25,6 +25,7 @@
  *************************************************************************
 */
 
+#include <linux/sched.h>
 #include "../rt_config.h"
 
 INT    Show_SSID_Proc(
index b396a9b..ed27b85 100644 (file)
@@ -25,6 +25,7 @@
  *************************************************************************
  */
 
+#include <linux/sched.h>
 #include "rt_config.h"
 
 ULONG  RTDebugLevel = RT_DEBUG_ERROR;
index 76841f6..aea5c82 100644 (file)
@@ -1,5 +1,5 @@
 config RT2870
        tristate "Ralink 2870/3070 wireless support"
-       depends on USB && X86 && WLAN_80211
+       depends on USB && X86 && WLAN
        ---help---
          This is an experimental driver for the Ralink xx70 wireless chips.
index 255e8ea..2b3f745 100644 (file)
@@ -1,5 +1,5 @@
 config RT3090
        tristate "Ralink 3090 wireless support"
-       depends on PCI && X86 && WLAN_80211
+       depends on PCI && X86 && WLAN
        ---help---
          This is an experimental driver for the Ralink 3090 wireless chip.
index 5be0714..3e51e98 100644 (file)
@@ -34,6 +34,7 @@
     ---------    ----------    ----------------------------------------------
  */
 
+#include <linux/sched.h>
 #include "../rt_config.h"
 
 
index d2241ec..9b94aa6 100644 (file)
@@ -25,6 +25,7 @@
  *************************************************************************
  */
 
+#include <linux/sched.h>
 #include "rt_config.h"
 
 ULONG  RTDebugLevel = RT_DEBUG_ERROR;
index 236e427..203c79b 100644 (file)
@@ -1,6 +1,6 @@
 config RTL8187SE
        tristate "RealTek RTL8187SE Wireless LAN NIC driver"
-       depends on PCI
+       depends on PCI && WLAN
        depends on WIRELESS_EXT
        default N
        ---help---
index 013c3e1..4c5d63f 100644 (file)
@@ -53,10 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
 
                list_del(ptr);
 
-               if (entry->ops) {
+               if (entry->ops)
                        entry->ops->deinit(entry->priv);
-                       module_put(entry->ops->owner);
-               }
                kfree(entry);
        }
 }
index 6fbe489..18392fc 100644 (file)
@@ -189,10 +189,8 @@ void free_ieee80211(struct net_device *dev)
        for (i = 0; i < WEP_KEYS; i++) {
                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
                if (crypt) {
-                       if (crypt->ops) {
+                       if (crypt->ops)
                                crypt->ops->deinit(crypt->priv);
-                               module_put(crypt->ops->owner);
-                       }
                        kfree(crypt);
                        ieee->crypt[i] = NULL;
                }
index 59b2ab4..334e4c7 100644 (file)
@@ -2839,16 +2839,12 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                goto skip_host_crypt;
 
        ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
+       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       }
        if (ops == NULL) {
                printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
                param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -2869,7 +2865,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                }
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+               if (new_crypt->ops)
                        new_crypt->priv =
                                new_crypt->ops->init(param->u.crypt.idx);
 
index 8d8bdd0..a08b97a 100644 (file)
@@ -331,12 +331,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                        return -ENOMEM;
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
+               if (!new_crypt->ops)
                        new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               }
 
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+               if (new_crypt->ops)
                        new_crypt->priv = new_crypt->ops->init(key);
 
                if (!new_crypt->ops || !new_crypt->priv) {
@@ -483,7 +481,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
         int i, idx, ret = 0;
         int group_key = 0;
-        const char *alg, *module;
+        const char *alg;
         struct ieee80211_crypto_ops *ops;
         struct ieee80211_crypt_data **crypt;
 
@@ -539,15 +537,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
                 alg = "WEP";
-                module = "ieee80211_crypt_wep";
                 break;
         case IW_ENCODE_ALG_TKIP:
                 alg = "TKIP";
-                module = "ieee80211_crypt_tkip";
                 break;
         case IW_ENCODE_ALG_CCMP:
                 alg = "CCMP";
-                module = "ieee80211_crypt_ccmp";
                 break;
         default:
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -558,10 +553,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
 //     printk("8-09-08-9=====>%s, alg name:%s\n",__func__, alg);
 
         ops = ieee80211_get_crypto_ops(alg);
-        if (ops == NULL) {
-                request_module(module);
+        if (ops == NULL)
                 ops = ieee80211_get_crypto_ops(alg);
-        }
         if (ops == NULL) {
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
                                    dev->name, ext->alg);
@@ -581,7 +574,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                         goto done;
                 }
                 new_crypt->ops = ops;
-                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                if (new_crypt->ops)
                         new_crypt->priv = new_crypt->ops->init(idx);
                 if (new_crypt->priv == NULL) {
                         kfree(new_crypt);
index 3100aa5..37e4fde 100644 (file)
@@ -1,6 +1,6 @@
 config RTL8192E
        tristate "RealTek RTL8192E Wireless LAN NIC driver"
-       depends on PCI
+       depends on PCI && WLAN
        depends on WIRELESS_EXT
        default N
        ---help---
index 1a8ea8a..b1c5493 100644 (file)
@@ -53,14 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
 
                list_del(ptr);
 
-               if (entry->ops) {
+               if (entry->ops)
                        entry->ops->deinit(entry->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                       module_put(entry->ops->owner);
-#else
-                       __MOD_DEC_USE_COUNT(entry->ops->owner);
-#endif
-               }
                kfree(entry);
        }
 }
index 16256a3..12c2a18 100644 (file)
@@ -242,14 +242,8 @@ void free_ieee80211(struct net_device *dev)
        for (i = 0; i < WEP_KEYS; i++) {
                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
                if (crypt) {
-                       if (crypt->ops) {
+                       if (crypt->ops)
                                crypt->ops->deinit(crypt->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-                               module_put(crypt->ops->owner);
-#else
-                               __MOD_DEC_USE_COUNT(crypt->ops->owner);
-#endif
-                       }
                        kfree(crypt);
                        ieee->crypt[i] = NULL;
                }
index 2fc04df..eae7c45 100644 (file)
@@ -3284,17 +3284,14 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                goto skip_host_crypt;
 
        ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
+       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-               //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
+               /* set WEP40 first, it will be modified according to WEP104 or
+                * WEP40 at other place */
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       }
        if (ops == NULL) {
                printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
                param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -3315,11 +3312,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                }
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
-               if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
+               if (new_crypt->ops)
                        new_crypt->priv =
                                new_crypt->ops->init(param->u.crypt.idx);
 
index 2234831..4e34a1f 100644 (file)
@@ -482,15 +482,9 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                        return -ENOMEM;
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
+               if (!new_crypt->ops)
                        new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
-               if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
+               if (new_crypt->ops)
                        new_crypt->priv = new_crypt->ops->init(key);
 
                if (!new_crypt->ops || !new_crypt->priv) {
@@ -644,7 +638,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
         int i, idx;
         int group_key = 0;
-        const char *alg, *module;
+        const char *alg;
         struct ieee80211_crypto_ops *ops;
         struct ieee80211_crypt_data **crypt;
 
@@ -711,15 +705,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
                 alg = "WEP";
-                module = "ieee80211_crypt_wep";
                 break;
         case IW_ENCODE_ALG_TKIP:
                 alg = "TKIP";
-                module = "ieee80211_crypt_tkip";
                 break;
         case IW_ENCODE_ALG_CCMP:
                 alg = "CCMP";
-                module = "ieee80211_crypt_ccmp";
                 break;
         default:
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -730,10 +721,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
        printk("alg name:%s\n",alg);
 
         ops = ieee80211_get_crypto_ops(alg);
-        if (ops == NULL) {
-                request_module(module);
+        if (ops == NULL)
                 ops = ieee80211_get_crypto_ops(alg);
-        }
         if (ops == NULL) {
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
                                    dev->name, ext->alg);
@@ -758,7 +747,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                         goto done;
                 }
                 new_crypt->ops = ops;
-                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                if (new_crypt->ops)
                         new_crypt->priv = new_crypt->ops->init(idx);
                 if (new_crypt->priv == NULL) {
                         kfree(new_crypt);
index 770f412..b8c95f9 100644 (file)
@@ -1,6 +1,6 @@
 config RTL8192SU
        tristate "RealTek RTL8192SU Wireless LAN NIC driver"
-       depends on PCI
+       depends on PCI && WLAN
        depends on WIRELESS_EXT
        default N
        ---help---
index d76a54d..521e7b9 100644 (file)
@@ -53,10 +53,8 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
 
                list_del(ptr);
 
-               if (entry->ops) {
+               if (entry->ops)
                        entry->ops->deinit(entry->priv);
-                       module_put(entry->ops->owner);
-               }
                kfree(entry);
        }
 }
index 68dc8fa..c3383bb 100644 (file)
@@ -216,10 +216,8 @@ void free_ieee80211(struct net_device *dev)
        for (i = 0; i < WEP_KEYS; i++) {
                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
                if (crypt) {
-                       if (crypt->ops) {
+                       if (crypt->ops)
                                crypt->ops->deinit(crypt->priv);
-                               module_put(crypt->ops->owner);
-                       }
                        kfree(crypt);
                        ieee->crypt[i] = NULL;
                }
index c64ae03..fd8e112 100644 (file)
@@ -3026,17 +3026,14 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                goto skip_host_crypt;
 
        ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
+       if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-               //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
+               /* set WEP40 first, it will be modified according to WEP104 or
+                * WEP40 at other place */
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
+       else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
                ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-       }
        if (ops == NULL) {
                printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
                param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
@@ -3058,7 +3055,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
 
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+               if (new_crypt->ops)
                        new_crypt->priv =
                                new_crypt->ops->init(param->u.crypt.idx);
 
index 1077590..6146c64 100644 (file)
@@ -358,11 +358,9 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                        return -ENOMEM;
                memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
+               if (!new_crypt->ops)
                        new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-               }
-               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+               if (new_crypt->ops)
                        new_crypt->priv = new_crypt->ops->init(key);
 
                if (!new_crypt->ops || !new_crypt->priv) {
@@ -507,7 +505,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
         int i, idx;
         int group_key = 0;
-        const char *alg, *module;
+        const char *alg;
         struct ieee80211_crypto_ops *ops;
         struct ieee80211_crypt_data **crypt;
 
@@ -570,15 +568,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
                 alg = "WEP";
-                module = "ieee80211_crypt_wep";
                 break;
         case IW_ENCODE_ALG_TKIP:
                 alg = "TKIP";
-                module = "ieee80211_crypt_tkip";
                 break;
         case IW_ENCODE_ALG_CCMP:
                 alg = "CCMP";
-                module = "ieee80211_crypt_ccmp";
                 break;
         default:
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -589,10 +584,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
        printk("alg name:%s\n",alg);
 
         ops = ieee80211_get_crypto_ops(alg);
-        if (ops == NULL) {
-                request_module("%s", module);
+        if (ops == NULL)
                 ops = ieee80211_get_crypto_ops(alg);
-        }
         if (ops == NULL) {
                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
                                    dev->name, ext->alg);
@@ -612,7 +605,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                         goto done;
                 }
                 new_crypt->ops = ops;
-                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                if (new_crypt->ops)
                         new_crypt->priv = new_crypt->ops->init(idx);
                 if (new_crypt->priv == NULL) {
                         kfree(new_crypt);
index 87f8a11..f890a16 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mm.h>
 #include <linux/poll.h>
 #include <linux/wait.h>
+#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <asm/ioctl.h>
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
deleted file mode 100644 (file)
index 947fb75..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-config STLC45XX
-       tristate "stlc4550/4560 support"
-       depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS
-       ---help---
-         This is a driver for stlc4550 and stlc4560 chipsets.
-
-         To compile this driver as a module, choose M here: the module will be
-         called stlc45xx.  If unsure, say N.
diff --git a/drivers/staging/stlc45xx/Makefile b/drivers/staging/stlc45xx/Makefile
deleted file mode 100644 (file)
index 7ee3290..0000000
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_STLC45XX) += stlc45xx.o
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
deleted file mode 100644 (file)
index be99eb3..0000000
+++ /dev/null
@@ -1,2594 +0,0 @@
-/*
- * This file is part of stlc45xx
- *
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "stlc45xx.h"
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/spi/spi.h>
-#include <linux/etherdevice.h>
-#include <linux/gpio.h>
-#include <linux/moduleparam.h>
-
-#include "stlc45xx_lmac.h"
-
-/*
- * gpios should be handled in board files and provided via platform data,
- * but because it's currently impossible for stlc45xx to have a header file
- * in include/linux, let's use module paramaters for now
- */
-static int stlc45xx_gpio_power = 97;
-module_param(stlc45xx_gpio_power, int, 0444);
-MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
-
-static int stlc45xx_gpio_irq = 87;
-module_param(stlc45xx_gpio_irq, int, 0444);
-MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
-
-static const u8 default_cal_channels[] = {
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
-       0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
-       0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
-       0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
-       0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
-       0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
-       0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
-       0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
-       0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
-       0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
-       0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
-       0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
-       0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
-       0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
-       0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
-       0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
-       0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
-       0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
-       0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
-       0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
-       0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
-       0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
-       0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
-       0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
-       0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
-       0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
-       0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
-       0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
-       0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
-       0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
-       0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
-       0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
-       0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
-       0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
-       0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
-       0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
-       0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
-       0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
-       0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
-       0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
-       0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
-       0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
-       0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
-       0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
-       0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
-       0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
-       0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
-       0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
-       0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
-       0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
-       0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
-       0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
-       0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
-       0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
-       0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
-       0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
-       0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
-       0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-       0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
-       0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
-       0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
-       0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
-       0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
-       0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
-       0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
-       0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
-       0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
-       0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
-       0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
-       0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
-       0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
-       0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
-       0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
-       0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
-       0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
-       0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
-       0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
-       0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
-       0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
-       0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
-       0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
-       0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
-       0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
-       0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
-       0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
-       0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
-       0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
-       0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
-       0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
-       0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
-       0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
-       0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
-       0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
-       0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
-       0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
-       0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
-       0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
-       0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
-       0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
-       0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
-       0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
-       0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
-       0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
-       0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
-       0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
-       0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
-       0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
-       0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
-       0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
-       0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
-       0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
-       0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
-       0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
-       0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
-       0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
-       0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
-       0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00 };
-
-static const u8 default_cal_rssi[] = {
-       0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
-       0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
-       0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
-       0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
-       0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
-       0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
-       0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
-       0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
-static void stlc45xx_tx_setup(struct stlc45xx *stlc);
-static void stlc45xx_tx_scan(struct stlc45xx *stlc);
-static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
-static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
-static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
-
-static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
-                                           struct device_attribute *attr,
-                                           char *buf)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(dev);
-       ssize_t len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       len = PAGE_SIZE;
-
-       mutex_lock(&stlc->mutex);
-
-       if (stlc->cal_rssi)
-               hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
-                                  2, buf, len, 0);
-       mutex_unlock(&stlc->mutex);
-
-       len = strlen(buf);
-
-       return len;
-}
-
-static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
-                                            struct device_attribute *attr,
-                                            const char *buf, size_t count)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(dev);
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       if (count != RSSI_CAL_ARRAY_LEN) {
-               stlc45xx_error("invalid cal_rssi length: %zu", count);
-               count = 0;
-               goto out_unlock;
-       }
-
-       kfree(stlc->cal_rssi);
-
-       stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
-
-       if (!stlc->cal_rssi) {
-               stlc45xx_error("failed to allocate memory for cal_rssi");
-               count = 0;
-               goto out_unlock;
-       }
-
- out_unlock:
-       mutex_unlock(&stlc->mutex);
-
-       return count;
-}
-
-static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
-                                               struct device_attribute *attr,
-                                               char *buf)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(dev);
-       ssize_t len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       len = PAGE_SIZE;
-
-       mutex_lock(&stlc->mutex);
-
-       if (stlc->cal_channels)
-               hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
-                                  16, 2, buf, len, 0);
-
-       mutex_unlock(&stlc->mutex);
-
-       len = strlen(buf);
-
-       return len;
-}
-
-static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
-                                                struct device_attribute *attr,
-                                                const char *buf, size_t count)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(dev);
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       if (count != CHANNEL_CAL_ARRAY_LEN) {
-               stlc45xx_error("invalid cal_channels size: %zu ", count);
-               count = 0;
-               goto out_unlock;
-       }
-
-       kfree(stlc->cal_channels);
-
-       stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
-
-       if (!stlc->cal_channels) {
-               stlc45xx_error("failed to allocate memory for cal_channels");
-               count = 0;
-               goto out_unlock;
-       }
-
-out_unlock:
-       mutex_unlock(&stlc->mutex);
-
-       return count;
-}
-
-static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
-                                         struct device_attribute *attr,
-                                         char *buf)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(dev);
-       struct txbuffer *entry;
-       ssize_t len = 0;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
-               len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
-                              entry->handle, entry->start,
-                              entry->end);
-       }
-
-       mutex_unlock(&stlc->mutex);
-
-       return len;
-}
-
-static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
-                  stlc45xx_sysfs_show_cal_rssi,
-                  stlc45xx_sysfs_store_cal_rssi);
-static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
-                  stlc45xx_sysfs_show_cal_channels,
-                  stlc45xx_sysfs_store_cal_channels);
-static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
-
-static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
-                             void *buf, size_t len)
-{
-       struct spi_transfer t[2];
-       struct spi_message m;
-
-       /* We first push the address */
-       addr = (addr << 8) | ADDR_READ_BIT_15;
-
-       spi_message_init(&m);
-       memset(t, 0, sizeof(t));
-
-       t[0].tx_buf = &addr;
-       t[0].len = 2;
-       spi_message_add_tail(&t[0], &m);
-
-       t[1].rx_buf = buf;
-       t[1].len = len;
-       spi_message_add_tail(&t[1], &m);
-
-       spi_sync(stlc->spi, &m);
-}
-
-
-static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
-                              void *buf, size_t len)
-{
-       struct spi_transfer t[3];
-       struct spi_message m;
-       u16 last_word;
-
-       /* We first push the address */
-       addr = addr << 8;
-
-       spi_message_init(&m);
-       memset(t, 0, sizeof(t));
-
-       t[0].tx_buf = &addr;
-       t[0].len = 2;
-       spi_message_add_tail(&t[0], &m);
-
-       t[1].tx_buf = buf;
-       t[1].len = len;
-       spi_message_add_tail(&t[1], &m);
-
-       if (len % 2) {
-               last_word = ((u8 *)buf)[len - 1];
-
-               t[2].tx_buf = &last_word;
-               t[2].len = 2;
-               spi_message_add_tail(&t[2], &m);
-       }
-
-       spi_sync(stlc->spi, &m);
-}
-
-static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
-{
-       u16 val;
-
-       stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
-
-       return val;
-}
-
-static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
-{
-       u32 val;
-
-       stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
-
-       return val;
-}
-
-static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
-{
-       stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
-}
-
-static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
-{
-       stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
-}
-
-struct stlc45xx_spi_reg {
-       u16 address;
-       u16 length;
-       char *name;
-};
-
-/* caller must hold tx_lock */
-static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
-{
-       struct txbuffer *txbuffer;
-       char *buf, *pos;
-       int buf_len, l, count;
-
-       if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
-               return;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
-       buf_len = 500;
-       buf = kmalloc(buf_len, GFP_ATOMIC);
-       if (!buf)
-               return;
-
-       pos = buf;
-       count = 0;
-
-       list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
-               l = snprintf(pos, buf_len, "0x%x-0x%x,",
-                            txbuffer->start, txbuffer->end);
-               /* drop the null byte */
-               pos += l;
-               buf_len -= l;
-               count++;
-       }
-
-       if (count == 0)
-               *pos = '\0';
-       else
-               *--pos = '\0';
-
-       stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
-                      count, buf);
-
-       kfree(buf);
-}
-
-/* caller must hold tx_lock */
-static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
-{
-       struct txbuffer *txbuffer;
-       int pos;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
-       pos = FIRMWARE_TXBUFFER_START;
-
-       if (list_empty(&stlc->txbuffer))
-               goto out;
-
-       /*
-        * the entries in txbuffer must be in the same order as they are in
-        * the real buffer
-        */
-       list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
-               if (pos + len < txbuffer->start)
-                       break;
-               pos = ALIGN(txbuffer->end + 1, 4);
-       }
-
-       if (pos + len > FIRMWARE_TXBUFFER_END)
-               /* not enough room */
-               pos = -1;
-
-       stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
-
-out:
-       return pos;
-}
-
-static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
-                                struct txbuffer *txbuffer)
-{
-       struct txbuffer *r, *prev = NULL;
-
-       if (list_empty(&stlc->txbuffer)) {
-               list_add(&txbuffer->buffer_list, &stlc->txbuffer);
-               return 0;
-       }
-
-       r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
-
-       if (txbuffer->start < r->start) {
-               /* add to the beginning of the list */
-               list_add(&txbuffer->buffer_list, &stlc->txbuffer);
-               return 0;
-       }
-
-       prev = NULL;
-       list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
-               /* skip first entry, we checked for that above */
-               if (!prev) {
-                       prev = r;
-                       continue;
-               }
-
-               /* double-check overlaps */
-               WARN_ON_ONCE(txbuffer->start >= r->start &&
-                            txbuffer->start <= r->end);
-               WARN_ON_ONCE(txbuffer->end >= r->start &&
-                            txbuffer->end <= r->end);
-
-               if (prev->end < txbuffer->start &&
-                   txbuffer->end < r->start) {
-                       /* insert at this spot */
-                       list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
-                       return 0;
-               }
-
-               prev = r;
-       }
-
-       /* not found */
-       list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
-
-       return 0;
-
-}
-
-/* caller must hold tx_lock */
-static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
-                                                size_t frame_len)
-{
-       struct txbuffer *entry = NULL;
-       size_t len;
-       int pos;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
-       len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
-       pos = stlc45xx_txbuffer_find(stlc, len);
-
-       if (pos < 0)
-               return NULL;
-
-       WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
-       WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
-
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       entry->start = pos;
-       entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
-       entry->end = entry->start + len - 1;
-
-       stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
-                      entry->start, entry->end);
-
-       stlc45xx_txbuffer_add(stlc, entry);
-
-       stlc45xx_txbuffer_dump(stlc);
-
-       return entry;
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
-                                  struct txbuffer *txbuffer)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
-
-       stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
-                      txbuffer->start, txbuffer->end);
-
-       list_del(&txbuffer->buffer_list);
-       kfree(txbuffer);
-}
-
-
-static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
-                            u32 expected)
-{
-       int i;
-       char buffer[4];
-
-       for (i = 0; i < 2000; i++) {
-               stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
-               if (((*(u32 *)buffer) & mask) == expected)
-                       return 1;
-               msleep(1);
-       }
-
-       return 0;
-}
-
-static int stlc45xx_request_firmware(struct stlc45xx *stlc)
-{
-       const struct firmware *fw;
-       int ret;
-
-       /* FIXME: should driver use it's own struct device? */
-       ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
-
-       if (ret < 0) {
-               stlc45xx_error("request_firmware() failed: %d", ret);
-               return ret;
-       }
-
-       if (fw->size % 4) {
-               stlc45xx_error("firmware size is not multiple of 32bit: %zu",
-                              fw->size);
-               return -EILSEQ; /* Illegal byte sequence  */;
-       }
-
-       if (fw->size < 1000) {
-               stlc45xx_error("firmware is too small: %zu", fw->size);
-               return -EILSEQ;
-       }
-
-       stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
-       if (!stlc->fw) {
-               stlc45xx_error("could not allocate memory for firmware");
-               return -ENOMEM;
-       }
-
-       stlc->fw_len = fw->size;
-
-       release_firmware(fw);
-
-       return 0;
-}
-
-static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
-{
-       struct s_dma_regs dma_regs;
-       unsigned long fw_len, fw_addr;
-       long _fw_len;
-       int ret;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       if (!stlc->fw) {
-               ret = stlc45xx_request_firmware(stlc);
-               if (ret < 0)
-                       return ret;
-       }
-
-       /* stop the device */
-       stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
-                        SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
-                        | SPI_CTRL_STAT_START_HALTED);
-
-       msleep(TARGET_BOOT_SLEEP);
-
-       stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
-                        SPI_CTRL_STAT_HOST_OVERRIDE
-                        | SPI_CTRL_STAT_START_HALTED);
-
-       msleep(TARGET_BOOT_SLEEP);
-
-       fw_addr = FIRMWARE_ADDRESS;
-       fw_len = stlc->fw_len;
-
-       while (fw_len > 0) {
-               _fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
-                       ? SPI_MAX_PACKET_SIZE : fw_len;
-               dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
-               dma_regs.len = cpu_to_le16(_fw_len);
-               dma_regs.addr = cpu_to_le32(fw_addr);
-
-               fw_len -= _fw_len;
-               fw_addr += _fw_len;
-
-               stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
-
-               if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
-                                     HOST_ALLOWED, HOST_ALLOWED) == 0) {
-                       stlc45xx_error("fw_upload not allowed to DMA write");
-                       return -EAGAIN;
-               }
-
-               stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
-               stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
-
-               stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
-
-               /* FIXME: I think this doesn't work if firmware is large,
-                * this loop goes to second round. fw->data is not
-                * increased at all! */
-       }
-
-       BUG_ON(fw_len != 0);
-
-       /* enable host interrupts */
-       stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
-
-       /* boot the device */
-       stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
-                        SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
-                        | SPI_CTRL_STAT_RAM_BOOT);
-
-       msleep(TARGET_BOOT_SLEEP);
-
-       stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
-                        SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
-       msleep(TARGET_BOOT_SLEEP);
-
-       return 0;
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_check_txsent(struct stlc45xx *stlc)
-{
-       struct txbuffer *entry, *n;
-
-       list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
-               if (time_after(jiffies, entry->lifetime)) {
-                       if (net_ratelimit())
-                               stlc45xx_warning("frame 0x%x lifetime exceeded",
-                                                entry->start);
-                       list_del(&entry->tx_list);
-                       skb_pull(entry->skb, entry->header_len);
-                       ieee80211_tx_status(stlc->hw, entry->skb);
-                       stlc45xx_txbuffer_free(stlc, entry);
-               }
-       }
-}
-
-static void stlc45xx_power_off(struct stlc45xx *stlc)
-{
-       disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
-       gpio_set_value(stlc45xx_gpio_power, 0);
-}
-
-static void stlc45xx_power_on(struct stlc45xx *stlc)
-{
-       gpio_set_value(stlc45xx_gpio_power, 1);
-       enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
-
-       /*
-        * need to wait a while before device can be accessed, the length
-        * is just a guess
-        */
-       msleep(10);
-}
-
-/* caller must hold tx_lock */
-static void stlc45xx_flush_queues(struct stlc45xx *stlc)
-{
-       struct txbuffer *entry;
-
-       while (!list_empty(&stlc->tx_sent)) {
-               entry = list_first_entry(&stlc->tx_sent,
-                                        struct txbuffer, tx_list);
-               list_del(&entry->tx_list);
-               dev_kfree_skb(entry->skb);
-               stlc45xx_txbuffer_free(stlc, entry);
-       }
-
-       WARN_ON(!list_empty(&stlc->tx_sent));
-
-       while (!list_empty(&stlc->tx_pending)) {
-               entry = list_first_entry(&stlc->tx_pending,
-                                        struct txbuffer, tx_list);
-               list_del(&entry->tx_list);
-               dev_kfree_skb(entry->skb);
-               stlc45xx_txbuffer_free(stlc, entry);
-       }
-
-       WARN_ON(!list_empty(&stlc->tx_pending));
-       WARN_ON(!list_empty(&stlc->txbuffer));
-}
-
-static void stlc45xx_work_reset(struct work_struct *work)
-{
-       struct stlc45xx *stlc = container_of(work, struct stlc45xx,
-                                            work_reset);
-
-       mutex_lock(&stlc->mutex);
-
-       if (stlc->fw_state != FW_STATE_RESET)
-               goto out;
-
-       stlc45xx_power_off(stlc);
-
-       mutex_unlock(&stlc->mutex);
-
-       /* wait that all work_structs have finished, we can't hold
-        * stlc->mutex to avoid deadlock */
-       cancel_work_sync(&stlc->work);
-
-       /* FIXME: find out good value to wait for chip power down */
-       msleep(100);
-
-       mutex_lock(&stlc->mutex);
-
-       /* FIXME: we should gracefully handle if the state has changed
-        * after re-acquiring mutex */
-       WARN_ON(stlc->fw_state != FW_STATE_RESET);
-
-       spin_lock_bh(&stlc->tx_lock);
-       stlc45xx_flush_queues(stlc);
-       spin_unlock_bh(&stlc->tx_lock);
-
-       stlc->fw_state = FW_STATE_RESETTING;
-
-       stlc45xx_power_on(stlc);
-       stlc45xx_upload_firmware(stlc);
-
-out:
-       mutex_unlock(&stlc->mutex);
-}
-
-/* caller must hold mutex */
-static void stlc45xx_reset(struct stlc45xx *stlc)
-{
-       stlc45xx_warning("resetting firmware");
-       stlc->fw_state = FW_STATE_RESET;
-       ieee80211_stop_queues(stlc->hw);
-       queue_work(stlc->hw->workqueue, &stlc->work_reset);
-}
-
-static void stlc45xx_work_tx_timeout(struct work_struct *work)
-{
-       struct stlc45xx *stlc = container_of(work, struct stlc45xx,
-                                            work_tx_timeout.work);
-
-       stlc45xx_warning("tx timeout");
-
-       mutex_lock(&stlc->mutex);
-
-       if (stlc->fw_state != FW_STATE_READY)
-               goto out;
-
-       stlc45xx_reset(stlc);
-
-out:
-       mutex_unlock(&stlc->mutex);
-}
-
-static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
-}
-
-static void stlc45xx_wakeup(struct stlc45xx *stlc)
-{
-       unsigned long timeout;
-       u32 ints;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       /* wake the chip */
-       stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
-
-       /* And wait for the READY interrupt */
-       timeout = jiffies + HZ;
-
-       ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       while (!(ints & SPI_HOST_INT_READY)) {
-               if (time_after(jiffies, timeout))
-                               goto out;
-               ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       }
-
-       stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
-
-out:
-       return;
-}
-
-static void stlc45xx_sleep(struct stlc45xx *stlc)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
-}
-
-static void stlc45xx_int_ready(struct stlc45xx *stlc)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
-                        SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
-
-       switch (stlc->fw_state) {
-       case FW_STATE_BOOTING:
-               stlc->fw_state = FW_STATE_READY;
-               complete(&stlc->fw_comp);
-               break;
-       case FW_STATE_RESETTING:
-               stlc->fw_state = FW_STATE_READY;
-
-               stlc45xx_tx_scan(stlc);
-               stlc45xx_tx_setup(stlc);
-               stlc45xx_tx_edcf(stlc);
-
-               ieee80211_wake_queues(stlc->hw);
-               break;
-       default:
-               break;
-       }
-}
-
-static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info;
-       struct s_lm_control *control;
-       struct s_lmo_tx *tx;
-       struct txbuffer *entry;
-       int found = 0;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       control = (struct s_lm_control *) skb->data;
-       tx = (struct s_lmo_tx *) (control + 1);
-
-       if (list_empty(&stlc->tx_sent)) {
-               if (net_ratelimit())
-                       stlc45xx_warning("no frames waiting for "
-                                        "acknowledgement");
-               return -1;
-       }
-
-       list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
-               if (control->handle == entry->handle) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (!found) {
-               if (net_ratelimit())
-                       stlc45xx_warning("couldn't find frame for tx ack 0x%x",
-                                        control->handle);
-               return -1;
-       }
-
-       stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
-
-       if (entry->status_needed) {
-               info = IEEE80211_SKB_CB(entry->skb);
-
-               if (!(tx->flags & LM_TX_FAILED)) {
-                       /* frame was acked */
-                       info->flags |= IEEE80211_TX_STAT_ACK;
-                       info->status.ack_signal = tx->rcpi / 2 - 110;
-               }
-
-               skb_pull(entry->skb, entry->header_len);
-
-               ieee80211_tx_status(stlc->hw, entry->skb);
-       }
-
-       list_del(&entry->tx_list);
-
-       stlc45xx_check_txsent(stlc);
-       if (list_empty(&stlc->tx_sent))
-               /* there are no pending frames, we can stop the tx timeout
-                * timer */
-               cancel_delayed_work(&stlc->work_tx_timeout);
-
-       spin_lock_bh(&stlc->tx_lock);
-
-       stlc45xx_txbuffer_free(stlc, entry);
-
-       if (stlc->tx_queue_stopped &&
-           stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
-               stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
-               ieee80211_wake_queues(stlc->hw);
-               stlc->tx_queue_stopped = 0;
-       }
-
-       spin_unlock_bh(&stlc->tx_lock);
-
-       return 0;
-}
-
-static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
-{
-       struct s_lm_control *control;
-       int ret = 0;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       control = (struct s_lm_control *) skb->data;
-
-       switch (control->oid) {
-       case LM_OID_TX:
-               ret = stlc45xx_rx_txack(stlc, skb);
-               break;
-       case LM_OID_SETUP:
-       case LM_OID_SCAN:
-       case LM_OID_TRAP:
-       case LM_OID_EDCF:
-       case LM_OID_KEYCACHE:
-       case LM_OID_PSM:
-       case LM_OID_STATS:
-       case LM_OID_LED:
-       default:
-               stlc45xx_warning("unhandled rx control oid %d\n",
-                                control->oid);
-               break;
-       }
-
-       dev_kfree_skb(skb);
-
-       return ret;
-}
-
-/* copied from mac80211 */
-static void stlc45xx_parse_elems(u8 *start, size_t len,
-                                struct stlc45xx_ie_tim **tim,
-                                size_t *tim_len)
-{
-       size_t left = len;
-       u8 *pos = start;
-
-       while (left >= 2) {
-               u8 id, elen;
-
-               id = *pos++;
-               elen = *pos++;
-               left -= 2;
-
-               if (elen > left)
-                       return;
-
-               switch (id) {
-               case WLAN_EID_TIM:
-                       *tim = (struct stlc45xx_ie_tim *) pos;
-                       *tim_len = elen;
-                       break;
-               default:
-                       break;
-               }
-
-               left -= elen;
-               pos += elen;
-       }
-}
-
-/*
- * mac80211 doesn't have support for asking frames with PS-Poll, so let's
- * implement in the driver for now. We have to add support to mac80211
- * later.
- */
-static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
-{
-       struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
-       struct ieee80211_hdr *hdr;
-       size_t len;
-       u16 fc;
-
-       hdr = (void *) skb->data + sizeof(*data);
-       len = skb->len - sizeof(*data);
-
-       /* minimum frame length is the null frame length 24 bytes */
-       if (len < 24) {
-               stlc45xx_warning("invalid frame length when checking for "
-                                "more data");
-               return -EINVAL;
-       }
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if (!(fc & IEEE80211_FCTL_FROMDS))
-               /* this is not from DS */
-               return 0;
-
-       if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
-               /* the frame was not for us */
-               return 0;
-
-       if (!(fc & IEEE80211_FCTL_MOREDATA)) {
-               /* AP has no more frames buffered for us */
-               stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
-               stlc->pspolling = false;
-               return 0;
-       }
-
-       /* MOREDATA bit is set, let's ask for a new frame from the AP */
-       stlc45xx_tx_pspoll(stlc, stlc->psm);
-
-       return 0;
-}
-
-/*
- * mac80211 cannot read TIM from beacons, so let's add a hack to the
- * driver. We have to add support to mac80211 later.
- */
-static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
-{
-       struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
-       size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
-       struct ieee80211_mgmt *mgmt;
-       struct stlc45xx_ie_tim *tim = NULL;
-       int bmap_offset, index, aid_bit;
-
-       mgmt = (void *) skb->data + sizeof(*data);
-
-       baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
-       if (baselen > len) {
-               stlc45xx_warning("invalid baselen in beacon");
-               return -EINVAL;
-       }
-
-       stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
-                            &tim_len);
-
-       if (!tim) {
-               stlc45xx_warning("didn't find tim from a beacon");
-               return -EINVAL;
-       }
-
-       bmap_offset = tim->bmap_control & 0xfe;
-       index = stlc->aid / 8 - bmap_offset;
-
-       pvbmap_len = tim_len - 3;
-       if (index > pvbmap_len)
-               return -EINVAL;
-
-       aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
-
-       stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
-                      "bmap_control 0x%x aid_bit %d",
-                      mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
-                      tim->dtim_count, tim->bmap_control, aid_bit);
-
-       if (!aid_bit)
-               return 0;
-
-       stlc->pspolling = true;
-       stlc45xx_tx_pspoll(stlc, stlc->psm);
-
-       return 0;
-}
-
-static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
-{
-       struct ieee80211_rx_status status;
-       struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
-       int align = 0;
-       u8 *p, align_len;
-       u16 len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       if (stlc->psm) {
-               if (data->flags & LM_IN_BEACON)
-                       stlc45xx_rx_data_beacon(stlc, skb);
-               else if (stlc->pspolling && (data->flags & LM_IN_DATA))
-                       stlc45xx_check_more_data(stlc, skb);
-       }
-
-       memset(&status, 0, sizeof(status));
-
-       status.freq = data->frequency;
-       status.signal = data->rcpi / 2 - 110;
-
-       /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
-       status.qual = data->rcpi * 100 / 140;
-
-       status.band = IEEE80211_BAND_2GHZ;
-
-       /*
-        * FIXME: this gives warning from __ieee80211_rx()
-        *
-        * status.rate_idx = data->rate;
-        */
-
-       len = data->length;
-
-       if (data->flags & LM_FLAG_ALIGN)
-               align = 1;
-
-       skb_pull(skb, sizeof(*data));
-
-       if (align) {
-               p = skb->data;
-               align_len = *p;
-               skb_pull(skb, align_len);
-       }
-
-       skb_trim(skb, len);
-
-       stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
-       stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
-
-       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-       ieee80211_rx(stlc->hw, skb);
-
-       return 0;
-}
-
-
-
-static int stlc45xx_rx(struct stlc45xx *stlc)
-{
-       struct s_lm_control *control;
-       struct sk_buff *skb;
-       int ret;
-       u16 len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       stlc45xx_wakeup(stlc);
-
-       /* dummy read to flush SPI DMA controller bug */
-       stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
-
-       len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
-
-       if (len == 0) {
-               stlc45xx_warning("rx request of zero bytes");
-               return 0;
-       }
-
-       skb = dev_alloc_skb(len);
-       if (!skb) {
-               stlc45xx_warning("could not alloc skb");
-               return 0;
-       }
-
-       stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
-
-       stlc45xx_sleep(stlc);
-
-       stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
-       stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
-
-       control = (struct s_lm_control *) skb->data;
-
-       if (control->flags & LM_FLAG_CONTROL)
-               ret = stlc45xx_rx_control(stlc, skb);
-       else
-               ret = stlc45xx_rx_data(stlc, skb);
-
-       return ret;
-}
-
-
-static irqreturn_t stlc45xx_interrupt(int irq, void *config)
-{
-       struct spi_device *spi = config;
-       struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
-
-       stlc45xx_debug(DEBUG_IRQ, "IRQ");
-
-       queue_work(stlc->hw->workqueue, &stlc->work);
-
-       return IRQ_HANDLED;
-}
-
-static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
-                            void *buf, size_t len)
-{
-       struct s_dma_regs dma_regs;
-       unsigned long timeout;
-       int ret = 0;
-       u32 ints;
-
-       stlc->tx_frames++;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
-       stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
-
-       stlc45xx_wakeup(stlc);
-
-       dma_regs.cmd  = SPI_DMA_WRITE_CTRL_ENABLE;
-       dma_regs.len  = cpu_to_le16(len);
-       dma_regs.addr = cpu_to_le32(address);
-
-       stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
-                          sizeof(dma_regs));
-
-       stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
-
-       timeout = jiffies + 2 * HZ;
-       ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       while (!(ints & SPI_HOST_INT_WR_READY)) {
-               if (time_after(jiffies, timeout)) {
-                       stlc45xx_warning("WR_READY timeout");
-                       ret = -1;
-                       goto out;
-               }
-               ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       }
-
-       stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
-
-       stlc45xx_sleep(stlc);
-
-out:
-       return ret;
-}
-
-static int stlc45xx_wq_tx(struct stlc45xx *stlc)
-{
-       struct txbuffer *entry;
-       int ret = 0;
-
-       spin_lock_bh(&stlc->tx_lock);
-
-       while (!list_empty(&stlc->tx_pending)) {
-               entry = list_entry(stlc->tx_pending.next,
-                                  struct txbuffer, tx_list);
-
-               list_del_init(&entry->tx_list);
-
-               spin_unlock_bh(&stlc->tx_lock);
-
-               ret = stlc45xx_tx_frame(stlc, entry->frame_start,
-                                       entry->skb->data, entry->skb->len);
-
-               spin_lock_bh(&stlc->tx_lock);
-
-               if (ret < 0) {
-                       /* frame transfer to firmware buffer failed */
-                       /* FIXME: report this to mac80211 */
-                       dev_kfree_skb(entry->skb);
-                       stlc45xx_txbuffer_free(stlc, entry);
-                       goto out;
-               }
-
-               list_add(&entry->tx_list, &stlc->tx_sent);
-               queue_delayed_work(stlc->hw->workqueue,
-                                  &stlc->work_tx_timeout,
-                                  msecs_to_jiffies(TX_TIMEOUT));
-       }
-
-out:
-       spin_unlock_bh(&stlc->tx_lock);
-       return ret;
-}
-
-static void stlc45xx_work(struct work_struct *work)
-{
-       struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
-       u32 ints;
-       int ret;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       if (stlc->fw_state == FW_STATE_OFF &&
-           stlc->fw_state == FW_STATE_RESET)
-               goto out;
-
-       ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
-
-       if (ints & SPI_HOST_INT_READY) {
-               stlc45xx_int_ready(stlc);
-               stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
-       }
-
-       if (stlc->fw_state != FW_STATE_READY)
-               goto out;
-
-       if (ints & SPI_HOST_INT_UPDATE) {
-               stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
-               ret = stlc45xx_rx(stlc);
-               if (ret < 0) {
-                       stlc45xx_reset(stlc);
-                       goto out;
-               }
-       }
-       if (ints & SPI_HOST_INT_SW_UPDATE) {
-               stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
-               ret = stlc45xx_rx(stlc);
-               if (ret < 0) {
-                       stlc45xx_reset(stlc);
-                       goto out;
-               }
-       }
-
-       ret = stlc45xx_wq_tx(stlc);
-       if (ret < 0) {
-               stlc45xx_reset(stlc);
-               goto out;
-       }
-
-       ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
-       stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
-
-out:
-       mutex_unlock(&stlc->mutex);
-}
-
-static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
-{
-       struct s_lm_control *control;
-       struct s_lmo_edcf *edcf;
-       size_t len, edcf_len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       edcf_len = sizeof(*edcf);
-       len = sizeof(*control) + edcf_len;
-       control = kzalloc(len, GFP_KERNEL);
-       edcf = (struct s_lmo_edcf *) (control + 1);
-
-       control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
-       control->length = edcf_len;
-       control->oid = LM_OID_EDCF;
-
-       edcf->slottime = 0x14;
-       edcf->sifs = 10;
-       edcf->eofpad = 6;
-       edcf->maxburst = 1500;
-
-       edcf->queues[0].aifs = 2;
-       edcf->queues[0].pad0 = 1;
-       edcf->queues[0].cwmin = 3;
-       edcf->queues[0].cwmax = 7;
-       edcf->queues[0].txop = 47;
-       edcf->queues[1].aifs = 2;
-       edcf->queues[1].pad0 = 0;
-       edcf->queues[1].cwmin = 7;
-       edcf->queues[1].cwmax = 15;
-       edcf->queues[1].txop = 94;
-       edcf->queues[2].aifs = 3;
-       edcf->queues[2].pad0 = 0;
-       edcf->queues[2].cwmin = 15;
-       edcf->queues[2].cwmax = 1023;
-       edcf->queues[2].txop = 0;
-       edcf->queues[3].aifs = 7;
-       edcf->queues[3].pad0 = 0;
-       edcf->queues[3].cwmin = 15;
-       edcf->queues[3].cwmax = 1023;
-       edcf->queues[3].txop = 0;
-       edcf->queues[4].aifs = 13;
-       edcf->queues[4].pad0 = 99;
-       edcf->queues[4].cwmin = 3437;
-       edcf->queues[4].cwmax = 512;
-       edcf->queues[4].txop = 12;
-       edcf->queues[5].aifs = 142;
-       edcf->queues[5].pad0 = 109;
-       edcf->queues[5].cwmin = 8756;
-       edcf->queues[5].cwmax = 6;
-       edcf->queues[5].txop = 0;
-       edcf->queues[6].aifs = 4;
-       edcf->queues[6].pad0 = 0;
-       edcf->queues[6].cwmin = 0;
-       edcf->queues[6].cwmax = 58705;
-       edcf->queues[6].txop = 25716;
-       edcf->queues[7].aifs = 0;
-       edcf->queues[7].pad0 = 0;
-       edcf->queues[7].cwmin = 0;
-       edcf->queues[7].cwmax = 0;
-       edcf->queues[7].txop = 0;
-
-       stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
-       kfree(control);
-}
-
-static void stlc45xx_tx_setup(struct stlc45xx *stlc)
-{
-       struct s_lm_control *control;
-       struct s_lmo_setup *setup;
-       size_t len, setup_len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       setup_len = sizeof(*setup);
-       len = sizeof(*control) + setup_len;
-       control = kzalloc(len, GFP_KERNEL);
-       setup = (struct s_lmo_setup *) (control + 1);
-
-       control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
-       control->length = setup_len;
-       control->oid = LM_OID_SETUP;
-
-       setup->flags = LM_SETUP_INFRA;
-       setup->antenna = 2;
-       setup->rx_align = 0;
-       setup->rx_buffer = FIRMWARE_RXBUFFER_START;
-       setup->rx_mtu = FIRMWARE_MTU;
-       setup->frontend = 5;
-       setup->timeout = 0;
-       setup->truncate = 48896;
-       setup->bratemask = 0xffffffff;
-       setup->ref_clock = 644245094;
-       setup->lpf_bandwidth = 65535;
-       setup->osc_start_delay = 65535;
-
-       memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
-       memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
-
-       stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
-       kfree(control);
-}
-
-static void stlc45xx_tx_scan(struct stlc45xx *stlc)
-{
-       struct s_lm_control *control;
-       struct s_lmo_scan *scan;
-       size_t len, scan_len;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       scan_len = sizeof(*scan);
-       len = sizeof(*control) + scan_len;
-       control = kzalloc(len, GFP_KERNEL);
-       scan = (struct s_lmo_scan *) (control + 1);
-
-       control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
-       control->length = scan_len;
-       control->oid = LM_OID_SCAN;
-
-       scan->flags = LM_SCAN_EXIT;
-       scan->bratemask = 0x15f;
-       scan->aloft[0] = 3;
-       scan->aloft[1] = 3;
-       scan->aloft[2] = 1;
-       scan->aloft[3] = 0;
-       scan->aloft[4] = 0;
-       scan->aloft[5] = 0;
-       scan->aloft[6] = 0;
-       scan->aloft[7] = 0;
-
-       memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
-                                              RSSI_CAL_LEN],
-              RSSI_CAL_LEN);
-       memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
-                                                  CHANNEL_CAL_LEN],
-              CHANNEL_CAL_LEN);
-
-       stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
-       kfree(control);
-}
-
-/*
- * caller must hold mutex
- */
-static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
-{
-       struct ieee80211_hdr *pspoll;
-       int payload_len, padding, i;
-       struct s_lm_data_out *data;
-       struct txbuffer *entry;
-       struct sk_buff *skb;
-       char *payload;
-       u16 fc;
-
-       skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
-       if (!skb) {
-               stlc45xx_warning("failed to allocate pspoll frame");
-               return -ENOMEM;
-       }
-       skb_reserve(skb, stlc->hw->extra_tx_headroom);
-
-       pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
-       memset(pspoll, 0, 16);
-       fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
-       if (powersave)
-               fc |= IEEE80211_FCTL_PM;
-       pspoll->frame_control = cpu_to_le16(fc);
-       pspoll->duration_id = cpu_to_le16(stlc->aid);
-
-       /* aid in PS-Poll has its two MSBs each set to 1 */
-       pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
-
-       memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
-       memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
-
-       stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %pM (powersave %d, "
-                      "fc 0x%x, aid %d)", pspoll->addr1,
-                      powersave, fc, stlc->aid);
-
-       spin_lock_bh(&stlc->tx_lock);
-
-       entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
-
-       spin_unlock_bh(&stlc->tx_lock);
-
-       if (!entry) {
-               /*
-                * The queue should be stopped before the firmware buffer
-                * is full, so firmware buffer should always have enough
-                * space.
-                *
-                * But I'm too lazy and omit it for now.
-                */
-               if (net_ratelimit())
-                       stlc45xx_warning("firmware tx buffer full is full "
-                                        "for null frame");
-               return -ENOSPC;
-       }
-
-       payload = skb->data;
-       payload_len = skb->len;
-       padding = (int) (skb->data - sizeof(*data)) & 3;
-       entry->header_len = sizeof(*data) + padding;
-
-       entry->skb = skb;
-       entry->status_needed = false;
-       entry->handle = (u32) skb;
-       entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
-       stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
-                      "padding %d header_len %d)",
-                      entry->handle, payload, payload_len, padding,
-                      entry->header_len);
-       stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
-       data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
-       memset(data, 0, entry->header_len);
-
-       if (padding)
-               data->flags = LM_FLAG_ALIGN;
-
-       data->flags = LM_OUT_BURST;
-       data->length = payload_len;
-       data->handle = entry->handle;
-       data->aid = 1;
-       data->rts_retries = 7;
-       data->retries = 7;
-       data->aloft_ctrl = 0;
-       data->crypt_offset = 58;
-       data->keytype = 0;
-       data->keylen = 0;
-       data->queue = LM_QUEUE_DATA3;
-       data->backlog = 32;
-       data->antenna = 2;
-       data->cts = 3;
-       data->power = 127;
-
-       for (i = 0; i < 8; i++)
-               data->aloft[i] = 0;
-
-       /*
-        * check if there's enough space in tx buffer
-        *
-        * FIXME: ignored for now
-        */
-
-       stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
-
-       list_add(&entry->tx_list, &stlc->tx_sent);
-
-       return 0;
-}
-
-/*
- * caller must hold mutex
- *
- * shamelessly stolen from mac80211/ieee80211_send_nullfunc
- */
-static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
-{
-       struct ieee80211_hdr *nullfunc;
-       int payload_len, padding, i;
-       struct s_lm_data_out *data;
-       struct txbuffer *entry;
-       struct sk_buff *skb;
-       char *payload;
-       u16 fc;
-
-       skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
-       if (!skb) {
-               stlc45xx_warning("failed to allocate buffer for null frame\n");
-               return -ENOMEM;
-       }
-       skb_reserve(skb, stlc->hw->extra_tx_headroom);
-
-       nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
-       memset(nullfunc, 0, 24);
-       fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
-            IEEE80211_FCTL_TODS;
-
-       if (powersave)
-               fc |= IEEE80211_FCTL_PM;
-
-       nullfunc->frame_control = cpu_to_le16(fc);
-       memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
-       memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
-       memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
-
-       stlc45xx_debug(DEBUG_PSM, "sending Null frame to %pM (powersave %d, "
-                      "fc 0x%x)", nullfunc->addr1, powersave, fc);
-
-       spin_lock_bh(&stlc->tx_lock);
-
-       entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
-
-       spin_unlock_bh(&stlc->tx_lock);
-
-       if (!entry) {
-               /*
-                * The queue should be stopped before the firmware buffer
-                * is full, so firmware buffer should always have enough
-                * space.
-                *
-                * But I'm too lazy and omit it for now.
-                */
-               if (net_ratelimit())
-                       stlc45xx_warning("firmware tx buffer full is full "
-                                        "for null frame");
-               return -ENOSPC;
-       }
-
-       payload = skb->data;
-       payload_len = skb->len;
-       padding = (int) (skb->data - sizeof(*data)) & 3;
-       entry->header_len = sizeof(*data) + padding;
-
-       entry->skb = skb;
-       entry->status_needed = false;
-       entry->handle = (u32) skb;
-       entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
-       stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
-                      "padding %d header_len %d)",
-                      entry->handle, payload, payload_len, padding,
-                      entry->header_len);
-       stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
-       data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
-       memset(data, 0, entry->header_len);
-
-       if (padding)
-               data->flags = LM_FLAG_ALIGN;
-
-       data->flags = LM_OUT_BURST;
-       data->length = payload_len;
-       data->handle = entry->handle;
-       data->aid = 1;
-       data->rts_retries = 7;
-       data->retries = 7;
-       data->aloft_ctrl = 0;
-       data->crypt_offset = 58;
-       data->keytype = 0;
-       data->keylen = 0;
-       data->queue = LM_QUEUE_DATA3;
-       data->backlog = 32;
-       data->antenna = 2;
-       data->cts = 3;
-       data->power = 127;
-
-       for (i = 0; i < 8; i++)
-               data->aloft[i] = 0;
-
-       /*
-        * check if there's enough space in tx buffer
-        *
-        * FIXME: ignored for now
-        */
-
-       stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
-
-       list_add(&entry->tx_list, &stlc->tx_sent);
-
-       return 0;
-}
-
-/* caller must hold mutex */
-static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
-{
-       struct s_lm_control *control;
-       struct s_lmo_psm *psm;
-       size_t len, psm_len;
-
-       WARN_ON(!stlc->associated);
-       WARN_ON(stlc->aid < 1);
-       WARN_ON(stlc->aid > 2007);
-
-       psm_len = sizeof(*psm);
-       len = sizeof(*control) + psm_len;
-       control = kzalloc(len, GFP_KERNEL);
-       psm = (struct s_lmo_psm *) (control + 1);
-
-       control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
-       control->length = psm_len;
-       control->oid = LM_OID_PSM;
-
-       if (enable)
-               psm->flags |= LM_PSM;
-
-       psm->aid = stlc->aid;
-
-       psm->beacon_rcpi_skip_max = 60;
-
-       psm->intervals[0].interval = 1;
-       psm->intervals[0].periods = 1;
-       psm->intervals[1].interval = 1;
-       psm->intervals[1].periods = 1;
-       psm->intervals[2].interval = 1;
-       psm->intervals[2].periods = 1;
-       psm->intervals[3].interval = 1;
-       psm->intervals[3].periods = 1;
-
-       psm->nr = 0;
-       psm->exclude[0] = 0;
-
-       stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
-                      psm->aid, psm->intervals[0].interval);
-
-       stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
-
-       kfree(control);
-}
-
-static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct stlc45xx *stlc = hw->priv;
-       struct ieee80211_tx_info *info;
-       struct ieee80211_rate *rate;
-       int payload_len, padding, i;
-       struct s_lm_data_out *data;
-       struct txbuffer *entry;
-       char *payload;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       spin_lock_bh(&stlc->tx_lock);
-
-       entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
-       if (!entry) {
-               /* the queue should be stopped before the firmware buffer
-                * is full, so firmware buffer should always have enough
-                * space */
-               if (net_ratelimit())
-                       stlc45xx_warning("firmware buffer full");
-               spin_unlock_bh(&stlc->tx_lock);
-               return NETDEV_TX_BUSY;
-       }
-
-       info = IEEE80211_SKB_CB(skb);
-
-       payload = skb->data;
-       payload_len = skb->len;
-       padding = (int) (skb->data - sizeof(*data)) & 3;
-       entry->header_len = sizeof(*data) + padding;
-
-       entry->skb = skb;
-       entry->status_needed = true;
-       entry->handle = (u32) skb;
-       entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
-
-       stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
-                      "padding %d header_len %d)",
-                      entry->handle, payload, payload_len, padding,
-                      entry->header_len);
-       stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
-
-       data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
-
-       memset(data, 0, entry->header_len);
-
-       if (padding)
-               data->flags = LM_FLAG_ALIGN;
-
-       data->flags = LM_OUT_BURST;
-       data->length = payload_len;
-       data->handle = entry->handle;
-       data->aid = 1;
-       data->rts_retries = 7;
-       data->retries = 7;
-       data->aloft_ctrl = 0;
-       data->crypt_offset = 58;
-       data->keytype = 0;
-       data->keylen = 0;
-       data->queue = 2;
-       data->backlog = 32;
-       data->antenna = 2;
-       data->cts = 3;
-       data->power = 127;
-
-       for (i = 0; i < 8; i++) {
-               rate = ieee80211_get_tx_rate(stlc->hw, info);
-               data->aloft[i] = rate->hw_value;
-       }
-
-       list_add_tail(&entry->tx_list, &stlc->tx_pending);
-
-       /* check if there's enough space in tx buffer */
-       if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
-               stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
-               stlc->tx_queue_stopped = 1;
-               ieee80211_stop_queues(stlc->hw);
-       }
-
-       queue_work(stlc->hw->workqueue, &stlc->work);
-
-       spin_unlock_bh(&stlc->tx_lock);
-
-       return NETDEV_TX_OK;
-}
-
-static int stlc45xx_op_start(struct ieee80211_hw *hw)
-{
-       struct stlc45xx *stlc = hw->priv;
-       unsigned long timeout;
-       int ret = 0;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       stlc->fw_state = FW_STATE_BOOTING;
-       stlc->channel = 1;
-
-       stlc45xx_power_on(stlc);
-
-       ret = stlc45xx_upload_firmware(stlc);
-       if (ret < 0) {
-               stlc45xx_power_off(stlc);
-               goto out_unlock;
-       }
-
-       stlc->tx_queue_stopped = 0;
-
-       mutex_unlock(&stlc->mutex);
-
-       timeout = msecs_to_jiffies(2000);
-       timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
-                                                           timeout);
-       if (!timeout) {
-               stlc45xx_error("firmware boot failed");
-               stlc45xx_power_off(stlc);
-               ret = -1;
-               goto out;
-       }
-
-       stlc45xx_debug(DEBUG_BOOT, "firmware booted");
-
-       /* FIXME: should we take mutex just after wait_for_completion()? */
-       mutex_lock(&stlc->mutex);
-
-       WARN_ON(stlc->fw_state != FW_STATE_READY);
-
-out_unlock:
-       mutex_unlock(&stlc->mutex);
-
-out:
-       return ret;
-}
-
-static void stlc45xx_op_stop(struct ieee80211_hw *hw)
-{
-       struct stlc45xx *stlc = hw->priv;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       WARN_ON(stlc->fw_state != FW_STATE_READY);
-
-       stlc45xx_power_off(stlc);
-
-       /* FIXME: make sure that all work_structs have completed */
-
-       spin_lock_bh(&stlc->tx_lock);
-       stlc45xx_flush_queues(stlc);
-       spin_unlock_bh(&stlc->tx_lock);
-
-       stlc->fw_state = FW_STATE_OFF;
-
-       mutex_unlock(&stlc->mutex);
-}
-
-static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
-                                    struct ieee80211_if_init_conf *conf)
-{
-       struct stlc45xx *stlc = hw->priv;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       switch (conf->type) {
-       case NL80211_IFTYPE_STATION:
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
-
-       return 0;
-}
-
-static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
-                                        struct ieee80211_if_init_conf *conf)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-}
-
-static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct stlc45xx *stlc = hw->priv;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       stlc->channel = hw->conf.channel->hw_value;
-       stlc45xx_tx_scan(stlc);
-       stlc45xx_tx_setup(stlc);
-       stlc45xx_tx_edcf(stlc);
-
-       if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
-               stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
-               if (stlc->associated) {
-                       stlc45xx_tx_psm(stlc, stlc->psm);
-                       stlc45xx_tx_nullfunc(stlc, stlc->psm);
-               }
-       }
-
-       mutex_unlock(&stlc->mutex);
-
-       return 0;
-}
-
-static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
-                                     unsigned int changed_flags,
-                                     unsigned int *total_flags,
-                                     int mc_count,
-                                     struct dev_addr_list *mc_list)
-{
-       *total_flags = 0;
-}
-
-static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
-                                        struct ieee80211_vif *vif,
-                                        struct ieee80211_bss_conf *info,
-                                        u32 changed)
-{
-       struct stlc45xx *stlc = hw->priv;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-       mutex_lock(&stlc->mutex);
-
-       memcpy(stlc->bssid, info->bssid, ETH_ALEN);
-       stlc45xx_tx_setup(stlc);
-
-       mutex_unlock(&stlc->mutex);
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               stlc->associated = info->assoc;
-               if (info->assoc)
-                       stlc->aid = info->aid;
-               else
-                       stlc->aid = -1;
-
-               if (stlc->psm) {
-                       stlc45xx_tx_psm(stlc, stlc->psm);
-                       stlc45xx_tx_nullfunc(stlc, stlc->psm);
-               }
-       }
-}
-
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate stlc45xx_rates[] = {
-       { .bitrate = 10,  .hw_value = 0,    .hw_value_short = 0, },
-       { .bitrate = 20,  .hw_value = 1,    .hw_value_short = 1, },
-       { .bitrate = 55,  .hw_value = 2,    .hw_value_short = 2, },
-       { .bitrate = 110, .hw_value = 3,    .hw_value_short = 3, },
-       { .bitrate = 60,  .hw_value = 4,    .hw_value_short = 4, },
-       { .bitrate = 90,  .hw_value = 5,    .hw_value_short = 5, },
-       { .bitrate = 120, .hw_value = 6,    .hw_value_short = 6, },
-       { .bitrate = 180, .hw_value = 7,    .hw_value_short = 7, },
-       { .bitrate = 240, .hw_value = 8,    .hw_value_short = 8, },
-       { .bitrate = 360, .hw_value = 9,    .hw_value_short = 9, },
-       { .bitrate = 480, .hw_value = 10,   .hw_value_short = 10, },
-       { .bitrate = 540, .hw_value = 11,   .hw_value_short = 11, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel stlc45xx_channels[] = {
-       { .hw_value = 1, .center_freq = 2412},
-       { .hw_value = 2, .center_freq = 2417},
-       { .hw_value = 3, .center_freq = 2422},
-       { .hw_value = 4, .center_freq = 2427},
-       { .hw_value = 5, .center_freq = 2432},
-       { .hw_value = 6, .center_freq = 2437},
-       { .hw_value = 7, .center_freq = 2442},
-       { .hw_value = 8, .center_freq = 2447},
-       { .hw_value = 9, .center_freq = 2452},
-       { .hw_value = 10, .center_freq = 2457},
-       { .hw_value = 11, .center_freq = 2462},
-       { .hw_value = 12, .center_freq = 2467},
-       { .hw_value = 13, .center_freq = 2472},
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_supported_band stlc45xx_band_2ghz = {
-       .channels = stlc45xx_channels,
-       .n_channels = ARRAY_SIZE(stlc45xx_channels),
-       .bitrates = stlc45xx_rates,
-       .n_bitrates = ARRAY_SIZE(stlc45xx_rates),
-};
-
-static const struct ieee80211_ops stlc45xx_ops = {
-       .start = stlc45xx_op_start,
-       .stop = stlc45xx_op_stop,
-       .add_interface = stlc45xx_op_add_interface,
-       .remove_interface = stlc45xx_op_remove_interface,
-       .config = stlc45xx_op_config,
-       .configure_filter = stlc45xx_op_configure_filter,
-       .tx = stlc45xx_op_tx,
-       .bss_info_changed = stlc45xx_op_bss_info_changed,
-};
-
-static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
-{
-       /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
-          to be non-const for some strange reason */
-       static u8 default_mac_addr[ETH_ALEN] = {
-               0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
-       };
-       int ret;
-
-       SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
-
-       ret = ieee80211_register_hw(stlc->hw);
-       if (ret) {
-               stlc45xx_error("unable to register mac80211 hw: %d", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static void stlc45xx_device_release(struct device *dev)
-{
-
-}
-
-static struct platform_device stlc45xx_device = {
-       .name           = "stlc45xx",
-       .id             = -1,
-
-       /* device model insists to have a release function */
-       .dev            = {
-               .release = stlc45xx_device_release,
-       },
-};
-
-static int __devinit stlc45xx_probe(struct spi_device *spi)
-{
-       struct stlc45xx *stlc;
-       struct ieee80211_hw *hw;
-       int ret;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       /* mac80211 alloc */
-       hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
-       if (!hw) {
-               stlc45xx_error("could not alloc ieee80211_hw");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* mac80211 clears hw->priv */
-       stlc = hw->priv;
-
-       stlc->hw = hw;
-       dev_set_drvdata(&spi->dev, stlc);
-       stlc->spi = spi;
-
-       spi->bits_per_word = 16;
-       spi->max_speed_hz = 24000000;
-
-       ret = spi_setup(spi);
-       if (ret < 0)
-               stlc45xx_error("spi_setup failed");
-
-       ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
-       if (ret < 0) {
-               stlc45xx_error("power GPIO request failed: %d", ret);
-               return ret;
-       }
-
-       ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
-       if (ret < 0) {
-               stlc45xx_error("irq GPIO request failed: %d", ret);
-               goto out;
-       }
-
-       gpio_direction_output(stlc45xx_gpio_power, 0);
-       gpio_direction_input(stlc45xx_gpio_irq);
-
-       ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
-                         stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
-                         stlc->spi);
-       if (ret < 0)
-               /* FIXME: handle the error */
-               stlc45xx_error("request_irq() failed");
-
-       set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
-                    IRQ_TYPE_EDGE_RISING);
-
-       disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
-
-       ret = platform_device_register(&stlc45xx_device);
-       if (ret) {
-               stlc45xx_error("Couldn't register wlan_omap device.");
-               return ret;
-       }
-       dev_set_drvdata(&stlc45xx_device.dev, stlc);
-
-       INIT_WORK(&stlc->work, stlc45xx_work);
-       INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
-       INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
-       mutex_init(&stlc->mutex);
-       init_completion(&stlc->fw_comp);
-       spin_lock_init(&stlc->tx_lock);
-       INIT_LIST_HEAD(&stlc->txbuffer);
-       INIT_LIST_HEAD(&stlc->tx_pending);
-       INIT_LIST_HEAD(&stlc->tx_sent);
-
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-               IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_NOISE_DBM;
-       /* four bytes for padding */
-       hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
-
-       /* unit us */
-       hw->channel_change_time = 1000;
-
-       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-       hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
-
-       SET_IEEE80211_DEV(hw, &spi->dev);
-
-       BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
-       BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
-
-       stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
-                                GFP_KERNEL);
-       stlc->cal_channels = kmemdup(default_cal_channels,
-                                    CHANNEL_CAL_ARRAY_LEN,
-                                    GFP_KERNEL);
-
-       ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
-       if (ret < 0) {
-               stlc45xx_error("failed to create sysfs file cal_rssi");
-               goto out;
-       }
-
-       ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
-       if (ret < 0) {
-               stlc45xx_error("failed to create sysfs file cal_channels");
-               goto out;
-       }
-
-       ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
-       if (ret < 0) {
-               stlc45xx_error("failed to create sysfs file tx_buf");
-               goto out;
-       }
-
-       ret = stlc45xx_register_mac80211(stlc);
-       if (ret < 0)
-               goto out;
-
-       stlc45xx_info("v" DRIVER_VERSION " loaded");
-
-       stlc45xx_info("config buffer 0x%x-0x%x",
-                     FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
-       stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
-                     FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
-                     FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
-
-out:
-       return ret;
-}
-
-static int __devexit stlc45xx_remove(struct spi_device *spi)
-{
-       struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       platform_device_unregister(&stlc45xx_device);
-
-       ieee80211_unregister_hw(stlc->hw);
-
-       free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
-
-       gpio_free(stlc45xx_gpio_power);
-       gpio_free(stlc45xx_gpio_irq);
-
-       /* FIXME: free cal_channels and cal_rssi? */
-
-       kfree(stlc->fw);
-
-       mutex_destroy(&stlc->mutex);
-
-       /* frees also stlc */
-       ieee80211_free_hw(stlc->hw);
-       stlc = NULL;
-
-       return 0;
-}
-
-
-static struct spi_driver stlc45xx_spi_driver = {
-       .driver = {
-               /* use cx3110x name because board-n800.c uses that for the
-                * SPI port */
-               .name           = "cx3110x",
-               .bus            = &spi_bus_type,
-               .owner          = THIS_MODULE,
-       },
-
-       .probe          = stlc45xx_probe,
-       .remove         = __devexit_p(stlc45xx_remove),
-};
-
-static int __init stlc45xx_init(void)
-{
-       int ret;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       ret = spi_register_driver(&stlc45xx_spi_driver);
-       if (ret < 0) {
-               stlc45xx_error("failed to register SPI driver: %d", ret);
-               goto out;
-       }
-
-out:
-       return ret;
-}
-
-static void __exit stlc45xx_exit(void)
-{
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       spi_unregister_driver(&stlc45xx_spi_driver);
-
-       stlc45xx_info("unloaded");
-}
-
-module_init(stlc45xx_init);
-module_exit(stlc45xx_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
-MODULE_ALIAS("spi:cx3110x");
diff --git a/drivers/staging/stlc45xx/stlc45xx.h b/drivers/staging/stlc45xx/stlc45xx.h
deleted file mode 100644 (file)
index ac96bbb..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * This file is part of stlc45xx
- *
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <net/mac80211.h>
-
-#include "stlc45xx_lmac.h"
-
-#define DRIVER_NAME "stlc45xx"
-#define DRIVER_VERSION "0.1.3"
-
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
-       DEBUG_NONE = 0,
-       DEBUG_FUNC = 1 << 0,
-       DEBUG_IRQ = 1 << 1,
-       DEBUG_BH = 1 << 2,
-       DEBUG_RX = 1 << 3,
-       DEBUG_RX_CONTENT = 1 << 5,
-       DEBUG_TX = 1 << 6,
-       DEBUG_TX_CONTENT = 1 << 8,
-       DEBUG_TXBUFFER = 1 << 9,
-       DEBUG_QUEUE = 1 << 10,
-       DEBUG_BOOT = 1 << 11,
-       DEBUG_PSM = 1 << 12,
-       DEBUG_ALL = ~0,
-};
-
-#define DEBUG_LEVEL DEBUG_NONE
-/* #define DEBUG_LEVEL DEBUG_ALL */
-/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */
-/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */
-/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */
-
-#define stlc45xx_error(fmt, arg...) \
-       printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define stlc45xx_warning(fmt, arg...) \
-       printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define stlc45xx_info(fmt, arg...) \
-       printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
-
-#define stlc45xx_debug(level, fmt, arg...) \
-       do { \
-               if (level & DEBUG_LEVEL) \
-                       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
-       } while (0)
-
-#define stlc45xx_dump(level, buf, len)         \
-       do { \
-               if (level & DEBUG_LEVEL) \
-                       print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
-                                      16, 1, buf, len, 1);             \
-       } while (0)
-
-#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5])
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
-/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
-#define ADDR_READ_BIT_15  0x8000
-
-#define SPI_ADRS_ARM_INTERRUPTS     0x00
-#define SPI_ADRS_ARM_INT_EN        0x04
-
-#define SPI_ADRS_HOST_INTERRUPTS    0x08
-#define SPI_ADRS_HOST_INT_EN       0x0c
-#define SPI_ADRS_HOST_INT_ACK      0x10
-
-#define SPI_ADRS_GEN_PURP_1        0x14
-#define SPI_ADRS_GEN_PURP_2        0x18
-
-/* high word */
-#define SPI_ADRS_DEV_CTRL_STAT      0x26
-
-#define SPI_ADRS_DMA_DATA                  0x28
-
-#define SPI_ADRS_DMA_WRITE_CTRL     0x2c
-#define SPI_ADRS_DMA_WRITE_LEN      0x2e
-#define SPI_ADRS_DMA_WRITE_BASE     0x30
-
-#define SPI_ADRS_DMA_READ_CTRL      0x34
-#define SPI_ADRS_DMA_READ_LEN       0x36
-#define SPI_ADRS_DMA_READ_BASE      0x38
-
-#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
-#define SPI_CTRL_STAT_START_HALTED  0x4000
-#define SPI_CTRL_STAT_RAM_BOOT      0x2000
-#define SPI_CTRL_STAT_HOST_RESET    0x1000
-#define SPI_CTRL_STAT_HOST_CPU_EN   0x0800
-
-#define SPI_DMA_WRITE_CTRL_ENABLE   0x0001
-#define SPI_DMA_READ_CTRL_ENABLE    0x0001
-#define HOST_ALLOWED                (1 << 7)
-
-#define FIRMWARE_ADDRESS                        0x20000
-
-#define SPI_TIMEOUT                             100         /* msec */
-
-#define SPI_MAX_TX_PACKETS                      32
-
-#define SPI_MAX_PACKET_SIZE                     32767
-
-#define SPI_TARGET_INT_WAKEUP                   0x00000001
-#define SPI_TARGET_INT_SLEEP                    0x00000002
-#define SPI_TARGET_INT_RDDONE                   0x00000004
-
-#define SPI_TARGET_INT_CTS                      0x00004000
-#define SPI_TARGET_INT_DR                       0x00008000
-
-#define SPI_HOST_INT_READY                      0x00000001
-#define SPI_HOST_INT_WR_READY                   0x00000002
-#define SPI_HOST_INT_SW_UPDATE                  0x00000004
-#define SPI_HOST_INT_UPDATE                     0x10000000
-
-/* clear to send */
-#define SPI_HOST_INT_CTS                       0x00004000
-
-/* data ready */
-#define SPI_HOST_INT_DR                                0x00008000
-
-#define SPI_HOST_INTS_DEFAULT \
-       (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
-
-#define TARGET_BOOT_SLEEP 50
-
-/* The firmware buffer is divided into three areas:
- *
- * o config area (for control commands)
- * o tx buffer
- * o rx buffer
- */
-#define FIRMWARE_BUFFER_START 0x20200
-#define FIRMWARE_BUFFER_END 0x27c60
-#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START)
-#define FIRMWARE_MTU 3240
-#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024
-#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START
-#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \
-                            FIRMWARE_CONFIG_PAYLOAD_LEN)
-#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1)
-#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024)
-#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN)
-#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \
-                              FIRMWARE_RXBUFFER_LEN - 1)
-#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN)
-#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \
-                              FIRMWARE_RXBUFFER_LEN)
-#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \
-                              FIRMWARE_TXBUFFER_LEN - 1)
-
-#define FIRMWARE_TXBUFFER_HEADER 100
-#define FIRMWARE_TXBUFFER_TRAILER 4
-
-/* FIXME: come up with a proper value */
-#define MAX_FRAME_LEN 2500
-
-/* unit is ms */
-#define TX_FRAME_LIFETIME 2000
-#define TX_TIMEOUT 4000
-
-#define SUPPORTED_CHANNELS 13
-
-/* FIXME */
-/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */
-/*     offsetof(struct s_lmo_scan, channel) */
-#define CHANNEL_CAL_LEN 292
-#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN)
-/* FIXME */
-/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */
-/*     offsetof(struct s_lmo_scan, rssical) */
-#define RSSI_CAL_LEN 8
-#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN)
-
-struct s_dma_regs {
-       unsigned short cmd;
-       unsigned short len;
-       unsigned long addr;
-};
-
-struct stlc45xx_ie_tim {
-       u8 dtim_count;
-       u8 dtim_period;
-       u8 bmap_control;
-       u8 pvbmap[251];
-};
-
-struct txbuffer {
-       /* can be removed when switched to skb queue */
-       struct list_head tx_list;
-
-       struct list_head buffer_list;
-
-       int start;
-       int frame_start;
-       int end;
-
-       struct sk_buff *skb;
-       u32 handle;
-
-       bool status_needed;
-
-       int header_len;
-
-       /* unit jiffies */
-       unsigned long lifetime;
-};
-
-enum fw_state {
-       FW_STATE_OFF,
-       FW_STATE_BOOTING,
-       FW_STATE_READY,
-       FW_STATE_RESET,
-       FW_STATE_RESETTING,
-};
-
-struct stlc45xx {
-       struct ieee80211_hw *hw;
-       struct spi_device *spi;
-       struct work_struct work;
-       struct work_struct work_reset;
-       struct delayed_work work_tx_timeout;
-       struct mutex mutex;
-       struct completion fw_comp;
-
-
-       u8 bssid[ETH_ALEN];
-       u8 mac_addr[ETH_ALEN];
-       int channel;
-
-       u8 *cal_rssi;
-       u8 *cal_channels;
-
-       enum fw_state fw_state;
-
-       spinlock_t tx_lock;
-
-       /* protected by tx_lock */
-       struct list_head txbuffer;
-
-       /* protected by tx_lock */
-       struct list_head tx_pending;
-
-       /* protected by tx_lock */
-       int tx_queue_stopped;
-
-       /* protected by mutex */
-       struct list_head tx_sent;
-
-       int tx_frames;
-
-       u8 *fw;
-       int fw_len;
-
-       bool psm;
-       bool associated;
-       int aid;
-       bool pspolling;
-};
-
-
diff --git a/drivers/staging/stlc45xx/stlc45xx_lmac.h b/drivers/staging/stlc45xx/stlc45xx_lmac.h
deleted file mode 100644 (file)
index af5db80..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/************************************************************************
-*  This is the LMAC API interface header file for STLC4560.            *
-*  Copyright (C) 2007 Conexant Systems, 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.               *
-*                                                                       *
-*  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 <http://www.gnu.org/licenses/>.*
-*************************************************************************/
-
-#ifndef __lmac_h__
-#define __lmac_h__
-
-#define LM_TOP_VARIANT      0x0506
-#define LM_BOTTOM_VARIANT   0x0506
-
-/*
- * LMAC - UMAC interface definition:
- */
-
-#define LM_FLAG_CONTROL     0x8000
-#define LM_FLAG_ALIGN       0x4000
-
-#define LM_CTRL_OPSET       0x0001
-
-#define LM_OUT_PROMISC      0x0001
-#define LM_OUT_TIMESTAMP    0x0002
-#define LM_OUT_SEQNR        0x0004
-#define LM_OUT_BURST        0x0010
-#define LM_OUT_NOCANCEL     0x0020
-#define LM_OUT_CLEARTIM     0x0040
-#define LM_OUT_HITCHHIKE    0x0080
-#define LM_OUT_COMPRESS     0x0100
-#define LM_OUT_CONCAT       0x0200
-#define LM_OUT_PCS_ACCEPT   0x0400
-#define LM_OUT_WAITEOSP     0x0800
-
-
-#define LM_ALOFT_SP         0x10
-#define LM_ALOFT_CTS        0x20
-#define LM_ALOFT_RTS        0x40
-#define LM_ALOFT_MASK       0x1f
-#define LM_ALOFT_RATE       0x0f
-
-#define LM_IN_FCS_GOOD      0x0001
-#define LM_IN_MATCH_MAC     0x0002
-#define LM_IN_MCBC          0x0004
-#define LM_IN_BEACON        0x0008
-#define LM_IN_MATCH_BSS     0x0010
-#define LM_IN_BCAST_BSS     0x0020
-#define LM_IN_DATA          0x0040
-#define LM_IN_TRUNCATED     0x0080
-
-#define LM_IN_TRANSPARENT   0x0200
-
-#define LM_QUEUE_BEACON     0
-#define LM_QUEUE_SCAN       1
-#define LM_QUEUE_MGT        2
-#define LM_QUEUE_MCBC       3
-#define LM_QUEUE_DATA       4
-#define LM_QUEUE_DATA0      4
-#define LM_QUEUE_DATA1      5
-#define LM_QUEUE_DATA2      6
-#define LM_QUEUE_DATA3      7
-
-#define LM_SETUP_INFRA          0x0001
-#define LM_SETUP_IBSS           0x0002
-#define LM_SETUP_TRANSPARENT    0x0008
-#define LM_SETUP_PROMISCUOUS    0x0010
-#define LM_SETUP_HIBERNATE      0x0020
-#define LM_SETUP_NOACK          0x0040
-#define LM_SETUP_RX_DISABLED    0x0080
-
-#define LM_ANTENNA_0            0
-#define LM_ANTENNA_1            1
-#define LM_ANTENNA_DIVERSITY    2
-
-#define LM_TX_FAILED            0x0001
-#define LM_TX_PSM               0x0002
-#define LM_TX_PSM_CANCELLED    0x0004
-
-#define LM_SCAN_EXIT            0x0001
-#define LM_SCAN_TRAP            0x0002
-#define LM_SCAN_ACTIVE          0x0004
-#define LM_SCAN_FILTER          0x0008
-
-#define LM_PSM                  0x0001
-#define LM_PSM_DTIM             0x0002
-#define LM_PSM_MCBC             0x0004
-#define LM_PSM_CHECKSUM         0x0008
-#define LM_PSM_SKIP_MORE_DATA   0x0010
-#define LM_PSM_BEACON_TIMEOUT   0x0020
-#define LM_PSM_HFOSLEEP         0x0040
-#define LM_PSM_AUTOSWITCH_SLEEP 0x0080
-#define        LM_PSM_LPIT             0x0100
-#define LM_PSM_BF_UCAST_SKIP    0x0200
-#define LM_PSM_BF_MCAST_SKIP    0x0400
-
-/* hfosleep */
-#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP)
-#define LM_PSM_SLEEP_OPTION_SHIFT       6
-/* hfosleepend */
-#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP)
-#define LM_PSM_BF_OPTION_SHIFT  9
-
-
-#define LM_PRIVACC_WEP          0x01
-#define LM_PRIVACC_TKIP         0x02
-#define LM_PRIVACC_MICHAEL      0x04
-#define LM_PRIVACC_CCX_KP       0x08
-#define LM_PRIVACC_CCX_MIC      0x10
-#define LM_PRIVACC_AES_CCMP     0x20
-
-/* size of s_lm_descr in words */
-#define LM_DESCR_SIZE_WORDS     11
-
-#ifndef __ASSEMBLER__
-
-enum {
-    LM_MODE_CLIENT = 0,
-    LM_MODE_AP
-};
-
-struct s_lm_descr {
-    uint16_t modes;
-    uint16_t flags;
-    uint32_t buffer_start;
-    uint32_t buffer_end;
-    uint8_t header;
-    uint8_t trailer;
-    uint8_t tx_queues;
-    uint8_t tx_depth;
-    uint8_t privacy;
-    uint8_t rx_keycache;
-    uint8_t tim_size;
-    uint8_t pad1;
-    uint8_t rates[16];
-    uint32_t link;
-       uint16_t mtu;
-};
-
-
-struct s_lm_control {
-    uint16_t flags;
-    uint16_t length;
-    uint32_t handle;
-    uint16_t oid;
-    uint16_t pad;
-    /* uint8_t data[]; */
-};
-
-enum {
-    LM_PRIV_NONE = 0,
-    LM_PRIV_WEP,
-    LM_PRIV_TKIP,
-    LM_PRIV_TKIPMICHAEL,
-    LM_PRIV_CCX_WEPMIC,
-    LM_PRIV_CCX_KPMIC,
-    LM_PRIV_CCX_KP,
-    LM_PRIV_AES_CCMP
-};
-
-enum {
-    LM_DECRYPT_NONE,
-    LM_DECRYPT_OK,
-    LM_DECRYPT_NOKEY,
-    LM_DECRYPT_NOMICHAEL,
-    LM_DECRYPT_NOCKIPMIC,
-    LM_DECRYPT_FAIL_WEP,
-    LM_DECRYPT_FAIL_TKIP,
-    LM_DECRYPT_FAIL_MICHAEL,
-    LM_DECRYPT_FAIL_CKIPKP,
-    LM_DECRYPT_FAIL_CKIPMIC,
-    LM_DECRYPT_FAIL_AESCCMP
-};
-
-struct s_lm_data_out {
-    uint16_t flags;
-    uint16_t length;
-    uint32_t handle;
-    uint16_t aid;
-    uint8_t rts_retries;
-    uint8_t retries;
-    uint8_t aloft[8];
-    uint8_t aloft_ctrl;
-    uint8_t crypt_offset;
-    uint8_t keytype;
-    uint8_t keylen;
-    uint8_t key[16];
-    uint8_t queue;
-    uint8_t backlog;
-    uint16_t durations[4];
-    uint8_t antenna;
-    uint8_t cts;
-    int16_t power;
-    uint8_t pad[2];
-    /*uint8_t data[];*/
-};
-
-#define LM_RCPI_INVALID         (0xff)
-
-struct s_lm_data_in {
-    uint16_t flags;
-    uint16_t length;
-    uint16_t frequency;
-    uint8_t antenna;
-    uint8_t rate;
-    uint8_t rcpi;
-    uint8_t sq;
-    uint8_t decrypt;
-    uint8_t rssi_raw;
-    uint32_t clock[2];
-    /*uint8_t data[];*/
-};
-
-union u_lm_data {
-    struct s_lm_data_out out;
-    struct s_lm_data_in in;
-};
-
-enum {
-    LM_OID_SETUP       = 0,
-    LM_OID_SCAN                = 1,
-    LM_OID_TRAP                = 2,
-    LM_OID_EDCF                = 3,
-    LM_OID_KEYCACHE    = 4,
-    LM_OID_PSM         = 6,
-    LM_OID_TXCANCEL    = 7,
-    LM_OID_TX          = 8,
-    LM_OID_BURST       = 9,
-    LM_OID_STATS       = 10,
-    LM_OID_LED         = 13,
-    LM_OID_TIMER       = 15,
-    LM_OID_NAV         = 20,
-    LM_OID_PCS         = 22,
-    LM_OID_BT_BALANCER  = 28,
-    LM_OID_GROUP_ADDRESS_TABLE = 30,
-    LM_OID_ARPTABLE     = 31,
-    LM_OID_BT_OPTIONS = 35
-};
-
-enum {
-    LM_FRONTEND_UNKNOWN = 0,
-    LM_FRONTEND_DUETTE3,
-    LM_FRONTEND_DUETTE2,
-    LM_FRONTEND_FRISBEE,
-    LM_FRONTEND_CROSSBOW,
-    LM_FRONTEND_LONGBOW
-};
-
-
-#define INVALID_LPF_BANDWIDTH   0xffff
-#define INVALID_OSC_START_DELAY 0xffff
-
-struct s_lmo_setup {
-    uint16_t flags;
-    uint8_t  macaddr[6];
-    uint8_t  bssid[6];
-    uint8_t  antenna;
-    uint8_t  rx_align;
-    uint32_t rx_buffer;
-    uint16_t rx_mtu;
-    uint16_t frontend;
-    uint16_t timeout;
-    uint16_t truncate;
-    uint32_t bratemask;
-    uint8_t  sbss_offset;
-    uint8_t  mcast_window;
-    uint8_t  rx_rssi_threshold;
-    uint8_t  rx_ed_threshold;
-    uint32_t ref_clock;
-    uint16_t lpf_bandwidth;
-    uint16_t osc_start_delay;
-};
-
-
-struct s_lmo_scan {
-    uint16_t flags;
-    uint16_t dwell;
-    uint8_t channel[292];
-    uint32_t bratemask;
-    uint8_t  aloft[8];
-    uint8_t  rssical[8];
-};
-
-
-enum {
-    LM_TRAP_SCAN = 0,
-    LM_TRAP_TIMER,
-    LM_TRAP_BEACON_TX,
-    LM_TRAP_FAA_RADIO_ON,
-    LM_TRAP_FAA_RADIO_OFF,
-    LM_TRAP_RADAR,
-    LM_TRAP_NO_BEACON,
-    LM_TRAP_TBTT,
-    LM_TRAP_SCO_ENTER,
-    LM_TRAP_SCO_EXIT
-};
-
-struct s_lmo_trap {
-    uint16_t event;
-    uint16_t frequency;
-};
-
-struct s_lmo_timer {
-    uint32_t interval;
-};
-
-struct s_lmo_nav {
-    uint32_t period;
-};
-
-
-struct s_lmo_edcf_queue;
-
-struct s_lmo_edcf {
-    uint8_t  flags;
-    uint8_t  slottime;
-    uint8_t  sifs;
-    uint8_t  eofpad;
-    struct s_lmo_edcf_queue {
-           uint8_t  aifs;
-           uint8_t  pad0;
-           uint16_t cwmin;
-           uint16_t cwmax;
-           uint16_t txop;
-    } queues[8];
-    uint8_t  mapping[4];
-    uint16_t maxburst;
-    uint16_t round_trip_delay;
-};
-
-struct s_lmo_keycache {
-    uint8_t entry;
-    uint8_t keyid;
-    uint8_t address[6];
-    uint8_t pad[2];
-    uint8_t keytype;
-    uint8_t keylen;
-    uint8_t key[24];
-};
-
-
-struct s_lm_interval;
-
-struct s_lmo_psm {
-    uint16_t    flags;
-    uint16_t    aid;
-    struct s_lm_interval {
-           uint16_t interval;
-           uint16_t periods;
-    } intervals[4];
-    /* uint16_t    pad; */
-    uint8_t     beacon_rcpi_skip_max;
-    uint8_t     rcpi_delta_threshold;
-    uint8_t     nr;
-    uint8_t     exclude[1];
-};
-
-#define MC_FILTER_ADDRESS_NUM   4
-
-struct s_lmo_group_address_table {
-    uint16_t    filter_enable;
-    uint16_t    num_address;
-    uint8_t     macaddr_list[MC_FILTER_ADDRESS_NUM][6];
-};
-
-struct s_lmo_txcancel {
-    uint32_t address[1];
-};
-
-
-struct s_lmo_tx {
-    uint8_t  flags;
-    uint8_t  retries;
-    uint8_t  rcpi;
-    uint8_t  sq;
-    uint16_t seqctrl;
-    uint8_t  antenna;
-    uint8_t  pad;
-};
-
-struct s_lmo_burst {
-    uint8_t  flags;
-    uint8_t  queue;
-    uint8_t  backlog;
-    uint8_t  pad;
-    uint16_t durations[32];
-};
-
-struct s_lmo_stats {
-    uint32_t valid;
-    uint32_t fcs;
-    uint32_t abort;
-    uint32_t phyabort;
-    uint32_t rts_success;
-    uint32_t rts_fail;
-    uint32_t timestamp;
-    uint32_t time_tx;
-    uint32_t noisefloor;
-    uint32_t sample_noise[8];
-    uint32_t sample_cca;
-    uint32_t sample_tx;
-};
-
-
-struct s_lmo_led {
-    uint16_t flags;
-    uint16_t mask[2];
-    uint16_t delay/*[2]*/;
-};
-
-
-struct s_lmo_bt_balancer {
-    uint16_t prio_thresh;
-    uint16_t acl_thresh;
-};
-
-
-struct s_lmo_arp_table {
-    uint16_t    filter_enable;
-    uint32_t    ipaddr;
-};
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* __lmac_h__ */
index 3d2a84c..e139eae 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/poll.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/sched.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 8960fa9..00fe080 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/sched.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 7f96bca..0518611 100644 (file)
@@ -1332,7 +1332,6 @@ device_release_WPADEV(pDevice);
         free_netdev(pDevice->dev);
     }
 
-       kfree(pDevice);
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
 }
 
index 940460c..132671d 100644 (file)
@@ -1,6 +1,6 @@
 config W35UND
        tristate "IS89C35 WLAN USB driver"
-       depends on MAC80211 && WLAN_80211 && USB && EXPERIMENTAL
+       depends on MAC80211 && WLAN && USB && EXPERIMENTAL
        default n
        ---help---
          This is highly experimental driver for Winbond WIFI card.
index 9959b65..f44294b 100644 (file)
@@ -1,6 +1,6 @@
 config PRISM2_USB
        tristate "Prism2.5/3 USB driver"
-       depends on WLAN_80211 && USB && WIRELESS_EXT
+       depends on WLAN && USB && WIRELESS_EXT
        default n
        ---help---
          This is the wlan-ng prism 2.5/3 USB driver for a wide range of
index 3335131..a18e3c5 100644 (file)
@@ -223,6 +223,7 @@ config USB_OTG
 config USB_GADGET_PXA25X
        boolean "PXA 25x or IXP 4xx"
        depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
+       select USB_OTG_UTILS
        help
           Intel's PXA 25x series XScale ARM-5TE processors include
           an integrated full speed USB 1.1 device controller.  The
index f37de28..167cb2a 100644 (file)
  * simpler, Microsoft pushes their own approach: RNDIS.  The published
  * RNDIS specs are ambiguous and appear to be incomplete, and are also
  * needlessly complex.  They borrow more from CDC ACM than CDC ECM.
- *
- * While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet
- * interface to the target, CDC EEM was designed to use ethernet over the USB
- * link between the host and target.  CDC EEM is implemented as an alternative
- * to those other protocols when that communication model is more appropriate
  */
 
 #define DRIVER_DESC            "Ethernet Gadget"
@@ -157,8 +152,8 @@ static inline bool has_rndis(void)
 #define RNDIS_PRODUCT_NUM      0xa4a2  /* Ethernet/RNDIS Gadget */
 
 /* For EEM gadgets */
-#define EEM_VENDOR_NUM 0x0525  /* INVALID - NEEDS TO BE ALLOCATED */
-#define EEM_PRODUCT_NUM        0xa4a1  /* INVALID - NEEDS TO BE ALLOCATED */
+#define EEM_VENDOR_NUM         0x1d6b  /* Linux Foundation */
+#define EEM_PRODUCT_NUM                0x0102  /* EEM Gadget */
 
 /*-------------------------------------------------------------------------*/
 
index 42a74b8..fa3d142 100644 (file)
@@ -2139,7 +2139,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 static void fsl_udc_release(struct device *dev)
 {
        complete(udc_controller->done);
-       dma_free_coherent(dev, udc_controller->ep_qh_size,
+       dma_free_coherent(dev->parent, udc_controller->ep_qh_size,
                        udc_controller->ep_qh, udc_controller->ep_qh_dma);
        kfree(udc_controller);
 }
index 3efa59b..b25cdea 100644 (file)
@@ -1400,6 +1400,10 @@ iso_stream_schedule (
                goto fail;
        }
 
+       period = urb->interval;
+       if (!stream->highspeed)
+               period <<= 3;
+
        now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
 
        /* when's the last uframe this urb could start? */
@@ -1417,8 +1421,8 @@ iso_stream_schedule (
 
                /* Fell behind (by up to twice the slop amount)? */
                if (start >= max - 2 * 8 * SCHEDULE_SLOP)
-                       start += stream->interval * DIV_ROUND_UP(
-                                       max - start, stream->interval) - mod;
+                       start += period * DIV_ROUND_UP(
+                                       max - start, period) - mod;
 
                /* Tried to schedule too far into the future? */
                if (unlikely((start + sched->span) >= max)) {
@@ -1441,10 +1445,6 @@ iso_stream_schedule (
 
        /* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
 
-       period = urb->interval;
-       if (!stream->highspeed)
-               period <<= 3;
-
        /* find a uframe slot with enough bandwidth */
        for (; start < (stream->next_uframe + period); start++) {
                int             enough_space;
index 749b537..e33d362 100644 (file)
@@ -1003,19 +1003,20 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
        if (syssts == SE0) {
                r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
                r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
-               return;
-       }
+       } else {
+               if (syssts == FS_JSTS)
+                       r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
+               else if (syssts == LS_JSTS)
+                       r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
 
-       if (syssts == FS_JSTS)
-               r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
-       else if (syssts == LS_JSTS)
-               r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
+               r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
+               r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
 
-       r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
-       r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
+               if (r8a66597->bus_suspended)
+                       usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+       }
 
-       if (r8a66597->bus_suspended)
-               usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+       usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597));
 }
 
 /* this function must be called with interrupt disabled */
@@ -1024,6 +1025,8 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port)
        u16 speed = get_rh_usb_speed(r8a66597, port);
        struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 
+       rh->port &= ~((1 << USB_PORT_FEAT_HIGHSPEED) |
+                     (1 << USB_PORT_FEAT_LOWSPEED));
        if (speed == HSMODE)
                rh->port |= (1 << USB_PORT_FEAT_HIGHSPEED);
        else if (speed == LSMODE)
index c632437..562eba1 100644 (file)
@@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
                if (status & QTD_STS_HALTED) {
                        /* Ug, an error. */
                        process_halted_qtd(whc, qset, td);
+                       /* A halted qTD always triggers an update
+                          because the qset was either removed or
+                          reactivated. */
+                       update |= WHC_UPDATE_UPDATED;
                        goto done;
                }
 
@@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
        struct whc_urb *wurb = urb->hcpriv;
        struct whc_qset *qset = wurb->qset;
        struct whc_std *std, *t;
+       bool has_qtd = false;
        int ret;
        unsigned long flags;
 
@@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
                goto out;
 
        list_for_each_entry_safe(std, t, &qset->stds, list_node) {
-               if (std->urb == urb)
+               if (std->urb == urb) {
+                       if (std->qtd)
+                               has_qtd = true;
                        qset_free_std(whc, std);
-               else
+               else
                        std->qtd = NULL; /* so this std is re-added when the qset is */
        }
 
-       asl_qset_remove(whc, qset);
-       wurb->status = status;
-       wurb->is_async = true;
-       queue_work(whc->workqueue, &wurb->dequeue_work);
-
+       if (has_qtd) {
+               asl_qset_remove(whc, qset);
+               wurb->status = status;
+               wurb->is_async = true;
+               queue_work(whc->workqueue, &wurb->dequeue_work);
+       } else
+               qset_remove_urb(whc, qset, urb, status);
 out:
        spin_unlock_irqrestore(&whc->lock, flags);
 
index a9e05ba..0db3fb2 100644 (file)
@@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
                if (status & QTD_STS_HALTED) {
                        /* Ug, an error. */
                        process_halted_qtd(whc, qset, td);
+                       /* A halted qTD always triggers an update
+                          because the qset was either removed or
+                          reactivated. */
+                       update |= WHC_UPDATE_UPDATED;
                        goto done;
                }
 
@@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
        struct whc_urb *wurb = urb->hcpriv;
        struct whc_qset *qset = wurb->qset;
        struct whc_std *std, *t;
+       bool has_qtd = false;
        int ret;
        unsigned long flags;
 
@@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
                goto out;
 
        list_for_each_entry_safe(std, t, &qset->stds, list_node) {
-               if (std->urb == urb)
+               if (std->urb == urb) {
+                       if (std->qtd)
+                               has_qtd = true;
                        qset_free_std(whc, std);
-               else
+               else
                        std->qtd = NULL; /* so this std is re-added when the qset is */
        }
 
-       pzl_qset_remove(whc, qset);
-       wurb->status = status;
-       wurb->is_async = false;
-       queue_work(whc->workqueue, &wurb->dequeue_work);
-
+       if (has_qtd) {
+               pzl_qset_remove(whc, qset);
+               update_pzl_hw_view(whc);
+               wurb->status = status;
+               wurb->is_async = false;
+               queue_work(whc->workqueue, &wurb->dequeue_work);
+       } else
+               qset_remove_urb(whc, qset, urb, status);
 out:
        spin_unlock_irqrestore(&whc->lock, flags);
 
index 760e727..b84abd8 100644 (file)
@@ -9,7 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options"
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
        depends on (USB || USB_GADGET)
-       depends on !SUPERH
+       depends on (ARM || BLACKFIN)
        select NOP_USB_XCEIV if ARCH_DAVINCI
        select TWL4030_USB if MACH_OMAP_3430SDP
        select NOP_USB_XCEIV if MACH_OMAP3EVM
index 43c2270..cd44c68 100644 (file)
@@ -315,6 +315,9 @@ static int  option_resume(struct usb_serial *serial);
 #define QISDA_PRODUCT_H20_4515                 0x4515
 #define QISDA_PRODUCT_H20_4519                 0x4519
 
+/* TLAYTECH PRODUCTS */
+#define TLAYTECH_VENDOR_ID                     0x20B9
+#define TLAYTECH_PRODUCT_TEU800                        0x1682
 
 /* TOSHIBA PRODUCTS */
 #define TOSHIBA_VENDOR_ID                      0x0930
@@ -328,6 +331,9 @@ static int  option_resume(struct usb_serial *serial);
 #define ALCATEL_VENDOR_ID                      0x1bbb
 #define ALCATEL_PRODUCT_X060S                  0x0000
 
+/* Airplus products */
+#define AIRPLUS_VENDOR_ID                      0x1011
+#define AIRPLUS_PRODUCT_MCD650                 0x3198
 
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -589,6 +595,8 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
        { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
        { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
+       { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+       { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 4588398..5019325 100644 (file)
@@ -296,7 +296,6 @@ struct sierra_port_private {
        int dsr_state;
        int dcd_state;
        int ri_state;
-
        unsigned int opened:1;
 };
 
@@ -306,6 +305,8 @@ static int sierra_send_setup(struct usb_serial_port *port)
        struct sierra_port_private *portdata;
        __u16 interface = 0;
        int val = 0;
+       int do_send = 0;
+       int retval;
 
        dev_dbg(&port->dev, "%s\n", __func__);
 
@@ -324,10 +325,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
                 */
                if (port->interrupt_in_urb) {
                        /* send control message */
-                       return usb_control_msg(serial->dev,
-                               usb_rcvctrlpipe(serial->dev, 0),
-                               0x22, 0x21, val, interface,
-                               NULL, 0, USB_CTRL_SET_TIMEOUT);
+                       do_send = 1;
                }
        }
 
@@ -339,12 +337,18 @@ static int sierra_send_setup(struct usb_serial_port *port)
                        interface = 1;
                else if (port->bulk_out_endpointAddress == 5)
                        interface = 2;
-               return usb_control_msg(serial->dev,
-                       usb_rcvctrlpipe(serial->dev, 0),
-                       0x22, 0x21, val, interface,
-                       NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+               do_send = 1;
        }
-       return 0;
+       if (!do_send)
+               return 0;
+
+       usb_autopm_get_interface(serial->interface);
+       retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+               0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
+       usb_autopm_put_interface(serial->interface);
+
+       return retval;
 }
 
 static void sierra_set_termios(struct tty_struct *tty,
@@ -773,8 +777,11 @@ static void sierra_close(struct usb_serial_port *port)
 
        if (serial->dev) {
                mutex_lock(&serial->disc_mutex);
-               if (!serial->disconnected)
+               if (!serial->disconnected) {
+                       serial->interface->needs_remote_wakeup = 0;
+                       usb_autopm_get_interface(serial->interface);
                        sierra_send_setup(port);
+               }
                mutex_unlock(&serial->disc_mutex);
                spin_lock_irq(&intfdata->susp_lock);
                portdata->opened = 0;
@@ -788,8 +795,6 @@ static void sierra_close(struct usb_serial_port *port)
                        sierra_release_urb(portdata->in_urbs[i]);
                        portdata->in_urbs[i] = NULL;
                }
-               usb_autopm_get_interface(serial->interface);
-               serial->interface->needs_remote_wakeup = 0;
        }
 }
 
@@ -827,6 +832,8 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
        if (err) {
                /* get rid of everything as in close */
                sierra_close(port);
+               /* restore balance for autopm */
+               usb_autopm_put_interface(serial->interface);
                return err;
        }
        sierra_send_setup(port);
@@ -915,7 +922,7 @@ static void sierra_release(struct usb_serial *serial)
 #ifdef CONFIG_PM
 static void stop_read_write_urbs(struct usb_serial *serial)
 {
-       int i, j;
+       int i;
        struct usb_serial_port *port;
        struct sierra_port_private *portdata;
 
@@ -923,8 +930,7 @@ static void stop_read_write_urbs(struct usb_serial *serial)
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                portdata = usb_get_serial_port_data(port);
-               for (j = 0; j < N_IN_URB; j++)
-                       usb_kill_urb(portdata->in_urbs[j]);
+               sierra_stop_rx_urbs(port);
                usb_kill_anchored_urbs(&portdata->active);
        }
 }
index 3a4fb02..589f6b4 100644 (file)
@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                /* device supports and needs bigger sense buffer */
                if (us->fflags & US_FL_SANE_SENSE)
                        sense_size = ~0;
-
+Retry_Sense:
                US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
 
                scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                        srb->result = DID_ABORT << 16;
                        goto Handle_Errors;
                }
+
+               /* Some devices claim to support larger sense but fail when
+                * trying to request it. When a transport failure happens
+                * using US_FS_SANE_SENSE, we always retry with a standard
+                * (small) sense request. This fixes some USB GSM modems
+                */
+               if (temp_result == USB_STOR_TRANSPORT_FAILED &&
+                   (us->fflags & US_FL_SANE_SENSE) &&
+                   sense_size != US_SENSE_SIZE) {
+                       US_DEBUGP("-- auto-sense failure, retry small sense\n");
+                       sense_size = US_SENSE_SIZE;
+                       goto Retry_Sense;
+               }
+
+               /* Other failures */
                if (temp_result != USB_STOR_TRANSPORT_GOOD) {
                        US_DEBUGP("-- auto-sense failure\n");
 
index b2f149f..4516c36 100644 (file)
@@ -200,35 +200,40 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
 {
        int result, bytes, secd_size;
        struct device *dev = &usb_dev->dev;
-       struct usb_security_descriptor secd;
+       struct usb_security_descriptor *secd;
        const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
-       void *secd_buf;
        const void *itr, *top;
        char buf[64];
 
+       secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
+       if (secd == NULL) {
+               result = -ENOMEM;
+               goto out;
+       }
+
        result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
-                                   0, &secd, sizeof(secd));
+                                   0, secd, sizeof(struct usb_security_descriptor));
        if (result < sizeof(secd)) {
                dev_err(dev, "Can't read security descriptor or "
                        "not enough data: %d\n", result);
-               goto error_secd;
+               goto out;
        }
-       secd_size = le16_to_cpu(secd.wTotalLength);
-       secd_buf = kmalloc(secd_size, GFP_KERNEL);
-       if (secd_buf == NULL) {
+       secd_size = le16_to_cpu(secd->wTotalLength);
+       secd = krealloc(secd, secd_size, GFP_KERNEL);
+       if (secd == NULL) {
                dev_err(dev, "Can't allocate space for security descriptors\n");
-               goto error_secd_alloc;
+               goto out;
        }
        result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
-                                   0, secd_buf, secd_size);
+                                   0, secd, secd_size);
        if (result < secd_size) {
                dev_err(dev, "Can't read security descriptor or "
                        "not enough data: %d\n", result);
-               goto error_secd_all;
+               goto out;
        }
        bytes = 0;
-       itr = secd_buf + sizeof(secd);
-       top = secd_buf + result;
+       itr = &secd[1];
+       top = (void *)secd + result;
        while (itr < top) {
                etd = itr;
                if (top - itr < sizeof(*etd)) {
@@ -259,24 +264,16 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
                dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
                        "can't use!\n");
                result = -EINVAL;
-               goto error_no_ccm1;
+               goto out;
        }
        wusb_dev->ccm1_etd = *ccm1_etd;
        dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
                buf, wusb_et_name(ccm1_etd->bEncryptionType),
                ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
        result = 0;
-       kfree(secd_buf);
 out:
+       kfree(secd);
        return result;
-
-
-error_no_ccm1:
-error_secd_all:
-       kfree(secd_buf);
-error_secd_alloc:
-error_secd:
-       goto out;
 }
 
 void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
index 200c22f..9dd5880 100644 (file)
@@ -19,7 +19,6 @@
  */
 //#define DEBUG
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_balloon.h>
 #include <linux/swap.h>
 #include <linux/kthread.h>
@@ -248,7 +247,7 @@ out:
        return err;
 }
 
-static void virtballoon_remove(struct virtio_device *vdev)
+static void __devexit virtballoon_remove(struct virtio_device *vdev)
 {
        struct virtio_balloon *vb = vdev->priv;
 
index 4a1f1eb..28d9cf7 100644 (file)
@@ -530,19 +530,22 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
                        err = PTR_ERR(vqs[i]);
                        goto error_find;
                }
+
+               if (!vp_dev->per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR)
+                       continue;
+
                /* allocate per-vq irq if available and necessary */
-               if (vp_dev->per_vq_vectors) {
-                       snprintf(vp_dev->msix_names[msix_vec],
-                                sizeof *vp_dev->msix_names,
-                                "%s-%s",
-                                dev_name(&vp_dev->vdev.dev), names[i]);
-                       err = request_irq(msix_vec, vring_interrupt, 0,
-                                         vp_dev->msix_names[msix_vec],
-                                         vqs[i]);
-                       if (err) {
-                               vp_del_vq(vqs[i]);
-                               goto error_find;
-                       }
+               snprintf(vp_dev->msix_names[msix_vec],
+                        sizeof *vp_dev->msix_names,
+                        "%s-%s",
+                        dev_name(&vp_dev->vdev.dev), names[i]);
+               err = request_irq(vp_dev->msix_entries[msix_vec].vector,
+                                 vring_interrupt, 0,
+                                 vp_dev->msix_names[msix_vec],
+                                 vqs[i]);
+               if (err) {
+                       vp_del_vq(vqs[i]);
+                       goto error_find;
                }
        }
        return 0;
index f536005..fbd2ecd 100644 (file)
@@ -285,6 +285,9 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
                return NULL;
        }
 
+       /* Only get used array entries after they have been exposed by host. */
+       rmb();
+
        i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
        *len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
 
index 1e8f02f..d3c824d 100644 (file)
@@ -206,7 +206,7 @@ static int __devinit riowd_probe(struct of_device *op,
 
        dev_set_drvdata(&op->dev, p);
        riowd_device = p;
-       err = 0;
+       return 0;
 
 out_iounmap:
        of_iounmap(&op->resource[0], p->regs, 2);
index d4bf8ca..2126078 100644 (file)
@@ -135,8 +135,8 @@ config TMPFS_POSIX_ACL
 
 config HUGETLBFS
        bool "HugeTLB file system support"
-       depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
-                  (S390 && 64BIT) || SYS_SUPPORTS_HUGETLBFS || BROKEN
+       depends on X86 || IA64 || PPC_BOOK3S_64 || SPARC64 || (S390 && 64BIT) || \
+                  SYS_SUPPORTS_HUGETLBFS || BROKEN
        help
          hugetlbfs is a filesystem backing for HugeTLB pages, based on
          ramfs. For architectures that support it, say Y here and read
index 9cf4b92..8bed055 100644 (file)
@@ -1248,8 +1248,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                        bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
                }
        } else {
-               put_disk(disk);
                module_put(disk->fops->owner);
+               put_disk(disk);
                disk = NULL;
                if (bdev->bd_contains == bdev) {
                        if (bdev->bd_disk->fops->open) {
index 69b355a..3616042 100644 (file)
@@ -27,7 +27,7 @@
 #include "btrfs_inode.h"
 #include "xattr.h"
 
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
 
 static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
 {
@@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = {
        .set    = btrfs_xattr_acl_access_set,
 };
 
-#else /* CONFIG_BTRFS_POSIX_ACL */
+#else /* CONFIG_BTRFS_FS_POSIX_ACL */
 
 int btrfs_acl_chmod(struct inode *inode)
 {
@@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
        return 0;
 }
 
-#endif /* CONFIG_BTRFS_POSIX_ACL */
+#endif /* CONFIG_BTRFS_FS_POSIX_ACL */
index c71abec..f6783a4 100644 (file)
@@ -86,6 +86,12 @@ struct btrfs_inode {
         * transid of the trans_handle that last modified this inode
         */
        u64 last_trans;
+
+       /*
+        * log transid when this inode was last modified
+        */
+       u64 last_sub_trans;
+
        /*
         * transid that last logged this inode
         */
index 1bb897e..444b3e9 100644 (file)
@@ -1009,6 +1009,7 @@ struct btrfs_root {
        atomic_t log_writers;
        atomic_t log_commit[2];
        unsigned long log_transid;
+       unsigned long last_log_commit;
        unsigned long log_batch;
        pid_t log_start_pid;
        bool log_multiple_pids;
@@ -1152,6 +1153,7 @@ struct btrfs_root {
 #define BTRFS_MOUNT_FLUSHONCOMMIT       (1 << 7)
 #define BTRFS_MOUNT_SSD_SPREAD         (1 << 8)
 #define BTRFS_MOUNT_NOSSD              (1 << 9)
+#define BTRFS_MOUNT_DISCARD            (1 << 10)
 
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
@@ -2373,7 +2375,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options);
 int btrfs_sync_fs(struct super_block *sb, int wait);
 
 /* acl.c */
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
 int btrfs_check_acl(struct inode *inode, int mask);
 #else
 #define btrfs_check_acl NULL
index 100551a..02b6afb 100644 (file)
@@ -917,6 +917,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
        atomic_set(&root->log_writers, 0);
        root->log_batch = 0;
        root->log_transid = 0;
+       root->last_log_commit = 0;
        extent_io_tree_init(&root->dirty_log_pages,
                             fs_info->btree_inode->i_mapping, GFP_NOFS);
 
@@ -1087,6 +1088,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
        WARN_ON(root->log_root);
        root->log_root = log_root;
        root->log_transid = 0;
+       root->last_log_commit = 0;
        return 0;
 }
 
index d0c4d58..e238a0c 100644 (file)
@@ -1568,23 +1568,23 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-#ifdef BIO_RW_DISCARD
 static void btrfs_issue_discard(struct block_device *bdev,
                                u64 start, u64 len)
 {
        blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL,
                             DISCARD_FL_BARRIER);
 }
-#endif
 
 static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
                                u64 num_bytes)
 {
-#ifdef BIO_RW_DISCARD
        int ret;
        u64 map_length = num_bytes;
        struct btrfs_multi_bio *multi = NULL;
 
+       if (!btrfs_test_opt(root, DISCARD))
+               return 0;
+
        /* Tell the block device(s) that the sectors can be discarded */
        ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
                              bytenr, &map_length, &multi, 0);
@@ -1604,9 +1604,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
        }
 
        return ret;
-#else
-       return 0;
-#endif
 }
 
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
@@ -3690,6 +3687,14 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
        if (is_data)
                goto pinit;
 
+       /*
+        * discard is sloooow, and so triggering discards on
+        * individual btree blocks isn't a good plan.  Just
+        * pin everything in discard mode.
+        */
+       if (btrfs_test_opt(root, DISCARD))
+               goto pinit;
+
        buf = btrfs_find_tree_block(root, bytenr, num_bytes);
        if (!buf)
                goto pinit;
index 2d623aa..06550af 100644 (file)
@@ -1086,8 +1086,10 @@ out_nolock:
                                        btrfs_end_transaction(trans, root);
                                else
                                        btrfs_commit_transaction(trans, root);
-                       } else {
+                       } else if (ret != BTRFS_NO_LOG_SYNC) {
                                btrfs_commit_transaction(trans, root);
+                       } else {
+                               btrfs_end_transaction(trans, root);
                        }
                }
                if (file->f_flags & O_DIRECT) {
@@ -1137,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
        int ret = 0;
        struct btrfs_trans_handle *trans;
 
+
+       /* we wait first, since the writeback may change the inode */
+       root->log_batch++;
+       /* the VFS called filemap_fdatawrite for us */
+       btrfs_wait_ordered_range(inode, 0, (u64)-1);
+       root->log_batch++;
+
        /*
         * check the transaction that last modified this inode
         * and see if its already been committed
@@ -1144,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
        if (!BTRFS_I(inode)->last_trans)
                goto out;
 
+       /*
+        * if the last transaction that changed this file was before
+        * the current transaction, we can bail out now without any
+        * syncing
+        */
        mutex_lock(&root->fs_info->trans_mutex);
        if (BTRFS_I(inode)->last_trans <=
            root->fs_info->last_trans_committed) {
@@ -1153,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
        }
        mutex_unlock(&root->fs_info->trans_mutex);
 
-       root->log_batch++;
-       filemap_fdatawrite(inode->i_mapping);
-       btrfs_wait_ordered_range(inode, 0, (u64)-1);
-       root->log_batch++;
-
-       if (datasync && !(inode->i_state & I_DIRTY_PAGES))
-               goto out;
        /*
         * ok we haven't committed the transaction yet, lets do a commit
         */
@@ -1188,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
         */
        mutex_unlock(&dentry->d_inode->i_mutex);
 
-       if (ret > 0) {
-               ret = btrfs_commit_transaction(trans, root);
-       } else {
-               ret = btrfs_sync_log(trans, root);
-               if (ret == 0)
-                       ret = btrfs_end_transaction(trans, root);
-               else
+       if (ret != BTRFS_NO_LOG_SYNC) {
+               if (ret > 0) {
                        ret = btrfs_commit_transaction(trans, root);
+               } else {
+                       ret = btrfs_sync_log(trans, root);
+                       if (ret == 0)
+                               ret = btrfs_end_transaction(trans, root);
+                       else
+                               ret = btrfs_commit_transaction(trans, root);
+               }
+       } else {
+               ret = btrfs_end_transaction(trans, root);
        }
        mutex_lock(&dentry->d_inode->i_mutex);
 out:
index 9e138b7..dae12dc 100644 (file)
@@ -3032,12 +3032,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
 
        if ((offset & (blocksize - 1)) == 0)
                goto out;
+       ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
+       if (ret)
+               goto out;
+
+       ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+       if (ret)
+               goto out;
 
        ret = -ENOMEM;
 again:
        page = grab_cache_page(mapping, index);
-       if (!page)
+       if (!page) {
+               btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+               btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
                goto out;
+       }
 
        page_start = page_offset(page);
        page_end = page_start + PAGE_CACHE_SIZE - 1;
@@ -3070,6 +3080,10 @@ again:
                goto again;
        }
 
+       clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+                         EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+                         GFP_NOFS);
+
        ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
        if (ret) {
                unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
@@ -3088,6 +3102,9 @@ again:
        unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
 
 out_unlock:
+       if (ret)
+               btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+       btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
        unlock_page(page);
        page_cache_release(page);
 out:
@@ -3111,7 +3128,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
        if (size <= hole_start)
                return 0;
 
-       btrfs_truncate_page(inode->i_mapping, inode->i_size);
+       err = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+       if (err)
+               return err;
 
        while (1) {
                struct btrfs_ordered_extent *ordered;
@@ -3480,6 +3499,7 @@ static noinline void init_btrfs_i(struct inode *inode)
        bi->generation = 0;
        bi->sequence = 0;
        bi->last_trans = 0;
+       bi->last_sub_trans = 0;
        bi->logged_trans = 0;
        bi->delalloc_bytes = 0;
        bi->reserved_bytes = 0;
@@ -4980,7 +5000,9 @@ again:
        set_page_dirty(page);
        SetPageUptodate(page);
 
-       BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
+       BTRFS_I(inode)->last_trans = root->fs_info->generation;
+       BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+
        unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
 
 out_unlock:
@@ -5005,7 +5027,9 @@ static void btrfs_truncate(struct inode *inode)
        if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
                return;
 
-       btrfs_truncate_page(inode->i_mapping, inode->i_size);
+       ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+       if (ret)
+               return;
        btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
 
        trans = btrfs_start_transaction(root, 1);
@@ -5100,6 +5124,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
        if (!ei)
                return NULL;
        ei->last_trans = 0;
+       ei->last_sub_trans = 0;
        ei->logged_trans = 0;
        ei->outstanding_extents = 0;
        ei->reserved_extents = 0;
index 9de9b22..752a546 100644 (file)
@@ -66,7 +66,8 @@ enum {
        Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
        Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
        Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
-       Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err,
+       Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
+       Opt_discard, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -88,6 +89,7 @@ static match_table_t tokens = {
        {Opt_notreelog, "notreelog"},
        {Opt_flushoncommit, "flushoncommit"},
        {Opt_ratio, "metadata_ratio=%d"},
+       {Opt_discard, "discard"},
        {Opt_err, NULL},
 };
 
@@ -257,6 +259,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                       info->metadata_ratio);
                        }
                        break;
+               case Opt_discard:
+                       btrfs_set_opt(info->mount_opt, DISCARD);
+                       break;
                default:
                        break;
                }
@@ -344,7 +349,7 @@ static int btrfs_fill_super(struct super_block *sb,
        sb->s_export_op = &btrfs_export_ops;
        sb->s_xattr = btrfs_xattr_handlers;
        sb->s_time_gran = 1;
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
 #endif
 
index 0b8f36d..bca82a4 100644 (file)
@@ -344,10 +344,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
 /*
  * when btree blocks are allocated, they have some corresponding bits set for
  * them in one of two extent_io trees.  This is used to make sure all of
- * those extents are on disk for transaction or log commit
+ * those extents are sent to disk but does not wait on them
  */
-int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
-                                       struct extent_io_tree *dirty_pages)
+int btrfs_write_marked_extents(struct btrfs_root *root,
+                              struct extent_io_tree *dirty_pages)
 {
        int ret;
        int err = 0;
@@ -394,6 +394,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
                        page_cache_release(page);
                }
        }
+       if (err)
+               werr = err;
+       return werr;
+}
+
+/*
+ * when btree blocks are allocated, they have some corresponding bits set for
+ * them in one of two extent_io trees.  This is used to make sure all of
+ * those extents are on disk for transaction or log commit.  We wait
+ * on all the pages and clear them from the dirty pages state tree
+ */
+int btrfs_wait_marked_extents(struct btrfs_root *root,
+                             struct extent_io_tree *dirty_pages)
+{
+       int ret;
+       int err = 0;
+       int werr = 0;
+       struct page *page;
+       struct inode *btree_inode = root->fs_info->btree_inode;
+       u64 start = 0;
+       u64 end;
+       unsigned long index;
+
        while (1) {
                ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
                                            EXTENT_DIRTY);
@@ -424,6 +447,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
        return werr;
 }
 
+/*
+ * when btree blocks are allocated, they have some corresponding bits set for
+ * them in one of two extent_io trees.  This is used to make sure all of
+ * those extents are on disk for transaction or log commit
+ */
+int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
+                                       struct extent_io_tree *dirty_pages)
+{
+       int ret;
+       int ret2;
+
+       ret = btrfs_write_marked_extents(root, dirty_pages);
+       ret2 = btrfs_wait_marked_extents(root, dirty_pages);
+       return ret || ret2;
+}
+
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root)
 {
index 663c674..d4e3e7a 100644 (file)
@@ -79,6 +79,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
                                              struct inode *inode)
 {
        BTRFS_I(inode)->last_trans = trans->transaction->transid;
+       BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
 }
 
 int btrfs_end_transaction(struct btrfs_trans_handle *trans,
@@ -107,5 +108,9 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root);
 int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
                                        struct extent_io_tree *dirty_pages);
+int btrfs_write_marked_extents(struct btrfs_root *root,
+                                       struct extent_io_tree *dirty_pages);
+int btrfs_wait_marked_extents(struct btrfs_root *root,
+                                       struct extent_io_tree *dirty_pages);
 int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
 #endif
index 4edfdc2..741666a 100644 (file)
@@ -1980,6 +1980,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        int ret;
        struct btrfs_root *log = root->log_root;
        struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
+       u64 log_transid = 0;
 
        mutex_lock(&root->log_mutex);
        index1 = root->log_transid % 2;
@@ -1994,12 +1995,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
                wait_log_commit(trans, root, root->log_transid - 1);
 
-       while (root->log_multiple_pids) {
+       while (1) {
                unsigned long batch = root->log_batch;
-               mutex_unlock(&root->log_mutex);
-               schedule_timeout_uninterruptible(1);
-               mutex_lock(&root->log_mutex);
-
+               if (root->log_multiple_pids) {
+                       mutex_unlock(&root->log_mutex);
+                       schedule_timeout_uninterruptible(1);
+                       mutex_lock(&root->log_mutex);
+               }
                wait_for_writer(trans, root);
                if (batch == root->log_batch)
                        break;
@@ -2012,12 +2014,16 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages);
+       /* we start IO on  all the marked extents here, but we don't actually
+        * wait for them until later.
+        */
+       ret = btrfs_write_marked_extents(log, &log->dirty_log_pages);
        BUG_ON(ret);
 
        btrfs_set_root_node(&log->root_item, log->node);
 
        root->log_batch = 0;
+       log_transid = root->log_transid;
        root->log_transid++;
        log->log_transid = root->log_transid;
        root->log_start_pid = 0;
@@ -2046,6 +2052,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
 
        index2 = log_root_tree->log_transid % 2;
        if (atomic_read(&log_root_tree->log_commit[index2])) {
+               btrfs_wait_marked_extents(log, &log->dirty_log_pages);
                wait_log_commit(trans, log_root_tree,
                                log_root_tree->log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
@@ -2065,6 +2072,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * check the full commit flag again
         */
        if (root->fs_info->last_trans_log_full_commit == trans->transid) {
+               btrfs_wait_marked_extents(log, &log->dirty_log_pages);
                mutex_unlock(&log_root_tree->log_mutex);
                ret = -EAGAIN;
                goto out_wake_log_root;
@@ -2073,6 +2081,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        ret = btrfs_write_and_wait_marked_extents(log_root_tree,
                                &log_root_tree->dirty_log_pages);
        BUG_ON(ret);
+       btrfs_wait_marked_extents(log, &log->dirty_log_pages);
 
        btrfs_set_super_log_root(&root->fs_info->super_for_commit,
                                log_root_tree->node->start);
@@ -2092,9 +2101,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * the running transaction open, so a full commit can't hop
         * in and cause problems either.
         */
-       write_ctree_super(trans, root->fs_info->tree_root, 2);
+       write_ctree_super(trans, root->fs_info->tree_root, 1);
        ret = 0;
 
+       mutex_lock(&root->log_mutex);
+       if (root->last_log_commit < log_transid)
+               root->last_log_commit = log_transid;
+       mutex_unlock(&root->log_mutex);
+
 out_wake_log_root:
        atomic_set(&log_root_tree->log_commit[index2], 0);
        smp_mb();
@@ -2862,6 +2876,21 @@ out:
        return ret;
 }
 
+static int inode_in_log(struct btrfs_trans_handle *trans,
+                struct inode *inode)
+{
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       int ret = 0;
+
+       mutex_lock(&root->log_mutex);
+       if (BTRFS_I(inode)->logged_trans == trans->transid &&
+           BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
+               ret = 1;
+       mutex_unlock(&root->log_mutex);
+       return ret;
+}
+
+
 /*
  * helper function around btrfs_log_inode to make sure newly created
  * parent directories also end up in the log.  A minimal inode and backref
@@ -2901,6 +2930,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
        if (ret)
                goto end_no_trans;
 
+       if (inode_in_log(trans, inode)) {
+               ret = BTRFS_NO_LOG_SYNC;
+               goto end_no_trans;
+       }
+
        start_log_trans(trans, root);
 
        ret = btrfs_log_inode(trans, root, inode, inode_only);
index d09c760..0776eac 100644 (file)
@@ -19,6 +19,9 @@
 #ifndef __TREE_LOG_
 #define __TREE_LOG_
 
+/* return value for btrfs_log_dentry_safe that means we don't need to log it at all */
+#define BTRFS_NO_LOG_SYNC 256
+
 int btrfs_sync_log(struct btrfs_trans_handle *trans,
                   struct btrfs_root *root);
 int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root);
index b0fc93f..b6dd596 100644 (file)
@@ -260,7 +260,7 @@ err:
  * attributes are handled directly.
  */
 struct xattr_handler *btrfs_xattr_handlers[] = {
-#ifdef CONFIG_BTRFS_POSIX_ACL
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
        &btrfs_xattr_acl_access_handler,
        &btrfs_xattr_acl_default_handler,
 #endif
index 43003e0..b090980 100644 (file)
@@ -1577,7 +1577,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 
 out_err:
        if (tcp_ses) {
-               kfree(tcp_ses->hostname);
+               if (!IS_ERR(tcp_ses->hostname))
+                       kfree(tcp_ses->hostname);
                if (tcp_ses->ssocket)
                        sock_release(tcp_ses->ssocket);
                kfree(tcp_ses);
index 240cef1..70736eb 100644 (file)
@@ -316,6 +316,10 @@ int dlm_lowcomms_connect_node(int nodeid)
 {
        struct connection *con;
 
+       /* with sctp there's no connecting without sending */
+       if (dlm_config.ci_protocol != 0)
+               return 0;
+
        if (nodeid == dlm_our_nodeid())
                return 0;
 
@@ -455,9 +459,9 @@ static void process_sctp_notification(struct connection *con,
                        int prim_len, ret;
                        int addr_len;
                        struct connection *new_con;
-                       struct file *file;
                        sctp_peeloff_arg_t parg;
                        int parglen = sizeof(parg);
+                       int err;
 
                        /*
                         * We get this before any data for an association.
@@ -512,19 +516,22 @@ static void process_sctp_notification(struct connection *con,
                        ret = kernel_getsockopt(con->sock, IPPROTO_SCTP,
                                                SCTP_SOCKOPT_PEELOFF,
                                                (void *)&parg, &parglen);
-                       if (ret) {
+                       if (ret < 0) {
                                log_print("Can't peel off a socket for "
-                                         "connection %d to node %d: err=%d\n",
+                                         "connection %d to node %d: err=%d",
                                          parg.associd, nodeid, ret);
+                               return;
+                       }
+                       new_con->sock = sockfd_lookup(parg.sd, &err);
+                       if (!new_con->sock) {
+                               log_print("sockfd_lookup error %d", err);
+                               return;
                        }
-                       file = fget(parg.sd);
-                       new_con->sock = SOCKET_I(file->f_dentry->d_inode);
                        add_sock(new_con->sock, new_con);
-                       fput(file);
-                       put_unused_fd(parg.sd);
+                       sockfd_put(new_con->sock);
 
-                       log_print("got new/restarted association %d nodeid %d",
-                                (int)sn->sn_assoc_change.sac_assoc_id, nodeid);
+                       log_print("connecting to %d sctp association %d",
+                                nodeid, (int)sn->sn_assoc_change.sac_assoc_id);
 
                        /* Send any pending writes */
                        clear_bit(CF_CONNECT_PENDING, &new_con->flags);
@@ -837,8 +844,6 @@ static void sctp_init_assoc(struct connection *con)
        if (con->retries++ > MAX_CONNECT_RETRIES)
                return;
 
-       log_print("Initiating association with node %d", con->nodeid);
-
        if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) {
                log_print("no address for nodeid %d", con->nodeid);
                return;
@@ -855,11 +860,14 @@ static void sctp_init_assoc(struct connection *con)
        outmessage.msg_flags = MSG_EOR;
 
        spin_lock(&con->writequeue_lock);
-       e = list_entry(con->writequeue.next, struct writequeue_entry,
-                      list);
 
-       BUG_ON((struct list_head *) e == &con->writequeue);
+       if (list_empty(&con->writequeue)) {
+               spin_unlock(&con->writequeue_lock);
+               log_print("writequeue empty for nodeid %d", con->nodeid);
+               return;
+       }
 
+       e = list_first_entry(&con->writequeue, struct writequeue_entry, list);
        len = e->len;
        offset = e->offset;
        spin_unlock(&con->writequeue_lock);
index 72743d3..7a520a8 100644 (file)
@@ -2321,7 +2321,18 @@ static int ext3_commit_super(struct super_block *sb,
 
        if (!sbh)
                return error;
-       es->s_wtime = cpu_to_le32(get_seconds());
+       /*
+        * If the file system is mounted read-only, don't update the
+        * superblock write time.  This avoids updating the superblock
+        * write time when we are mounting the root file system
+        * read/only but we need to replay the journal; at that point,
+        * for people who are east of GMT and who make their clock
+        * tick in localtime for Windows bug-for-bug compatibility,
+        * the clock is set in the future, and this will cause e2fsck
+        * to complain and force a full file system check.
+        */
+       if (!(sb->s_flags & MS_RDONLY))
+               es->s_wtime = cpu_to_le32(get_seconds());
        es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
        es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
        BUFFER_TRACE(sbh, "marking dirty");
index 9b9d639..052f214 100644 (file)
@@ -58,6 +58,11 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
        }
        unlock_new_inode(tree->inode);
 
+       if (!HFS_I(tree->inode)->first_blocks) {
+               printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n");
+               goto free_inode;
+       }
+
        mapping = tree->inode->i_mapping;
        page = read_mapping_page(mapping, 0, NULL);
        if (IS_ERR(page))
index 175d08e..bed78ac 100644 (file)
@@ -99,6 +99,10 @@ int hfsplus_read_wrapper(struct super_block *sb)
 
        if (hfsplus_get_last_session(sb, &part_start, &part_size))
                return -EINVAL;
+       if ((u64)part_start + part_size > 0x100000000ULL) {
+               pr_err("hfs: volumes larger than 2TB are not supported yet\n");
+               return -EINVAL;
+       }
        while (1) {
                bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr);
                if (!bh)
index 32062c3..7cb2985 100644 (file)
@@ -1536,6 +1536,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
                old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
                dentry->d_parent->d_name.name, dentry->d_name.name);
 
+       nfs_inode_return_delegation(inode);
+
        d_drop(dentry);
        error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
        if (error == 0) {
index 6c32100..e1d415e 100644 (file)
@@ -457,6 +457,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
        };
        struct rpc_task_setup task_setup_data = {
                .rpc_client = NFS_CLIENT(inode),
+               .rpc_message = &msg,
                .callback_ops = &nfs_write_direct_ops,
                .workqueue = nfsiod_workqueue,
                .flags = RPC_TASK_ASYNC,
index ed7c269..ff37454 100644 (file)
@@ -72,12 +72,17 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 /* Prevent leaks of NFSv4 errors into userland */
 static int nfs4_map_errors(int err)
 {
-       if (err < -1000) {
+       if (err >= -1000)
+               return err;
+       switch (err) {
+       case -NFS4ERR_RESOURCE:
+               return -EREMOTEIO;
+       default:
                dprintk("%s could not handle NFSv4 error %d\n",
                                __func__, -err);
-               return -EIO;
+               break;
        }
-       return err;
+       return -EIO;
 }
 
 /*
@@ -3060,9 +3065,6 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
        if (time_before(clp->cl_last_renewal,timestamp))
                clp->cl_last_renewal = timestamp;
        spin_unlock(&clp->cl_lock);
-       dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
-                               task->tk_msg.rpc_cred);
-       put_rpccred(task->tk_msg.rpc_cred);
 }
 
 static const struct rpc_call_ops nfs4_renew_ops = {
@@ -4877,7 +4879,6 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
        nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
        dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
 
-       put_rpccred(task->tk_msg.rpc_cred);
        kfree(task->tk_msg.rpc_argp);
        kfree(task->tk_msg.rpc_resp);
 
index 83ad47c..20b4e30 100644 (file)
@@ -5681,7 +5681,6 @@ static struct {
        { NFS4ERR_SERVERFAULT,  -ESERVERFAULT   },
        { NFS4ERR_BADTYPE,      -EBADTYPE       },
        { NFS4ERR_LOCKED,       -EAGAIN         },
-       { NFS4ERR_RESOURCE,     -EREMOTEIO      },
        { NFS4ERR_SYMLINK,      -ELOOP          },
        { NFS4ERR_OP_ILLEGAL,   -EOPNOTSUPP     },
        { NFS4ERR_DEADLOCK,     -EDEADLK        },
index 6dabf6f..90be551 100644 (file)
@@ -1253,6 +1253,7 @@ static int nfs_parse_mount_options(char *raw,
                        default:
                                dfprintk(MOUNT, "NFS:   unrecognized "
                                                "transport protocol\n");
+                               kfree(string);
                                return 0;
                        }
                        break;
@@ -1848,8 +1849,8 @@ nfs_compare_remount_data(struct nfs_server *nfss,
            data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
            data->nfs_server.port != nfss->port ||
            data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
-           !rpc_cmp_addr(&data->nfs_server.address,
-                   &nfss->nfs_client->cl_addr))
+           !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address,
+                         (struct sockaddr *)&nfss->nfs_client->cl_addr))
                return -EINVAL;
 
        return 0;
index 828a889..7e54e52 100644 (file)
@@ -91,6 +91,7 @@ static int dnotify_handle_event(struct fsnotify_group *group,
        struct dnotify_struct *dn;
        struct dnotify_struct **prev;
        struct fown_struct *fown;
+       __u32 test_mask = event->mask & ~FS_EVENT_ON_CHILD;
 
        to_tell = event->to_tell;
 
@@ -106,7 +107,7 @@ static int dnotify_handle_event(struct fsnotify_group *group,
        spin_lock(&entry->lock);
        prev = &dnentry->dn;
        while ((dn = *prev) != NULL) {
-               if ((dn->dn_mask & event->mask) == 0) {
+               if ((dn->dn_mask & test_mask) == 0) {
                        prev = &dn->dn_next;
                        continue;
                }
index c8a07c6..3165d85 100644 (file)
@@ -324,11 +324,11 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry,
        spin_lock(&group->mark_lock);
        spin_lock(&inode->i_lock);
 
-       entry->group = group;
-       entry->inode = inode;
-
        lentry = fsnotify_find_mark_entry(group, inode);
        if (!lentry) {
+               entry->group = group;
+               entry->inode = inode;
+
                hlist_add_head(&entry->i_list, &inode->i_fsnotify_mark_entries);
                list_add(&entry->g_list, &group->mark_entries);
 
index 3816d57..b8bf53b 100644 (file)
@@ -143,7 +143,7 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new
                        /* remember, after old was put on the wait_q we aren't
                         * allowed to look at the inode any more, only thing
                         * left to check was if the file_name is the same */
-                       if (old->name_len &&
+                       if (!old->name_len ||
                            !strcmp(old->file_name, new->file_name))
                                return true;
                        break;
index f38fee0..7b685e1 100644 (file)
@@ -248,11 +248,19 @@ ssize_t part_stat_show(struct device *dev,
                part_stat_read(p, merges[WRITE]),
                (unsigned long long)part_stat_read(p, sectors[WRITE]),
                jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
-               p->in_flight,
+               part_in_flight(p),
                jiffies_to_msecs(part_stat_read(p, io_ticks)),
                jiffies_to_msecs(part_stat_read(p, time_in_queue)));
 }
 
+ssize_t part_inflight_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       struct hd_struct *p = dev_to_part(dev);
+
+       return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]);
+}
+
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 ssize_t part_fail_show(struct device *dev,
                       struct device_attribute *attr, char *buf)
@@ -281,6 +289,7 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
 static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
+static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
        __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -292,6 +301,7 @@ static struct attribute *part_attrs[] = {
        &dev_attr_size.attr,
        &dev_attr_alignment_offset.attr,
        &dev_attr_stat.attr,
+       &dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &dev_attr_fail.attr,
 #endif
index 52c4151..ae17d02 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -777,36 +777,55 @@ pipe_rdwr_release(struct inode *inode, struct file *filp)
 static int
 pipe_read_open(struct inode *inode, struct file *filp)
 {
-       /* We could have perhaps used atomic_t, but this and friends
-          below are the only places.  So it doesn't seem worthwhile.  */
+       int ret = -ENOENT;
+
        mutex_lock(&inode->i_mutex);
-       inode->i_pipe->readers++;
+
+       if (inode->i_pipe) {
+               ret = 0;
+               inode->i_pipe->readers++;
+       }
+
        mutex_unlock(&inode->i_mutex);
 
-       return 0;
+       return ret;
 }
 
 static int
 pipe_write_open(struct inode *inode, struct file *filp)
 {
+       int ret = -ENOENT;
+
        mutex_lock(&inode->i_mutex);
-       inode->i_pipe->writers++;
+
+       if (inode->i_pipe) {
+               ret = 0;
+               inode->i_pipe->writers++;
+       }
+
        mutex_unlock(&inode->i_mutex);
 
-       return 0;
+       return ret;
 }
 
 static int
 pipe_rdwr_open(struct inode *inode, struct file *filp)
 {
+       int ret = -ENOENT;
+
        mutex_lock(&inode->i_mutex);
-       if (filp->f_mode & FMODE_READ)
-               inode->i_pipe->readers++;
-       if (filp->f_mode & FMODE_WRITE)
-               inode->i_pipe->writers++;
+
+       if (inode->i_pipe) {
+               ret = 0;
+               if (filp->f_mode & FMODE_READ)
+                       inode->i_pipe->readers++;
+               if (filp->f_mode & FMODE_WRITE)
+                       inode->i_pipe->writers++;
+       }
+
        mutex_unlock(&inode->i_mutex);
 
-       return 0;
+       return ret;
 }
 
 /*
index c7bff4f..a65239c 100644 (file)
@@ -99,7 +99,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                "VmallocUsed:    %8lu kB\n"
                "VmallocChunk:   %8lu kB\n"
 #ifdef CONFIG_MEMORY_FAILURE
-               "HardwareCorrupted: %8lu kB\n"
+               "HardwareCorrupted: %5lu kB\n"
 #endif
                ,
                K(i.totalram),
index 0050fc4..5fad489 100644 (file)
@@ -894,7 +894,8 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
 
        mutex_lock(&sysfs_rename_mutex);
        BUG_ON(!sd->s_parent);
-       new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root;
+       new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ?
+               new_parent_kobj->sd : &sysfs_root;
 
        error = 0;
        if (sd->s_parent == new_parent_sd)
index 561a9c0..f5ea468 100644 (file)
@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
        struct sysfs_open_dirent *od, *new_od = NULL;
 
  retry:
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irq(&sysfs_open_dirent_lock);
 
        if (!sd->s_attr.open && new_od) {
                sd->s_attr.open = new_od;
@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
                list_add_tail(&buffer->list, &od->buffers);
        }
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irq(&sysfs_open_dirent_lock);
 
        if (od) {
                kfree(new_od);
@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
                                  struct sysfs_buffer *buffer)
 {
        struct sysfs_open_dirent *od = sd->s_attr.open;
+       unsigned long flags;
 
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
 
        list_del(&buffer->list);
        if (atomic_dec_and_test(&od->refcnt))
@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
        else
                od = NULL;
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
 
        kfree(od);
 }
@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 void sysfs_notify_dirent(struct sysfs_dirent *sd)
 {
        struct sysfs_open_dirent *od;
+       unsigned long flags;
 
-       spin_lock(&sysfs_open_dirent_lock);
+       spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
 
        od = sd->s_attr.open;
        if (od) {
@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
                wake_up_interruptible(&od->poll);
        }
 
-       spin_unlock(&sysfs_open_dirent_lock);
+       spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
 }
 EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
 
index 9e41f91..3d4a0c8 100644 (file)
@@ -80,7 +80,7 @@ xfs_fs_set_xstate(
 
        if (sb->s_flags & MS_RDONLY)
                return -EROFS;
-       if (!XFS_IS_QUOTA_RUNNING(mp))
+       if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
                return -ENOSYS;
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
index 4e4276b..5d1a3b9 100644 (file)
@@ -876,7 +876,6 @@ xfs_dqrele_inode(
                ip->i_gdquot = NULL;
        }
        xfs_iput(ip, XFS_ILOCK_EXCL);
-       IRELE(ip);
 
        return 0;
 }
index ab64f3e..0785797 100644 (file)
@@ -880,6 +880,7 @@ nextag:
                                 * Not in range - save last search
                                 * location and allocate a new inode
                                 */
+                               xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
                                pag->pagl_leftrec = trec.ir_startino;
                                pag->pagl_rightrec = rec.ir_startino;
                                pag->pagl_pagino = pagino;
index 3f384d4..1feed71 100644 (file)
@@ -364,6 +364,7 @@ unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
 unifdef-y += virtio_config.h
+unifdef-y += virtio_ids.h
 unifdef-y += virtio_blk.h
 unifdef-y += virtio_net.h
 unifdef-y += virtio_9p.h
index 2511904..221cecd 100644 (file)
@@ -1172,11 +1172,7 @@ static inline void put_dev_sector(Sector p)
 }
 
 struct work_struct;
-struct delayed_work;
 int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
-int kblockd_schedule_delayed_work(struct request_queue *q,
-                                       struct delayed_work *work,
-                                       unsigned long delay);
 
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
        MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
index 44717eb..79a2340 100644 (file)
@@ -291,8 +291,15 @@ struct global_attr {
 int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
 int cpufreq_update_policy(unsigned int cpu);
 
+#ifdef CONFIG_CPU_FREQ
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
+#else
+static inline unsigned int cpufreq_get(unsigned int cpu)
+{
+       return 0;
+}
+#endif
 
 /* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
 #ifdef CONFIG_CPU_FREQ
index aca31bf..2ea3e49 100644 (file)
@@ -124,7 +124,9 @@ struct device_driver {
        struct bus_type         *bus;
 
        struct module           *owner;
-       const char              *mod_name;      /* used for built-in modules */
+       const char              *mod_name;      /* used for built-in modules */
+
+       bool suppress_bind_attrs;       /* disables bind/unbind via sysfs */
 
        int (*probe) (struct device *dev);
        int (*remove) (struct device *dev);
index 7beaa21..297df45 100644 (file)
@@ -98,7 +98,7 @@ struct hd_struct {
        int make_it_fail;
 #endif
        unsigned long stamp;
-       int in_flight;
+       int in_flight[2];
 #ifdef CONFIG_SMP
        struct disk_stats *dkstats;
 #else
@@ -322,18 +322,23 @@ static inline void free_part_stats(struct hd_struct *part)
 #define part_stat_sub(cpu, gendiskp, field, subnd)                     \
        part_stat_add(cpu, gendiskp, field, -subnd)
 
-static inline void part_inc_in_flight(struct hd_struct *part)
+static inline void part_inc_in_flight(struct hd_struct *part, int rw)
 {
-       part->in_flight++;
+       part->in_flight[rw]++;
        if (part->partno)
-               part_to_disk(part)->part0.in_flight++;
+               part_to_disk(part)->part0.in_flight[rw]++;
 }
 
-static inline void part_dec_in_flight(struct hd_struct *part)
+static inline void part_dec_in_flight(struct hd_struct *part, int rw)
 {
-       part->in_flight--;
+       part->in_flight[rw]--;
        if (part->partno)
-               part_to_disk(part)->part0.in_flight--;
+               part_to_disk(part)->part0.in_flight[rw]--;
+}
+
+static inline int part_in_flight(struct hd_struct *part)
+{
+       return part->in_flight[0] + part->in_flight[1];
 }
 
 /* block/blk-core.c */
@@ -546,6 +551,8 @@ extern ssize_t part_size_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
 extern ssize_t part_stat_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
+extern ssize_t part_inflight_show(struct device *dev,
+                             struct device_attribute *attr, char *buf);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 extern ssize_t part_fail_show(struct device *dev,
                              struct device_attribute *attr, char *buf);
index d3cd23f..f4e3184 100644 (file)
@@ -659,6 +659,12 @@ extern int do_sysinfo(struct sysinfo *info);
 
 #endif /* __KERNEL__ */
 
+#ifndef __EXPORTED_HEADERS__
+#ifndef __KERNEL__
+#warning Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders
+#endif /* __KERNEL__ */
+#endif /* __EXPORTED_HEADERS__ */
+
 #define SI_LOAD_SHIFT  16
 struct sysinfo {
        long uptime;                    /* Seconds since boot */
index 6547c3c..82a9124 100644 (file)
@@ -37,7 +37,6 @@ typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
 typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
 
 /* Flag bits for kernel_param.flags */
-#define KPARAM_KMALLOCED       1
 #define KPARAM_ISBOOL          2
 
 struct kernel_param {
index 94958c1..812a5f3 100644 (file)
@@ -557,7 +557,7 @@ struct netdev_queue {
  *     Callback uses when the transmitter has not made any progress
  *     for dev->watchdog ticks.
  *
- * struct net_device_stats* (*get_stats)(struct net_device *dev);
+ * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
  *     Called when a user wants to get the network device usage
  *     statistics. If not defined, the counters in dev->stats will
  *     be used.
index da1fda8..b0f0f38 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 #define PCI_DEVICE_ID_ATI_IXP700_SATA  0x4390
 #define PCI_DEVICE_ID_ATI_IXP700_IDE   0x439c
-/* AMD SB Chipset */
-#define PCI_DEVICE_ID_AMD_SB900_IDE     0x780c
-#define PCI_DEVICE_ID_AMD_SB900_SATA_IDE 0x7800
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_VLSI_82C592      0x0005
 #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361
 #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252
 
+#define PCI_SUBVENDOR_ID_IBM           0x1014
+#define PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT    0x03d4
+
 #define PCI_VENDOR_ID_UNISYS           0x1018
 #define PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR 0x001C
 
 #define PCI_DEVICE_ID_AMD_CS5536_UDC    0x2096
 #define PCI_DEVICE_ID_AMD_CS5536_UOC    0x2097
 #define PCI_DEVICE_ID_AMD_CS5536_IDE    0x209A
-
 #define PCI_DEVICE_ID_AMD_LX_VIDEO  0x2081
 #define PCI_DEVICE_ID_AMD_LX_AES    0x2082
+#define PCI_DEVICE_ID_AMD_HUDSON2_IDE          0x780c
+#define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE     0x7800
 
 #define PCI_VENDOR_ID_TRIDENT          0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX        0x2000
 #define PCI_DEVICE_ID_TI_X515          0x8036
 #define PCI_DEVICE_ID_TI_XX12          0x8039
 #define PCI_DEVICE_ID_TI_XX12_FM       0x803b
+#define PCI_DEVICE_ID_TI_XIO2000A      0x8231
 #define PCI_DEVICE_ID_TI_1130          0xac12
 #define PCI_DEVICE_ID_TI_1031          0xac13
 #define PCI_DEVICE_ID_TI_1131          0xac15
 #define PCI_DEVICE_ID_ADDIDATA_APCI7420_3      0x700D
 #define PCI_DEVICE_ID_ADDIDATA_APCI7300_3      0x700E
 #define PCI_DEVICE_ID_ADDIDATA_APCI7800_3      0x700F
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7300       0x7010
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7420       0x7011
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7500       0x7012
+#define PCI_DEVICE_ID_ADDIDATA_APCIe7800       0x7013
 
 #define PCI_VENDOR_ID_PDC              0x15e9
 
index 9311505..a3baeb2 100644 (file)
 #define PR_TASK_PERF_EVENTS_DISABLE            31
 #define PR_TASK_PERF_EVENTS_ENABLE             32
 
+/*
+ * Set early/late kill mode for hwpoison memory corruption.
+ * This influences when the process gets killed on a memory corruption.
+ */
 #define PR_MCE_KILL    33
+# define PR_MCE_KILL_CLEAR   0
+# define PR_MCE_KILL_SET     1
+
+# define PR_MCE_KILL_LATE    0
+# define PR_MCE_KILL_EARLY   1
+# define PR_MCE_KILL_DEFAULT 2
+
+#define PR_MCE_KILL_GET 34
 
 #endif /* _LINUX_PRCTL_H */
index 46e9ab3..9642c6b 100644 (file)
@@ -76,11 +76,7 @@ static inline void __rcu_read_unlock_bh(void)
 
 extern void call_rcu_sched(struct rcu_head *head,
                           void (*func)(struct rcu_head *rcu));
-
-static inline void synchronize_rcu_expedited(void)
-{
-       synchronize_sched_expedited();
-}
+extern void synchronize_rcu_expedited(void);
 
 static inline void synchronize_rcu_bh_expedited(void)
 {
index 489019e..b850886 100644 (file)
@@ -62,7 +62,7 @@ extern char * strnchr(const char *, size_t, int);
 #ifndef __HAVE_ARCH_STRRCHR
 extern char * strrchr(const char *,int);
 #endif
-extern char * strstrip(char *);
+extern char * __must_check strstrip(char *);
 #ifndef __HAVE_ARCH_STRSTR
 extern char * strstr(const char *,const char *);
 #endif
index fc0bf3e..57e6357 100644 (file)
@@ -129,7 +129,7 @@ int arch_update_cpu_topology(void);
                                | 1*SD_BALANCE_FORK                     \
                                | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_PREFER_LOCAL                     \
+                               | 0*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 1*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
@@ -162,7 +162,7 @@ int arch_update_cpu_topology(void);
                                | 1*SD_BALANCE_FORK                     \
                                | 0*SD_BALANCE_WAKE                     \
                                | 1*SD_WAKE_AFFINE                      \
-                               | 1*SD_PREFER_LOCAL                     \
+                               | 0*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_SHARE_PKG_RESOURCES              \
                                | 0*SD_SERIALIZE                        \
index c134dd1..09077f6 100644 (file)
@@ -7,7 +7,7 @@
 
 /*
  * Trace sequences are used to allow a function to call several other functions
- * to create a string of data to use (up to a max of PAGE_SIZE.
+ * to create a string of data to use (up to a max of PAGE_SIZE).
  */
 
 struct trace_seq {
index ea7226a..095e10d 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_VIRTIO_9P_H
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
 /* Maximum number of virtio channels per partition (1 for now) */
index 09d7300..1418f04 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_VIRTIO_BALLOON_H
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
 /* The feature bitmap for virtio balloon */
index 15cb666..fd294c5 100644 (file)
@@ -3,6 +3,7 @@
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
 #include <linux/types.h>
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
 /* Feature bits */
 #define VIRTIO_BLK_F_RO                5       /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE  6       /* Block size of disk is available*/
 #define VIRTIO_BLK_F_SCSI      7       /* Supports scsi command passthru */
-#define VIRTIO_BLK_F_IDENTIFY  8       /* ATA IDENTIFY supported */
 #define VIRTIO_BLK_F_FLUSH     9       /* Cache flush command support */
 
-#define VIRTIO_BLK_ID_BYTES    (sizeof(__u16[256]))    /* IDENTIFY DATA */
-
 struct virtio_blk_config {
        /* The capacity (in 512-byte sectors). */
        __u64 capacity;
@@ -33,7 +31,6 @@ struct virtio_blk_config {
        } geometry;
        /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
        __u32 blk_size;
-       __u8 identify[VIRTIO_BLK_ID_BYTES];
 } __attribute__((packed));
 
 /*
index b5f5198..fe88517 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_VIRTIO_CONSOLE_H
 #define _LINUX_VIRTIO_CONSOLE_H
 #include <linux/types.h>
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
  * anyone can use the definitions to implement compatible drivers/servers. */
index 1f41734..085e422 100644 (file)
@@ -3,6 +3,7 @@
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
 #include <linux/types.h>
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 #include <linux/if_ether.h>
 
index 48121c3..c4d5de8 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_VIRTIO_RNG_H
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
+#include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 
 #endif /* _LINUX_VIRTIO_RNG_H */
index 7ef0c7b..cf24c20 100644 (file)
@@ -207,6 +207,7 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
 
 extern void flush_workqueue(struct workqueue_struct *wq);
 extern void flush_scheduled_work(void);
+extern void flush_delayed_work(struct delayed_work *work);
 
 extern int schedule_work(struct work_struct *work);
 extern int schedule_work_on(int cpu, struct work_struct *work);
index b63b80f..f93ad90 100644 (file)
@@ -130,11 +130,11 @@ struct inet_timewait_sock {
        __u16                   tw_num;
        kmemcheck_bitfield_begin(flags);
        /* And these are ours. */
-       __u8                    tw_ipv6only:1,
-                               tw_transparent:1;
-       /* 14 bits hole, try to pack */
+       unsigned int            tw_ipv6only     : 1,
+                               tw_transparent  : 1,
+                               tw_pad          : 14,   /* 14 bits hole */
+                               tw_ipv6_offset  : 16;
        kmemcheck_bitfield_end(flags);
-       __u16                   tw_ipv6_offset;
        unsigned long           tw_ttd;
        struct inet_bind_bucket *tw_tb;
        struct hlist_node       tw_death_node;
index 466859b..c75b960 100644 (file)
@@ -1669,6 +1669,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
  * to this function and ieee80211_rx_irqsafe() may not be mixed for a
  * single hardware.
  *
+ * Note that right now, this function must be called with softirqs disabled.
+ *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
  */
index 1621935..9f96394 100644 (file)
@@ -226,12 +226,12 @@ struct sock {
 #define sk_prot                        __sk_common.skc_prot
 #define sk_net                 __sk_common.skc_net
        kmemcheck_bitfield_begin(flags);
-       unsigned char           sk_shutdown : 2,
-                               sk_no_check : 2,
-                               sk_userlocks : 4;
+       unsigned int            sk_shutdown  : 2,
+                               sk_no_check  : 2,
+                               sk_userlocks : 4,
+                               sk_protocol  : 8,
+                               sk_type      : 16;
        kmemcheck_bitfield_end(flags);
-       unsigned char           sk_protocol;
-       unsigned short          sk_type;
        int                     sk_rcvbuf;
        socket_lock_t           sk_lock;
        /*
index 09c5c64..f515864 100644 (file)
@@ -297,7 +297,7 @@ config AUDIT
 
 config AUDITSYSCALL
        bool "Enable system-call auditing support"
-       depends on AUDIT && (X86 || PPC || PPC64 || S390 || IA64 || UML || SPARC64|| SUPERH)
+       depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH)
        default y if SECURITY_SELINUX
        help
          Enable low-overhead system-call auditing infrastructure that
index ca83b73..0249f4b 100644 (file)
@@ -1710,14 +1710,13 @@ static ssize_t cgroup_write_X64(struct cgroup *cgrp, struct cftype *cft,
                return -EFAULT;
 
        buffer[nbytes] = 0;     /* nul-terminate */
-       strstrip(buffer);
        if (cft->write_u64) {
-               u64 val = simple_strtoull(buffer, &end, 0);
+               u64 val = simple_strtoull(strstrip(buffer), &end, 0);
                if (*end)
                        return -EINVAL;
                retval = cft->write_u64(cgrp, cft, val);
        } else {
-               s64 val = simple_strtoll(buffer, &end, 0);
+               s64 val = simple_strtoll(strstrip(buffer), &end, 0);
                if (*end)
                        return -EINVAL;
                retval = cft->write_s64(cgrp, cft, val);
@@ -1753,8 +1752,7 @@ static ssize_t cgroup_write_string(struct cgroup *cgrp, struct cftype *cft,
        }
 
        buffer[nbytes] = 0;     /* nul-terminate */
-       strstrip(buffer);
-       retval = cft->write_string(cgrp, cft, buffer);
+       retval = cft->write_string(cgrp, cft, strstrip(buffer));
        if (!retval)
                retval = nbytes;
 out:
index e61891f..f7864ac 100644 (file)
@@ -359,10 +359,8 @@ void __set_special_pids(struct pid *pid)
 {
        struct task_struct *curr = current->group_leader;
 
-       if (task_session(curr) != pid) {
+       if (task_session(curr) != pid)
                change_pid(curr, PIDTYPE_SID, pid);
-               proc_sid_connector(curr);
-       }
 
        if (task_pgrp(curr) != pid)
                change_pid(curr, PIDTYPE_PGID, pid);
index 4949d33..642f3bb 100644 (file)
@@ -150,7 +150,8 @@ static struct futex_hash_bucket *hash_futex(union futex_key *key)
  */
 static inline int match_futex(union futex_key *key1, union futex_key *key2)
 {
-       return (key1->both.word == key2->both.word
+       return (key1 && key2
+               && key1->both.word == key2->both.word
                && key1->both.ptr == key2->both.ptr
                && key1->both.offset == key2->both.offset);
 }
@@ -1028,7 +1029,6 @@ static inline
 void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
                           struct futex_hash_bucket *hb)
 {
-       drop_futex_key_refs(&q->key);
        get_futex_key_refs(key);
        q->key = *key;
 
@@ -1226,6 +1226,7 @@ retry_private:
                 */
                if (ret == 1) {
                        WARN_ON(pi_state);
+                       drop_count++;
                        task_count++;
                        ret = get_futex_value_locked(&curval2, uaddr2);
                        if (!ret)
@@ -1304,6 +1305,7 @@ retry_private:
                        if (ret == 1) {
                                /* We got the lock. */
                                requeue_pi_wake_futex(this, &key2, hb2);
+                               drop_count++;
                                continue;
                        } else if (ret) {
                                /* -EDEADLK */
@@ -1791,6 +1793,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
                                             current->timer_slack_ns);
        }
 
+retry:
        /* Prepare to wait on uaddr. */
        ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
        if (ret)
@@ -1808,9 +1811,14 @@ static int futex_wait(u32 __user *uaddr, int fshared,
                goto out_put_key;
 
        /*
-        * We expect signal_pending(current), but another thread may
-        * have handled it for us already.
+        * We expect signal_pending(current), but we might be the
+        * victim of a spurious wakeup as well.
         */
+       if (!signal_pending(current)) {
+               put_futex_key(fshared, &q.key);
+               goto retry;
+       }
+
        ret = -ERESTARTSYS;
        if (!abs_time)
                goto out_put_key;
@@ -2118,9 +2126,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
                 */
                plist_del(&q->list, &q->list.plist);
 
+               /* Handle spurious wakeups gracefully */
+               ret = -EAGAIN;
                if (timeout && !timeout->task)
                        ret = -ETIMEDOUT;
-               else
+               else if (signal_pending(current))
                        ret = -ERESTARTNOINTR;
        }
        return ret;
@@ -2198,6 +2208,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
        debug_rt_mutex_init_waiter(&rt_waiter);
        rt_waiter.task = NULL;
 
+retry:
        key2 = FUTEX_KEY_INIT;
        ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
        if (unlikely(ret != 0))
@@ -2292,6 +2303,9 @@ out_put_keys:
 out_key2:
        put_futex_key(fshared, &key2);
 
+       /* Spurious wakeup ? */
+       if (ret == -EAGAIN)
+               goto retry;
 out:
        if (to) {
                hrtimer_cancel(&to->timer);
index 3815ac1..9af5672 100644 (file)
@@ -142,6 +142,11 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
 #ifdef CONFIG_LOCK_STAT
 static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats);
 
+static inline u64 lockstat_clock(void)
+{
+       return cpu_clock(smp_processor_id());
+}
+
 static int lock_point(unsigned long points[], unsigned long ip)
 {
        int i;
@@ -158,7 +163,7 @@ static int lock_point(unsigned long points[], unsigned long ip)
        return i;
 }
 
-static void lock_time_inc(struct lock_time *lt, s64 time)
+static void lock_time_inc(struct lock_time *lt, u64 time)
 {
        if (time > lt->max)
                lt->max = time;
@@ -234,12 +239,12 @@ static void put_lock_stats(struct lock_class_stats *stats)
 static void lock_release_holdtime(struct held_lock *hlock)
 {
        struct lock_class_stats *stats;
-       s64 holdtime;
+       u64 holdtime;
 
        if (!lock_stat)
                return;
 
-       holdtime = sched_clock() - hlock->holdtime_stamp;
+       holdtime = lockstat_clock() - hlock->holdtime_stamp;
 
        stats = get_lock_stats(hlock_class(hlock));
        if (hlock->read)
@@ -2792,7 +2797,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        hlock->references = references;
 #ifdef CONFIG_LOCK_STAT
        hlock->waittime_stamp = 0;
-       hlock->holdtime_stamp = sched_clock();
+       hlock->holdtime_stamp = lockstat_clock();
 #endif
 
        if (check == 2 && !mark_irqflags(curr, hlock))
@@ -3322,7 +3327,7 @@ found_it:
        if (hlock->instance != lock)
                return;
 
-       hlock->waittime_stamp = sched_clock();
+       hlock->waittime_stamp = lockstat_clock();
 
        contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
        contending_point = lock_point(hlock_class(hlock)->contending_point,
@@ -3345,8 +3350,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
        struct held_lock *hlock, *prev_hlock;
        struct lock_class_stats *stats;
        unsigned int depth;
-       u64 now;
-       s64 waittime = 0;
+       u64 now, waittime = 0;
        int i, cpu;
 
        depth = curr->lockdep_depth;
@@ -3374,7 +3378,7 @@ found_it:
 
        cpu = smp_processor_id();
        if (hlock->waittime_stamp) {
-               now = sched_clock();
+               now = lockstat_clock();
                waittime = now - hlock->waittime_stamp;
                hlock->holdtime_stamp = now;
        }
index 9da58ea..d656c27 100644 (file)
@@ -218,15 +218,11 @@ int param_set_charp(const char *val, struct kernel_param *kp)
                return -ENOSPC;
        }
 
-       if (kp->flags & KPARAM_KMALLOCED)
-               kfree(*(char **)kp->arg);
-
        /* This is a hack.  We can't need to strdup in early boot, and we
         * don't need to; this mangled commandline is preserved. */
        if (slab_is_available()) {
-               kp->flags |= KPARAM_KMALLOCED;
                *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
-               if (!kp->arg)
+               if (!*(char **)kp->arg)
                        return -ENOMEM;
        } else
                *(const char **)kp->arg = val;
@@ -304,6 +300,7 @@ static int param_array(const char *name,
                       unsigned int min, unsigned int max,
                       void *elem, int elemsize,
                       int (*set)(const char *, struct kernel_param *kp),
+                      u16 flags,
                       unsigned int *num)
 {
        int ret;
@@ -313,6 +310,7 @@ static int param_array(const char *name,
        /* Get the name right for errors. */
        kp.name = name;
        kp.arg = elem;
+       kp.flags = flags;
 
        /* No equals sign? */
        if (!val) {
@@ -358,7 +356,8 @@ int param_array_set(const char *val, struct kernel_param *kp)
        unsigned int temp_num;
 
        return param_array(kp->name, val, 1, arr->max, arr->elem,
-                          arr->elemsize, arr->set, arr->num ?: &temp_num);
+                          arr->elemsize, arr->set, kp->flags,
+                          arr->num ?: &temp_num);
 }
 
 int param_array_get(char *buffer, struct kernel_param *kp)
@@ -605,11 +604,7 @@ void module_param_sysfs_remove(struct module *mod)
 
 void destroy_params(const struct kernel_param *params, unsigned num)
 {
-       unsigned int i;
-
-       for (i = 0; i < num; i++)
-               if (params[i].flags & KPARAM_KMALLOCED)
-                       kfree(*(char **)params[i].arg);
+       /* FIXME: This should free kmalloced charp parameters.  It doesn't. */
 }
 
 static void __init kernel_add_sysfs_param(const char *name,
index 17d8bb1..25596e4 100644 (file)
@@ -19,7 +19,7 @@
  * The time it takes is system-specific though, so when we test this
  * during system bootup we allow a LOT of time.
  */
-#define TEST_SUSPEND_SECONDS   5
+#define TEST_SUSPEND_SECONDS   10
 
 static unsigned long suspend_test_start_time;
 
@@ -49,7 +49,8 @@ void suspend_test_finish(const char *label)
         * has some performance issues.  The stack dump of a WARN_ON
         * is more likely to get the right attention than a printk...
         */
-       WARN(msec > (TEST_SUSPEND_SECONDS * 1000), "Component: %s\n", label);
+       WARN(msec > (TEST_SUSPEND_SECONDS * 1000),
+            "Component: %s, time: %u\n", label, msec);
 }
 
 /*
index 705f02a..0536125 100644 (file)
@@ -913,7 +913,20 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
                        spin_unlock(&rnp->lock); /* irqs remain disabled. */
                        break;
                }
-               rcu_preempt_offline_tasks(rsp, rnp, rdp);
+
+               /*
+                * If there was a task blocking the current grace period,
+                * and if all CPUs have checked in, we need to propagate
+                * the quiescent state up the rcu_node hierarchy.  But that
+                * is inconvenient at the moment due to deadlock issues if
+                * this should end the current grace period.  So set the
+                * offlined CPU's bit in ->qsmask in order to force the
+                * next force_quiescent_state() invocation to clean up this
+                * mess in a deadlock-free manner.
+                */
+               if (rcu_preempt_offline_tasks(rsp, rnp, rdp) && !rnp->qsmask)
+                       rnp->qsmask |= mask;
+
                mask = rnp->grpmask;
                spin_unlock(&rnp->lock);        /* irqs remain disabled. */
                rnp = rnp->parent;
@@ -958,7 +971,7 @@ static void rcu_offline_cpu(int cpu)
  * Invoke any RCU callbacks that have made it to the end of their grace
  * period.  Thottle as specified by rdp->blimit.
  */
-static void rcu_do_batch(struct rcu_data *rdp)
+static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 {
        unsigned long flags;
        struct rcu_head *next, *list, **tail;
@@ -1011,6 +1024,13 @@ static void rcu_do_batch(struct rcu_data *rdp)
        if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark)
                rdp->blimit = blimit;
 
+       /* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */
+       if (rdp->qlen == 0 && rdp->qlen_last_fqs_check != 0) {
+               rdp->qlen_last_fqs_check = 0;
+               rdp->n_force_qs_snap = rsp->n_force_qs;
+       } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark)
+               rdp->qlen_last_fqs_check = rdp->qlen;
+
        local_irq_restore(flags);
 
        /* Re-raise the RCU softirq if there are callbacks remaining. */
@@ -1224,7 +1244,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
        }
 
        /* If there are callbacks ready, invoke them. */
-       rcu_do_batch(rdp);
+       rcu_do_batch(rsp, rdp);
 }
 
 /*
@@ -1288,10 +1308,20 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
                rcu_start_gp(rsp, nestflag);  /* releases rnp_root->lock. */
        }
 
-       /* Force the grace period if too many callbacks or too long waiting. */
-       if (unlikely(++rdp->qlen > qhimark)) {
+       /*
+        * Force the grace period if too many callbacks or too long waiting.
+        * Enforce hysteresis, and don't invoke force_quiescent_state()
+        * if some other CPU has recently done so.  Also, don't bother
+        * invoking force_quiescent_state() if the newly enqueued callback
+        * is the only one waiting for a grace period to complete.
+        */
+       if (unlikely(++rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) {
                rdp->blimit = LONG_MAX;
-               force_quiescent_state(rsp, 0);
+               if (rsp->n_force_qs == rdp->n_force_qs_snap &&
+                   *rdp->nxttail[RCU_DONE_TAIL] != head)
+                       force_quiescent_state(rsp, 0);
+               rdp->n_force_qs_snap = rsp->n_force_qs;
+               rdp->qlen_last_fqs_check = rdp->qlen;
        } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
                force_quiescent_state(rsp, 1);
        local_irq_restore(flags);
@@ -1523,6 +1553,8 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
        rdp->beenonline = 1;     /* We have now been online. */
        rdp->preemptable = preemptable;
        rdp->passed_quiesc_completed = lastcomp - 1;
+       rdp->qlen_last_fqs_check = 0;
+       rdp->n_force_qs_snap = rsp->n_force_qs;
        rdp->blimit = blimit;
        spin_unlock(&rnp->lock);                /* irqs remain disabled. */
 
index b40ac57..1823c6e 100644 (file)
@@ -167,6 +167,10 @@ struct rcu_data {
        struct rcu_head *nxtlist;
        struct rcu_head **nxttail[RCU_NEXT_SIZE];
        long            qlen;           /* # of queued callbacks */
+       long            qlen_last_fqs_check;
+                                       /* qlen at last check for QS forcing */
+       unsigned long   n_force_qs_snap;
+                                       /* did other CPU force QS recently? */
        long            blimit;         /* Upper limit on a processed batch */
 
 #ifdef CONFIG_NO_HZ
@@ -302,9 +306,9 @@ static void rcu_print_task_stall(struct rcu_node *rnp);
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
 #ifdef CONFIG_HOTPLUG_CPU
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                     struct rcu_node *rnp,
-                                     struct rcu_data *rdp);
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp);
 static void rcu_preempt_offline_cpu(int cpu);
 #endif /* #ifdef CONFIG_HOTPLUG_CPU */
 static void rcu_preempt_check_callbacks(int cpu);
index c0cb783..ef2a58c 100644 (file)
@@ -304,21 +304,25 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
  * parent is to remove the need for rcu_read_unlock_special() to
  * make more than two attempts to acquire the target rcu_node's lock.
  *
+ * Returns 1 if there was previously a task blocking the current grace
+ * period on the specified rcu_node structure.
+ *
  * The caller must hold rnp->lock with irqs disabled.
  */
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                     struct rcu_node *rnp,
-                                     struct rcu_data *rdp)
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp)
 {
        int i;
        struct list_head *lp;
        struct list_head *lp_root;
+       int retval = rcu_preempted_readers(rnp);
        struct rcu_node *rnp_root = rcu_get_root(rsp);
        struct task_struct *tp;
 
        if (rnp == rnp_root) {
                WARN_ONCE(1, "Last CPU thought to be offlined?");
-               return;  /* Shouldn't happen: at least one CPU online. */
+               return 0;  /* Shouldn't happen: at least one CPU online. */
        }
        WARN_ON_ONCE(rnp != rdp->mynode &&
                     (!list_empty(&rnp->blocked_tasks[0]) ||
@@ -342,6 +346,8 @@ static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
                        spin_unlock(&rnp_root->lock); /* irqs remain disabled */
                }
        }
+
+       return retval;
 }
 
 /*
@@ -392,6 +398,17 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
+/*
+ * Wait for an rcu-preempt grace period.  We are supposed to expedite the
+ * grace period, but this is the crude slow compatability hack, so just
+ * invoke synchronize_rcu().
+ */
+void synchronize_rcu_expedited(void)
+{
+       synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
 /*
  * Check to see if there is any immediate preemptable-RCU-related work
  * to be done.
@@ -521,12 +538,15 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
 
 /*
  * Because preemptable RCU does not exist, it never needs to migrate
- * tasks that were blocked within RCU read-side critical sections.
+ * tasks that were blocked within RCU read-side critical sections, and
+ * such non-existent tasks cannot possibly have been blocking the current
+ * grace period.
  */
-static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
-                                     struct rcu_node *rnp,
-                                     struct rcu_data *rdp)
+static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
+                                    struct rcu_node *rnp,
+                                    struct rcu_data *rdp)
 {
+       return 0;
 }
 
 /*
@@ -564,6 +584,16 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
+/*
+ * Wait for an rcu-preempt grace period, but make it happen quickly.
+ * But because preemptable RCU does not exist, map to rcu-sched.
+ */
+void synchronize_rcu_expedited(void)
+{
+       synchronize_sched_expedited();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+
 /*
  * Because preemptable RCU does not exist, it never has any work to do.
  */
index 76c0e96..a455dca 100644 (file)
@@ -676,6 +676,7 @@ inline void update_rq_clock(struct rq *rq)
 
 /**
  * runqueue_is_locked
+ * @cpu: the processor in question.
  *
  * Returns true if the current cpu runqueue is locked.
  * This interface allows printk to be called with the runqueue lock
@@ -1563,11 +1564,7 @@ static unsigned long cpu_avg_load_per_task(int cpu)
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 
-struct update_shares_data {
-       unsigned long rq_weight[NR_CPUS];
-};
-
-static DEFINE_PER_CPU(struct update_shares_data, update_shares_data);
+static __read_mostly unsigned long *update_shares_data;
 
 static void __set_se_shares(struct sched_entity *se, unsigned long shares);
 
@@ -1577,12 +1574,12 @@ static void __set_se_shares(struct sched_entity *se, unsigned long shares);
 static void update_group_shares_cpu(struct task_group *tg, int cpu,
                                    unsigned long sd_shares,
                                    unsigned long sd_rq_weight,
-                                   struct update_shares_data *usd)
+                                   unsigned long *usd_rq_weight)
 {
        unsigned long shares, rq_weight;
        int boost = 0;
 
-       rq_weight = usd->rq_weight[cpu];
+       rq_weight = usd_rq_weight[cpu];
        if (!rq_weight) {
                boost = 1;
                rq_weight = NICE_0_LOAD;
@@ -1617,7 +1614,7 @@ static void update_group_shares_cpu(struct task_group *tg, int cpu,
 static int tg_shares_up(struct task_group *tg, void *data)
 {
        unsigned long weight, rq_weight = 0, shares = 0;
-       struct update_shares_data *usd;
+       unsigned long *usd_rq_weight;
        struct sched_domain *sd = data;
        unsigned long flags;
        int i;
@@ -1626,11 +1623,11 @@ static int tg_shares_up(struct task_group *tg, void *data)
                return 0;
 
        local_irq_save(flags);
-       usd = &__get_cpu_var(update_shares_data);
+       usd_rq_weight = per_cpu_ptr(update_shares_data, smp_processor_id());
 
        for_each_cpu(i, sched_domain_span(sd)) {
                weight = tg->cfs_rq[i]->load.weight;
-               usd->rq_weight[i] = weight;
+               usd_rq_weight[i] = weight;
 
                /*
                 * If there are currently no tasks on the cpu pretend there
@@ -1651,7 +1648,7 @@ static int tg_shares_up(struct task_group *tg, void *data)
                shares = tg->shares;
 
        for_each_cpu(i, sched_domain_span(sd))
-               update_group_shares_cpu(tg, i, shares, rq_weight, usd);
+               update_group_shares_cpu(tg, i, shares, rq_weight, usd_rq_weight);
 
        local_irq_restore(flags);
 
@@ -2311,7 +2308,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 {
        int cpu, orig_cpu, this_cpu, success = 0;
        unsigned long flags;
-       struct rq *rq;
+       struct rq *rq, *orig_rq;
 
        if (!sched_feat(SYNC_WAKEUPS))
                wake_flags &= ~WF_SYNC;
@@ -2319,7 +2316,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
        this_cpu = get_cpu();
 
        smp_wmb();
-       rq = task_rq_lock(p, &flags);
+       rq = orig_rq = task_rq_lock(p, &flags);
        update_rq_clock(rq);
        if (!(p->state & state))
                goto out;
@@ -2350,6 +2347,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
                set_task_cpu(p, cpu);
 
        rq = task_rq_lock(p, &flags);
+
+       if (rq != orig_rq)
+               update_rq_clock(rq);
+
        WARN_ON(p->state != TASK_WAKING);
        cpu = task_cpu(p);
 
@@ -3656,6 +3657,7 @@ static void update_group_power(struct sched_domain *sd, int cpu)
 
 /**
  * update_sg_lb_stats - Update sched_group's statistics for load balancing.
+ * @sd: The sched_domain whose statistics are to be updated.
  * @group: sched_group whose statistics are to be updated.
  * @this_cpu: Cpu for which load balance is currently performed.
  * @idle: Idle status of this_cpu
@@ -6718,9 +6720,6 @@ EXPORT_SYMBOL(yield);
 /*
  * This task is about to go to sleep on IO. Increment rq->nr_iowait so
  * that process accounting knows that this is a task in IO wait state.
- *
- * But don't do that if it is a deliberate, throttling IO wait (this task
- * has set its backing_dev_info: the queue against which it should throttle)
  */
 void __sched io_schedule(void)
 {
@@ -9404,6 +9403,10 @@ void __init sched_init(void)
 #endif /* CONFIG_USER_SCHED */
 #endif /* CONFIG_GROUP_SCHED */
 
+#if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP
+       update_shares_data = __alloc_percpu(nr_cpu_ids * sizeof(unsigned long),
+                                           __alignof__(unsigned long));
+#endif
        for_each_possible_cpu(i) {
                struct rq *rq;
 
index 4e777b4..c32c3e6 100644 (file)
@@ -861,12 +861,21 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
 static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
 {
        struct sched_entity *se = __pick_next_entity(cfs_rq);
+       struct sched_entity *buddy;
 
-       if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, se) < 1)
-               return cfs_rq->next;
+       if (cfs_rq->next) {
+               buddy = cfs_rq->next;
+               cfs_rq->next = NULL;
+               if (wakeup_preempt_entity(buddy, se) < 1)
+                       return buddy;
+       }
 
-       if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, se) < 1)
-               return cfs_rq->last;
+       if (cfs_rq->last) {
+               buddy = cfs_rq->last;
+               cfs_rq->last = NULL;
+               if (wakeup_preempt_entity(buddy, se) < 1)
+                       return buddy;
+       }
 
        return se;
 }
@@ -1654,16 +1663,6 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
 
        do {
                se = pick_next_entity(cfs_rq);
-               /*
-                * If se was a buddy, clear it so that it will have to earn
-                * the favour again.
-                *
-                * If se was not a buddy, clear the buddies because neither
-                * was elegible to run, let them earn it again.
-                *
-                * IOW. unconditionally clear buddies.
-                */
-               __clear_buddies(cfs_rq, NULL);
                set_next_entity(cfs_rq, se);
                cfs_rq = group_cfs_rq(se);
        } while (cfs_rq);
index 255475d..ce17760 100644 (file)
@@ -1110,6 +1110,8 @@ SYSCALL_DEFINE0(setsid)
        err = session;
 out:
        write_unlock_irq(&tasklist_lock);
+       if (err > 0)
+               proc_sid_connector(group_leader);
        return err;
 }
 
@@ -1546,24 +1548,37 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                        if (arg4 | arg5)
                                return -EINVAL;
                        switch (arg2) {
-                       case 0:
+                       case PR_MCE_KILL_CLEAR:
                                if (arg3 != 0)
                                        return -EINVAL;
                                current->flags &= ~PF_MCE_PROCESS;
                                break;
-                       case 1:
+                       case PR_MCE_KILL_SET:
                                current->flags |= PF_MCE_PROCESS;
-                               if (arg3 != 0)
+                               if (arg3 == PR_MCE_KILL_EARLY)
                                        current->flags |= PF_MCE_EARLY;
-                               else
+                               else if (arg3 == PR_MCE_KILL_LATE)
                                        current->flags &= ~PF_MCE_EARLY;
+                               else if (arg3 == PR_MCE_KILL_DEFAULT)
+                                       current->flags &=
+                                               ~(PF_MCE_EARLY|PF_MCE_PROCESS);
+                               else
+                                       return -EINVAL;
                                break;
                        default:
                                return -EINVAL;
                        }
                        error = 0;
                        break;
-
+               case PR_MCE_KILL_GET:
+                       if (arg2 | arg3 | arg4 | arg5)
+                               return -EINVAL;
+                       if (current->flags & PF_MCE_PROCESS)
+                               error = (current->flags & PF_MCE_EARLY) ?
+                                       PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
+                       else
+                               error = PR_MCE_KILL_DEFAULT;
+                       break;
                default:
                        error = -EINVAL;
                        break;
index b38423c..b6e7aae 100644 (file)
@@ -1521,7 +1521,7 @@ int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
                        if (!table->ctl_name && table->strategy)
                                set_fail(&fail, table, "Strategy without ctl_name");
 #endif
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_PROC_SYSCTL
                        if (table->procname && !table->proc_handler)
                                set_fail(&fail, table, "No proc_handler");
 #endif
index 37ba67e..9c451a1 100644 (file)
@@ -740,7 +740,7 @@ ftrace_profile_write(struct file *filp, const char __user *ubuf,
  out:
        mutex_unlock(&ftrace_profile_lock);
 
-       filp->f_pos += cnt;
+       *ppos += cnt;
 
        return cnt;
 }
index d4ff019..3ffa502 100644 (file)
@@ -483,7 +483,7 @@ struct ring_buffer_iter {
 /* Up this if you want to test the TIME_EXTENTS and normalization */
 #define DEBUG_SHIFT 0
 
-static inline u64 rb_time_stamp(struct ring_buffer *buffer, int cpu)
+static inline u64 rb_time_stamp(struct ring_buffer *buffer)
 {
        /* shift to debug/test normalization and TIME_EXTENTS */
        return buffer->clock() << DEBUG_SHIFT;
@@ -494,7 +494,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
        u64 time;
 
        preempt_disable_notrace();
-       time = rb_time_stamp(buffer, cpu);
+       time = rb_time_stamp(buffer);
        preempt_enable_no_resched_notrace();
 
        return time;
@@ -599,7 +599,7 @@ static struct list_head *rb_list_head(struct list_head *list)
 }
 
 /*
- * rb_is_head_page - test if the give page is the head page
+ * rb_is_head_page - test if the given page is the head page
  *
  * Because the reader may move the head_page pointer, we can
  * not trust what the head page is (it may be pointing to
@@ -1868,7 +1868,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
                 * Nested commits always have zero deltas, so
                 * just reread the time stamp
                 */
-               *ts = rb_time_stamp(buffer, cpu_buffer->cpu);
+               *ts = rb_time_stamp(buffer);
                next_page->page->time_stamp = *ts;
        }
 
@@ -2111,7 +2111,7 @@ rb_reserve_next_event(struct ring_buffer *buffer,
        if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000))
                goto out_fail;
 
-       ts = rb_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu);
+       ts = rb_time_stamp(cpu_buffer->buffer);
 
        /*
         * Only the first commit can update the timestamp.
@@ -2681,7 +2681,7 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer)
 EXPORT_SYMBOL_GPL(ring_buffer_entries);
 
 /**
- * ring_buffer_overrun_cpu - get the number of overruns in buffer
+ * ring_buffer_overruns - get the number of overruns in buffer
  * @buffer: The ring buffer
  *
  * Returns the total number of overruns in the ring buffer
index 4506826..b20d3ec 100644 (file)
@@ -1393,7 +1393,7 @@ int trace_array_vprintk(struct trace_array *tr,
 
 int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
 {
-       return trace_array_printk(&global_trace, ip, fmt, args);
+       return trace_array_vprintk(&global_trace, ip, fmt, args);
 }
 EXPORT_SYMBOL_GPL(trace_vprintk);
 
@@ -2440,7 +2440,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
                        return ret;
        }
 
-       filp->f_pos += cnt;
+       *ppos += cnt;
 
        return cnt;
 }
@@ -2582,7 +2582,7 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf,
        }
        mutex_unlock(&trace_types_lock);
 
-       filp->f_pos += cnt;
+       *ppos += cnt;
 
        return cnt;
 }
@@ -2764,7 +2764,7 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
        if (err)
                return err;
 
-       filp->f_pos += ret;
+       *ppos += ret;
 
        return ret;
 }
@@ -3299,7 +3299,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
                }
        }
 
-       filp->f_pos += cnt;
+       *ppos += cnt;
 
        /* If check pages failed, return ENOMEM */
        if (tracing_disabled)
index 2324578..98a6cc5 100644 (file)
@@ -933,8 +933,9 @@ static void postfix_clear(struct filter_parse_state *ps)
 
        while (!list_empty(&ps->postfix)) {
                elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
-               kfree(elt->operand);
                list_del(&elt->list);
+               kfree(elt->operand);
+               kfree(elt);
        }
 }
 
index ed17565..b6c12c6 100644 (file)
@@ -69,6 +69,9 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
  * @s: trace sequence descriptor
  * @fmt: printf format string
  *
+ * It returns 0 if the trace oversizes the buffer's free
+ * space, 1 otherwise.
+ *
  * The tracer may use either sequence operations or its own
  * copy to user routines. To simplify formating of a trace
  * trace_seq_printf is used to store strings into a special
@@ -95,7 +98,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
 
        s->len += ret;
 
-       return len;
+       return 1;
 }
 EXPORT_SYMBOL_GPL(trace_seq_printf);
 
index addfe2d..1232814 100644 (file)
@@ -639,6 +639,24 @@ int schedule_delayed_work(struct delayed_work *dwork,
 }
 EXPORT_SYMBOL(schedule_delayed_work);
 
+/**
+ * flush_delayed_work - block until a dwork_struct's callback has terminated
+ * @dwork: the delayed work which is to be flushed
+ *
+ * Any timeout is cancelled, and any pending work is run immediately.
+ */
+void flush_delayed_work(struct delayed_work *dwork)
+{
+       if (del_timer_sync(&dwork->timer)) {
+               struct cpu_workqueue_struct *cwq;
+               cwq = wq_per_cpu(keventd_wq, get_cpu());
+               __queue_work(cwq, &dwork->work);
+               put_cpu();
+       }
+       flush_work(&dwork->work);
+}
+EXPORT_SYMBOL(flush_delayed_work);
+
 /**
  * schedule_delayed_work_on - queue work in global workqueue on CPU after delay
  * @cpu: cpu to use
@@ -667,21 +685,38 @@ EXPORT_SYMBOL(schedule_delayed_work_on);
 int schedule_on_each_cpu(work_func_t func)
 {
        int cpu;
+       int orig = -1;
        struct work_struct *works;
 
        works = alloc_percpu(struct work_struct);
        if (!works)
                return -ENOMEM;
 
+       /*
+        * when running in keventd don't schedule a work item on itself.
+        * Can just call directly because the work queue is already bound.
+        * This also is faster.
+        * Make this a generic parameter for other workqueues?
+        */
+       if (current_is_keventd()) {
+               orig = raw_smp_processor_id();
+               INIT_WORK(per_cpu_ptr(works, orig), func);
+               func(per_cpu_ptr(works, orig));
+       }
+
        get_online_cpus();
        for_each_online_cpu(cpu) {
                struct work_struct *work = per_cpu_ptr(works, cpu);
 
+               if (cpu == orig)
+                       continue;
                INIT_WORK(work, func);
                schedule_work_on(cpu, work);
        }
-       for_each_online_cpu(cpu)
-               flush_work(per_cpu_ptr(works, cpu));
+       for_each_online_cpu(cpu) {
+               if (cpu != orig)
+                       flush_work(per_cpu_ptr(works, cpu));
+       }
        put_online_cpus();
        free_percpu(works);
        return 0;
index 30df586..234ceb1 100644 (file)
@@ -392,7 +392,7 @@ config DEBUG_KMEMLEAK_TEST
 
 config DEBUG_PREEMPT
        bool "Debug preemptible kernel"
-       depends on DEBUG_KERNEL && PREEMPT && (TRACE_IRQFLAGS_SUPPORT || PPC64)
+       depends on DEBUG_KERNEL && PREEMPT && TRACE_IRQFLAGS_SUPPORT
        default y
        help
          If you say Y here then the kernel will use a debug variant of the
index 57963c6..fd33862 100644 (file)
@@ -67,7 +67,7 @@ config DISCONTIGMEM
 
 config SPARSEMEM
        def_bool y
-       depends on SPARSEMEM_MANUAL
+       depends on (!SELECT_MEMORY_MODEL && ARCH_SPARSEMEM_ENABLE) || SPARSEMEM_MANUAL
 
 config FLATMEM
        def_bool y
@@ -129,7 +129,7 @@ config MEMORY_HOTPLUG
        bool "Allow for memory hot-add"
        depends on SPARSEMEM || X86_64_ACPI_NUMA
        depends on HOTPLUG && !(HIBERNATION && !S390) && ARCH_ENABLE_MEMORY_HOTPLUG
-       depends on (IA64 || X86 || PPC64 || SUPERH || S390)
+       depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
 
 comment "Memory hotplug is currently incompatible with Software Suspend"
        depends on SPARSEMEM && HOTPLUG && HIBERNATION && !S390
index 3d3accb..1065b71 100644 (file)
@@ -92,7 +92,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
                   "BdiDirtyThresh:   %8lu kB\n"
                   "DirtyThresh:      %8lu kB\n"
                   "BackgroundThresh: %8lu kB\n"
-                  "WriteBack threads:%8lu\n"
+                  "WritebackThreads: %8lu\n"
                   "b_dirty:          %8lu\n"
                   "b_io:             %8lu\n"
                   "b_more_io:        %8lu\n"
@@ -610,6 +610,21 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
                kthread_stop(wb->task);
 }
 
+/*
+ * This bdi is going away now, make sure that no super_blocks point to it
+ */
+static void bdi_prune_sb(struct backing_dev_info *bdi)
+{
+       struct super_block *sb;
+
+       spin_lock(&sb_lock);
+       list_for_each_entry(sb, &super_blocks, s_list) {
+               if (sb->s_bdi == bdi)
+                       sb->s_bdi = NULL;
+       }
+       spin_unlock(&sb_lock);
+}
+
 void bdi_unregister(struct backing_dev_info *bdi)
 {
        if (bdi->dev) {
@@ -682,6 +697,7 @@ void bdi_destroy(struct backing_dev_info *bdi)
                spin_unlock(&inode_lock);
        }
 
+       bdi_prune_sb(bdi);
        bdi_unregister(bdi);
 
        for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
index 729d4b1..dacc641 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mm.h>
 #include <linux/page-flags.h>
 #include <linux/sched.h>
+#include <linux/ksm.h>
 #include <linux/rmap.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
@@ -370,9 +371,6 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
        int ret = FAILED;
        struct address_space *mapping;
 
-       if (!isolate_lru_page(p))
-               page_cache_release(p);
-
        /*
         * For anonymous pages we're done the only reference left
         * should be the one m_f() holds.
@@ -498,30 +496,18 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
  */
 static int me_swapcache_dirty(struct page *p, unsigned long pfn)
 {
-       int ret = FAILED;
-
        ClearPageDirty(p);
        /* Trigger EIO in shmem: */
        ClearPageUptodate(p);
 
-       if (!isolate_lru_page(p)) {
-               page_cache_release(p);
-               ret = DELAYED;
-       }
-
-       return ret;
+       return DELAYED;
 }
 
 static int me_swapcache_clean(struct page *p, unsigned long pfn)
 {
-       int ret = FAILED;
-
-       if (!isolate_lru_page(p)) {
-               page_cache_release(p);
-               ret = RECOVERED;
-       }
        delete_from_swap_cache(p);
-       return ret;
+
+       return RECOVERED;
 }
 
 /*
@@ -611,8 +597,6 @@ static struct page_state {
        { 0,            0,              "unknown page state",   me_unknown },
 };
 
-#undef lru
-
 static void action_result(unsigned long pfn, char *msg, int result)
 {
        struct page *page = NULL;
@@ -629,13 +613,16 @@ static int page_action(struct page_state *ps, struct page *p,
                        unsigned long pfn, int ref)
 {
        int result;
+       int count;
 
        result = ps->action(p, pfn);
        action_result(pfn, ps->msg, result);
-       if (page_count(p) != 1 + ref)
+
+       count = page_count(p) - 1 - ref;
+       if (count != 0)
                printk(KERN_ERR
                       "MCE %#lx: %s page still referenced by %d users\n",
-                      pfn, ps->msg, page_count(p) - 1);
+                      pfn, ps->msg, count);
 
        /* Could do more checks here if page looks ok */
        /*
@@ -661,12 +648,9 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
        int i;
        int kill = 1;
 
-       if (PageReserved(p) || PageCompound(p) || PageSlab(p))
+       if (PageReserved(p) || PageCompound(p) || PageSlab(p) || PageKsm(p))
                return;
 
-       if (!PageLRU(p))
-               lru_add_drain_all();
-
        /*
         * This check implies we don't kill processes if their pages
         * are in the swap cache early. Those are always late kills.
@@ -738,6 +722,7 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
 
 int __memory_failure(unsigned long pfn, int trapno, int ref)
 {
+       unsigned long lru_flag;
        struct page_state *ps;
        struct page *p;
        int res;
@@ -774,6 +759,24 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
                return PageBuddy(compound_head(p)) ? 0 : -EBUSY;
        }
 
+       /*
+        * We ignore non-LRU pages for good reasons.
+        * - PG_locked is only well defined for LRU pages and a few others
+        * - to avoid races with __set_page_locked()
+        * - to avoid races with __SetPageSlab*() (and more non-atomic ops)
+        * The check (unnecessarily) ignores LRU pages being isolated and
+        * walked by the page reclaim code, however that's not a big loss.
+        */
+       if (!PageLRU(p))
+               lru_add_drain_all();
+       lru_flag = p->flags & lru;
+       if (isolate_lru_page(p)) {
+               action_result(pfn, "non LRU", IGNORED);
+               put_page(p);
+               return -EBUSY;
+       }
+       page_cache_release(p);
+
        /*
         * Lock the page and wait for writeback to finish.
         * It's very difficult to mess with pages currently under IO
@@ -790,7 +793,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
        /*
         * Torn down by someone else?
         */
-       if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
+       if ((lru_flag & lru) && !PageSwapCache(p) && p->mapping == NULL) {
                action_result(pfn, "already truncated LRU", IGNORED);
                res = 0;
                goto out;
@@ -798,7 +801,7 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
 
        res = -EBUSY;
        for (ps = error_states;; ps++) {
-               if ((p->flags & ps->mask) == ps->res) {
+               if (((p->flags | lru_flag)& ps->mask) == ps->res) {
                        res = page_action(ps, p, pfn, ref);
                        break;
                }
index 7e91b5f..6ab19dd 100644 (file)
@@ -641,6 +641,7 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
                pmd_t *dst_pmd, pmd_t *src_pmd, struct vm_area_struct *vma,
                unsigned long addr, unsigned long end)
 {
+       pte_t *orig_src_pte, *orig_dst_pte;
        pte_t *src_pte, *dst_pte;
        spinlock_t *src_ptl, *dst_ptl;
        int progress = 0;
@@ -654,6 +655,8 @@ again:
        src_pte = pte_offset_map_nested(src_pmd, addr);
        src_ptl = pte_lockptr(src_mm, src_pmd);
        spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+       orig_src_pte = src_pte;
+       orig_dst_pte = dst_pte;
        arch_enter_lazy_mmu_mode();
 
        do {
@@ -677,9 +680,9 @@ again:
 
        arch_leave_lazy_mmu_mode();
        spin_unlock(src_ptl);
-       pte_unmap_nested(src_pte - 1);
+       pte_unmap_nested(orig_src_pte);
        add_mm_rss(dst_mm, rss[0], rss[1]);
-       pte_unmap_unlock(dst_pte - 1, dst_ptl);
+       pte_unmap_unlock(orig_dst_pte, dst_ptl);
        cond_resched();
        if (addr != end)
                goto again;
@@ -1820,10 +1823,10 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
        token = pmd_pgtable(*pmd);
 
        do {
-               err = fn(pte, token, addr, data);
+               err = fn(pte++, token, addr, data);
                if (err)
                        break;
-       } while (pte++, addr += PAGE_SIZE, addr != end);
+       } while (addr += PAGE_SIZE, addr != end);
 
        arch_leave_lazy_mmu_mode();
 
@@ -2539,7 +2542,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
        } else if (PageHWPoison(page)) {
                ret = VM_FAULT_HWPOISON;
                delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
-               goto out;
+               goto out_release;
        }
 
        lock_page(page);
@@ -2611,6 +2614,7 @@ out_nomap:
        pte_unmap_unlock(page_table, ptl);
 out_page:
        unlock_page(page);
+out_release:
        page_cache_release(page);
        return ret;
 }
index 7dd9d9f..4545d59 100644 (file)
@@ -1024,7 +1024,7 @@ static long do_mbind(unsigned long start, unsigned long len,
 
                err = migrate_prep();
                if (err)
-                       return err;
+                       goto mpol_out;
        }
        {
                NODEMASK_SCRATCH(scratch);
@@ -1039,10 +1039,9 @@ static long do_mbind(unsigned long start, unsigned long len,
                        err = -ENOMEM;
                NODEMASK_SCRATCH_FREE(scratch);
        }
-       if (err) {
-               mpol_put(new);
-               return err;
-       }
+       if (err)
+               goto mpol_out;
+
        vma = check_range(mm, start, end, nmask,
                          flags | MPOL_MF_INVERT, &pagelist);
 
@@ -1058,9 +1057,11 @@ static long do_mbind(unsigned long start, unsigned long len,
 
                if (!err && nr_failed && (flags & MPOL_MF_STRICT))
                        err = -EIO;
-       }
+       } else
+               putback_lru_pages(&pagelist);
 
        up_write(&mm->mmap_sem);
+ mpol_out:
        mpol_put(new);
        return err;
 }
index 5189b5a..9876fa0 100644 (file)
@@ -1362,9 +1362,11 @@ share:
 error_just_free:
        up_write(&nommu_region_sem);
 error:
-       fput(region->vm_file);
+       if (region->vm_file)
+               fput(region->vm_file);
        kmem_cache_free(vm_region_jar, region);
-       fput(vma->vm_file);
+       if (vma->vm_file)
+               fput(vma->vm_file);
        if (vma->vm_flags & VM_EXECUTABLE)
                removed_exe_file_vma(vma->vm_mm);
        kmem_cache_free(vm_area_cachep, vma);
index a3b1409..2c5d792 100644 (file)
@@ -566,7 +566,8 @@ static void balance_dirty_pages(struct address_space *mapping,
                if (pages_written >= write_chunk)
                        break;          /* We've done our duty */
 
-               schedule_timeout_interruptible(pause);
+               __set_current_state(TASK_INTERRUPTIBLE);
+               io_schedule_timeout(pause);
 
                /*
                 * Increase the delay for each loop, up to our previous
index bf72055..cdcedf6 100644 (file)
@@ -2183,7 +2183,7 @@ void show_free_areas(void)
        printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n"
                " active_file:%lu inactive_file:%lu isolated_file:%lu\n"
                " unevictable:%lu"
-               " dirty:%lu writeback:%lu unstable:%lu buffer:%lu\n"
+               " dirty:%lu writeback:%lu unstable:%lu\n"
                " free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
                " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
                global_page_state(NR_ACTIVE_ANON),
@@ -2196,7 +2196,6 @@ void show_free_areas(void)
                global_page_state(NR_FILE_DIRTY),
                global_page_state(NR_WRITEBACK),
                global_page_state(NR_UNSTABLE_NFS),
-               nr_blockdev_pages(),
                global_page_state(NR_FREE_PAGES),
                global_page_state(NR_SLAB_RECLAIMABLE),
                global_page_state(NR_SLAB_UNRECLAIMABLE),
index 4a048ab..d907971 100644 (file)
@@ -153,7 +153,10 @@ static int pcpu_reserved_chunk_limit;
  *
  * During allocation, pcpu_alloc_mutex is kept locked all the time and
  * pcpu_lock is grabbed and released as necessary.  All actual memory
- * allocations are done using GFP_KERNEL with pcpu_lock released.
+ * allocations are done using GFP_KERNEL with pcpu_lock released.  In
+ * general, percpu memory can't be allocated with irq off but
+ * irqsave/restore are still used in alloc path so that it can be used
+ * from early init path - sched_init() specifically.
  *
  * Free path accesses and alters only the index data structures, so it
  * can be safely called from atomic context.  When memory needs to be
@@ -366,7 +369,7 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
  * RETURNS:
  * 0 if noop, 1 if successfully extended, -errno on failure.
  */
-static int pcpu_extend_area_map(struct pcpu_chunk *chunk)
+static int pcpu_extend_area_map(struct pcpu_chunk *chunk, unsigned long *flags)
 {
        int new_alloc;
        int *new;
@@ -376,7 +379,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk)
        if (chunk->map_alloc >= chunk->map_used + 2)
                return 0;
 
-       spin_unlock_irq(&pcpu_lock);
+       spin_unlock_irqrestore(&pcpu_lock, *flags);
 
        new_alloc = PCPU_DFL_MAP_ALLOC;
        while (new_alloc < chunk->map_used + 2)
@@ -384,7 +387,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk)
 
        new = pcpu_mem_alloc(new_alloc * sizeof(new[0]));
        if (!new) {
-               spin_lock_irq(&pcpu_lock);
+               spin_lock_irqsave(&pcpu_lock, *flags);
                return -ENOMEM;
        }
 
@@ -393,7 +396,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk)
         * could have happened inbetween, so map_used couldn't have
         * grown.
         */
-       spin_lock_irq(&pcpu_lock);
+       spin_lock_irqsave(&pcpu_lock, *flags);
        BUG_ON(new_alloc < chunk->map_used + 2);
 
        size = chunk->map_alloc * sizeof(chunk->map[0]);
@@ -1047,6 +1050,7 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
        struct pcpu_chunk *chunk;
        const char *err;
        int slot, off;
+       unsigned long flags;
 
        if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
                WARN(true, "illegal size (%zu) or align (%zu) for "
@@ -1055,13 +1059,13 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
        }
 
        mutex_lock(&pcpu_alloc_mutex);
-       spin_lock_irq(&pcpu_lock);
+       spin_lock_irqsave(&pcpu_lock, flags);
 
        /* serve reserved allocations from the reserved chunk if available */
        if (reserved && pcpu_reserved_chunk) {
                chunk = pcpu_reserved_chunk;
                if (size > chunk->contig_hint ||
-                   pcpu_extend_area_map(chunk) < 0) {
+                   pcpu_extend_area_map(chunk, &flags) < 0) {
                        err = "failed to extend area map of reserved chunk";
                        goto fail_unlock;
                }
@@ -1079,7 +1083,7 @@ restart:
                        if (size > chunk->contig_hint)
                                continue;
 
-                       switch (pcpu_extend_area_map(chunk)) {
+                       switch (pcpu_extend_area_map(chunk, &flags)) {
                        case 0:
                                break;
                        case 1:
@@ -1096,7 +1100,7 @@ restart:
        }
 
        /* hmmm... no space left, create a new chunk */
-       spin_unlock_irq(&pcpu_lock);
+       spin_unlock_irqrestore(&pcpu_lock, flags);
 
        chunk = alloc_pcpu_chunk();
        if (!chunk) {
@@ -1104,16 +1108,16 @@ restart:
                goto fail_unlock_mutex;
        }
 
-       spin_lock_irq(&pcpu_lock);
+       spin_lock_irqsave(&pcpu_lock, flags);
        pcpu_chunk_relocate(chunk, -1);
        goto restart;
 
 area_found:
-       spin_unlock_irq(&pcpu_lock);
+       spin_unlock_irqrestore(&pcpu_lock, flags);
 
        /* populate, map and clear the area */
        if (pcpu_populate_chunk(chunk, off, size)) {
-               spin_lock_irq(&pcpu_lock);
+               spin_lock_irqsave(&pcpu_lock, flags);
                pcpu_free_area(chunk, off);
                err = "failed to populate";
                goto fail_unlock;
@@ -1125,7 +1129,7 @@ area_found:
        return __addr_to_pcpu_ptr(chunk->base_addr + off);
 
 fail_unlock:
-       spin_unlock_irq(&pcpu_lock);
+       spin_unlock_irqrestore(&pcpu_lock, flags);
 fail_unlock_mutex:
        mutex_unlock(&pcpu_alloc_mutex);
        if (warn_limit) {
@@ -1870,13 +1874,14 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
        max_distance = 0;
        for (group = 0; group < ai->nr_groups; group++) {
                ai->groups[group].base_offset = areas[group] - base;
-               max_distance = max(max_distance, ai->groups[group].base_offset);
+               max_distance = max_t(size_t, max_distance,
+                                    ai->groups[group].base_offset);
        }
        max_distance += ai->unit_size;
 
        /* warn if maximum distance is further than 75% of vmalloc space */
        if (max_distance > (VMALLOC_END - VMALLOC_START) * 3 / 4) {
-               pr_warning("PERCPU: max_distance=0x%lx too large for vmalloc "
+               pr_warning("PERCPU: max_distance=0x%zx too large for vmalloc "
                           "space 0x%lx\n",
                           max_distance, VMALLOC_END - VMALLOC_START);
 #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
index a1bc6b9..9c590ee 100644 (file)
@@ -1151,8 +1151,7 @@ static int try_to_unuse(unsigned int type)
                                } else
                                        retval = unuse_mm(mm, entry, page);
 
-                               if (set_start_mm &&
-                                   swap_count(*swap_map) < swcount) {
+                               if (set_start_mm && *swap_map < swcount) {
                                        mmput(new_start_mm);
                                        atomic_inc(&mm->mm_users);
                                        new_start_mm = mm;
index 64e4388..777af57 100644 (file)
@@ -544,6 +544,16 @@ redo:
                 */
                lru = LRU_UNEVICTABLE;
                add_page_to_unevictable_list(page);
+               /*
+                * When racing with an mlock clearing (page is
+                * unlocked), make sure that if the other thread does
+                * not observe our setting of PG_lru and fails
+                * isolation, we see PG_mlocked cleared below and move
+                * the page back to the evictable list.
+                *
+                * The other side is TestClearPageMlocked().
+                */
+               smp_mb();
        }
 
        /*
@@ -1088,7 +1098,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
        int lumpy_reclaim = 0;
 
        while (unlikely(too_many_isolated(zone, file, sc))) {
-               congestion_wait(WRITE, HZ/10);
+               congestion_wait(BLK_RW_ASYNC, HZ/10);
 
                /* We are about to die and free our memory. Return now. */
                if (fatal_signal_pending(current))
@@ -1356,7 +1366,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
                         * IO, plus JVM can create lots of anon VM_EXEC pages,
                         * so we ignore them here.
                         */
-                       if ((vm_flags & VM_EXEC) && !PageAnon(page)) {
+                       if ((vm_flags & VM_EXEC) && page_is_file_cache(page)) {
                                list_add(&page->lru, &l_active);
                                continue;
                        }
index b2e07f0..ea1e3da 100644 (file)
@@ -43,7 +43,6 @@
 #include <net/9p/transport.h>
 #include <linux/scatterlist.h>
 #include <linux/virtio.h>
-#include <linux/virtio_ids.h>
 #include <linux/virtio_9p.h>
 
 #define VIRTQUEUE_NUM  128
index 7f939ce..2bc6f6a 100644 (file)
@@ -92,6 +92,8 @@ static void add_conn(struct work_struct *work)
 
        dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
 
+       dev_set_drvdata(&conn->dev, conn);
+
        if (device_add(&conn->dev) < 0) {
                BT_ERR("Failed to register connection device");
                return;
@@ -144,8 +146,6 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
        conn->dev.class = bt_class;
        conn->dev.parent = &hdev->dev;
 
-       dev_set_drvdata(&conn->dev, conn);
-
        device_initialize(&conn->dev);
 
        INIT_WORK(&conn->work_add, add_conn);
index 555d9da..77e9fb1 100644 (file)
@@ -555,12 +555,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 
        conn->feat_mask = 0;
 
-       setup_timer(&conn->info_timer, l2cap_info_timeout,
-                                               (unsigned long) conn);
-
        spin_lock_init(&conn->lock);
        rwlock_init(&conn->chan_list.lock);
 
+       setup_timer(&conn->info_timer, l2cap_info_timeout,
+                                               (unsigned long) conn);
+
        conn->disc_reason = 0x13;
 
        return conn;
@@ -783,6 +783,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
        /* Default config options */
        pi->conf_len = 0;
        pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+       skb_queue_head_init(TX_QUEUE(sk));
+       skb_queue_head_init(SREJ_QUEUE(sk));
+       INIT_LIST_HEAD(SREJ_LIST(sk));
 }
 
 static struct proto l2cap_proto = {
index 86acdba..6eb8d47 100644 (file)
@@ -335,6 +335,7 @@ struct pktgen_dev {
        __u32 cur_src_mac_offset;
        __be32 cur_saddr;
        __be32 cur_daddr;
+       __u16 ip_id;
        __u16 cur_udp_dst;
        __u16 cur_udp_src;
        __u16 cur_queue_map;
@@ -2630,6 +2631,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        iph->protocol = IPPROTO_UDP;    /* UDP */
        iph->saddr = pkt_dev->cur_saddr;
        iph->daddr = pkt_dev->cur_daddr;
+       iph->id = htons(pkt_dev->ip_id);
+       pkt_dev->ip_id++;
        iph->frag_off = 0;
        iplen = 20 + 8 + datalen;
        iph->tot_len = htons(iplen);
@@ -2641,24 +2644,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        skb->dev = odev;
        skb->pkt_type = PACKET_HOST;
 
-       if (pkt_dev->nfrags <= 0)
+       if (pkt_dev->nfrags <= 0) {
                pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
-       else {
+               memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr));
+       } else {
                int frags = pkt_dev->nfrags;
-               int i;
+               int i, len;
 
                pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
 
                if (frags > MAX_SKB_FRAGS)
                        frags = MAX_SKB_FRAGS;
                if (datalen > frags * PAGE_SIZE) {
-                       skb_put(skb, datalen - frags * PAGE_SIZE);
+                       len = datalen - frags * PAGE_SIZE;
+                       memset(skb_put(skb, len), 0, len);
                        datalen = frags * PAGE_SIZE;
                }
 
                i = 0;
                while (datalen > 0) {
-                       struct page *page = alloc_pages(GFP_KERNEL, 0);
+                       struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
                        skb_shinfo(skb)->frags[i].page = page;
                        skb_shinfo(skb)->frags[i].page_offset = 0;
                        skb_shinfo(skb)->frags[i].size =
index 4351ca2..537731b 100644 (file)
@@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries;
 
 EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add);
 
+/* Decide when to expire the request and when to resend SYN-ACK */
+static inline void syn_ack_recalc(struct request_sock *req, const int thresh,
+                                 const int max_retries,
+                                 const u8 rskq_defer_accept,
+                                 int *expire, int *resend)
+{
+       if (!rskq_defer_accept) {
+               *expire = req->retrans >= thresh;
+               *resend = 1;
+               return;
+       }
+       *expire = req->retrans >= thresh &&
+                 (!inet_rsk(req)->acked || req->retrans >= max_retries);
+       /*
+        * Do not resend while waiting for data after ACK,
+        * start to resend on end of deferring period to give
+        * last chance for data or ACK to create established socket.
+        */
+       *resend = !inet_rsk(req)->acked ||
+                 req->retrans >= rskq_defer_accept - 1;
+}
+
 void inet_csk_reqsk_queue_prune(struct sock *parent,
                                const unsigned long interval,
                                const unsigned long timeout,
@@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
                reqp=&lopt->syn_table[i];
                while ((req = *reqp) != NULL) {
                        if (time_after_eq(now, req->expires)) {
-                               if ((req->retrans < thresh ||
-                                    (inet_rsk(req)->acked && req->retrans < max_retries))
-                                   && !req->rsk_ops->rtx_syn_ack(parent, req)) {
+                               int expire = 0, resend = 0;
+
+                               syn_ack_recalc(req, thresh, max_retries,
+                                              queue->rskq_defer_accept,
+                                              &expire, &resend);
+                               if (!expire &&
+                                   (!resend ||
+                                    !req->rsk_ops->rtx_syn_ack(parent, req) ||
+                                    inet_rsk(req)->acked)) {
                                        unsigned long timeo;
 
                                        if (req->retrans++ == 0)
index 0c0b6e3..e982b5c 100644 (file)
@@ -634,17 +634,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                                break;
                        }
                        dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
-                       if (dev) {
+                       if (dev)
                                mreq.imr_ifindex = dev->ifindex;
-                               dev_put(dev);
-                       }
                } else
-                       dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
+                       dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
 
 
                err = -EADDRNOTAVAIL;
                if (!dev)
                        break;
+               dev_put(dev);
 
                err = -EINVAL;
                if (sk->sk_bound_dev_if &&
index 757c917..ab996f9 100644 (file)
@@ -352,13 +352,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        skb->ip_summed = CHECKSUM_NONE;
 
        skb->transport_header = skb->network_header;
-       err = memcpy_fromiovecend((void *)iph, from, 0, length);
-       if (err)
-               goto error_fault;
+       err = -EFAULT;
+       if (memcpy_fromiovecend((void *)iph, from, 0, length))
+               goto error_free;
 
-       /* We don't modify invalid header */
        iphlen = iph->ihl * 4;
-       if (iphlen >= sizeof(*iph) && iphlen <= length) {
+
+       /*
+        * We don't want to modify the ip header, but we do need to
+        * be sure that it won't cause problems later along the network
+        * stack.  Specifically we want to make sure that iph->ihl is a
+        * sane value.  If ihl points beyond the length of the buffer passed
+        * in, reject the frame as invalid
+        */
+       err = -EINVAL;
+       if (iphlen > length)
+               goto error_free;
+
+       if (iphlen >= sizeof(*iph)) {
                if (!iph->saddr)
                        iph->saddr = rt->rt_src;
                iph->check   = 0;
@@ -381,8 +392,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 out:
        return 0;
 
-error_fault:
-       err = -EFAULT;
+error_free:
        kfree_skb(skb);
 error:
        IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
index 64d0af6..98440ad 100644 (file)
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk)
 
 EXPORT_SYMBOL(tcp_enter_memory_pressure);
 
+/* Convert seconds to retransmits based on initial and max timeout */
+static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
+{
+       u8 res = 0;
+
+       if (seconds > 0) {
+               int period = timeout;
+
+               res = 1;
+               while (seconds > period && res < 255) {
+                       res++;
+                       timeout <<= 1;
+                       if (timeout > rto_max)
+                               timeout = rto_max;
+                       period += timeout;
+               }
+       }
+       return res;
+}
+
+/* Convert retransmits to seconds based on initial and max timeout */
+static int retrans_to_secs(u8 retrans, int timeout, int rto_max)
+{
+       int period = 0;
+
+       if (retrans > 0) {
+               period = timeout;
+               while (--retrans) {
+                       timeout <<= 1;
+                       if (timeout > rto_max)
+                               timeout = rto_max;
+                       period += timeout;
+               }
+       }
+       return period;
+}
+
 /*
  *     Wait for a TCP event.
  *
@@ -1405,7 +1442,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                goto found_ok_skb;
                        if (tcp_hdr(skb)->fin)
                                goto found_fin_ok;
-                       WARN_ON(!(flags & MSG_PEEK));
+                       WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
+                                       "copied %X seq %X\n", *seq,
+                                       TCP_SKB_CB(skb)->seq);
                }
 
                /* Well, if we have backlog, try to process it now yet. */
@@ -2163,16 +2202,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                break;
 
        case TCP_DEFER_ACCEPT:
-               icsk->icsk_accept_queue.rskq_defer_accept = 0;
-               if (val > 0) {
-                       /* Translate value in seconds to number of
-                        * retransmits */
-                       while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
-                              val > ((TCP_TIMEOUT_INIT / HZ) <<
-                                      icsk->icsk_accept_queue.rskq_defer_accept))
-                               icsk->icsk_accept_queue.rskq_defer_accept++;
-                       icsk->icsk_accept_queue.rskq_defer_accept++;
-               }
+               /* Translate value in seconds to number of retransmits */
+               icsk->icsk_accept_queue.rskq_defer_accept =
+                       secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
+                                       TCP_RTO_MAX / HZ);
                break;
 
        case TCP_WINDOW_CLAMP:
@@ -2353,8 +2386,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
                        val = (val ? : sysctl_tcp_fin_timeout) / HZ;
                break;
        case TCP_DEFER_ACCEPT:
-               val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 :
-                       ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1));
+               val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
+                                     TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
                break;
        case TCP_WINDOW_CLAMP:
                val = tp->window_clamp;
index 624c3c9..4c03598 100644 (file)
@@ -641,8 +641,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
        if (!(flg & TCP_FLAG_ACK))
                return NULL;
 
-       /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
-       if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
+       /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */
+       if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
            TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
                inet_rsk(req)->acked = 1;
                return NULL;
index 6ec6a8a..d0d436d 100644 (file)
@@ -841,6 +841,42 @@ out:
        return ret;
 }
 
+
+/**
+ *     first_packet_length     - return length of first packet in receive queue
+ *     @sk: socket
+ *
+ *     Drops all bad checksum frames, until a valid one is found.
+ *     Returns the length of found skb, or 0 if none is found.
+ */
+static unsigned int first_packet_length(struct sock *sk)
+{
+       struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue;
+       struct sk_buff *skb;
+       unsigned int res;
+
+       __skb_queue_head_init(&list_kill);
+
+       spin_lock_bh(&rcvq->lock);
+       while ((skb = skb_peek(rcvq)) != NULL &&
+               udp_lib_checksum_complete(skb)) {
+               UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
+                                IS_UDPLITE(sk));
+               __skb_unlink(skb, rcvq);
+               __skb_queue_tail(&list_kill, skb);
+       }
+       res = skb ? skb->len : 0;
+       spin_unlock_bh(&rcvq->lock);
+
+       if (!skb_queue_empty(&list_kill)) {
+               lock_sock(sk);
+               __skb_queue_purge(&list_kill);
+               sk_mem_reclaim_partial(sk);
+               release_sock(sk);
+       }
+       return res;
+}
+
 /*
  *     IOCTL requests applicable to the UDP protocol
  */
@@ -857,21 +893,16 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 
        case SIOCINQ:
        {
-               struct sk_buff *skb;
-               unsigned long amount;
+               unsigned int amount = first_packet_length(sk);
 
-               amount = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               skb = skb_peek(&sk->sk_receive_queue);
-               if (skb != NULL) {
+               if (amount)
                        /*
                         * We will only return the amount
                         * of this packet since that is all
                         * that will be read.
                         */
-                       amount = skb->len - sizeof(struct udphdr);
-               }
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
+                       amount -= sizeof(struct udphdr);
+
                return put_user(amount, (int __user *)arg);
        }
 
@@ -1540,29 +1571,11 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
 {
        unsigned int mask = datagram_poll(file, sock, wait);
        struct sock *sk = sock->sk;
-       int     is_lite = IS_UDPLITE(sk);
 
        /* Check for false positives due to checksum errors */
-       if ((mask & POLLRDNORM) &&
-           !(file->f_flags & O_NONBLOCK) &&
-           !(sk->sk_shutdown & RCV_SHUTDOWN)) {
-               struct sk_buff_head *rcvq = &sk->sk_receive_queue;
-               struct sk_buff *skb;
-
-               spin_lock_bh(&rcvq->lock);
-               while ((skb = skb_peek(rcvq)) != NULL &&
-                      udp_lib_checksum_complete(skb)) {
-                       UDP_INC_STATS_BH(sock_net(sk),
-                                       UDP_MIB_INERRORS, is_lite);
-                       __skb_unlink(skb, rcvq);
-                       kfree_skb(skb);
-               }
-               spin_unlock_bh(&rcvq->lock);
-
-               /* nothing to see, move along */
-               if (skb == NULL)
-                       mask &= ~(POLLIN | POLLRDNORM);
-       }
+       if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
+           !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
+               mask &= ~(POLLIN | POLLRDNORM);
 
        return mask;
 
index 14f54eb..4f7aaf6 100644 (file)
@@ -496,13 +496,17 @@ done:
                        goto e_inval;
 
                if (val) {
+                       struct net_device *dev;
+
                        if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val)
                                goto e_inval;
 
-                       if (__dev_get_by_index(net, val) == NULL) {
+                       dev = dev_get_by_index(net, val);
+                       if (!dev) {
                                retv = -ENODEV;
                                break;
                        }
+                       dev_put(dev);
                }
                np->mcast_oif = val;
                retv = 0;
index 920ec87..ca8ecce 100644 (file)
@@ -538,13 +538,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                                       WLAN_CAPABILITY_PRIVACY,
                                       capability);
 
+       if (bss) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-       if (bss)
                printk(KERN_DEBUG "   sta_find_ibss: selected %pM current "
                       "%pM\n", bss->cbss.bssid, ifibss->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
-       if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
                printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
                       " based on configured SSID\n",
                       sdata->dev->name, bss->cbss.bssid);
@@ -552,8 +551,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                ieee80211_sta_join_ibss(sdata, bss);
                ieee80211_rx_bss_put(local, bss);
                return;
-       } else if (bss)
-               ieee80211_rx_bss_put(local, bss);
+       }
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        printk(KERN_DEBUG "   did not try to join ibss\n");
@@ -829,7 +827,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
                if (!sdata->u.ibss.ssid_len)
                        continue;
                sdata->u.ibss.last_scan_completed = jiffies;
-               ieee80211_sta_find_ibss(sdata);
+               mod_timer(&sdata->u.ibss.timer, 0);
        }
        mutex_unlock(&local->iflist_mtx);
 }
index e12a786..29b82e9 100644 (file)
@@ -259,7 +259,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
  * @hwmp_ie: hwmp information element (PREP or PREQ)
  *
  * This function updates the path routing information to the originator and the
- * transmitter of a HWMP PREQ or PREP fram.
+ * transmitter of a HWMP PREQ or PREP frame.
  *
  * Returns: metric to frame originator or 0 if the frame should not be further
  * processed
index 8d26e9b..dc5049d 100644 (file)
@@ -1457,8 +1457,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        if (status_code != WLAN_STATUS_SUCCESS) {
                printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
                       sdata->dev->name, status_code);
-               list_del(&wk->list);
-               kfree(wk);
+               wk->state = IEEE80211_MGD_STATE_IDLE;
                return RX_MGMT_CFG80211_ASSOC;
        }
 
index c01588f..7170bf4 100644 (file)
@@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 
        skb = rx.skb;
 
-       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+       if (rx.sdata && ieee80211_is_data(hdr->frame_control)) {
+               rx.flags |= IEEE80211_RX_RA_MATCH;
+               prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
+               if (prepares)
+                       prev = rx.sdata;
+       } else list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                if (!netif_running(sdata->dev))
                        continue;
 
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+               if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+                   sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
                        continue;
 
                rx.flags |= IEEE80211_RX_RA_MATCH;
@@ -2447,6 +2453,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ieee80211_supported_band *sband;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 
+       WARN_ON_ONCE(softirq_count() == 0);
+
        if (WARN_ON(status->band < 0 ||
                    status->band >= IEEE80211_NUM_BANDS))
                goto drop;
index eec0014..594f231 100644 (file)
@@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta)
                                             u.ap);
 
                drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
+               sdata = sta->sdata;
        }
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta)
 
                drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
                               &(*sta)->sta);
+               sdata = (*sta)->sdata;
        }
 
        if (ieee80211_vif_is_mesh(&sdata->vif)) {
index fd40282..eaa4118 100644 (file)
@@ -1445,7 +1445,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
                                if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
                                        continue;
                                if (compare_ether_addr(tmp_sdata->dev->dev_addr,
-                                                      hdr->addr2)) {
+                                                      hdr->addr2) == 0) {
                                        dev_hold(tmp_sdata->dev);
                                        dev_put(sdata->dev);
                                        sdata = tmp_sdata;
@@ -1704,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        if (!is_multicast_ether_addr(hdr.addr1)) {
                rcu_read_lock();
                sta = sta_info_get(local, hdr.addr1);
-               if (sta)
+               /* XXX: in the future, use sdata to look up the sta */
+               if (sta && sta->sdata == sdata)
                        sta_flags = get_sta_flags(sta);
                rcu_read_unlock();
        }
index dd65643..aeb65b3 100644 (file)
@@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        if (WARN_ON(!info->control.vif)) {
-               kfree(skb);
+               kfree_skb(skb);
                return;
        }
 
@@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
                struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
                if (WARN_ON(!info->control.vif)) {
-                       kfree(skb);
+                       kfree_skb(skb);
                        continue;
                }
 
index d7ecca0..f2d116a 100644 (file)
@@ -982,10 +982,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                goto out_put;
 
        size_max = po->tx_ring.frame_size
-               - sizeof(struct skb_shared_info)
-               - po->tp_hdrlen
-               - LL_ALLOCATED_SPACE(dev)
-               - sizeof(struct sockaddr_ll);
+               - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
        if (size_max > dev->mtu + reserve)
                size_max = dev->mtu + reserve;
index 96c0ed1..6b0359a 100644 (file)
@@ -34,7 +34,7 @@ static struct tcf_hashinfo pedit_hash_info = {
 };
 
 static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
-       [TCA_PEDIT_PARMS]       = { .len = sizeof(struct tcf_pedit) },
+       [TCA_PEDIT_PARMS]       = { .len = sizeof(struct tc_pedit) },
 };
 
 static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
index 6a53694..7cf6c0f 100644 (file)
@@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
        tcm = NLMSG_DATA(nlh);
        tcm->tcm_family = AF_UNSPEC;
        tcm->tcm__pad1 = 0;
-       tcm->tcm__pad1 = 0;
+       tcm->tcm__pad2 = 0;
        tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
        tcm->tcm_parent = tp->classid;
        tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
index 51ab497..fc820cd 100644 (file)
@@ -1074,6 +1074,8 @@ restart:
        err = -ECONNREFUSED;
        if (other->sk_state != TCP_LISTEN)
                goto out_unlock;
+       if (other->sk_shutdown & RCV_SHUTDOWN)
+               goto out_unlock;
 
        if (unix_recvq_full(other)) {
                err = -EAGAIN;
index 2a33d8b..68b3219 100644 (file)
@@ -358,6 +358,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
                              struct wireless_dev *wdev);
 
 void cfg80211_conn_work(struct work_struct *work);
+void cfg80211_sme_failed_assoc(struct wireless_dev *wdev);
 bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
 
 /* internal helpers */
index 79d2eec..0a6b7a0 100644 (file)
@@ -62,6 +62,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
        u8 *ie = mgmt->u.assoc_resp.variable;
        int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
        struct cfg80211_internal_bss *bss = NULL;
+       bool need_connect_result = true;
 
        wdev_lock(wdev);
 
@@ -94,6 +95,14 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
                }
 
                WARN_ON(!bss);
+       } else if (wdev->conn) {
+               cfg80211_sme_failed_assoc(wdev);
+               need_connect_result = false;
+               /*
+                * do not call connect_result() now because the
+                * sme will schedule work that does it later.
+                */
+               goto out;
        }
 
        if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
index eddab09..ca3c92a 100644 (file)
@@ -4029,7 +4029,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
        rdev = cfg80211_get_dev_from_info(info);
        if (IS_ERR(rdev)) {
                err = PTR_ERR(rdev);
-               goto out;
+               goto out_rtnl;
        }
 
        net = get_net_ns_by_pid(pid);
@@ -4049,6 +4049,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
        put_net(net);
  out:
        cfg80211_unlock_rdev(rdev);
+ out_rtnl:
        rtnl_unlock();
        return err;
 }
index 93c3ed3..ece378d 100644 (file)
@@ -26,6 +26,7 @@ struct cfg80211_conn {
                CFG80211_CONN_AUTHENTICATING,
                CFG80211_CONN_ASSOCIATE_NEXT,
                CFG80211_CONN_ASSOCIATING,
+               CFG80211_CONN_DEAUTH_ASSOC_FAIL,
        } state;
        u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
        u8 *ie;
@@ -148,6 +149,12 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
                                               NULL, 0,
                                               WLAN_REASON_DEAUTH_LEAVING);
                return err;
+       case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
+               __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
+                                      NULL, 0,
+                                      WLAN_REASON_DEAUTH_LEAVING);
+               /* return an error so that we call __cfg80211_connect_result() */
+               return -EINVAL;
        default:
                return 0;
        }
@@ -158,6 +165,7 @@ void cfg80211_conn_work(struct work_struct *work)
        struct cfg80211_registered_device *rdev =
                container_of(work, struct cfg80211_registered_device, conn_work);
        struct wireless_dev *wdev;
+       u8 bssid[ETH_ALEN];
 
        rtnl_lock();
        cfg80211_lock_rdev(rdev);
@@ -173,10 +181,10 @@ void cfg80211_conn_work(struct work_struct *work)
                        wdev_unlock(wdev);
                        continue;
                }
+               memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN);
                if (cfg80211_conn_do_work(wdev))
                        __cfg80211_connect_result(
-                                       wdev->netdev,
-                                       wdev->conn->params.bssid,
+                                       wdev->netdev, bssid,
                                        NULL, 0, NULL, 0,
                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
                                        false, NULL);
@@ -337,6 +345,15 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev)
        return true;
 }
 
+void cfg80211_sme_failed_assoc(struct wireless_dev *wdev)
+{
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+       wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL;
+       schedule_work(&rdev->conn_work);
+}
+
 void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
                               const u8 *req_ie, size_t req_ie_len,
                               const u8 *resp_ie, size_t resp_ie_len,
index 4f9c190..c67e73e 100644 (file)
@@ -100,7 +100,7 @@ as-option = $(call try-run,\
 # Usage: cflags-y += $(call as-instr,instr,option1,option2)
 
 as-instr = $(call try-run,\
-       echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
+       /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
 
 # cc-option
 # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
index 7a77787..ffdafb2 100644 (file)
@@ -208,7 +208,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
 
 # Bzip2 and LZMA do not include size in file... so we have to fake that;
 # append the size as a 32-bit littleendian number as gzip does.
-size_append = echo -ne $(shell                                         \
+size_append = /bin/echo -ne $(shell                                    \
 dec_size=0;                                                            \
 for F in $1; do                                                                \
        fsize=$$(stat -c "%s" $$F);                                     \
index 39677c8..46be3c5 100755 (executable)
@@ -9,7 +9,7 @@ paths="$@"
 # Doing this once at the beginning saves a lot of time, on a cache-hot tree.
 Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`"
 
-echo -e "File list \tundefined symbol used"
+/bin/echo -e "File list \tundefined symbol used"
 find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i
 do
        # Output the bare Kconfig variable and the filename; the _MODULE part at
@@ -54,6 +54,6 @@ while read symb files; do
        # beyond the purpose of this script.
        symb_bare=`echo $symb | sed -e 's/_MODULE//'`
        if ! grep -q "\<$symb_bare\>" $Kconfigs; then
-               echo -e "$files: \t$symb"
+               /bin/echo -e "$files: \t$symb"
        fi
 done|sort
index 87bbb8b..bc4114f 100755 (executable)
@@ -2,7 +2,7 @@
 # (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
-# (c) 2008, Andy Whitcroft <apw@canonical.com>
+# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
 # Licensed under the terms of the GNU GPL License version 2
 
 use strict;
@@ -10,7 +10,7 @@ use strict;
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.29';
+my $V = '0.30';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -130,7 +130,10 @@ if ($tree) {
 
 my $emitted_corrupt = 0;
 
-our $Ident       = qr{[A-Za-z_][A-Za-z\d_]*};
+our $Ident     = qr{
+                       [A-Za-z_][A-Za-z\d_]*
+                       (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
+               }x;
 our $Storage   = qr{extern|static|asmlinkage};
 our $Sparse    = qr{
                        __user|
@@ -997,23 +1000,25 @@ sub annotate_values {
 
 sub possible {
        my ($possible, $line) = @_;
-
-       print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
-       if ($possible !~ /(?:
+       my $notPermitted = qr{(?:
                ^(?:
                        $Modifier|
                        $Storage|
                        $Type|
-                       DEFINE_\S+|
+                       DEFINE_\S+
+               )$|
+               ^(?:
                        goto|
                        return|
                        case|
                        else|
                        asm|__asm__|
                        do
-               )$|
+               )(?:\s|$)|
                ^(?:typedef|struct|enum)\b
-           )/x) {
+           )}x;
+       warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+       if ($possible !~ $notPermitted) {
                # Check for modifiers.
                $possible =~ s/\s*$Storage\s*//g;
                $possible =~ s/\s*$Sparse\s*//g;
@@ -1022,8 +1027,10 @@ sub possible {
                } elsif ($possible =~ /\s/) {
                        $possible =~ s/\s*$Type\s*//g;
                        for my $modifier (split(' ', $possible)) {
-                               warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
-                               push(@modifierList, $modifier);
+                               if ($modifier !~ $notPermitted) {
+                                       warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
+                                       push(@modifierList, $modifier);
+                               }
                        }
 
                } else {
@@ -1138,6 +1145,7 @@ sub process {
        # suppression flags
        my %suppress_ifbraces;
        my %suppress_whiletrailers;
+       my %suppress_export;
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
@@ -1230,7 +1238,6 @@ sub process {
                $linenr++;
 
                my $rawline = $rawlines[$linenr - 1];
-               my $hunk_line = ($realcnt != 0);
 
 #extract the line range in the file after the patch is applied
                if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1247,6 +1254,7 @@ sub process {
 
                        %suppress_ifbraces = ();
                        %suppress_whiletrailers = ();
+                       %suppress_export = ();
                        next;
 
 # track the line number as we move through the hunk, note that
@@ -1270,6 +1278,8 @@ sub process {
                        $realcnt--;
                }
 
+               my $hunk_line = ($realcnt != 0);
+
 #make up the handle for any error we report on this line
                $prefix = "$filename:$realline: " if ($emacs && $file);
                $prefix = "$filename:$linenr: " if ($emacs && !$file);
@@ -1420,13 +1430,22 @@ sub process {
                }
 
 # Check for potential 'bare' types
-               my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
+               my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
+                   $realline_next);
                if ($realcnt && $line =~ /.\s*\S/) {
                        ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
                                ctx_statement_block($linenr, $realcnt, 0);
                        $stat =~ s/\n./\n /g;
                        $cond =~ s/\n./\n /g;
 
+                       # Find the real next line.
+                       $realline_next = $line_nr_next;
+                       if (defined $realline_next &&
+                           (!defined $lines[$realline_next - 1] ||
+                            substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
+                               $realline_next++;
+                       }
+
                        my $s = $stat;
                        $s =~ s/{.*$//s;
 
@@ -1661,8 +1680,8 @@ sub process {
                }
 
 # check for initialisation to aggregates open brace on the next line
-               if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
-                   $line =~ /^.\s*{/) {
+               if ($line =~ /^.\s*{/ &&
+                   $prevline =~ /(?:^|[^=])=\s*$/) {
                        ERROR("that open brace { should be on the previous line\n" . $hereprev);
                }
 
@@ -1687,21 +1706,40 @@ sub process {
                $line =~ s@//.*@@;
                $opline =~ s@//.*@@;
 
-#EXPORT_SYMBOL should immediately follow its function closing }.
-               if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
-                   ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
+# the whole statement.
+#print "APW <$lines[$realline_next - 1]>\n";
+               if (defined $realline_next &&
+                   exists $lines[$realline_next - 1] &&
+                   !defined $suppress_export{$realline_next} &&
+                   ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+                    $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
                        my $name = $1;
-                       if ($prevline !~ /(?:
-                               ^.}|
+                       if ($stat !~ /(?:
+                               \n.}\s*$|
                                ^.DEFINE_$Ident\(\Q$name\E\)|
                                ^.DECLARE_$Ident\(\Q$name\E\)|
                                ^.LIST_HEAD\(\Q$name\E\)|
-                               ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
-                               \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
+                               ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+                               \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
                            )/x) {
-                               WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
+#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
+                               $suppress_export{$realline_next} = 2;
+                       } else {
+                               $suppress_export{$realline_next} = 1;
                        }
                }
+               if (!defined $suppress_export{$linenr} &&
+                   $prevline =~ /^.\s*$/ &&
+                   ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+                    $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+#print "FOO B <$lines[$linenr - 1]>\n";
+                       $suppress_export{$linenr} = 2;
+               }
+               if (defined $suppress_export{$linenr} &&
+                   $suppress_export{$linenr} == 2) {
+                       WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
+               }
 
 # check for external initialisers.
                if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
index cdb44b6..102b766 100755 (executable)
@@ -13,7 +13,7 @@
 use strict;
 
 my $P = $0;
-my $V = '0.20';
+my $V = '0.21';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -37,6 +37,7 @@ my $scm = 0;
 my $web = 0;
 my $subsystem = 0;
 my $status = 0;
+my $keywords = 1;
 my $from_filename = 0;
 my $pattern_depth = 0;
 my $version = 0;
@@ -84,6 +85,7 @@ if (!GetOptions(
                'scm!' => \$scm,
                'web!' => \$web,
                'pattern-depth=i' => \$pattern_depth,
+               'k|keywords!' => \$keywords,
                'f|file' => \$from_filename,
                'v|version' => \$version,
                'h|help' => \$help,
@@ -132,6 +134,8 @@ if (!top_of_kernel_tree($lk_path)) {
 ## Read MAINTAINERS for type/value pairs
 
 my @typevalue = ();
+my %keyword_hash;
+
 open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n";
 while (<MAINT>) {
     my $line = $_;
@@ -149,6 +153,8 @@ while (<MAINT>) {
            if ((-d $value)) {
                $value =~ s@([^/])$@$1/@;
            }
+       } elsif ($type eq "K") {
+           $keyword_hash{@typevalue} = $value;
        }
        push(@typevalue, "$type:$value");
     } elsif (!/^(\s)*$/) {
@@ -188,6 +194,7 @@ if ($email_remove_duplicates) {
 
 my @files = ();
 my @range = ();
+my @keyword_tvi = ();
 
 foreach my $file (@ARGV) {
     ##if $file is a directory and it lacks a trailing slash, add one
@@ -198,11 +205,24 @@ foreach my $file (@ARGV) {
     }
     if ($from_filename) {
        push(@files, $file);
+       if (-f $file && $keywords) {
+           open(FILE, "<$file") or die "$P: Can't open ${file}\n";
+           while (<FILE>) {
+               my $patch_line = $_;
+               foreach my $line (keys %keyword_hash) {
+                   if ($patch_line =~ m/^.*$keyword_hash{$line}/x) {
+                       push(@keyword_tvi, $line);
+                   }
+               }
+           }
+           close(FILE);
+       }
     } else {
        my $file_cnt = @files;
        my $lastfile;
        open(PATCH, "<$file") or die "$P: Can't open ${file}\n";
        while (<PATCH>) {
+           my $patch_line = $_;
            if (m/^\+\+\+\s+(\S+)/) {
                my $filename = $1;
                $filename =~ s@^[^/]*/@@;
@@ -213,6 +233,12 @@ foreach my $file (@ARGV) {
                if ($email_git_blame) {
                    push(@range, "$lastfile:$1:$2");
                }
+           } elsif ($keywords) {
+               foreach my $line (keys %keyword_hash) {
+                   if ($patch_line =~ m/^[+-].*$keyword_hash{$line}/x) {
+                       push(@keyword_tvi, $line);
+                   }
+               }
            }
        }
        close(PATCH);
@@ -286,6 +312,13 @@ foreach my $file (@files) {
     }
 }
 
+if ($keywords) {
+    @keyword_tvi = sort_and_uniq(@keyword_tvi);
+    foreach my $line (@keyword_tvi) {
+       add_categories($line);
+    }
+}
+
 if ($email) {
     foreach my $chief (@penguin_chief) {
        if ($chief =~ m/^(.*):(.*)/) {
@@ -384,6 +417,7 @@ Output type options:
 
 Other options:
   --pattern-depth => Number of pattern directory traversals (default: 0 (all))
+  --keywords => scan patch for keywords (default: 1 (on))
   --version => show version
   --help => show this help information
 
@@ -486,7 +520,6 @@ sub format_email {
 }
 
 sub find_starting_index {
-
     my ($index) = @_;
 
     while ($index > 0) {
index c6ae405..b89ca2c 100644 (file)
@@ -20,7 +20,7 @@ use strict;
 
 my ($readdir, $installdir, $arch, @files) = @ARGV;
 
-my $unifdef = "scripts/unifdef -U__KERNEL__";
+my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
 
 foreach my $file (@files) {
        local *INFILE;
index 6a12dd9..bce3d0f 100755 (executable)
@@ -1,3 +1,5 @@
+#!/bin/sh
+
 TARGET=$1
 ARCH=$2
 SMP=$3
@@ -50,7 +52,7 @@ UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"
 # Truncate to maximum length
 
 UTS_LEN=64
-UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
+UTS_TRUNCATE="cut -b -$UTS_LEN"
 
 # Generate a temporary compile.h
 
@@ -66,9 +68,13 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
   echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
 
   if [ -x /bin/dnsdomainname ]; then
-    echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\"
+    domain=`dnsdomainname 2> /dev/null`
   elif [ -x /bin/domainname ]; then
-    echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\"
+    domain=`domainname 2> /dev/null`
+  fi
+
+  if [ -n "$domain" ]; then
+    echo \#define LINUX_COMPILE_DOMAIN \"`echo $domain | $UTS_TRUNCATE`\"
   else
     echo \#define LINUX_COMPILE_DOMAIN
   fi
index fa4a0a1..f67cc88 100644 (file)
@@ -18,6 +18,9 @@
 # e) generate the rpm files, based on kernel.spec
 # - Use /. to avoid tar packing just the symlink
 
+# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT,
+# but the binrpm-pkg target can; for some reason O= gets ignored.
+
 # Do we have rpmbuild, otherwise fall back to the older rpm
 RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
                   else echo rpm; fi)
@@ -33,6 +36,12 @@ $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
        $(CONFIG_SHELL) $(MKSPEC) > $@
 
 rpm-pkg rpm: $(objtree)/kernel.spec FORCE
+       @if test -n "$(KBUILD_OUTPUT)"; then \
+               echo "Building source + binary RPM is not possible outside the"; \
+               echo "kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \
+               echo "binrpm-pkg target instead."; \
+               false; \
+       fi
        $(MAKE) clean
        $(PREV) ln -sf $(srctree) $(KERNELPATH)
        $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion
@@ -61,7 +70,7 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
        set -e; \
        mv -f $(objtree)/.tmp_version $(objtree)/.version
 
-       $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \
+       $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \
                $(UTS_MACHINE) -bb $<
 
 clean-files += $(objtree)/binkernel.spec
index 3d93f8c..47bdd2f 100755 (executable)
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
 echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
 echo "%endif"
 
-echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
+echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} KBUILD_SRC= modules_install'
 echo "%ifarch ia64"
 echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
 echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
index 2fb28ef..06ec722 100644 (file)
@@ -873,7 +873,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
        /* otherwise specify the destination keyring recorded in the
         * authorisation key (any KEY_SPEC_*_KEYRING) */
        if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) {
-               *_dest_keyring = rka->dest_keyring;
+               *_dest_keyring = key_get(rka->dest_keyring);
                return 0;
        }
 
index dc78272..1f0f821 100644 (file)
@@ -937,6 +937,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
        struct snd_ac97 *ac97;
        int ret;
 
+       writel(0, aaci->base + AC97_POWERDOWN);
        /*
         * Assert AACIRESET for 2us
         */
index 24585c6..4e2b925 100644 (file)
@@ -808,6 +808,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
        /* Leadtek Winfast tv 2000xp delux */
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
+       /* Pinnacle PCTV */
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x11bd, 0x0012, GENERIC),
        /* Voodoo TV 200 */
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
        /* Askey Computer Corp. MagicTView'99 */
index c8435c9..9fb6027 100644 (file)
@@ -29,6 +29,9 @@
 #include "hda_codec.h"
 #include "hda_local.h"
 
+/* define below to restrict the supported rates and formats */
+/* #define LIMITED_RATE_FMT_SUPPORT */
+
 struct nvhdmi_spec {
        struct hda_multi_out multiout;
 
@@ -60,6 +63,22 @@ static struct hda_verb nvhdmi_basic_init[] = {
        {} /* terminator */
 };
 
+#ifdef LIMITED_RATE_FMT_SUPPORT
+/* support only the safe format and rate */
+#define SUPPORTED_RATES                SNDRV_PCM_RATE_48000
+#define SUPPORTED_MAXBPS       16
+#define SUPPORTED_FORMATS      SNDRV_PCM_FMTBIT_S16_LE
+#else
+/* support all rates and formats */
+#define SUPPORTED_RATES \
+       (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+       SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+        SNDRV_PCM_RATE_192000)
+#define SUPPORTED_MAXBPS       24
+#define SUPPORTED_FORMATS \
+       (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
+#endif
+
 /*
  * Controls
  */
@@ -258,9 +277,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = {
        .channels_min = 2,
        .channels_max = 8,
        .nid = Nv_Master_Convert_nid,
-       .rates = SNDRV_PCM_RATE_48000,
-       .maxbps = 16,
-       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .rates = SUPPORTED_RATES,
+       .maxbps = SUPPORTED_MAXBPS,
+       .formats = SUPPORTED_FORMATS,
        .ops = {
                .open = nvhdmi_dig_playback_pcm_open,
                .close = nvhdmi_dig_playback_pcm_close_8ch,
@@ -273,9 +292,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
        .channels_min = 2,
        .channels_max = 2,
        .nid = Nv_Master_Convert_nid,
-       .rates = SNDRV_PCM_RATE_48000,
-       .maxbps = 16,
-       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .rates = SUPPORTED_RATES,
+       .maxbps = SUPPORTED_MAXBPS,
+       .formats = SUPPORTED_FORMATS,
        .ops = {
                .open = nvhdmi_dig_playback_pcm_open,
                .close = nvhdmi_dig_playback_pcm_close_2ch,
index 470fd74..c08ca66 100644 (file)
@@ -275,7 +275,7 @@ struct alc_spec {
        struct snd_kcontrol_new *cap_mixer;     /* capture mixer */
        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
 
-       const struct hda_verb *init_verbs[5];   /* initialization verbs
+       const struct hda_verb *init_verbs[10];  /* initialization verbs
                                                 * don't forget NULL
                                                 * termination!
                                                 */
index a9b2682..66c0876 100644 (file)
@@ -158,6 +158,7 @@ enum {
        STAC_D965_5ST_NO_FP,
        STAC_DELL_3ST,
        STAC_DELL_BIOS,
+       STAC_927X_VOLKNOB,
        STAC_927X_MODELS
 };
 
@@ -907,6 +908,16 @@ static struct hda_verb d965_core_init[] = {
        {}
 };
 
+static struct hda_verb dell_3st_core_init[] = {
+       /* don't set delta bit */
+       {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
+       /* unmute node 0x1b */
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+       /* select node 0x03 as DAC */
+       {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
+       {}
+};
+
 static struct hda_verb stac927x_core_init[] = {
        /* set master volume and direct control */      
        { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -915,6 +926,14 @@ static struct hda_verb stac927x_core_init[] = {
        {}
 };
 
+static struct hda_verb stac927x_volknob_core_init[] = {
+       /* don't set delta bit */
+       {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
+       /* enable analog pc beep path */
+       {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
+       {}
+};
+
 static struct hda_verb stac9205_core_init[] = {
        /* set master volume and direct control */      
        { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -1999,6 +2018,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
        [STAC_D965_5ST_NO_FP]  = d965_5st_no_fp_pin_configs,
        [STAC_DELL_3ST]  = dell_3st_pin_configs,
        [STAC_DELL_BIOS] = NULL,
+       [STAC_927X_VOLKNOB] = NULL,
 };
 
 static const char *stac927x_models[STAC_927X_MODELS] = {
@@ -2010,6 +2030,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
        [STAC_D965_5ST_NO_FP]   = "5stack-no-fp",
        [STAC_DELL_3ST]         = "dell-3stack",
        [STAC_DELL_BIOS]        = "dell-bios",
+       [STAC_927X_VOLKNOB]     = "volknob",
 };
 
 static struct snd_pci_quirk stac927x_cfg_tbl[] = {
@@ -2045,6 +2066,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
                           "Intel D965", STAC_D965_5ST),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
                           "Intel D965", STAC_D965_5ST),
+       /* volume-knob fixes */
+       SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
        {} /* terminator */
 };
 
@@ -5612,10 +5635,14 @@ static int patch_stac927x(struct hda_codec *codec)
                spec->dmic_nids = stac927x_dmic_nids;
                spec->num_dmics = STAC927X_NUM_DMICS;
 
-               spec->init = d965_core_init;
+               spec->init = dell_3st_core_init;
                spec->dmux_nids = stac927x_dmux_nids;
                spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
                break;
+       case STAC_927X_VOLKNOB:
+               spec->num_dmics = 0;
+               spec->init = stac927x_volknob_core_init;
+               break;
        default:
                spec->num_dmics = 0;
                spec->init = stac927x_core_init;
index 3756430..6da21a2 100644 (file)
@@ -52,11 +52,13 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
 
        /* only use basic functionality for now */
 
-       ice->num_total_dacs = 2;        /* only PSDOUT0 is connected */
+       /* VT1616 6ch codec connected to PSDOUT0 using packed mode */
+       ice->num_total_dacs = 6;
        ice->num_total_adcs = 2;
 
-       /* Chaintech AV-710 has another codecs, which need initialization */
-       /* initialize WM8728 codec */
+       /* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4
+          (shared with the SPDIF output). Mixer control for this codec
+          is not yet supported. */
        if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
                for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
                        wm_put(ice, wm_inits[i], wm_inits[i+1]);
index 76b717d..10fc92c 100644 (file)
@@ -648,7 +648,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
            (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
                /* running? we cannot change the rate now... */
                spin_unlock_irqrestore(&ice->reg_lock, flags);
-               return -EBUSY;
+               return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
        }
        if (!force && is_pro_rate_locked(ice)) {
                spin_unlock_irqrestore(&ice->reg_lock, flags);
index bd2338a..0519c60 100644 (file)
@@ -2,7 +2,7 @@
 
 menuconfig SND_PPC
        bool "PowerPC sound devices"
-       depends on PPC64 || PPC32
+       depends on PPC
        default y
        help
          Support for sound devices specific to PowerPC architectures.
index b7c78a4..7495ce3 100644 (file)
@@ -2717,8 +2717,6 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
        int r;
        int cpu;
 
-       kvm_init_debug();
-
        r = kvm_arch_init(opaque);
        if (r)
                goto out_fail;
@@ -2785,6 +2783,8 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
        kvm_preempt_ops.sched_in = kvm_sched_in;
        kvm_preempt_ops.sched_out = kvm_sched_out;
 
+       kvm_init_debug();
+
        return 0;
 
 out_free:
@@ -2807,7 +2807,6 @@ out_free_0:
 out:
        kvm_arch_exit();
 out_fail:
-       kvm_exit_debug();
        return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);
@@ -2815,6 +2814,7 @@ EXPORT_SYMBOL_GPL(kvm_init);
 void kvm_exit(void)
 {
        tracepoint_synchronize_unregister();
+       kvm_exit_debug();
        misc_deregister(&kvm_dev);
        kmem_cache_destroy(kvm_vcpu_cache);
        sysdev_unregister(&kvm_sysdev);
@@ -2824,7 +2824,6 @@ void kvm_exit(void)
        on_each_cpu(hardware_disable, NULL, 1);
        kvm_arch_hardware_unsetup();
        kvm_arch_exit();
-       kvm_exit_debug();
        free_cpumask_var(cpus_hardware_enabled);
        __free_page(bad_page);
 }