summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/hwsleep.c43
-rw-r--r--drivers/acpi/acpica/hwvalid.c85
-rw-r--r--drivers/acpi/acpica/rscreate.c27
-rw-r--r--drivers/acpi/button.c140
-rw-r--r--drivers/acpi/ec.c1
-rw-r--r--drivers/acpi/osl.c4
-rw-r--r--drivers/acpi/proc.c13
-rw-r--r--drivers/acpi/processor_idle.c31
-rw-r--r--drivers/acpi/scan.c31
-rw-r--r--drivers/acpi/sleep.c35
-rw-r--r--drivers/acpi/sleep.h3
-rw-r--r--drivers/acpi/system.c11
-rw-r--r--drivers/acpi/thermal.c70
-rw-r--r--drivers/acpi/video.c84
-rw-r--r--drivers/acpi/wakeup.c30
-rw-r--r--drivers/ata/ahci.c57
-rw-r--r--drivers/ata/libata-core.c29
-rw-r--r--drivers/ata/libata-scsi.c30
-rw-r--r--drivers/ata/libata-sff.c27
-rw-r--r--drivers/ata/pata_hpt37x.c22
-rw-r--r--drivers/ata/pata_legacy.c37
-rw-r--r--drivers/ata/pata_ninja32.c4
-rw-r--r--drivers/ata/pata_via.c74
-rw-r--r--drivers/ata/sata_mv.c58
-rw-r--r--drivers/ata/sata_via.c2
-rw-r--r--drivers/atm/solos-pci.c2
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/core.c6
-rw-r--r--drivers/base/dd.c1
-rw-r--r--drivers/base/platform.c239
-rw-r--r--drivers/block/brd.c5
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/hd.c17
-rw-r--r--drivers/block/mg_disk.c19
-rw-r--r--drivers/block/ub.c20
-rw-r--r--drivers/block/umem.c1
-rw-r--r--drivers/block/xsysace.c12
-rw-r--r--drivers/char/agp/generic.c4
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/hw_random/virtio-rng.c4
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c211
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c150
-rw-r--r--drivers/char/mem.c27
-rw-r--r--drivers/char/sysrq.c1
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/clocksource/acpi_pm.c12
-rw-r--r--drivers/clocksource/cyclone.c2
-rw-r--r--drivers/clocksource/scx200_hrt.c2
-rw-r--r--drivers/clocksource/tcb_clksrc.c2
-rw-r--r--drivers/edac/edac_core.h12
-rw-r--r--drivers/edac/edac_device.c2
-rw-r--r--drivers/edac/edac_mc.c2
-rw-r--r--drivers/edac/edac_pci.c2
-rw-r--r--drivers/edac/mpc85xx_edac.c2
-rw-r--r--drivers/gpu/drm/drm_stub.c11
-rw-r--r--drivers/gpu/drm/drm_sysfs.c1
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c8
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h15
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c191
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debugfs.c93
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c112
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c2
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c15
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c4
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c23
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c22
-rw-r--r--drivers/gpu/drm/via/via_dma.c12
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/hp_accel.c1
-rw-r--r--drivers/hwmon/sht15.c692
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c2
-rw-r--r--drivers/i2c/busses/Kconfig6
-rw-r--r--drivers/i2c/i2c-core.c3
-rw-r--r--drivers/ide/at91_ide.c91
-rw-r--r--drivers/ide/cs5536.c1
-rw-r--r--drivers/ide/falconide.c13
-rw-r--r--drivers/ide/hpt366.c14
-rw-r--r--drivers/ide/ide-acpi.c5
-rw-r--r--drivers/ide/ide-atapi.c38
-rw-r--r--drivers/ide/ide-cd.c290
-rw-r--r--drivers/ide/ide-disk.c70
-rw-r--r--drivers/ide/ide-disk_proc.c6
-rw-r--r--drivers/ide/ide-dma-sff.c9
-rw-r--r--drivers/ide/ide-gd.c17
-rw-r--r--drivers/ide/ide-h8300.c101
-rw-r--r--drivers/ide/ide-io-std.c75
-rw-r--r--drivers/ide/ide-io.c24
-rw-r--r--drivers/ide/ide-ioctls.c14
-rw-r--r--drivers/ide/ide-iops.c20
-rw-r--r--drivers/ide/ide-lib.c28
-rw-r--r--drivers/ide/ide-park.c3
-rw-r--r--drivers/ide/ide-pm.c3
-rw-r--r--drivers/ide/ide-probe.c18
-rw-r--r--drivers/ide/ide-proc.c4
-rw-r--r--drivers/ide/ide-taskfile.c97
-rw-r--r--drivers/ide/ns87415.c34
-rw-r--r--drivers/ide/palm_bk3710.c93
-rw-r--r--drivers/ide/pmac.c2
-rw-r--r--drivers/ide/q40ide.c14
-rw-r--r--drivers/ide/scc_pata.c71
-rw-r--r--drivers/ide/tx4938ide.c89
-rw-r--r--drivers/ide/tx4939ide.c110
-rw-r--r--drivers/infiniband/core/cma.c45
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c10
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c11
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.h5
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c124
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.h3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c5
-rw-r--r--drivers/infiniband/hw/mlx4/main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c16
-rw-r--r--drivers/infiniband/hw/nes/nes.h8
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c106
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c395
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c52
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c67
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c25
-rw-r--r--drivers/input/gameport/gameport.c14
-rw-r--r--drivers/input/input.c14
-rw-r--r--drivers/input/keyboard/atkbd.c155
-rw-r--r--drivers/input/keyboard/bf54x-keys.c6
-rw-r--r--drivers/input/keyboard/hilkbd.c140
-rw-r--r--drivers/input/misc/Kconfig25
-rw-r--r--drivers/input/misc/Makefile28
-rw-r--r--drivers/input/misc/ati_remote2.c277
-rw-r--r--drivers/input/misc/rb532_button.c120
-rw-r--r--drivers/input/misc/rotary_encoder.c221
-rw-r--r--drivers/input/mouse/Kconfig11
-rw-r--r--drivers/input/mouse/Makefile9
-rw-r--r--drivers/input/mouse/hgpk.c2
-rw-r--r--drivers/input/mouse/maplemouse.c150
-rw-r--r--drivers/input/mouse/pc110pad.c6
-rw-r--r--drivers/input/serio/hp_sdc.c24
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h36
-rw-r--r--drivers/input/serio/i8042.c37
-rw-r--r--drivers/input/touchscreen/Kconfig58
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/ad7877.c844
-rw-r--r--drivers/input/touchscreen/ad7879.c781
-rw-r--r--drivers/input/touchscreen/ads7846.c12
-rw-r--r--drivers/input/touchscreen/da9034-ts.c29
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c10
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c16
-rw-r--r--drivers/input/touchscreen/zylonite-wm97xx.c240
-rw-r--r--drivers/isdn/hisax/st5481_usb.c9
-rw-r--r--drivers/leds/leds-gpio.c2
-rw-r--r--drivers/lguest/lg.h3
-rw-r--r--drivers/lguest/segments.c13
-rw-r--r--drivers/lguest/x86/core.c9
-rw-r--r--drivers/macintosh/Kconfig2
-rw-r--r--drivers/macintosh/mediabay.c3
-rw-r--r--drivers/md/bitmap.c7
-rw-r--r--drivers/md/dm-bio-list.h117
-rw-r--r--drivers/md/dm-delay.c2
-rw-r--r--drivers/md/dm-ioctl.c21
-rw-r--r--drivers/md/dm-kcopyd.c23
-rw-r--r--drivers/md/dm-linear.c1
-rw-r--r--drivers/md/dm-mpath.c1
-rw-r--r--drivers/md/dm-raid1.c1
-rw-r--r--drivers/md/dm-region-hash.c1
-rw-r--r--drivers/md/dm-snap.c1
-rw-r--r--drivers/md/dm-table.c59
-rw-r--r--drivers/md/dm.c200
-rw-r--r--drivers/md/dm.h1
-rw-r--r--drivers/md/md.c41
-rw-r--r--drivers/md/md.h21
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/md/raid10.c1
-rw-r--r--drivers/md/raid5.c7
-rw-r--r--drivers/media/dvb/ttpci/Kconfig23
-rw-r--r--drivers/media/dvb/ttpci/Makefile9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c16
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c35
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h3
-rw-r--r--drivers/media/dvb/ttpci/fdump.c44
-rw-r--r--drivers/media/radio/radio-si470x.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c1
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c238
-rw-r--r--drivers/message/fusion/mptbase.c2
-rw-r--r--drivers/misc/eeprom/at24.c8
-rw-r--r--drivers/misc/eeprom/at25.c5
-rw-r--r--drivers/misc/sgi-gru/grufile.c2
-rw-r--r--drivers/misc/sgi-xp/xp_main.c12
-rw-r--r--drivers/misc/sgi-xp/xpc.h254
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c138
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c128
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c20
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c164
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c257
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/core/sd.c21
-rw-r--r--drivers/mmc/host/imxmmc.c19
-rw-r--r--drivers/mmc/host/mmc_spi.c188
-rw-r--r--drivers/mmc/host/omap_hsmmc.c7
-rw-r--r--drivers/mmc/host/sdhci-pci.c2
-rw-r--r--drivers/mmc/host/sdhci.c2
-rw-r--r--drivers/mmc/host/wbsd.c2
-rw-r--r--drivers/mtd/nand/cafe_nand.c2
-rw-r--r--drivers/net/8139too.c10
-rw-r--r--drivers/net/Kconfig27
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/a2065.c17
-rw-r--r--drivers/net/ariadne.c19
-rw-r--r--drivers/net/arm/am79c961a.c24
-rw-r--r--drivers/net/arm/at91_ether.c32
-rw-r--r--drivers/net/arm/ep93xx_eth.c21
-rw-r--r--drivers/net/arm/ether1.c19
-rw-r--r--drivers/net/arm/ether3.c19
-rw-r--r--drivers/net/atarilance.c18
-rw-r--r--drivers/net/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/au1000_eth.c23
-rw-r--r--drivers/net/benet/be_ethtool.c4
-rw-r--r--drivers/net/benet/be_main.c4
-rw-r--r--drivers/net/bfin_mac.c24
-rw-r--r--drivers/net/bnx2.c26
-rw-r--r--drivers/net/bonding/bond_alb.c2
-rw-r--r--drivers/net/bonding/bond_main.c5
-rw-r--r--drivers/net/bonding/bond_sysfs.c14
-rw-r--r--drivers/net/cris/eth_v10.c30
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c44
-rw-r--r--drivers/net/cxgb3/t3_hw.c11
-rw-r--r--drivers/net/declance.c17
-rw-r--r--drivers/net/e1000/e1000_main.c52
-rw-r--r--drivers/net/e1000e/netdev.c67
-rw-r--r--drivers/net/ehea/ehea_main.c4
-rw-r--r--drivers/net/eql.c2
-rw-r--r--drivers/net/fec.c1
-rw-r--r--drivers/net/forcedeth.c4
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c27
-rw-r--r--drivers/net/gianfar.c2
-rw-r--r--drivers/net/ibm_newemac/core.c41
-rw-r--r--drivers/net/igb/e1000_mac.c2
-rw-r--r--drivers/net/igb/e1000_mac.h1
-rw-r--r--drivers/net/igb/e1000_mbx.c17
-rw-r--r--drivers/net/igb/e1000_mbx.h2
-rw-r--r--drivers/net/igb/igb_main.c166
-rw-r--r--drivers/net/igbvf/Makefile38
-rw-r--r--drivers/net/igbvf/defines.h125
-rw-r--r--drivers/net/igbvf/ethtool.c540
-rw-r--r--drivers/net/igbvf/igbvf.h332
-rw-r--r--drivers/net/igbvf/mbx.c350
-rw-r--r--drivers/net/igbvf/mbx.h75
-rw-r--r--drivers/net/igbvf/netdev.c2922
-rw-r--r--drivers/net/igbvf/regs.h108
-rw-r--r--drivers/net/igbvf/vf.c398
-rw-r--r--drivers/net/igbvf/vf.h264
-rw-r--r--drivers/net/ioc3-eth.c22
-rw-r--r--drivers/net/isa-skeleton.c20
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c59
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c40
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c55
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h3
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c28
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c24
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c111
-rw-r--r--drivers/net/jme.c8
-rw-r--r--drivers/net/mac89x0.c18
-rw-r--r--drivers/net/macb.c47
-rw-r--r--drivers/net/macsonic.c19
-rw-r--r--drivers/net/macvlan.c9
-rw-r--r--drivers/net/mlx4/en_main.c5
-rw-r--r--drivers/net/mlx4/en_netdev.c21
-rw-r--r--drivers/net/mlx4/en_port.c45
-rw-r--r--drivers/net/mlx4/en_resources.c6
-rw-r--r--drivers/net/mlx4/en_rx.c12
-rw-r--r--drivers/net/mlx4/en_tx.c1
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mlx4_en.h1
-rw-r--r--drivers/net/mlx4/port.c5
-rw-r--r--drivers/net/mv643xx_eth.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c1
-rw-r--r--drivers/net/niu.c3
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c2
-rw-r--r--drivers/net/phy/fixed.c5
-rw-r--r--drivers/net/phy/marvell.c54
-rw-r--r--drivers/net/phy/phy.c14
-rw-r--r--drivers/net/ps3_gelic_wireless.c3
-rw-r--r--drivers/net/r6040.c1
-rw-r--r--drivers/net/sfc/efx.c7
-rw-r--r--drivers/net/sfc/falcon.c4
-rw-r--r--drivers/net/sh_eth.c21
-rw-r--r--drivers/net/skge.c4
-rw-r--r--drivers/net/smc91x.h2
-rw-r--r--drivers/net/smsc911x.c2
-rw-r--r--drivers/net/sun3_82586.c19
-rw-r--r--drivers/net/tc35815.c27
-rw-r--r--drivers/net/tg3.c17
-rw-r--r--drivers/net/tsi108_eth.c20
-rw-r--r--drivers/net/tun.c52
-rw-r--r--drivers/net/ucc_geth.c3
-rw-r--r--drivers/net/usb/pegasus.c1
-rw-r--r--drivers/net/via-velocity.c4
-rw-r--r--drivers/net/wireless/airo.c2
-rw-r--r--drivers/net/wireless/ar9170/hw.h8
-rw-r--r--drivers/net/wireless/ar9170/usb.c114
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/ath9k/pci.c4
-rw-r--r--drivers/net/wireless/ath9k/recv.c4
-rw-r--r--drivers/net/wireless/atmel.c1
-rw-r--r--drivers/net/wireless/b43/dma.c50
-rw-r--r--drivers/net/wireless/b43/main.c5
-rw-r--r--drivers/net/wireless/b43/phy_common.c16
-rw-r--r--drivers/net/wireless/b43/phy_common.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c99
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c152
-rw-r--r--drivers/net/wireless/libertas/rx.c2
-rw-r--r--drivers/net/wireless/mwl8k.c7
-rw-r--r--drivers/net/wireless/orinoco/hw.c8
-rw-r--r--drivers/net/wireless/p54/p54.h12
-rw-r--r--drivers/net/wireless/p54/p54common.c2
-rw-r--r--drivers/net/wireless/p54/p54pci.c4
-rw-r--r--drivers/net/wireless/p54/p54spi.c25
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/xtsonic.c19
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/pci/access.c4
-rw-r--r--drivers/pci/dmar.c11
-rw-r--r--drivers/pci/htirq.c1
-rw-r--r--drivers/pci/intel-iommu.c4
-rw-r--r--drivers/pci/pci-sysfs.c12
-rw-r--r--drivers/pci/pci.c70
-rw-r--r--drivers/pci/probe.c6
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/pci/setup-bus.c6
-rw-r--r--drivers/pci/slot.c4
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c3
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c60
-rw-r--r--drivers/platform/x86/panasonic-laptop.c28
-rw-r--r--drivers/platform/x86/sony-laptop.c57
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c81
-rw-r--r--drivers/platform/x86/wmi.c15
-rw-r--r--drivers/power/pcf50633-charger.c88
-rw-r--r--drivers/power/pda_power.c89
-rw-r--r--drivers/regulator/bq24022.c3
-rw-r--r--drivers/regulator/core.c19
-rw-r--r--drivers/regulator/virtual.c8
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-cmos.c20
-rw-r--r--drivers/rtc/rtc-sh.c67
-rw-r--r--drivers/s390/block/dasd.c37
-rw-r--r--drivers/s390/block/dasd_eckd.c16
-rw-r--r--drivers/s390/char/tape.h2
-rw-r--r--drivers/s390/char/tape_34xx.c8
-rw-r--r--drivers/s390/char/tape_3590.c8
-rw-r--r--drivers/s390/char/tape_core.c5
-rw-r--r--drivers/s390/cio/qdio_main.c43
-rw-r--r--drivers/sbus/char/jsflash.c15
-rw-r--r--drivers/sbus/char/uctrl.c7
-rw-r--r--drivers/scsi/3w-9xxx.c8
-rw-r--r--drivers/scsi/a4000t.c2
-rw-r--r--drivers/scsi/aacraid/aachba.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c10
-rw-r--r--drivers/scsi/qla1280.c4
-rw-r--r--drivers/scsi/scsi_priv.h3
-rw-r--r--drivers/scsi/scsi_scan.c2
-rw-r--r--drivers/scsi/scsi_wait_scan.c13
-rw-r--r--drivers/serial/8250_pci.c2
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/bfin_5xx.c6
-rw-r--r--drivers/serial/max3100.c927
-rw-r--r--drivers/serial/samsung.c4
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/sh/intc.c35
-rw-r--r--drivers/spi/pxa2xx_spi.c15
-rw-r--r--drivers/spi/spi.c22
-rw-r--r--drivers/staging/android/binder.c201
-rw-r--r--drivers/staging/at76_usb/at76_usb.c20
-rw-r--r--drivers/staging/b3dfg/b3dfg.c2
-rw-r--r--drivers/staging/epl/VirtualEthernetLinux.c17
-rw-r--r--drivers/staging/et131x/et131x_netdev.c23
-rw-r--r--drivers/staging/go7007/go7007-driver.c26
-rw-r--r--drivers/staging/go7007/go7007-i2c.c83
-rw-r--r--drivers/staging/go7007/go7007-priv.h1
-rw-r--r--drivers/staging/go7007/go7007-usb.c14
-rw-r--r--drivers/staging/go7007/s2250-board.c71
-rw-r--r--drivers/staging/go7007/wis-i2c.h9
-rw-r--r--drivers/staging/go7007/wis-ov7640.c56
-rw-r--r--drivers/staging/go7007/wis-saa7113.c60
-rw-r--r--drivers/staging/go7007/wis-saa7115.c60
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c62
-rw-r--r--drivers/staging/go7007/wis-tw2804.c57
-rw-r--r--drivers/staging/go7007/wis-tw9903.c60
-rw-r--r--drivers/staging/go7007/wis-uda1342.c52
-rw-r--r--drivers/staging/line6/audio.c9
-rw-r--r--drivers/staging/otus/usbdrv.c47
-rw-r--r--drivers/staging/otus/zdusb.c3
-rw-r--r--drivers/staging/otus/zdusb.h4
-rw-r--r--drivers/staging/pohmelfs/config.c61
-rw-r--r--drivers/staging/pohmelfs/dir.c24
-rw-r--r--drivers/staging/pohmelfs/inode.c137
-rw-r--r--drivers/staging/pohmelfs/lock.c3
-rw-r--r--drivers/staging/pohmelfs/net.c72
-rw-r--r--drivers/staging/pohmelfs/netfs.h21
-rw-r--r--drivers/staging/pohmelfs/trans.c33
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c25
-rw-r--r--drivers/staging/rt2870/rt2870.h1
-rw-r--r--drivers/staging/rt2870/rt_main_dev.c28
-rw-r--r--drivers/staging/rt3070/rt_main_dev.c29
-rw-r--r--drivers/staging/slicoss/README31
-rw-r--r--drivers/staging/slicoss/slicoss.c25
-rw-r--r--drivers/staging/stlc45xx/Kconfig2
-rw-r--r--drivers/staging/sxg/sxg.c127
-rw-r--r--drivers/staging/uc2322/aten2011.c28
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c20
-rw-r--r--drivers/uio/uio_cif.c1
-rw-r--r--drivers/usb/class/cdc-acm.c4
-rw-r--r--drivers/usb/class/cdc-wdm.c27
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/hcd.c26
-rw-r--r--drivers/usb/core/hcd.h14
-rw-r--r--drivers/usb/core/message.c58
-rw-r--r--drivers/usb/core/usb.c2
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c5
-rw-r--r--drivers/usb/gadget/file_storage.c20
-rw-r--r--drivers/usb/gadget/omap_udc.c3
-rw-r--r--drivers/usb/gadget/u_ether.c8
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/host/ohci-at91.c4
-rw-r--r--drivers/usb/host/whci/asl.c15
-rw-r--r--drivers/usb/host/whci/hcd.c23
-rw-r--r--drivers/usb/host/whci/pzl.c16
-rw-r--r--drivers/usb/host/whci/qset.c24
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/host/whci/whci-hc.h1
-rw-r--r--drivers/usb/musb/cppi_dma.c23
-rw-r--r--drivers/usb/musb/musb_core.c14
-rw-r--r--drivers/usb/musb/musb_gadget.c33
-rw-r--r--drivers/usb/musb/musb_host.c406
-rw-r--r--drivers/usb/musb/musbhsdma.c66
-rw-r--r--drivers/usb/musb/omap2430.c1
-rw-r--r--drivers/usb/musb/tusb6010.c1
-rw-r--r--drivers/usb/musb/tusb6010.h1
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c4
-rw-r--r--drivers/usb/otg/otg.c3
-rw-r--r--drivers/usb/serial/cyberjack.c7
-rw-r--r--drivers/usb/serial/cypress_m8.c4
-rw-r--r--drivers/usb/serial/empeg.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.h7
-rw-r--r--drivers/usb/serial/garmin_gps.c8
-rw-r--r--drivers/usb/serial/generic.c6
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_ti.c8
-rw-r--r--drivers/usb/serial/ipaq.c6
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c1
-rw-r--r--drivers/usb/serial/kobil_sct.c6
-rw-r--r--drivers/usb/serial/mos7720.c7
-rw-r--r--drivers/usb/serial/mos7840.c43
-rw-r--r--drivers/usb/serial/moto_modem.c1
-rw-r--r--drivers/usb/serial/opticon.c8
-rw-r--r--drivers/usb/serial/option.c8
-rw-r--r--drivers/usb/serial/qcserial.c21
-rw-r--r--drivers/usb/serial/sierra.c24
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c40
-rw-r--r--drivers/usb/serial/usb-serial.c104
-rw-r--r--drivers/usb/serial/visor.c8
-rw-r--r--drivers/usb/storage/Makefile3
-rw-r--r--drivers/usb/storage/transport.c4
-rw-r--r--drivers/usb/storage/unusual_devs.h20
-rw-r--r--drivers/usb/wusbcore/devconnect.c21
-rw-r--r--drivers/usb/wusbcore/wusbhc.c32
-rw-r--r--drivers/video/asiliantfb.c1
-rw-r--r--drivers/video/aty/radeon_base.c4
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/lcd.c3
-rw-r--r--drivers/video/cirrusfb.c4
-rw-r--r--drivers/video/console/fbcon.c55
-rw-r--r--drivers/video/efifb.c7
-rw-r--r--drivers/video/fbmem.c19
-rw-r--r--drivers/video/intelfb/intelfb.h2
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c5
-rw-r--r--drivers/video/logo/logo_linux_clut224.ppm4428
-rw-r--r--drivers/video/logo/logo_linux_vga16.ppm4339
-rw-r--r--drivers/video/pxafb.c16
-rw-r--r--drivers/video/s3fb.c6
-rw-r--r--drivers/video/sa1100fb.c15
-rw-r--r--drivers/video/sa1100fb.h7
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c8
-rw-r--r--drivers/video/uvesafb.c35
-rw-r--r--drivers/video/vfb.c11
-rw-r--r--drivers/virtio/virtio_balloon.c3
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c6
-rw-r--r--drivers/watchdog/i6300esb.c155
-rw-r--r--drivers/watchdog/ks8695_wdt.c6
-rw-r--r--drivers/watchdog/omap_wdt.c6
-rw-r--r--drivers/watchdog/orion5x_wdt.c58
-rw-r--r--drivers/xen/cpu_hotplug.c40
-rw-r--r--drivers/xen/manage.c5
517 files changed, 20447 insertions, 11523 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index baa5fc05e124..db307a356f08 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -211,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
 
+static unsigned int gts, bfs;
+module_param(gts, uint, 0644);
+module_param(bfs, uint, 0644);
+MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
+MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_enter_sleep_state
@@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 		return_ACPI_STATUS(status);
 	}
 
-	/* Execute the _GTS method */
+	if (gts) {
+		/* Execute the _GTS method */
 
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = sleep_state;
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = sleep_state;
 
-	status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		return_ACPI_STATUS(status);
+		status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
+		if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+			return_ACPI_STATUS(status);
+		}
 	}
 
 	/* Get current value of PM1A control */
@@ -513,18 +521,19 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
 		}
 	}
 
-	/* Execute the _BFS method */
+	if (bfs) {
+		/* Execute the _BFS method */
 
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = sleep_state;
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = sleep_state;
 
-	status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+		status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
+		if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+		}
 	}
-
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index bd3c937b0ac0..ec33f270c5b7 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -152,7 +152,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
 		ACPI_ERROR((AE_INFO,
 			    "Illegal I/O port address/length above 64K: 0x%p/%X",
 			    ACPI_CAST_PTR(void, address), byte_width));
-		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+		return_ACPI_STATUS(AE_LIMIT);
 	}
 
 	/* Exit if requested address is not within the protected port table */
@@ -179,11 +179,12 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
 			/* Port illegality may depend on the _OSI calls made by the BIOS */
 
 			if (acpi_gbl_osi_data >= port_info->osi_dependency) {
-				ACPI_ERROR((AE_INFO,
-					    "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
-					    ACPI_CAST_PTR(void, address),
-					    byte_width, port_info->name,
-					    port_info->start, port_info->end));
+				ACPI_DEBUG_PRINT((ACPI_DB_IO,
+						  "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+						  ACPI_CAST_PTR(void, address),
+						  byte_width, port_info->name,
+						  port_info->start,
+						  port_info->end));
 
 				return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
 			}
@@ -207,7 +208,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
  *              Value               Where value is placed
  *              Width               Number of bits
  *
- * RETURN:      Value read from port
+ * RETURN:      Status and value read from port
  *
  * DESCRIPTION: Read data from an I/O port or register. This is a front-end
  *              to acpi_os_read_port that performs validation on both the port
@@ -218,14 +219,43 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
 acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
 {
 	acpi_status status;
+	u32 one_byte;
+	u32 i;
+
+	/* Validate the entire request and perform the I/O */
 
 	status = acpi_hw_validate_io_request(address, width);
-	if (ACPI_FAILURE(status)) {
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_os_read_port(address, value, width);
 		return status;
 	}
 
-	status = acpi_os_read_port(address, value, width);
-	return status;
+	if (status != AE_AML_ILLEGAL_ADDRESS) {
+		return status;
+	}
+
+	/*
+	 * There has been a protection violation within the request. Fall
+	 * back to byte granularity port I/O and ignore the failing bytes.
+	 * This provides Windows compatibility.
+	 */
+	for (i = 0, *value = 0; i < width; i += 8) {
+
+		/* Validate and read one byte */
+
+		if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+			status = acpi_os_read_port(address, &one_byte, 8);
+			if (ACPI_FAILURE(status)) {
+				return status;
+			}
+
+			*value |= (one_byte << i);
+		}
+
+		address++;
+	}
+
+	return AE_OK;
 }
 
 /******************************************************************************
@@ -236,7 +266,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
  *              Value               Value to write
  *              Width               Number of bits
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Write data to an I/O port or register. This is a front-end
  *              to acpi_os_write_port that performs validation on both the port
@@ -247,12 +277,39 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
 acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
 {
 	acpi_status status;
+	u32 i;
+
+	/* Validate the entire request and perform the I/O */
 
 	status = acpi_hw_validate_io_request(address, width);
-	if (ACPI_FAILURE(status)) {
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_os_write_port(address, value, width);
 		return status;
 	}
 
-	status = acpi_os_write_port(address, value, width);
-	return status;
+	if (status != AE_AML_ILLEGAL_ADDRESS) {
+		return status;
+	}
+
+	/*
+	 * There has been a protection violation within the request. Fall
+	 * back to byte granularity port I/O and ignore the failing bytes.
+	 * This provides Windows compatibility.
+	 */
+	for (i = 0; i < width; i += 8) {
+
+		/* Validate and write one byte */
+
+		if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+			status =
+			    acpi_os_write_port(address, (value >> i) & 0xFF, 8);
+			if (ACPI_FAILURE(status)) {
+				return status;
+			}
+		}
+
+		address++;
+	}
+
+	return AE_OK;
 }
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 663f692fffcf..a3c23d686d5f 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 	user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
 
 	for (index = 0; index < number_of_elements; index++) {
-		int source_name_index = 2;
-		int source_index_index = 3;
 
 		/*
 		 * Point user_prt past this current structure
@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
-		/*
-		 * If BIOS erroneously reversed the _PRT source_name and source_index,
-		 * then reverse them back.
-		 */
-		if ((sub_object_list[3])->common.type !=
-		    ACPI_TYPE_INTEGER) {
-			if (acpi_gbl_enable_interpreter_slack) {
-				source_name_index = 3;
-				source_index_index = 2;
-				printk(KERN_WARNING
-				       "ACPI: Handling Garbled _PRT entry\n");
-			} else {
-				ACPI_ERROR((AE_INFO,
-					    "(PRT[%X].source_index) Need Integer, found %s",
-					    index,
-					    acpi_ut_get_object_type_name
-					    (sub_object_list[3])));
-				return_ACPI_STATUS(AE_BAD_DATA);
-			}
-		}
-
 		user_prt->pin = (u32) obj_desc->integer.value;
 
 		/*
@@ -304,7 +281,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 		 * 3) Third subobject: Dereference the PRT.source_name
 		 * The name may be unresolved (slack mode), so allow a null object
 		 */
-		obj_desc = sub_object_list[source_name_index];
+		obj_desc = sub_object_list[2];
 		if (obj_desc) {
 			switch (obj_desc->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
@@ -378,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 
 		/* 4) Fourth subobject: Dereference the PRT.source_index */
 
-		obj_desc = sub_object_list[source_index_index];
+		obj_desc = sub_object_list[3];
 		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].SourceIndex) Need Integer, found %s",
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index d73c94b8441d..9195deba9d94 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -1,5 +1,5 @@
 /*
- *  acpi_button.c - ACPI Button Driver ($Revision: 30 $)
+ *  button.c - ACPI Button Driver
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -41,17 +41,13 @@
 
 #define ACPI_BUTTON_SUBCLASS_POWER	"power"
 #define ACPI_BUTTON_HID_POWER		"PNP0C0C"
-#define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_POWERF	"Power Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button"
 #define ACPI_BUTTON_TYPE_POWER		0x01
-#define ACPI_BUTTON_TYPE_POWERF		0x02
 
 #define ACPI_BUTTON_SUBCLASS_SLEEP	"sleep"
 #define ACPI_BUTTON_HID_SLEEP		"PNP0C0E"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEPF	"Sleep Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button"
 #define ACPI_BUTTON_TYPE_SLEEP		0x03
-#define ACPI_BUTTON_TYPE_SLEEPF		0x04
 
 #define ACPI_BUTTON_SUBCLASS_LID	"lid"
 #define ACPI_BUTTON_HID_LID		"PNP0C0D"
@@ -95,7 +91,6 @@ static struct acpi_driver acpi_button_driver = {
 };
 
 struct acpi_button {
-	struct acpi_device *device;	/* Fixed button kludge */
 	unsigned int type;
 	struct input_dev *input;
 	char phys[32];			/* for input device */
@@ -126,14 +121,10 @@ static struct proc_dir_entry *acpi_button_dir;
 
 static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = seq->private;
-
-	if (!button || !button->device)
-		return 0;
+	struct acpi_device *device = seq->private;
 
 	seq_printf(seq, "type:                    %s\n",
-		   acpi_device_name(button->device));
-
+		   acpi_device_name(device));
 	return 0;
 }
 
@@ -144,14 +135,11 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
 
 static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = seq->private;
+	struct acpi_device *device = seq->private;
 	acpi_status status;
 	unsigned long long state;
 
-	if (!button || !button->device)
-		return 0;
-
-	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
+	status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
 	seq_printf(seq, "state:      %s\n",
 		   ACPI_FAILURE(status) ? "unsupported" :
 			(state ? "open" : "closed"));
@@ -169,24 +157,17 @@ static struct proc_dir_entry *acpi_lid_dir;
 
 static int acpi_button_add_fs(struct acpi_device *device)
 {
+	struct acpi_button *button = acpi_driver_data(device);
 	struct proc_dir_entry *entry = NULL;
-	struct acpi_button *button;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	button = acpi_driver_data(device);
 
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
 		if (!acpi_power_dir)
 			acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
 						    acpi_button_dir);
 		entry = acpi_power_dir;
 		break;
 	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
 		if (!acpi_sleep_dir)
 			acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
 						    acpi_button_dir);
@@ -210,8 +191,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
 	/* 'info' [R] */
 	entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
 				 S_IRUGO, acpi_device_dir(device),
-				 &acpi_button_info_fops,
-				 acpi_driver_data(device));
+				 &acpi_button_info_fops, device);
 	if (!entry)
 		return -ENODEV;
 
@@ -219,8 +199,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
 	if (button->type == ACPI_BUTTON_TYPE_LID) {
 		entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
 					 S_IRUGO, acpi_device_dir(device),
-					 &acpi_button_state_fops,
-					 acpi_driver_data(device));
+					 &acpi_button_state_fops, device);
 		if (!entry)
 			return -ENODEV;
 	}
@@ -250,15 +229,16 @@ static int acpi_button_remove_fs(struct acpi_device *device)
 /* --------------------------------------------------------------------------
                                 Driver Interface
    -------------------------------------------------------------------------- */
-static int acpi_lid_send_state(struct acpi_button *button)
+static int acpi_lid_send_state(struct acpi_device *device)
 {
+	struct acpi_button *button = acpi_driver_data(device);
 	unsigned long long state;
 	acpi_status status;
 
-	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
-					&state);
+	status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
+
 	/* input layer checks if event is redundant */
 	input_report_switch(button->input, SW_LID, !state);
 	input_sync(button->input);
@@ -270,9 +250,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 	struct acpi_button *button = acpi_driver_data(device);
 	struct input_dev *input;
 
-	if (!button || !button->device)
-		return;
-
 	switch (event) {
 	case ACPI_FIXED_HARDWARE_EVENT:
 		event = ACPI_BUTTON_NOTIFY_STATUS;
@@ -280,7 +257,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 	case ACPI_BUTTON_NOTIFY_STATUS:
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
-			acpi_lid_send_state(button);
+			acpi_lid_send_state(device);
 		} else {
 			int keycode = test_bit(KEY_SLEEP, input->keybit) ?
 						KEY_SLEEP : KEY_POWER;
@@ -291,43 +268,35 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 			input_sync(input);
 		}
 
-		acpi_bus_generate_proc_event(button->device, event,
-					++button->pushed);
+		acpi_bus_generate_proc_event(device, event, ++button->pushed);
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
-
-	return;
 }
 
 static int acpi_button_resume(struct acpi_device *device)
 {
-	struct acpi_button *button;
-	if (!device)
-		return -EINVAL;
-	button = acpi_driver_data(device);
-	if (button && button->type == ACPI_BUTTON_TYPE_LID)
-		return acpi_lid_send_state(button);
+	struct acpi_button *button = acpi_driver_data(device);
+
+	if (button->type == ACPI_BUTTON_TYPE_LID)
+		return acpi_lid_send_state(device);
 	return 0;
 }
 
 static int acpi_button_add(struct acpi_device *device)
 {
-	int error;
 	struct acpi_button *button;
 	struct input_dev *input;
-
-	if (!device)
-		return -EINVAL;
+	char *hid, *name, *class;
+	int error;
 
 	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
 	if (!button)
 		return -ENOMEM;
 
-	button->device = device;
 	device->driver_data = button;
 
 	button->input = input = input_allocate_device();
@@ -336,40 +305,29 @@ static int acpi_button_add(struct acpi_device *device)
 		goto err_free_button;
 	}
 
-	/*
-	 * Determine the button type (via hid), as fixed-feature buttons
-	 * need to be handled a bit differently than generic-space.
-	 */
-	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
+	hid = acpi_device_hid(device);
+	name = acpi_device_name(device);
+	class = acpi_device_class(device);
+
+	if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
+	    !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
 		button->type = ACPI_BUTTON_TYPE_POWER;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_POWER);
-		sprintf(acpi_device_class(device), "%s/%s",
-			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
-		button->type = ACPI_BUTTON_TYPE_POWERF;
-		strcpy(acpi_device_name(device),
-		       ACPI_BUTTON_DEVICE_NAME_POWERF);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
+	} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
+		   !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
 		button->type = ACPI_BUTTON_TYPE_SLEEP;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_SLEEP);
-		sprintf(acpi_device_class(device), "%s/%s",
-			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
-		button->type = ACPI_BUTTON_TYPE_SLEEPF;
-		strcpy(acpi_device_name(device),
-		       ACPI_BUTTON_DEVICE_NAME_SLEEPF);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
+	} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
 		button->type = ACPI_BUTTON_TYPE_LID;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_LID);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
 	} else {
-		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
-			    acpi_device_hid(device));
+		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
 		error = -ENODEV;
 		goto err_free_input;
 	}
@@ -378,10 +336,9 @@ static int acpi_button_add(struct acpi_device *device)
 	if (error)
 		goto err_free_input;
 
-	snprintf(button->phys, sizeof(button->phys),
-		 "%s/button/input0", acpi_device_hid(device));
+	snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
 
-	input->name = acpi_device_name(device);
+	input->name = name;
 	input->phys = button->phys;
 	input->id.bustype = BUS_HOST;
 	input->id.product = button->type;
@@ -389,13 +346,11 @@ static int acpi_button_add(struct acpi_device *device)
 
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
 		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_POWER, input->keybit);
 		break;
 
 	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
 		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_SLEEP, input->keybit);
 		break;
@@ -410,7 +365,7 @@ static int acpi_button_add(struct acpi_device *device)
 	if (error)
 		goto err_remove_fs;
 	if (button->type == ACPI_BUTTON_TYPE_LID)
-		acpi_lid_send_state(button);
+		acpi_lid_send_state(device);
 
 	if (device->wakeup.flags.valid) {
 		/* Button's GPE is run-wake GPE */
@@ -422,9 +377,7 @@ static int acpi_button_add(struct acpi_device *device)
 		device->wakeup.state.enabled = 1;
 	}
 
-	printk(KERN_INFO PREFIX "%s [%s]\n",
-	       acpi_device_name(device), acpi_device_bid(device));
-
+	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
 	return 0;
 
  err_remove_fs:
@@ -438,17 +391,11 @@ static int acpi_button_add(struct acpi_device *device)
 
 static int acpi_button_remove(struct acpi_device *device, int type)
 {
-	struct acpi_button *button;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	button = acpi_driver_data(device);
+	struct acpi_button *button = acpi_driver_data(device);
 
 	acpi_button_remove_fs(device);
 	input_unregister_device(button->input);
 	kfree(button);
-
 	return 0;
 }
 
@@ -459,6 +406,7 @@ static int __init acpi_button_init(void)
 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
 	if (!acpi_button_dir)
 		return -ENODEV;
+
 	result = acpi_bus_register_driver(&acpi_button_driver);
 	if (result < 0) {
 		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 04e90443eff7..391f331674c7 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1065,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_device *device)
 	struct acpi_ec *ec = acpi_driver_data(device);
 	/* Enable use of GPE back */
 	clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
+	set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 	acpi_enable_gpe(NULL, ec->gpe);
 	return 0;
 }
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d59f08ecaf16..d916bea729f1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -353,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, void *dev_id)
 	if (handled) {
 		acpi_irq_handled++;
 		return IRQ_HANDLED;
-	} else
+	} else {
+		acpi_irq_not_handled++;
 		return IRQ_NONE;
+	}
 }
 
 acpi_status
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 05dfdc96802e..d0d550d22a6d 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -343,9 +343,6 @@ acpi_system_write_alarm(struct file *file,
 }
 #endif				/* HAVE_ACPI_LEGACY_ALARM */
 
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
 static int
 acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 {
@@ -353,7 +350,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 
 	seq_printf(seq, "Device\tS-state\t  Status   Sysfs node\n");
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
@@ -361,7 +358,6 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 
 		if (!dev->wakeup.flags.valid)
 			continue;
-		spin_unlock(&acpi_device_lock);
 
 		ldev = acpi_get_physical_device(dev->handle);
 		seq_printf(seq, "%s\t  S%d\t%c%-8s  ",
@@ -376,9 +372,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 		seq_printf(seq, "\n");
 		put_device(ldev);
 
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return 0;
 }
 
@@ -409,7 +404,7 @@ acpi_system_write_wakeup_device(struct file *file,
 	strbuf[len] = '\0';
 	sscanf(strbuf, "%s", str);
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
@@ -446,7 +441,7 @@ acpi_system_write_wakeup_device(struct file *file,
 			}
 		}
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return count;
 }
 
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 429be896a030..d2830f39d46b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -145,6 +145,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
 	struct acpi_processor_power *pwr = &pr->power;
 	u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
 
+	if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
+		return;
+
 	/*
 	 * Check, if one of the previous states already marked the lapic
 	 * unstable
@@ -578,6 +581,11 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
 	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
 		struct acpi_processor_cx *cx = &pr->power.states[i];
 
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+		/* TSC could halt in idle, so notify users */
+		if (tsc_halts_in_c(cx->type))
+			mark_tsc_unstable("TSC halts in idle");;
+#endif
 		switch (cx->type) {
 		case ACPI_STATE_C1:
 			cx->valid = 1;
@@ -654,11 +662,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 
 	seq_printf(seq, "active state:            C%zd\n"
 		   "max_cstate:              C%d\n"
-		   "bus master activity:     %08x\n"
 		   "maximum allowed latency: %d usec\n",
 		   pr->power.state ? pr->power.state - pr->power.states : 0,
-		   max_cstate, (unsigned)pr->power.bm_activity,
-		   pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
+		   max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
 
 	seq_puts(seq, "states:\n");
 
@@ -872,11 +878,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 	kt2 = ktime_get_real();
 	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-	/* TSC could halt in idle, so notify users */
-	if (tsc_halts_in_c(cx->type))
-		mark_tsc_unstable("TSC halts in idle");;
-#endif
 	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 
 	/* Tell the scheduler how much we idled: */
@@ -956,6 +957,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	 */
 	acpi_state_timer_broadcast(pr, cx, 1);
 
+	kt1 = ktime_get_real();
 	/*
 	 * disable bus master
 	 * bm_check implies we need ARB_DIS
@@ -977,10 +979,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 		ACPI_FLUSH_CPU_CACHE();
 	}
 
-	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	kt2 = ktime_get_real();
-	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	/* Re-enable bus master arbitration */
 	if (pr->flags.bm_check && pr->flags.bm_control) {
@@ -989,12 +988,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 		c3_cpu_count--;
 		spin_unlock(&c3_lock);
 	}
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-	/* TSC could halt in idle, so notify users */
-	if (tsc_halts_in_c(ACPI_STATE_C3))
-		mark_tsc_unstable("TSC halts in idle");
-#endif
 	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -1038,6 +1034,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
 		dev->states[i].desc[0] = '\0';
 	}
 
+	if (max_cstate == 0)
+		max_cstate = 1;
+
 	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
 		cx = &pr->power.states[i];
 		state = &dev->states[count];
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 20c23c049207..8ff510b91d88 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -24,7 +24,7 @@ extern struct acpi_device *acpi_root;
 
 static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_bus_id_list);
-DEFINE_SPINLOCK(acpi_device_lock);
+DEFINE_MUTEX(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
 struct acpi_device_bus_id{
@@ -491,7 +491,6 @@ static int acpi_device_register(struct acpi_device *device,
 	 */
 	INIT_LIST_HEAD(&device->children);
 	INIT_LIST_HEAD(&device->node);
-	INIT_LIST_HEAD(&device->g_list);
 	INIT_LIST_HEAD(&device->wakeup_list);
 
 	new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
@@ -500,7 +499,7 @@ static int acpi_device_register(struct acpi_device *device,
 		return -ENOMEM;
 	}
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	/*
 	 * Find suitable bus_id and instance number in acpi_bus_id_list
 	 * If failed, create one and link it into acpi_bus_id_list
@@ -521,14 +520,12 @@ static int acpi_device_register(struct acpi_device *device,
 	}
 	dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
 
-	if (device->parent) {
+	if (device->parent)
 		list_add_tail(&device->node, &device->parent->children);
-		list_add_tail(&device->g_list, &device->parent->g_list);
-	} else
-		list_add_tail(&device->g_list, &acpi_device_list);
+
 	if (device->wakeup.flags.valid)
 		list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 
 	if (device->parent)
 		device->dev.parent = &parent->dev;
@@ -549,28 +546,22 @@ static int acpi_device_register(struct acpi_device *device,
 	device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
 	return 0;
   end:
-	spin_lock(&acpi_device_lock);
-	if (device->parent) {
+	mutex_lock(&acpi_device_lock);
+	if (device->parent)
 		list_del(&device->node);
-		list_del(&device->g_list);
-	} else
-		list_del(&device->g_list);
 	list_del(&device->wakeup_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return result;
 }
 
 static void acpi_device_unregister(struct acpi_device *device, int type)
 {
-	spin_lock(&acpi_device_lock);
-	if (device->parent) {
+	mutex_lock(&acpi_device_lock);
+	if (device->parent)
 		list_del(&device->node);
-		list_del(&device->g_list);
-	} else
-		list_del(&device->g_list);
 
 	list_del(&device->wakeup_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 
 	acpi_detach_data(device->handle, acpi_bus_data_handler);
 
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 779e4e500df4..01574a066534 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -300,9 +300,9 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state)
 static struct platform_suspend_ops acpi_suspend_ops = {
 	.valid = acpi_suspend_state_valid,
 	.begin = acpi_suspend_begin,
-	.prepare = acpi_pm_prepare,
+	.prepare_late = acpi_pm_prepare,
 	.enter = acpi_suspend_enter,
-	.finish = acpi_pm_finish,
+	.wake = acpi_pm_finish,
 	.end = acpi_pm_end,
 };
 
@@ -328,9 +328,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
 static struct platform_suspend_ops acpi_suspend_ops_old = {
 	.valid = acpi_suspend_state_valid,
 	.begin = acpi_suspend_begin_old,
-	.prepare = acpi_pm_disable_gpes,
+	.prepare_late = acpi_pm_disable_gpes,
 	.enter = acpi_suspend_enter,
-	.finish = acpi_pm_finish,
+	.wake = acpi_pm_finish,
 	.end = acpi_pm_end,
 	.recover = acpi_pm_finish,
 };
@@ -713,6 +713,32 @@ static void acpi_power_off(void)
 	acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
+/*
+ * ACPI 2.0 created the optional _GTS and _BFS,
+ * but industry adoption has been neither rapid nor broad.
+ *
+ * Linux gets into trouble when it executes poorly validated
+ * paths through the BIOS, so disable _GTS and _BFS by default,
+ * but do speak up and offer the option to enable them.
+ */
+void __init acpi_gts_bfs_check(void)
+{
+	acpi_handle dummy;
+
+	if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy)))
+	{
+		printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
+		printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
+			"please notify linux-acpi@vger.kernel.org\n");
+	}
+	if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy)))
+	{
+		printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
+		printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "
+			"please notify linux-acpi@vger.kernel.org\n");
+	}
+}
+
 int __init acpi_sleep_init(void)
 {
 	acpi_status status;
@@ -771,5 +797,6 @@ int __init acpi_sleep_init(void)
 	 * object can also be evaluated when the system enters S5.
 	 */
 	register_reboot_notifier(&tts_notifier);
+	acpi_gts_bfs_check();
 	return 0;
 }
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index cfaf8f5b0a14..8a8f3b3382a6 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -5,3 +5,6 @@ extern int acpi_suspend (u32 state);
 extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
 extern void acpi_enable_wakeup_device(u8 sleep_state);
 extern void acpi_disable_wakeup_device(u8 sleep_state);
+
+extern struct list_head acpi_wakeup_device_list;
+extern struct mutex acpi_device_lock;
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index da51f05ef8d8..0944daec064f 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -38,6 +38,7 @@ ACPI_MODULE_NAME("system");
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
 
 u32 acpi_irq_handled;
+u32 acpi_irq_not_handled;
 
 /*
  * Make ACPICA version work as module param
@@ -214,8 +215,9 @@ err:
 
 #define COUNT_GPE 0
 #define COUNT_SCI 1	/* acpi_irq_handled */
-#define COUNT_ERROR 2	/* other */
-#define NUM_COUNTERS_EXTRA 3
+#define COUNT_SCI_NOT 2	/* acpi_irq_not_handled */
+#define COUNT_ERROR 3	/* other */
+#define NUM_COUNTERS_EXTRA 4
 
 struct event_counter {
 	u32 count;
@@ -317,6 +319,8 @@ static ssize_t counter_show(struct kobject *kobj,
 
 	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
 		acpi_irq_handled;
+	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
+		acpi_irq_not_handled;
 	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
 		acpi_gpe_count;
 
@@ -363,6 +367,7 @@ static ssize_t counter_set(struct kobject *kobj,
 			all_counters[i].count = 0;
 		acpi_gpe_count = 0;
 		acpi_irq_handled = 0;
+		acpi_irq_not_handled = 0;
 		goto end;
 	}
 
@@ -456,6 +461,8 @@ void acpi_irq_stats_init(void)
 			sprintf(buffer, "gpe_all");
 		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
 			sprintf(buffer, "sci");
+		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
+			sprintf(buffer, "sci_not");
 		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
 			sprintf(buffer, "error");
 		else
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index e8c143caf0fd..564ea1424288 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
 static int acpi_thermal_add(struct acpi_device *device);
 static int acpi_thermal_remove(struct acpi_device *device, int type);
 static int acpi_thermal_resume(struct acpi_device *device);
+static void acpi_thermal_notify(struct acpi_device *device, u32 event);
 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -123,6 +124,7 @@ static struct acpi_driver acpi_thermal_driver = {
 		.add = acpi_thermal_add,
 		.remove = acpi_thermal_remove,
 		.resume = acpi_thermal_resume,
+		.notify = acpi_thermal_notify,
 		},
 };
 
@@ -192,6 +194,7 @@ struct acpi_thermal {
 	struct acpi_handle_list devices;
 	struct thermal_zone_device *thermal_zone;
 	int tz_enabled;
+	int kelvin_offset;
 	struct mutex lock;
 };
 
@@ -581,7 +584,7 @@ static void acpi_thermal_check(void *data)
 }
 
 /* sys I/F for generic thermal sysfs support */
-#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
 
 static int thermal_get_temp(struct thermal_zone_device *thermal,
 			    unsigned long *temp)
@@ -596,7 +599,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal,
 	if (result)
 		return result;
 
-	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
 	return 0;
 }
 
@@ -702,7 +705,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 	if (tz->trips.critical.flags.valid) {
 		if (!trip) {
 			*temp = KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature);
+				tz->trips.critical.temperature,
+				tz->kelvin_offset);
 			return 0;
 		}
 		trip--;
@@ -711,7 +715,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 	if (tz->trips.hot.flags.valid) {
 		if (!trip) {
 			*temp = KELVIN_TO_MILLICELSIUS(
-				tz->trips.hot.temperature);
+				tz->trips.hot.temperature,
+				tz->kelvin_offset);
 			return 0;
 		}
 		trip--;
@@ -720,7 +725,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 	if (tz->trips.passive.flags.valid) {
 		if (!trip) {
 			*temp = KELVIN_TO_MILLICELSIUS(
-				tz->trips.passive.temperature);
+				tz->trips.passive.temperature,
+				tz->kelvin_offset);
 			return 0;
 		}
 		trip--;
@@ -730,7 +736,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 		tz->trips.active[i].flags.valid; i++) {
 		if (!trip) {
 			*temp = KELVIN_TO_MILLICELSIUS(
-				tz->trips.active[i].temperature);
+				tz->trips.active[i].temperature,
+				tz->kelvin_offset);
 			return 0;
 		}
 		trip--;
@@ -745,7 +752,8 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
 
 	if (tz->trips.critical.flags.valid) {
 		*temperature = KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature);
+				tz->trips.critical.temperature,
+				tz->kelvin_offset);
 		return 0;
 	} else
 		return -EINVAL;
@@ -901,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 			thermal_zone_device_register("acpitz", trips, tz,
 						     &acpi_thermal_zone_ops,
 						     0, 0, 0,
-						     tz->polling_frequency);
+						     tz->polling_frequency*100);
 	if (IS_ERR(tz->thermal_zone))
 		return -ENODEV;
 
@@ -1264,17 +1272,14 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
-static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_thermal_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_thermal *tz = data;
-	struct acpi_device *device = NULL;
+	struct acpi_thermal *tz = acpi_driver_data(device);
 
 
 	if (!tz)
 		return;
 
-	device = tz->device;
-
 	switch (event) {
 	case ACPI_THERMAL_NOTIFY_TEMPERATURE:
 		acpi_thermal_check(tz);
@@ -1298,8 +1303,6 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
-
-	return;
 }
 
 static int acpi_thermal_get_info(struct acpi_thermal *tz)
@@ -1334,10 +1337,28 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
 	return 0;
 }
 
+/*
+ * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
+ * handles temperature values with a single decimal place. As a consequence,
+ * some implementations use an offset of 273.1 and others use an offset of
+ * 273.2. Try to find out which one is being used, to present the most
+ * accurate and visually appealing number.
+ *
+ * The heuristic below should work for all ACPI thermal zones which have a
+ * critical trip point with a value being a multiple of 0.5 degree Celsius.
+ */
+static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
+{
+	if (tz->trips.critical.flags.valid &&
+	    (tz->trips.critical.temperature % 5) == 1)
+		tz->kelvin_offset = 2731;
+	else
+		tz->kelvin_offset = 2732;
+}
+
 static int acpi_thermal_add(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
 
@@ -1360,6 +1381,8 @@ static int acpi_thermal_add(struct acpi_device *device)
 	if (result)
 		goto free_memory;
 
+	acpi_thermal_guess_offset(tz);
+
 	result = acpi_thermal_register_thermal_zone(tz);
 	if (result)
 		goto free_memory;
@@ -1368,21 +1391,11 @@ static int acpi_thermal_add(struct acpi_device *device)
 	if (result)
 		goto unregister_thermal_zone;
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_thermal_notify, tz);
-	if (ACPI_FAILURE(status)) {
-		result = -ENODEV;
-		goto remove_fs;
-	}
-
 	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       KELVIN_TO_CELSIUS(tz->temperature));
 	goto end;
 
-remove_fs:
-	acpi_thermal_remove_fs(device);
 unregister_thermal_zone:
 	thermal_zone_device_unregister(tz->thermal_zone);
 free_memory:
@@ -1393,7 +1406,6 @@ end:
 
 static int acpi_thermal_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
 	if (!device || !acpi_driver_data(device))
@@ -1401,10 +1413,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
 
 	tz = acpi_driver_data(device);
 
-	status = acpi_remove_notify_handler(device->handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_thermal_notify);
-
 	acpi_thermal_remove_fs(device);
 	acpi_thermal_unregister_thermal_zone(tz);
 	mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index ab06143672bc..d7ff61c0d571 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -79,6 +79,7 @@ module_param(brightness_switch_enabled, bool, 0644);
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
 static int acpi_video_resume(struct acpi_device *device);
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id video_device_ids[] = {
 	{ACPI_VIDEO_HID, 0},
@@ -94,6 +95,7 @@ static struct acpi_driver acpi_video_bus = {
 		.add = acpi_video_bus_add,
 		.remove = acpi_video_bus_remove,
 		.resume = acpi_video_resume,
+		.notify = acpi_video_bus_notify,
 		},
 };
 
@@ -768,10 +770,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
 	 * In this case, the first two elements in _BCL packages
 	 * are also supported brightness levels that OS should take care of.
 	 */
-	for (i = 2; i < count; i++)
-		if (br->levels[i] == br->levels[0] ||
-		    br->levels[i] == br->levels[1])
+	for (i = 2; i < count; i++) {
+		if (br->levels[i] == br->levels[0])
 			level_ac_battery++;
+		if (br->levels[i] == br->levels[1])
+			level_ac_battery++;
+	}
 
 	if (level_ac_battery < 2) {
 		level_ac_battery = 2 - level_ac_battery;
@@ -805,12 +809,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
 	br->flags._BCM_use_index = br->flags._BCL_use_index;
 
 	/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
-	br->curr = max_level;
+	br->curr = level_old = max_level;
+
+	if (!device->cap._BQC)
+		goto set_level;
+
 	result = acpi_video_device_lcd_get_level_current(device, &level_old);
 	if (result)
 		goto out_free_levels;
 
-	result = acpi_video_device_lcd_set_level(device, br->curr);
+	/*
+	 * Set the level to maximum and check if _BQC uses indexed value
+	 */
+	result = acpi_video_device_lcd_set_level(device, max_level);
 	if (result)
 		goto out_free_levels;
 
@@ -818,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
 	if (result)
 		goto out_free_levels;
 
-	if ((level != level_old) && !br->flags._BCM_use_index) {
-		/* Note:
-		 * This piece of code does not work correctly if the current
-		 * brightness levels is 0.
-		 * But I guess boxes that boot with such a dark screen are rare
-		 * and no more code is needed to cover this specifial case.
-		 */
-
-		if (level_ac_battery != 2) {
-			/*
-			 * For now, we don't support the _BCL like this:
-			 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
-			 * because we may mess up the index returned by _BQC.
-			 * Plus: we have not got a box like this.
-			 */
-			ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
-		}
-		br->flags._BQC_use_index = 1;
-	}
+	br->flags._BQC_use_index = (level == max_level ? 0 : 1);
+
+	if (!br->flags._BQC_use_index)
+		goto set_level;
+
+	if (br->flags._BCL_reversed)
+		level_old = (br->count - 1) - level_old;
+	level_old = br->levels[level_old];
+
+set_level:
+	result = acpi_video_device_lcd_set_level(device, level_old);
+	if (result)
+		goto out_free_levels;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "found %d brightness levels\n", count - 2));
@@ -1986,17 +1991,15 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
 	return acpi_video_bus_DOS(video, 0, 1);
 }
 
-static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_video_bus *video = data;
-	struct acpi_device *device = NULL;
+	struct acpi_video_bus *video = acpi_driver_data(device);
 	struct input_dev *input;
 	int keycode;
 
 	if (!video)
 		return;
 
-	device = video->device;
 	input = video->input;
 
 	switch (event) {
@@ -2127,7 +2130,6 @@ static int acpi_video_resume(struct acpi_device *device)
 
 static int acpi_video_bus_add(struct acpi_device *device)
 {
-	acpi_status status;
 	struct acpi_video_bus *video;
 	struct input_dev *input;
 	int error;
@@ -2169,20 +2171,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
 	acpi_video_bus_get_devices(video, device);
 	acpi_video_bus_start_devices(video);
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_video_bus_notify, video);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX
-				  "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop_video;
-	}
-
 	video->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_stop_video;
 	}
 
 	snprintf(video->phys, sizeof(video->phys),
@@ -2218,9 +2210,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
  err_free_input_dev:
 	input_free_device(input);
- err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_video_bus_notify);
  err_stop_video:
 	acpi_video_bus_stop_devices(video);
 	acpi_video_bus_put_devices(video);
@@ -2235,7 +2224,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
 static int acpi_video_bus_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = 0;
 	struct acpi_video_bus *video = NULL;
 
 
@@ -2245,11 +2233,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
 	video = acpi_driver_data(device);
 
 	acpi_video_bus_stop_devices(video);
-
-	status = acpi_remove_notify_handler(video->device->handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_video_bus_notify);
-
 	acpi_video_bus_put_devices(video);
 	acpi_video_bus_remove_fs(device);
 
@@ -2313,7 +2296,7 @@ static int __init acpi_video_init(void)
 	return acpi_video_register();
 }
 
-static void __exit acpi_video_exit(void)
+void __exit acpi_video_exit(void)
 {
 
 	acpi_bus_unregister_driver(&acpi_video_bus);
@@ -2322,6 +2305,7 @@ static void __exit acpi_video_exit(void)
 
 	return;
 }
+EXPORT_SYMBOL(acpi_video_exit);
 
 module_init(acpi_video_init);
 module_exit(acpi_video_exit);
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 5aee8c26cc9f..88725dcdf8bc 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -12,12 +12,14 @@
 #include "internal.h"
 #include "sleep.h"
 
+/*
+ * We didn't lock acpi_device_lock in the file, because it invokes oops in
+ * suspend/resume and isn't really required as this is called in S-state. At
+ * that time, there is no device hotplug
+ **/
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("wakeup_devices")
 
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
 /**
  * acpi_enable_wakeup_device_prep - prepare wakeup devices
  *	@sleep_state:	ACPI state
@@ -29,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
 {
 	struct list_head *node, *next;
 
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
 						       struct acpi_device,
@@ -40,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
 		    (sleep_state > (u32) dev->wakeup.sleep_state))
 			continue;
 
-		spin_unlock(&acpi_device_lock);
 		acpi_enable_wakeup_device_power(dev, sleep_state);
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -60,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state)
 	 * Caution: this routine must be invoked when interrupt is disabled 
 	 * Refer ACPI2.0: P212
 	 */
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 			container_of(node, struct acpi_device, wakeup_list);
@@ -74,22 +71,17 @@ void acpi_enable_wakeup_device(u8 sleep_state)
 		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
-				spin_unlock(&acpi_device_lock);
 				/* set_gpe_type will disable GPE, leave it like that */
 				acpi_set_gpe_type(dev->wakeup.gpe_device,
 						  dev->wakeup.gpe_number,
 						  ACPI_GPE_TYPE_RUNTIME);
-				spin_lock(&acpi_device_lock);
 			}
 			continue;
 		}
-		spin_unlock(&acpi_device_lock);
 		if (!dev->wakeup.flags.run_wake)
 			acpi_enable_gpe(dev->wakeup.gpe_device,
 					dev->wakeup.gpe_number);
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -101,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 {
 	struct list_head *node, *next;
 
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 			container_of(node, struct acpi_device, wakeup_list);
@@ -112,19 +103,16 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
-				spin_unlock(&acpi_device_lock);
 				acpi_set_gpe_type(dev->wakeup.gpe_device,
 						  dev->wakeup.gpe_number,
 						  ACPI_GPE_TYPE_WAKE_RUN);
 				/* Re-enable it, since set_gpe_type will disable it */
 				acpi_enable_gpe(dev->wakeup.gpe_device,
 						dev->wakeup.gpe_number);
-				spin_lock(&acpi_device_lock);
 			}
 			continue;
 		}
 
-		spin_unlock(&acpi_device_lock);
 		acpi_disable_wakeup_device_power(dev);
 		/* Never disable run-wake GPE */
 		if (!dev->wakeup.flags.run_wake) {
@@ -133,16 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 			acpi_clear_gpe(dev->wakeup.gpe_device,
 				       dev->wakeup.gpe_number, ACPI_NOT_ISR);
 		}
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
 int __init acpi_wakeup_device_init(void)
 {
 	struct list_head *node, *next;
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
 						       struct acpi_device,
@@ -150,15 +136,13 @@ int __init acpi_wakeup_device_init(void)
 		/* In case user doesn't load button driver */
 		if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
 			continue;
-		spin_unlock(&acpi_device_lock);
 		acpi_set_gpe_type(dev->wakeup.gpe_device,
 				  dev->wakeup.gpe_number,
 				  ACPI_GPE_TYPE_WAKE_RUN);
 		acpi_enable_gpe(dev->wakeup.gpe_device,
 				dev->wakeup.gpe_number);
 		dev->wakeup.state.enabled = 1;
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return 0;
 }
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 57be6bea48eb..08186ecbaf8d 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -114,6 +114,7 @@ enum {
 	board_ahci_sb700	= 5, /* for SB700 and SB800 */
 	board_ahci_mcp65	= 6,
 	board_ahci_nopmp	= 7,
+	board_ahci_yesncq	= 8,
 
 	/* global controller registers */
 	HOST_CAP		= 0x00, /* host capabilities */
@@ -469,6 +470,14 @@ static const struct ata_port_info ahci_port_info[] = {
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
+	/* board_ahci_yesncq */
+	{
+		AHCI_HFLAGS	(AHCI_HFLAG_YES_NCQ),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -535,30 +544,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 },	/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 },	/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 },	/* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_yesncq },	/* MCP67 */
+	{ 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, 0x07f0), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_yesncq },	/* MCP73 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci },		/* MCP77 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci },		/* MCP77 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci },		/* MCP77 */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e7ea77cf6069..17c5d48a75d2 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
 	 *
 	 * We follow the current spec and consider that 0x69/0x96
 	 * identifies a port multiplier and 0x3c/0xc3 a SEMB device.
+	 * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports
+	 * SEMB signature.  This is worked around in
+	 * ata_dev_read_id().
 	 */
 	if ((tf->lbam == 0) && (tf->lbah == 0)) {
 		DPRINTK("found ATA device by sig\n");
@@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
 	}
 
 	if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) {
-		printk(KERN_INFO "ata: SEMB device ignored\n");
-		return ATA_DEV_SEMB_UNSUP; /* not yet */
+		DPRINTK("found SEMB device by sig (could be ATA device)\n");
+		return ATA_DEV_SEMB;
 	}
 
 	DPRINTK("unknown device\n");
@@ -1653,8 +1656,8 @@ unsigned long ata_id_xfermask(const u16 *id)
 		/*
 		 *	Process compact flash extended modes
 		 */
-		int pio = id[163] & 0x7;
-		int dma = (id[163] >> 3) & 7;
+		int pio = (id[ATA_ID_CFA_MODES] >> 0) & 0x7;
+		int dma = (id[ATA_ID_CFA_MODES] >> 3) & 0x7;
 
 		if (pio)
 			pio_mask |= (1 << 5);
@@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 	struct ata_taskfile tf;
 	unsigned int err_mask = 0;
 	const char *reason;
+	bool is_semb = class == ATA_DEV_SEMB;
 	int may_fallback = 1, tried_spinup = 0;
 	int rc;
 
@@ -2090,6 +2094,8 @@ retry:
 	ata_tf_init(dev, &tf);
 
 	switch (class) {
+	case ATA_DEV_SEMB:
+		class = ATA_DEV_ATA;	/* some hard drives report SEMB sig */
 	case ATA_DEV_ATA:
 		tf.command = ATA_CMD_ID_ATA;
 		break;
@@ -2126,6 +2132,14 @@ retry:
 			return -ENOENT;
 		}
 
+		if (is_semb) {
+			ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on "
+				       "device w/ SEMB sig, disabled\n");
+			/* SEMB is not supported yet */
+			*p_class = ATA_DEV_SEMB_UNSUP;
+			return 0;
+		}
+
 		if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
 			/* Device or controller might have reported
 			 * the wrong device class.  Give a shot at the
@@ -2412,7 +2426,8 @@ int ata_dev_configure(struct ata_device *dev)
 	/* ATA-specific feature tests */
 	if (dev->class == ATA_DEV_ATA) {
 		if (ata_id_is_cfa(id)) {
-			if (id[162] & 1) /* CPRM may make this media unusable */
+			/* CPRM may make this media unusable */
+			if (id[ATA_ID_CFA_KEY_MGMT] & 1)
 				ata_dev_printk(dev, KERN_WARNING,
 					       "supports DRM functions and may "
 					       "not be fully accessable.\n");
@@ -6110,13 +6125,11 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 			ata_port_printk(ap, KERN_INFO, "DUMMY\n");
 	}
 
-	/* perform each probe synchronously */
-	DPRINTK("probe begin\n");
+	/* perform each probe asynchronously */
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 		async_schedule(async_port_probe, ap);
 	}
-	DPRINTK("probe end\n");
 
 	return 0;
 }
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b9747fa59e54..2733b0c90b75 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -647,23 +647,45 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
 	return rc;
 }
 
+static int ata_ioc32(struct ata_port *ap)
+{
+	if (ap->flags & ATA_FLAG_PIO_DMA)
+		return 1;
+	if (ap->pflags & ATA_PFLAG_PIO32)
+		return 1;
+	return 0;
+}
+
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
 		     int cmd, void __user *arg)
 {
 	int val = -EINVAL, rc = -EINVAL;
+	unsigned long flags;
 
 	switch (cmd) {
 	case ATA_IOC_GET_IO32:
-		val = 0;
+		spin_lock_irqsave(ap->lock, flags);
+		val = ata_ioc32(ap);
+		spin_unlock_irqrestore(ap->lock, flags);
 		if (copy_to_user(arg, &val, 1))
 			return -EFAULT;
 		return 0;
 
 	case ATA_IOC_SET_IO32:
 		val = (unsigned long) arg;
-		if (val != 0)
-			return -EINVAL;
-		return 0;
+		rc = 0;
+		spin_lock_irqsave(ap->lock, flags);
+		if (ap->pflags & ATA_PFLAG_PIO32CHANGE) {
+			if (val)
+				ap->pflags |= ATA_PFLAG_PIO32;
+			else
+				ap->pflags &= ~ATA_PFLAG_PIO32;
+		} else {
+			if (val != ata_ioc32(ap))
+				rc = -EINVAL;
+		}
+		spin_unlock_irqrestore(ap->lock, flags);
+		return rc;
 
 	case HDIO_GET_IDENTITY:
 		return ata_get_identity(ap, scsidev, arg);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 8332e97a9de3..bb18415d3d63 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -87,6 +87,7 @@ const struct ata_port_operations ata_bmdma32_port_ops = {
 	.inherits		= &ata_bmdma_port_ops,
 
 	.sff_data_xfer		= ata_sff_data_xfer32,
+	.port_start		= ata_sff_port_start32,
 };
 EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
 
@@ -769,6 +770,9 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
 	void __iomem *data_addr = ap->ioaddr.data_addr;
 	unsigned int words = buflen >> 2;
 	int slop = buflen & 3;
+	
+	if (!(ap->pflags & ATA_PFLAG_PIO32))
+		return ata_sff_data_xfer(dev, buf, buflen, rw);
 
 	/* Transfer multiple of 4 bytes */
 	if (rw == READ)
@@ -2402,6 +2406,29 @@ int ata_sff_port_start(struct ata_port *ap)
 EXPORT_SYMBOL_GPL(ata_sff_port_start);
 
 /**
+ *	ata_sff_port_start32 - Set port up for dma.
+ *	@ap: Port to initialize
+ *
+ *	Called just after data structures for each port are
+ *	initialized.  Allocates space for PRD table if the device
+ *	is DMA capable SFF.
+ *
+ *	May be used as the port_start() entry in ata_port_operations for
+ *	devices that are capable of 32bit PIO.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+int ata_sff_port_start32(struct ata_port *ap)
+{
+	ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
+	if (ap->ioaddr.bmdma_addr)
+		return ata_port_start(ap);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ata_sff_port_start32);
+
+/**
  *	ata_sff_std_ports - initialize ioaddr with standard port offsets.
  *	@ioaddr: IO address structure to be initialized
  *
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 81ab57003aba..122c786449a9 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -8,7 +8,7 @@
  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2003		Red Hat Inc
- * Portions Copyright (C) 2005-2007	MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009	MontaVista Software, Inc.
  *
  * TODO
  *	Look into engine reset on timeout errors. Should not be	required.
@@ -24,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt37x"
-#define DRV_VERSION	"0.6.11"
+#define DRV_VERSION	"0.6.12"
 
 struct hpt_clock {
 	u8	xfer_speed;
@@ -445,23 +445,6 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 }
 
 /**
- *	hpt370_bmdma_start		-	DMA engine begin
- *	@qc: ATA command
- *
- *	The 370 and 370A want us to reset the DMA engine each time we
- *	use it. The 372 and later are fine.
- */
-
-static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
-{
-	struct ata_port *ap = qc->ap;
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
-	udelay(10);
-	ata_bmdma_start(qc);
-}
-
-/**
  *	hpt370_bmdma_end		-	DMA engine stop
  *	@qc: ATA command
  *
@@ -598,7 +581,6 @@ static struct scsi_host_template hpt37x_sht = {
 static struct ata_port_operations hpt370_port_ops = {
 	.inherits	= &ata_bmdma_port_ops,
 
-	.bmdma_start 	= hpt370_bmdma_start,
 	.bmdma_stop	= hpt370_bmdma_stop,
 
 	.mode_filter	= hpt370_filter,
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 3f830f0fe2cc..f72c6c5b820f 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -108,6 +108,7 @@ struct legacy_controller {
 	struct ata_port_operations *ops;
 	unsigned int pio_mask;
 	unsigned int flags;
+	unsigned int pflags;
 	int (*setup)(struct platform_device *, struct legacy_probe *probe,
 		struct legacy_data *data);
 };
@@ -284,9 +285,11 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
 			unsigned char *buf, unsigned int buflen, int rw)
 {
 	int slop = buflen & 3;
+	struct ata_port *ap = dev->link->ap;
+
 	/* 32bit I/O capable *and* we need to write a whole number of dwords */
-	if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) {
-		struct ata_port *ap = dev->link->ap;
+	if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)
+					&& (ap->pflags & ATA_PFLAG_PIO32)) {
 		unsigned long flags;
 
 		local_irq_save(flags);
@@ -736,7 +739,8 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
 	struct ata_port *ap = adev->link->ap;
 	int slop = buflen & 3;
 
-	if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) {
+	if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)
+					&& (ap->pflags & ATA_PFLAG_PIO32)) {
 		if (rw == WRITE)
 			iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
 		else
@@ -858,27 +862,30 @@ static struct ata_port_operations winbond_port_ops = {
 
 static struct legacy_controller controllers[] = {
 	{"BIOS",	&legacy_port_ops, 	0x1F,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"Snooping", 	&simple_port_ops, 	0x1F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"PDC20230",	&pdc20230_port_ops,	0x7,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,
+			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,	NULL },
 	{"HT6560A",	&ht6560a_port_ops,	0x07,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"HT6560B",	&ht6560b_port_ops,	0x1F,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"OPTI82C611A",	&opti82c611a_port_ops,	0x0F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"OPTI82C46X",	&opti82c46x_port_ops,	0x0F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"QDI6500",	&qdi6500_port_ops,	0x07,
-					ATA_FLAG_NO_IORDY,	qdi_port },
+			ATA_FLAG_NO_IORDY,
+			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,    qdi_port },
 	{"QDI6580",	&qdi6580_port_ops,	0x1F,
-					0	       ,	qdi_port },
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
 	{"QDI6580DP",	&qdi6580dp_port_ops,	0x1F,
-					0	       ,	qdi_port },
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
 	{"W83759A",	&winbond_port_ops,	0x1F,
-					0	       ,	winbond_port }
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,
+								winbond_port }
 };
 
 /**
@@ -1008,6 +1015,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
 	ap->ops = ops;
 	ap->pio_mask = pio_modes;
 	ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
+	ap->pflags |= controller->pflags;
 	ap->ioaddr.cmd_addr = io_addr;
 	ap->ioaddr.altstatus_addr = ctrl_addr;
 	ap->ioaddr.ctl_addr = ctrl_addr;
@@ -1032,6 +1040,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
 			return 0;
 		}
 	}
+	ata_host_detach(host);
 fail:
 	platform_device_unregister(pdev);
 	return ret;
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 0fb6b1b1e634..dd53a66b19e3 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -44,7 +44,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_ninja32"
-#define DRV_VERSION "0.1.3"
+#define DRV_VERSION "0.1.5"
 
 
 /**
@@ -86,6 +86,7 @@ static struct ata_port_operations ninja32_port_ops = {
 	.sff_dev_select = ninja32_dev_select,
 	.cable_detect	= ata_cable_40wire,
 	.set_piomode	= ninja32_set_piomode,
+	.sff_data_xfer	= ata_sff_data_xfer32
 };
 
 static void ninja32_program(void __iomem *base)
@@ -144,6 +145,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 	ap->ioaddr.altstatus_addr = base + 0x1E;
 	ap->ioaddr.bmdma_addr = base;
 	ata_sff_std_ports(&ap->ioaddr);
+	ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
 
 	ninja32_program(base);
 	/* FIXME: Should we disable them at remove ? */
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index b08e6e0f82b6..45657cacec43 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -62,7 +62,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME "pata_via"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.4"
 
 /*
  *	The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -136,6 +136,9 @@ static const struct via_isa_bridge {
 	{ NULL }
 };
 
+struct via_port {
+	u8 cached_device;
+};
 
 /*
  *	Cable special cases
@@ -346,14 +349,70 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  */
 static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-	struct ata_taskfile tmp_tf;
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	struct via_port *vp = ap->private_data;
+	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+	int newctl = 0;
+
+	if (tf->ctl != ap->last_ctl) {
+		iowrite8(tf->ctl, ioaddr->ctl_addr);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+		newctl = 1;
+	}
+
+	if (tf->flags & ATA_TFLAG_DEVICE) {
+		iowrite8(tf->device, ioaddr->device_addr);
+		vp->cached_device = tf->device;
+	} else if (newctl)
+		iowrite8(vp->cached_device, ioaddr->device_addr);
+
+	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+		WARN_ON_ONCE(!ioaddr->ctl_addr);
+		iowrite8(tf->hob_feature, ioaddr->feature_addr);
+		iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
+		iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
+		iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
+		iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
+		VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+			tf->hob_feature,
+			tf->hob_nsect,
+			tf->hob_lbal,
+			tf->hob_lbam,
+			tf->hob_lbah);
+	}
 
-	if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
-		tmp_tf = *tf;
-		tmp_tf.flags |= ATA_TFLAG_DEVICE;
-		tf = &tmp_tf;
+	if (is_addr) {
+		iowrite8(tf->feature, ioaddr->feature_addr);
+		iowrite8(tf->nsect, ioaddr->nsect_addr);
+		iowrite8(tf->lbal, ioaddr->lbal_addr);
+		iowrite8(tf->lbam, ioaddr->lbam_addr);
+		iowrite8(tf->lbah, ioaddr->lbah_addr);
+		VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+			tf->feature,
+			tf->nsect,
+			tf->lbal,
+			tf->lbam,
+			tf->lbah);
 	}
-	ata_sff_tf_load(ap, tf);
+
+	ata_wait_idle(ap);
+}
+
+static int via_port_start(struct ata_port *ap)
+{
+	struct via_port *vp;
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+	int ret = ata_sff_port_start(ap);
+	if (ret < 0)
+		return ret;
+
+	vp = devm_kzalloc(&pdev->dev, sizeof(struct via_port), GFP_KERNEL);
+	if (vp == NULL)
+		return -ENOMEM;
+	ap->private_data = vp;
+	return 0;
 }
 
 static struct scsi_host_template via_sht = {
@@ -367,6 +426,7 @@ static struct ata_port_operations via_port_ops = {
 	.set_dmamode	= via_set_dmamode,
 	.prereset	= via_pre_reset,
 	.sff_tf_load	= via_tf_load,
+	.port_start	= via_port_start,
 };
 
 static struct ata_port_operations via_port_ops_noirq = {
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 37ae5dc1070c..870dcfd82357 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1881,6 +1881,39 @@ static u8 mv_bmdma_status(struct ata_port *ap)
 	return status;
 }
 
+static void mv_rw_multi_errata_sata24(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *tf = &qc->tf;
+	/*
+	 * Workaround for 88SX60x1 FEr SATA#24.
+	 *
+	 * Chip may corrupt WRITEs if multi_count >= 4kB.
+	 * Note that READs are unaffected.
+	 *
+	 * It's not clear if this errata really means "4K bytes",
+	 * or if it always happens for multi_count > 7
+	 * regardless of device sector_size.
+	 *
+	 * So, for safety, any write with multi_count > 7
+	 * gets converted here into a regular PIO write instead:
+	 */
+	if ((tf->flags & ATA_TFLAG_WRITE) && is_multi_taskfile(tf)) {
+		if (qc->dev->multi_count > 7) {
+			switch (tf->command) {
+			case ATA_CMD_WRITE_MULTI:
+				tf->command = ATA_CMD_PIO_WRITE;
+				break;
+			case ATA_CMD_WRITE_MULTI_FUA_EXT:
+				tf->flags &= ~ATA_TFLAG_FUA; /* ugh */
+				/* fall through */
+			case ATA_CMD_WRITE_MULTI_EXT:
+				tf->command = ATA_CMD_PIO_WRITE_EXT;
+				break;
+			}
+		}
+	}
+}
+
 /**
  *      mv_qc_prep - Host specific command preparation.
  *      @qc: queued command to prepare
@@ -1898,17 +1931,24 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
 	struct ata_port *ap = qc->ap;
 	struct mv_port_priv *pp = ap->private_data;
 	__le16 *cw;
-	struct ata_taskfile *tf;
+	struct ata_taskfile *tf = &qc->tf;
 	u16 flags = 0;
 	unsigned in_index;
 
-	if ((qc->tf.protocol != ATA_PROT_DMA) &&
-	    (qc->tf.protocol != ATA_PROT_NCQ))
+	switch (tf->protocol) {
+	case ATA_PROT_DMA:
+	case ATA_PROT_NCQ:
+		break;	/* continue below */
+	case ATA_PROT_PIO:
+		mv_rw_multi_errata_sata24(qc);
+		return;
+	default:
 		return;
+	}
 
 	/* Fill in command request block
 	 */
-	if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+	if (!(tf->flags & ATA_TFLAG_WRITE))
 		flags |= CRQB_FLAG_READ;
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
 	flags |= qc->tag << CRQB_TAG_SHIFT;
@@ -1924,7 +1964,6 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
 	pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags);
 
 	cw = &pp->crqb[in_index].ata_cmd[0];
-	tf = &qc->tf;
 
 	/* Sadly, the CRQB cannot accomodate all registers--there are
 	 * only 11 bytes...so we must pick and choose required
@@ -1990,16 +2029,16 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
 	struct ata_port *ap = qc->ap;
 	struct mv_port_priv *pp = ap->private_data;
 	struct mv_crqb_iie *crqb;
-	struct ata_taskfile *tf;
+	struct ata_taskfile *tf = &qc->tf;
 	unsigned in_index;
 	u32 flags = 0;
 
-	if ((qc->tf.protocol != ATA_PROT_DMA) &&
-	    (qc->tf.protocol != ATA_PROT_NCQ))
+	if ((tf->protocol != ATA_PROT_DMA) &&
+	    (tf->protocol != ATA_PROT_NCQ))
 		return;
 
 	/* Fill in Gen IIE command request block */
-	if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+	if (!(tf->flags & ATA_TFLAG_WRITE))
 		flags |= CRQB_FLAG_READ;
 
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
@@ -2015,7 +2054,6 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
 	crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16);
 	crqb->flags = cpu_to_le32(flags);
 
-	tf = &qc->tf;
 	crqb->ata_cmd[0] = cpu_to_le32(
 			(tf->command << 16) |
 			(tf->feature << 24)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 98e8c50703b3..bdd43c7f432e 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -566,7 +566,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	static int printed_version;
 	unsigned int i;
 	int rc;
-	struct ata_host *host;
+	struct ata_host *host = NULL;
 	int board_id = (int) ent->driver_data;
 	const unsigned *bar_sizes;
 
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index be204308cc1b..9359613addc5 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1059,7 +1059,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
 		goto out;
 	}
 
-	err = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
 	if (err) {
 		dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
 		goto out;
diff --git a/drivers/base/base.h b/drivers/base/base.h
index ddc97496db4a..b528145a078f 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -115,7 +115,7 @@ extern int driver_probe_device(struct device_driver *drv, struct device *dev);
 static inline int driver_match_device(struct device_driver *drv,
 				      struct device *dev)
 {
-	return drv->bus->match && drv->bus->match(dev, drv);
+	return drv->bus->match ? drv->bus->match(dev, drv) : 1;
 }
 
 extern void sysdev_shutdown(void);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e73c92d13a23..4aa527b8a913 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -891,7 +891,8 @@ int device_add(struct device *dev)
 		set_dev_node(dev, dev_to_node(parent));
 
 	/* first, register with generic layer. */
-	error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev_name(dev));
+	/* we require the name to be set before, and pass NULL */
+	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
 	if (error)
 		goto Error;
 
@@ -1142,6 +1143,9 @@ int device_for_each_child(struct device *parent, void *data,
 	struct device *child;
 	int error = 0;
 
+	if (!parent->p)
+		return 0;
+
 	klist_iter_init(&parent->p->klist_children, &i);
 	while ((child = next_device(&i)) && !error)
 		error = fn(child, data);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index f17c3266a0e0..742cbe6b042b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -179,6 +179,7 @@ void wait_for_device_probe(void)
 	wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
 	async_synchronize_full();
 }
+EXPORT_SYMBOL_GPL(wait_for_device_probe);
 
 /**
  * driver_probe_device - attempt to bind device & driver together
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index d2198f64ad4e..b5b6c973a2e0 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -990,6 +990,8 @@ int __init platform_bus_init(void)
 {
 	int error;
 
+	early_platform_cleanup();
+
 	error = device_register(&platform_bus);
 	if (error)
 		return error;
@@ -1020,3 +1022,240 @@ u64 dma_get_required_mask(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(dma_get_required_mask);
 #endif
+
+static __initdata LIST_HEAD(early_platform_driver_list);
+static __initdata LIST_HEAD(early_platform_device_list);
+
+/**
+ * early_platform_driver_register
+ * @edrv: early_platform driver structure
+ * @buf: string passed from early_param()
+ */
+int __init early_platform_driver_register(struct early_platform_driver *epdrv,
+					  char *buf)
+{
+	unsigned long index;
+	int n;
+
+	/* Simply add the driver to the end of the global list.
+	 * Drivers will by default be put on the list in compiled-in order.
+	 */
+	if (!epdrv->list.next) {
+		INIT_LIST_HEAD(&epdrv->list);
+		list_add_tail(&epdrv->list, &early_platform_driver_list);
+	}
+
+	/* If the user has specified device then make sure the driver
+	 * gets prioritized. The driver of the last device specified on
+	 * command line will be put first on the list.
+	 */
+	n = strlen(epdrv->pdrv->driver.name);
+	if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
+		list_move(&epdrv->list, &early_platform_driver_list);
+
+		if (!strcmp(buf, epdrv->pdrv->driver.name))
+			epdrv->requested_id = -1;
+		else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10,
+							 &index) == 0)
+			epdrv->requested_id = index;
+		else
+			epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+	}
+
+	return 0;
+}
+
+/**
+ * early_platform_add_devices - add a numbers of early platform devices
+ * @devs: array of early platform devices to add
+ * @num: number of early platform devices in array
+ */
+void __init early_platform_add_devices(struct platform_device **devs, int num)
+{
+	struct device *dev;
+	int i;
+
+	/* simply add the devices to list */
+	for (i = 0; i < num; i++) {
+		dev = &devs[i]->dev;
+
+		if (!dev->devres_head.next) {
+			INIT_LIST_HEAD(&dev->devres_head);
+			list_add_tail(&dev->devres_head,
+				      &early_platform_device_list);
+		}
+	}
+}
+
+/**
+ * early_platform_driver_register_all
+ * @class_str: string to identify early platform driver class
+ */
+void __init early_platform_driver_register_all(char *class_str)
+{
+	/* The "class_str" parameter may or may not be present on the kernel
+	 * command line. If it is present then there may be more than one
+	 * matching parameter.
+	 *
+	 * Since we register our early platform drivers using early_param()
+	 * we need to make sure that they also get registered in the case
+	 * when the parameter is missing from the kernel command line.
+	 *
+	 * We use parse_early_options() to make sure the early_param() gets
+	 * called at least once. The early_param() may be called more than
+	 * once since the name of the preferred device may be specified on
+	 * the kernel command line. early_platform_driver_register() handles
+	 * this case for us.
+	 */
+	parse_early_options(class_str);
+}
+
+/**
+ * early_platform_match
+ * @edrv: early platform driver structure
+ * @id: id to match against
+ */
+static  __init struct platform_device *
+early_platform_match(struct early_platform_driver *epdrv, int id)
+{
+	struct platform_device *pd;
+
+	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+			if (pd->id == id)
+				return pd;
+
+	return NULL;
+}
+
+/**
+ * early_platform_left
+ * @edrv: early platform driver structure
+ * @id: return true if id or above exists
+ */
+static  __init int early_platform_left(struct early_platform_driver *epdrv,
+				       int id)
+{
+	struct platform_device *pd;
+
+	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+			if (pd->id >= id)
+				return 1;
+
+	return 0;
+}
+
+/**
+ * early_platform_driver_probe_id
+ * @class_str: string to identify early platform driver class
+ * @id: id to match against
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ */
+static int __init early_platform_driver_probe_id(char *class_str,
+						 int id,
+						 int nr_probe)
+{
+	struct early_platform_driver *epdrv;
+	struct platform_device *match;
+	int match_id;
+	int n = 0;
+	int left = 0;
+
+	list_for_each_entry(epdrv, &early_platform_driver_list, list) {
+		/* only use drivers matching our class_str */
+		if (strcmp(class_str, epdrv->class_str))
+			continue;
+
+		if (id == -2) {
+			match_id = epdrv->requested_id;
+			left = 1;
+
+		} else {
+			match_id = id;
+			left += early_platform_left(epdrv, id);
+
+			/* skip requested id */
+			switch (epdrv->requested_id) {
+			case EARLY_PLATFORM_ID_ERROR:
+			case EARLY_PLATFORM_ID_UNSET:
+				break;
+			default:
+				if (epdrv->requested_id == id)
+					match_id = EARLY_PLATFORM_ID_UNSET;
+			}
+		}
+
+		switch (match_id) {
+		case EARLY_PLATFORM_ID_ERROR:
+			pr_warning("%s: unable to parse %s parameter\n",
+				   class_str, epdrv->pdrv->driver.name);
+			/* fall-through */
+		case EARLY_PLATFORM_ID_UNSET:
+			match = NULL;
+			break;
+		default:
+			match = early_platform_match(epdrv, match_id);
+		}
+
+		if (match) {
+			if (epdrv->pdrv->probe(match))
+				pr_warning("%s: unable to probe %s early.\n",
+					   class_str, match->name);
+			else
+				n++;
+		}
+
+		if (n >= nr_probe)
+			break;
+	}
+
+	if (left)
+		return n;
+	else
+		return -ENODEV;
+}
+
+/**
+ * early_platform_driver_probe
+ * @class_str: string to identify early platform driver class
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ * @user_only: only probe user specified early platform devices
+ */
+int __init early_platform_driver_probe(char *class_str,
+				       int nr_probe,
+				       int user_only)
+{
+	int k, n, i;
+
+	n = 0;
+	for (i = -2; n < nr_probe; i++) {
+		k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
+
+		if (k < 0)
+			break;
+
+		n += k;
+
+		if (user_only)
+			break;
+	}
+
+	return n;
+}
+
+/**
+ * early_platform_cleanup - clean up early platform code
+ */
+void __init early_platform_cleanup(void)
+{
+	struct platform_device *pd, *pd2;
+
+	/* clean up the devres list used to chain devices */
+	list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
+				 dev.devres_head) {
+		list_del(&pd->dev.devres_head);
+		memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
+	}
+}
+
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index bdd4f5f45575..5f7e64ba87e5 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -275,8 +275,10 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,
 	if (rw == READ) {
 		copy_from_brd(mem + off, brd, sector, len);
 		flush_dcache_page(page);
-	} else
+	} else {
+		flush_dcache_page(page);
 		copy_to_brd(brd, mem + off, sector, len);
+	}
 	kunmap_atomic(mem, KM_USER0);
 
 out:
@@ -436,6 +438,7 @@ static struct brd_device *brd_alloc(int i)
 	if (!brd->brd_queue)
 		goto out_free_dev;
 	blk_queue_make_request(brd->brd_queue, brd_make_request);
+	blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL);
 	blk_queue_max_sectors(brd->brd_queue, 1024);
 	blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
 
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0ef6f08aa6ea..4d4d5e0d3fa6 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3505,7 +3505,7 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
 	/* The Inbound Post Queue only accepts 32-bit physical addresses for the
 	   CCISS commands, so they must be allocated from the lower 4GiB of
 	   memory. */
-	err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		iounmap(vaddr);
 		return -ENOMEM;
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 3c11f062a18c..baaa9e486e50 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -509,7 +509,6 @@ ok_to_write:
 	if (i > 0) {
 		SET_HANDLER(&write_intr);
 		outsw(HD_DATA, req->buffer, 256);
-		local_irq_enable();
 	} else {
 #if (HD_DELAY > 0)
 		last_req = read_timer();
@@ -541,8 +540,7 @@ static void hd_times_out(unsigned long dummy)
 	if (!CURRENT)
 		return;
 
-	disable_irq(HD_IRQ);
-	local_irq_enable();
+	spin_lock_irq(hd_queue->queue_lock);
 	reset = 1;
 	name = CURRENT->rq_disk->disk_name;
 	printk("%s: timeout\n", name);
@@ -552,9 +550,8 @@ static void hd_times_out(unsigned long dummy)
 #endif
 		end_request(CURRENT, 0);
 	}
-	local_irq_disable();
 	hd_request();
-	enable_irq(HD_IRQ);
+	spin_unlock_irq(hd_queue->queue_lock);
 }
 
 static int do_special_op(struct hd_i_struct *disk, struct request *req)
@@ -592,7 +589,6 @@ static void hd_request(void)
 		return;
 repeat:
 	del_timer(&device_timer);
-	local_irq_enable();
 
 	req = CURRENT;
 	if (!req) {
@@ -601,7 +597,6 @@ repeat:
 	}
 
 	if (reset) {
-		local_irq_disable();
 		reset_hd();
 		return;
 	}
@@ -660,9 +655,7 @@ repeat:
 
 static void do_hd_request(struct request_queue *q)
 {
-	disable_irq(HD_IRQ);
 	hd_request();
-	enable_irq(HD_IRQ);
 }
 
 static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -684,12 +677,16 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id)
 {
 	void (*handler)(void) = do_hd;
 
+	spin_lock(hd_queue->queue_lock);
+
 	do_hd = NULL;
 	del_timer(&device_timer);
 	if (!handler)
 		handler = unexpected_hd_interrupt;
 	handler();
-	local_irq_enable();
+
+	spin_unlock(hd_queue->queue_lock);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index fb39d9aa3cdc..f3898353d0a8 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -79,7 +79,7 @@ static void mg_dump_status(const char *msg, unsigned int stat,
 			if (host->breq) {
 				req = elv_next_request(host->breq);
 				if (req)
-					printk(", sector=%ld", req->sector);
+					printk(", sector=%u", (u32)req->sector);
 			}
 
 		}
@@ -160,11 +160,16 @@ static irqreturn_t mg_irq(int irq, void *dev_id)
 	struct mg_host *host = dev_id;
 	void (*handler)(struct mg_host *) = host->mg_do_intr;
 
-	host->mg_do_intr = 0;
+	spin_lock(&host->lock);
+
+	host->mg_do_intr = NULL;
 	del_timer(&host->timer);
 	if (!handler)
 		handler = mg_unexpected_intr;
 	handler(host);
+
+	spin_unlock(&host->lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -319,7 +324,7 @@ static void mg_read(struct request *req)
 
 	remains = req->nr_sectors;
 
-	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, 0) !=
+	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
 			MG_ERR_NONE)
 		mg_bad_rw_intr(host);
 
@@ -363,7 +368,7 @@ static void mg_write(struct request *req)
 
 	remains = req->nr_sectors;
 
-	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, 0) !=
+	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
 			MG_ERR_NONE) {
 		mg_bad_rw_intr(host);
 		return;
@@ -521,9 +526,11 @@ void mg_times_out(unsigned long data)
 	char *name;
 	struct request *req;
 
+	spin_lock_irq(&host->lock);
+
 	req = elv_next_request(host->breq);
 	if (!req)
-		return;
+		goto out_unlock;
 
 	host->mg_do_intr = NULL;
 
@@ -534,6 +541,8 @@ void mg_times_out(unsigned long data)
 	mg_bad_rw_intr(host);
 
 	mg_request(host->breq);
+out_unlock:
+	spin_unlock_irq(&host->lock);
 }
 
 static void mg_request_poll(struct request_queue *q)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 69b7f8e77596..689cd27ac890 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
 	struct urb *urb = &sc->work_urb;
 	struct bulk_cs_wrap *bcs;
+	int endp;
 	int len;
 	int rc;
 
@@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		return;
 	}
 
+	endp = usb_pipeendpoint(sc->last_pipe);
+	if (usb_pipein(sc->last_pipe))
+		endp |= USB_DIR_IN;
+
 	if (cmd->state == UB_CMDST_CLEAR) {
 		if (urb->status == -EPIPE) {
 			/*
@@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_sense(sc, cmd);
 
@@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_stat(sc, cmd);
 
@@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_stat_counted(sc, cmd);
 
@@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe)
 	del_timer_sync(&timer);
 	usb_kill_urb(&sc->work_urb);
 
-	/* reset the endpoint toggle */
-	usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);
+	usb_reset_endpoint(sc->dev, endp);
 
 	return 0;
 }
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 9744d59a69f2..858c34dd032d 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -906,6 +906,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev,
 		goto failed_alloc;
 
 	blk_queue_make_request(card->queue, mm_make_request);
+	card->queue->queue_lock = &card->lock;
 	card->queue->queuedata = card;
 	card->queue->unplug_fn = mm_unplug_device;
 
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 6cccdc3f5220..4aecf5dc6a93 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -563,7 +563,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
 	case ACE_FSM_STATE_IDENTIFY_PREPARE:
 		/* Send identify command */
 		ace->fsm_task = ACE_TASK_IDENTIFY;
-		ace->data_ptr = &ace->cf_id;
+		ace->data_ptr = ace->cf_id;
 		ace->data_count = ACE_BUF_PER_SECTOR;
 		ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY);
 
@@ -608,8 +608,8 @@ static void ace_fsm_dostate(struct ace_device *ace)
 		break;
 
 	case ACE_FSM_STATE_IDENTIFY_COMPLETE:
-		ace_fix_driveid(&ace->cf_id[0]);
-		ace_dump_mem(&ace->cf_id, 512);	/* Debug: Dump out disk ID */
+		ace_fix_driveid(ace->cf_id);
+		ace_dump_mem(ace->cf_id, 512);	/* Debug: Dump out disk ID */
 
 		if (ace->data_result) {
 			/* Error occured, disable the disk */
@@ -622,9 +622,9 @@ static void ace_fsm_dostate(struct ace_device *ace)
 
 			/* Record disk parameters */
 			set_capacity(ace->gd,
-				ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
+				ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
 			dev_info(ace->dev, "capacity: %i sectors\n",
-				ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
+				ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
 		}
 
 		/* We're done, drop to IDLE state and notify waiters */
@@ -923,7 +923,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
 static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	struct ace_device *ace = bdev->bd_disk->private_data;
-	u16 *cf_id = &ace->cf_id[0];
+	u16 *cf_id = ace->cf_id;
 
 	dev_dbg(ace->dev, "ace_getgeo()\n");
 
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 10d6cbd7c05e..2224b762b7fb 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *m
 	int i, ret = -ENOMEM;
 
 	for (i = 0; i < num_pages; i++) {
-		page = alloc_page(GFP_KERNEL | GFP_DMA32);
+		page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
 		/* agp_free_memory() needs gart address */
 		if (page == NULL)
 			goto out;
@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
 {
 	struct page * page;
 
-	page = alloc_page(GFP_KERNEL | GFP_DMA32);
+	page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
 	if (page == NULL)
 		return NULL;
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 9d9490e22e07..3686912427ba 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -2131,6 +2131,8 @@ static const struct intel_driver_description {
 	{ PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M",
 		&intel_845_driver, &intel_830_driver },
 	{ PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, 0, "854",
+		&intel_845_driver, &intel_830_driver },
 	{ PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL },
 	{ PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM",
 		&intel_845_driver, &intel_830_driver },
@@ -2355,6 +2357,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
 	ID(PCI_DEVICE_ID_INTEL_82845_HB),
 	ID(PCI_DEVICE_ID_INTEL_82845G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82850_HB),
+	ID(PCI_DEVICE_ID_INTEL_82854_HB),
 	ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82860_HB),
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 50dfa3bc71ce..340ba4f9dc54 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -72,7 +72,7 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
 #ifdef CONFIG_IA64
 static void __iomem *hpet_mctr;
 
-static cycle_t read_hpet(void)
+static cycle_t read_hpet(struct clocksource *cs)
 {
 	return (cycle_t)read_counter((void __iomem *)hpet_mctr);
 }
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index d0e563e4fc39..86e83f883139 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -37,9 +37,9 @@ static void random_recv_done(struct virtqueue *vq)
 {
 	int len;
 
-	/* We never get spurious callbacks. */
+	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
 	if (!vq->vq_ops->get_buf(vq, &len))
-		BUG();
+		return;
 
 	data_left = len / sizeof(random_data[0]);
 	complete(&have_data);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index e93fc8d22fb2..aa83a0865ec1 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -285,6 +285,11 @@ enum ipmi_stat_indexes {
 	/* Events that were received with the proper format. */
 	IPMI_STAT_events,
 
+	/* Retransmissions on IPMB that failed. */
+	IPMI_STAT_dropped_rexmit_ipmb_commands,
+
+	/* Retransmissions on LAN that failed. */
+	IPMI_STAT_dropped_rexmit_lan_commands,
 
 	/* This *must* remain last, add new values above this. */
 	IPMI_NUM_STATS
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex);
 #define ipmi_get_stat(intf, stat) \
 	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
 
+static int is_lan_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_LAN_ADDR_TYPE;
+}
+
+static int is_ipmb_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
+}
+
+static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
+}
 
 static void free_recv_msg_list(struct list_head *q)
 {
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
 		return (smi_addr1->lun == smi_addr2->lun);
 	}
 
-	if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
 		struct ipmi_ipmb_addr *ipmb_addr1
 		    = (struct ipmi_ipmb_addr *) addr1;
 		struct ipmi_ipmb_addr *ipmb_addr2
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
 			&& (ipmb_addr1->lun == ipmb_addr2->lun));
 	}
 
-	if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr1)) {
 		struct ipmi_lan_addr *lan_addr1
 			= (struct ipmi_lan_addr *) addr1;
 		struct ipmi_lan_addr *lan_addr2
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
 	    || (addr->channel < 0))
 		return -EINVAL;
 
-	if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		if (len < sizeof(struct ipmi_ipmb_addr))
 			return -EINVAL;
 		return 0;
 	}
 
-	if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr)) {
 		if (len < sizeof(struct ipmi_lan_addr))
 			return -EINVAL;
 		return 0;
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t          user,
 			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
 		smi_msg->data_size = msg->data_len + 2;
 		ipmi_inc_stat(intf, sent_local_commands);
-	} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-		   || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	} else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		struct ipmi_ipmb_addr *ipmb_addr;
 		unsigned char         ipmb_seq;
 		long                  seqid;
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t          user,
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
-			ipmi_inc_stat(intf, sent_ipmb_commands);
-
 			/*
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t          user,
 				goto out_err;
 			}
 
+			ipmi_inc_stat(intf, sent_ipmb_commands);
+
 			/*
 			 * Store the sequence number in the message,
 			 * so that when the send message response
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t          user,
 			 */
 			spin_unlock_irqrestore(&(intf->seq_lock), flags);
 		}
-	} else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	} else if (is_lan_addr(addr)) {
 		struct ipmi_lan_addr  *lan_addr;
 		unsigned char         ipmb_seq;
 		long                  seqid;
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t          user,
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
-			ipmi_inc_stat(intf, sent_lan_commands);
-
 			/*
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t          user,
 				goto out_err;
 			}
 
+			ipmi_inc_stat(intf, sent_lan_commands);
+
 			/*
 			 * Store the sequence number in the message,
 			 * so that when the send message response
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
 		       ipmi_get_stat(intf, invalid_events));
 	out += sprintf(out, "events:                      %u\n",
 		       ipmi_get_stat(intf, events));
+	out += sprintf(out, "failed rexmit LAN msgs:      %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_lan_commands));
+	out += sprintf(out, "failed rexmit IPMB msgs:     %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
 
 	return (out - ((char *) page));
 }
@@ -3264,6 +3284,114 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
 	return rv;
 }
 
+/*
+ * This routine will handle "Get Message" command responses with
+ * channels that use an OEM Medium. The message format belongs to
+ * the OEM.  See IPMI 2.0 specification, Chapter 6 and
+ * Chapter 22, sections 22.6 and 22.24 for more details.
+ */
+static int handle_oem_get_msg_cmd(ipmi_smi_t          intf,
+				  struct ipmi_smi_msg *msg)
+{
+	struct cmd_rcvr       *rcvr;
+	int                   rv = 0;
+	unsigned char         netfn;
+	unsigned char         cmd;
+	unsigned char         chan;
+	ipmi_user_t           user = NULL;
+	struct ipmi_system_interface_addr *smi_addr;
+	struct ipmi_recv_msg  *recv_msg;
+
+	/*
+	 * We expect the OEM SW to perform error checking
+	 * so we just do some basic sanity checks
+	 */
+	if (msg->rsp_size < 4) {
+		/* Message not big enough, just ignore it. */
+		ipmi_inc_stat(intf, invalid_commands);
+		return 0;
+	}
+
+	if (msg->rsp[2] != 0) {
+		/* An error getting the response, just ignore it. */
+		return 0;
+	}
+
+	/*
+	 * This is an OEM Message so the OEM needs to know how
+	 * handle the message. We do no interpretation.
+	 */
+	netfn = msg->rsp[0] >> 2;
+	cmd = msg->rsp[1];
+	chan = msg->rsp[3] & 0xf;
+
+	rcu_read_lock();
+	rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
+	if (rcvr) {
+		user = rcvr->user;
+		kref_get(&user->refcount);
+	} else
+		user = NULL;
+	rcu_read_unlock();
+
+	if (user == NULL) {
+		/* We didn't find a user, just give up. */
+		ipmi_inc_stat(intf, unhandled_commands);
+
+		/*
+		 * Don't do anything with these messages, just allow
+		 * them to be freed.
+		 */
+
+		rv = 0;
+	} else {
+		/* Deliver the message to the user. */
+		ipmi_inc_stat(intf, handled_commands);
+
+		recv_msg = ipmi_alloc_recv_msg();
+		if (!recv_msg) {
+			/*
+			 * We couldn't allocate memory for the
+			 * message, so requeue it for handling
+			 * later.
+			 */
+			rv = 1;
+			kref_put(&user->refcount, free_user);
+		} else {
+			/*
+			 * OEM Messages are expected to be delivered via
+			 * the system interface to SMS software.  We might
+			 * need to visit this again depending on OEM
+			 * requirements
+			 */
+			smi_addr = ((struct ipmi_system_interface_addr *)
+				    &(recv_msg->addr));
+			smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+			smi_addr->channel = IPMI_BMC_CHANNEL;
+			smi_addr->lun = msg->rsp[0] & 3;
+
+			recv_msg->user = user;
+			recv_msg->user_msg_data = NULL;
+			recv_msg->recv_type = IPMI_OEM_RECV_TYPE;
+			recv_msg->msg.netfn = msg->rsp[0] >> 2;
+			recv_msg->msg.cmd = msg->rsp[1];
+			recv_msg->msg.data = recv_msg->msg_data;
+
+			/*
+			 * The message starts at byte 4 which follows the
+			 * the Channel Byte in the "GET MESSAGE" command
+			 */
+			recv_msg->msg.data_len = msg->rsp_size - 4;
+			memcpy(recv_msg->msg_data,
+			       &(msg->rsp[4]),
+			       msg->rsp_size - 4);
+			deliver_response(recv_msg);
+		}
+	}
+
+	return rv;
+}
+
 static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
 				     struct ipmi_smi_msg  *msg)
 {
@@ -3519,6 +3647,17 @@ static int handle_new_recv_msg(ipmi_smi_t          intf,
 			goto out;
 		}
 
+		/*
+		** We need to make sure the channels have been initialized.
+		** The channel_handler routine will set the "curr_channel"
+		** equal to or greater than IPMI_MAX_CHANNELS when all the
+		** channels for this interface have been initialized.
+		*/
+		if (intf->curr_channel < IPMI_MAX_CHANNELS) {
+			requeue = 1;     /* Just put the message back for now */
+			goto out;
+		}
+
 		switch (intf->channels[chan].medium) {
 		case IPMI_CHANNEL_MEDIUM_IPMB:
 			if (msg->rsp[4] & 0x04) {
@@ -3554,11 +3693,20 @@ static int handle_new_recv_msg(ipmi_smi_t          intf,
 			break;
 
 		default:
-			/*
-			 * We don't handle the channel type, so just
-			 * free the message.
-			 */
-			requeue = 0;
+			/* Check for OEM Channels.  Clients had better
+			   register for these commands. */
+			if ((intf->channels[chan].medium
+			     >= IPMI_CHANNEL_MEDIUM_OEM_MIN)
+			    && (intf->channels[chan].medium
+				<= IPMI_CHANNEL_MEDIUM_OEM_MAX)) {
+				requeue = handle_oem_get_msg_cmd(intf, msg);
+			} else {
+				/*
+				 * We don't handle the channel type, so just
+				 * free the message.
+				 */
+				requeue = 0;
+			}
 		}
 
 	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
@@ -3730,7 +3878,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 		list_add_tail(&msg->link, timeouts);
 		if (ent->broadcast)
 			ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
-		else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+		else if (is_lan_addr(&ent->recv_msg->addr))
 			ipmi_inc_stat(intf, timed_out_lan_commands);
 		else
 			ipmi_inc_stat(intf, timed_out_ipmb_commands);
@@ -3744,15 +3892,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 		 */
 		ent->timeout = MAX_MSG_TIMEOUT;
 		ent->retries_left--;
-		if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
-			ipmi_inc_stat(intf, retransmitted_lan_commands);
-		else
-			ipmi_inc_stat(intf, retransmitted_ipmb_commands);
-
 		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
 					    ent->seqid);
-		if (!smi_msg)
+		if (!smi_msg) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_ipmb_commands);
 			return;
+		}
 
 		spin_unlock_irqrestore(&intf->seq_lock, *flags);
 
@@ -3764,10 +3914,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 		 * resent.
 		 */
 		handlers = intf->handlers;
-		if (handlers)
+		if (handlers) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      retransmitted_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      retransmitted_ipmb_commands);
+
 			intf->handlers->sender(intf->send_info,
 					       smi_msg, 0);
-		else
+		} else
 			ipmi_free_smi_msg(smi_msg);
 
 		spin_lock_irqsave(&intf->seq_lock, *flags);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index e58ea4cd55ce..259644646b82 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -82,12 +82,6 @@
 #define SI_SHORT_TIMEOUT_USEC  250 /* .25ms when the SM request a
 				      short timeout */
 
-/* Bit for BMC global enables. */
-#define IPMI_BMC_RCV_MSG_INTR     0x01
-#define IPMI_BMC_EVT_MSG_INTR     0x02
-#define IPMI_BMC_EVT_MSG_BUFF     0x04
-#define IPMI_BMC_SYS_LOG          0x08
-
 enum si_intf_state {
 	SI_NORMAL,
 	SI_GETTING_FLAGS,
@@ -220,6 +214,9 @@ struct smi_info {
 			     OEM2_DATA_AVAIL)
 	unsigned char       msg_flags;
 
+	/* Does the BMC have an event buffer? */
+	char		    has_event_buffer;
+
 	/*
 	 * If set to true, this will request events the next time the
 	 * state machine is idle.
@@ -968,7 +965,8 @@ static void request_events(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
 
-	if (atomic_read(&smi_info->stop_operation))
+	if (atomic_read(&smi_info->stop_operation) ||
+				!smi_info->has_event_buffer)
 		return;
 
 	atomic_set(&smi_info->req_events, 1);
@@ -2407,26 +2405,9 @@ static struct of_platform_driver ipmi_of_platform_driver = {
 };
 #endif /* CONFIG_PPC_OF */
 
-
-static int try_get_dev_id(struct smi_info *smi_info)
+static int wait_for_msg_done(struct smi_info *smi_info)
 {
-	unsigned char         msg[2];
-	unsigned char         *resp;
-	unsigned long         resp_len;
 	enum si_sm_result     smi_result;
-	int                   rv = 0;
-
-	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
-	if (!resp)
-		return -ENOMEM;
-
-	/*
-	 * Do a Get Device ID command, since it comes back with some
-	 * useful info.
-	 */
-	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
-	msg[1] = IPMI_GET_DEVICE_ID_CMD;
-	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
 
 	smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
 	for (;;) {
@@ -2441,16 +2422,39 @@ static int try_get_dev_id(struct smi_info *smi_info)
 		} else
 			break;
 	}
-	if (smi_result == SI_SM_HOSED) {
+	if (smi_result == SI_SM_HOSED)
 		/*
 		 * We couldn't get the state machine to run, so whatever's at
 		 * the port is probably not an IPMI SMI interface.
 		 */
-		rv = -ENODEV;
+		return -ENODEV;
+
+	return 0;
+}
+
+static int try_get_dev_id(struct smi_info *smi_info)
+{
+	unsigned char         msg[2];
+	unsigned char         *resp;
+	unsigned long         resp_len;
+	int                   rv = 0;
+
+	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	/*
+	 * Do a Get Device ID command, since it comes back with some
+	 * useful info.
+	 */
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_GET_DEVICE_ID_CMD;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv)
 		goto out;
-	}
 
-	/* Otherwise, we got some data. */
 	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
 						  resp, IPMI_MAX_MSG_LENGTH);
 
@@ -2462,6 +2466,88 @@ static int try_get_dev_id(struct smi_info *smi_info)
 	return rv;
 }
 
+static int try_enable_event_buffer(struct smi_info *smi_info)
+{
+	unsigned char         msg[3];
+	unsigned char         *resp;
+	unsigned long         resp_len;
+	int                   rv = 0;
+
+	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv) {
+		printk(KERN_WARNING
+		       "ipmi_si: Error getting response from get global,"
+		       " enables command, the event buffer is not"
+		       " enabled.\n");
+		goto out;
+	}
+
+	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+						  resp, IPMI_MAX_MSG_LENGTH);
+
+	if (resp_len < 4 ||
+			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+			resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD   ||
+			resp[2] != 0) {
+		printk(KERN_WARNING
+		       "ipmi_si: Invalid return from get global"
+		       " enables command, cannot enable the event"
+		       " buffer.\n");
+		rv = -EINVAL;
+		goto out;
+	}
+
+	if (resp[3] & IPMI_BMC_EVT_MSG_BUFF)
+		/* buffer is already enabled, nothing to do. */
+		goto out;
+
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+	msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv) {
+		printk(KERN_WARNING
+		       "ipmi_si: Error getting response from set global,"
+		       " enables command, the event buffer is not"
+		       " enabled.\n");
+		goto out;
+	}
+
+	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+						  resp, IPMI_MAX_MSG_LENGTH);
+
+	if (resp_len < 3 ||
+			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+			resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
+		printk(KERN_WARNING
+		       "ipmi_si: Invalid return from get global,"
+		       "enables command, not enable the event"
+		       " buffer.\n");
+		rv = -EINVAL;
+		goto out;
+	}
+
+	if (resp[2] != 0)
+		/*
+		 * An error when setting the event buffer bit means
+		 * that the event buffer is not supported.
+		 */
+		rv = -ENOENT;
+ out:
+	kfree(resp);
+	return rv;
+}
+
 static int type_file_read_proc(char *page, char **start, off_t off,
 			       int count, int *eof, void *data)
 {
@@ -2847,6 +2933,10 @@ static int try_smi_init(struct smi_info *new_smi)
 	new_smi->intf_num = smi_num;
 	smi_num++;
 
+	rv = try_enable_event_buffer(new_smi);
+	if (rv == 0)
+		new_smi->has_event_buffer = 1;
+
 	/*
 	 * Start clearing the flags before we enable interrupts or the
 	 * timer to avoid racing with the timer.
@@ -2863,7 +2953,7 @@ static int try_smi_init(struct smi_info *new_smi)
 		 */
 		new_smi->pdev = platform_device_alloc("ipmi_si",
 						      new_smi->intf_num);
-		if (rv) {
+		if (!new_smi->pdev) {
 			printk(KERN_ERR
 			       "ipmi_si_intf:"
 			       " Unable to allocate platform device\n");
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 3586b3b3df3f..8f05c38c2f06 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -301,33 +301,7 @@ static inline int private_mapping_ok(struct vm_area_struct *vma)
 }
 #endif
 
-void __attribute__((weak))
-map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
-	/* nothing. architectures can override. */
-}
-
-void __attribute__((weak))
-unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
-	/* nothing. architectures can override. */
-}
-
-static void mmap_mem_open(struct vm_area_struct *vma)
-{
-	map_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
-			vma->vm_page_prot);
-}
-
-static void mmap_mem_close(struct vm_area_struct *vma)
-{
-	unmap_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
-			vma->vm_page_prot);
-}
-
 static struct vm_operations_struct mmap_mem_ops = {
-	.open  = mmap_mem_open,
-	.close = mmap_mem_close,
 #ifdef CONFIG_HAVE_IOREMAP_PROT
 	.access = generic_access_phys
 #endif
@@ -362,7 +336,6 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 			    vma->vm_pgoff,
 			    size,
 			    vma->vm_page_prot)) {
-		unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot);
 		return -EAGAIN;
 	}
 	return 0;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 0540d5de2c17..aed2b2936ecf 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -36,7 +36,6 @@
 #include <linux/vt_kern.h>
 #include <linux/workqueue.h>
 #include <linux/kexec.h>
-#include <linux/interrupt.h>
 #include <linux/hrtimer.h>
 #include <linux/oom.h>
 
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 2c1d133819b5..08151d4de489 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2274,7 +2274,7 @@ rescan_last_byte:
 				    continue; /* nothing to display */
 				}
 				/* Glyph not found */
-				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) && c < 128) && !(c & ~charmask)) {
+				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
 				    /* In legacy mode use the glyph we get by a 1:1 mapping.
 				       This would make absolutely no sense with Unicode in mind,
 				       but do this for ASCII characters since a font may lack
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index ee19b6e8fcb4..40bd8c61c7d7 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -57,7 +57,7 @@ u32 acpi_pm_read_verified(void)
 	return v2;
 }
 
-static cycle_t acpi_pm_read(void)
+static cycle_t acpi_pm_read(struct clocksource *cs)
 {
 	return (cycle_t)read_pmtmr();
 }
@@ -83,7 +83,7 @@ static int __init acpi_pm_good_setup(char *__str)
 }
 __setup("acpi_pm_good", acpi_pm_good_setup);
 
-static cycle_t acpi_pm_read_slow(void)
+static cycle_t acpi_pm_read_slow(struct clocksource *cs)
 {
 	return (cycle_t)acpi_pm_read_verified();
 }
@@ -156,9 +156,9 @@ static int verify_pmtmr_rate(void)
 	unsigned long count, delta;
 
 	mach_prepare_counter();
-	value1 = clocksource_acpi_pm.read();
+	value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 	mach_countup(&count);
-	value2 = clocksource_acpi_pm.read();
+	value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 	delta = (value2 - value1) & ACPI_PM_MASK;
 
 	/* Check that the PMTMR delta is within 5% of what we expect */
@@ -195,9 +195,9 @@ static int __init init_acpi_pm_clocksource(void)
 	/* "verify" this timing source: */
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 		udelay(100 * j);
-		value1 = clocksource_acpi_pm.read();
+		value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 		for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
-			value2 = clocksource_acpi_pm.read();
+			value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 			if (value2 == value1)
 				continue;
 			if (value2 > value1)
diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c
index 8615059a8729..64e528e8bfa6 100644
--- a/drivers/clocksource/cyclone.c
+++ b/drivers/clocksource/cyclone.c
@@ -19,7 +19,7 @@
 int use_cyclone = 0;
 static void __iomem *cyclone_ptr;
 
-static cycle_t read_cyclone(void)
+static cycle_t read_cyclone(struct clocksource *cs)
 {
 	return (cycle_t)readl(cyclone_ptr);
 }
diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c
index b92da677aa5d..27f4d9637b62 100644
--- a/drivers/clocksource/scx200_hrt.c
+++ b/drivers/clocksource/scx200_hrt.c
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)");
 /* The base timer frequency, * 27 if selected */
 #define HRT_FREQ   1000000
 
-static cycle_t read_hrt(void)
+static cycle_t read_hrt(struct clocksource *cs)
 {
 	/* Read the timer value */
 	return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 254f1064d973..01b886e68822 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -39,7 +39,7 @@
 
 static void __iomem *tcaddr;
 
-static cycle_t tc_get_cycles(void)
+static cycle_t tc_get_cycles(struct clocksource *cs)
 {
 	unsigned long	flags;
 	u32		lower, upper;
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 28f2c3f959b5..6ad95c8d6363 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -767,11 +767,19 @@ static inline void pci_write_bits16(struct pci_dev *pdev, int offset,
 	pci_write_config_word(pdev, offset, value);
 }
 
-/* write all or some bits in a dword-register*/
+/*
+ * pci_write_bits32
+ *
+ * edac local routine to do pci_write_config_dword, but adds
+ * a mask parameter. If mask is all ones, ignore the mask.
+ * Otherwise utilize the mask to isolate specified bits
+ *
+ * write all or some bits in a dword-register
+ */
 static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
 				    u32 value, u32 mask)
 {
-	if (mask != 0xffff) {
+	if (mask != 0xffffffff) {
 		u32 buf;
 
 		pci_read_config_dword(pdev, offset, &buf);
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index ca9113e1c106..a7d2c717d033 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -389,7 +389,7 @@ static void del_edac_device_from_global_list(struct edac_device_ctl_info
  */
 static void edac_device_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work);
 
 	mutex_lock(&device_ctls_mutex);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 25d66940b4fa..335b7ebdb11c 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -260,7 +260,7 @@ static int edac_mc_assert_error_check_and_clear(void)
  */
 static void edac_mc_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work);
 
 	mutex_lock(&mem_ctls_mutex);
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index 5b150aea703a..30b585b1d60b 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(edac_pci_find);
  */
 static void edac_pci_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work);
 	int msec;
 	unsigned long delay;
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 4637a4a757df..7c8c2d72916f 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -674,7 +674,7 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
 	int row_index;
 
 	err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
-	if (err_detect)
+	if (!err_detect)
 		return;
 
 	mpc85xx_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n",
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index d009661781bc..ef878615c49f 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -159,6 +159,9 @@ void drm_master_put(struct drm_master **master)
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
+	if (file_priv->is_master)
+		return 0;
+
 	if (file_priv->minor->master && file_priv->minor->master != file_priv->master)
 		return -EINVAL;
 
@@ -169,6 +172,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 	    file_priv->minor->master != file_priv->master) {
 		mutex_lock(&dev->struct_mutex);
 		file_priv->minor->master = drm_master_get(file_priv->master);
+		file_priv->is_master = 1;
 		mutex_unlock(&dev->struct_mutex);
 	}
 
@@ -178,10 +182,15 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv)
 {
-	if (!file_priv->master)
+	if (!file_priv->is_master)
 		return -EINVAL;
+
+	if (!file_priv->minor->master)
+		return -EINVAL;
+
 	mutex_lock(&dev->struct_mutex);
 	drm_master_put(&file_priv->minor->master);
+	file_priv->is_master = 0;
 	mutex_unlock(&dev->struct_mutex);
 	return 0;
 }
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index bc0c6849360c..022876ae34f0 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -132,6 +132,7 @@ void drm_sysfs_destroy(void)
  */
 static void drm_sysfs_device_release(struct device *dev)
 {
+	memset(dev, 0, sizeof(struct device));
 	return;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a000cf028826..051134c56aef 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -713,18 +713,18 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
 	mutex_unlock(&dev->struct_mutex);
 	if (ret) {
 		DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
-		goto fail_batch_free;
+		goto fail_clip_free;
 	}
 
 	if (sarea_priv)
 		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
 
-fail_batch_free:
-	drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
 fail_clip_free:
 	drm_free(cliprects,
 		 cmdbuf->num_cliprects * sizeof(struct drm_clip_rect),
 		 DRM_MEM_DRIVER);
+fail_batch_free:
+	drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
 
 	return ret;
 }
@@ -1232,7 +1232,7 @@ int i915_driver_unload(struct drm_device *dev)
 	if (dev_priv->regs != NULL)
 		iounmap(dev_priv->regs);
 
-	intel_opregion_free(dev);
+	intel_opregion_free(dev, 0);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		intel_modeset_cleanup(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6503e2210f65..98560e1e899a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -77,7 +77,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
 		drm_irq_uninstall(dev);
 	}
 
-	intel_opregion_free(dev);
+	intel_opregion_free(dev, 1);
 
 	if (state.event == PM_EVENT_SUSPEND) {
 		/* Shut down the device */
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3750d8003048..25065923b8a8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -446,6 +446,9 @@ struct drm_i915_gem_object {
 	uint32_t tiling_mode;
 	uint32_t stride;
 
+	/** Record of address bit 17 of each page at last unbind. */
+	long *bit_17;
+
 	/** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
 	uint32_t agp_type;
 
@@ -635,9 +638,13 @@ int i915_gem_attach_phys_object(struct drm_device *dev,
 void i915_gem_detach_phys_object(struct drm_device *dev,
 				 struct drm_gem_object *obj);
 void i915_gem_free_all_phys_object(struct drm_device *dev);
+int i915_gem_object_get_pages(struct drm_gem_object *obj);
+void i915_gem_object_put_pages(struct drm_gem_object *obj);
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
+void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
+void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
 
 /* i915_gem_debug.c */
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
@@ -667,12 +674,12 @@ extern int i915_restore_state(struct drm_device *dev);
 #ifdef CONFIG_ACPI
 /* i915_opregion.c */
 extern int intel_opregion_init(struct drm_device *dev, int resume);
-extern void intel_opregion_free(struct drm_device *dev);
+extern void intel_opregion_free(struct drm_device *dev, int suspend);
 extern void opregion_asle_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
 static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
-static inline void intel_opregion_free(struct drm_device *dev) { return; }
+static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
@@ -780,7 +787,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 		       (dev)->pci_device == 0x2A42 || \
 		       (dev)->pci_device == 0x2E02 || \
 		       (dev)->pci_device == 0x2E12 || \
-		       (dev)->pci_device == 0x2E22)
+		       (dev)->pci_device == 0x2E22 || \
+		       (dev)->pci_device == 0x2E32)
 
 #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
 
@@ -789,6 +797,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 #define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
 		     (dev)->pci_device == 0x2E12 || \
 		     (dev)->pci_device == 0x2E22 || \
+		     (dev)->pci_device == 0x2E32 || \
 		     IS_GM45(dev))
 
 #define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1449b452cc63..ee896d91c5bc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -43,8 +43,6 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
 						     uint64_t offset,
 						     uint64_t size);
 static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj);
-static int i915_gem_object_get_pages(struct drm_gem_object *obj);
-static void i915_gem_object_put_pages(struct drm_gem_object *obj);
 static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
 static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
 					   unsigned alignment);
@@ -143,15 +141,27 @@ fast_shmem_read(struct page **pages,
 		int length)
 {
 	char __iomem *vaddr;
-	int ret;
+	int unwritten;
 
 	vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
 	if (vaddr == NULL)
 		return -ENOMEM;
-	ret = __copy_to_user_inatomic(data, vaddr + page_offset, length);
+	unwritten = __copy_to_user_inatomic(data, vaddr + page_offset, length);
 	kunmap_atomic(vaddr, KM_USER0);
 
-	return ret;
+	if (unwritten)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
+{
+	drm_i915_private_t *dev_priv = obj->dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
+		obj_priv->tiling_mode != I915_TILING_NONE;
 }
 
 static inline int
@@ -181,6 +191,64 @@ slow_shmem_copy(struct page *dst_page,
 	return 0;
 }
 
+static inline int
+slow_shmem_bit17_copy(struct page *gpu_page,
+		      int gpu_offset,
+		      struct page *cpu_page,
+		      int cpu_offset,
+		      int length,
+		      int is_read)
+{
+	char *gpu_vaddr, *cpu_vaddr;
+
+	/* Use the unswizzled path if this page isn't affected. */
+	if ((page_to_phys(gpu_page) & (1 << 17)) == 0) {
+		if (is_read)
+			return slow_shmem_copy(cpu_page, cpu_offset,
+					       gpu_page, gpu_offset, length);
+		else
+			return slow_shmem_copy(gpu_page, gpu_offset,
+					       cpu_page, cpu_offset, length);
+	}
+
+	gpu_vaddr = kmap_atomic(gpu_page, KM_USER0);
+	if (gpu_vaddr == NULL)
+		return -ENOMEM;
+
+	cpu_vaddr = kmap_atomic(cpu_page, KM_USER1);
+	if (cpu_vaddr == NULL) {
+		kunmap_atomic(gpu_vaddr, KM_USER0);
+		return -ENOMEM;
+	}
+
+	/* Copy the data, XORing A6 with A17 (1). The user already knows he's
+	 * XORing with the other bits (A9 for Y, A9 and A10 for X)
+	 */
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		if (is_read) {
+			memcpy(cpu_vaddr + cpu_offset,
+			       gpu_vaddr + swizzled_gpu_offset,
+			       this_length);
+		} else {
+			memcpy(gpu_vaddr + swizzled_gpu_offset,
+			       cpu_vaddr + cpu_offset,
+			       this_length);
+		}
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	kunmap_atomic(cpu_vaddr, KM_USER1);
+	kunmap_atomic(gpu_vaddr, KM_USER0);
+
+	return 0;
+}
+
 /**
  * This is the fast shmem pread path, which attempts to copy_from_user directly
  * from the backing pages of the object to the user's address space.  On a
@@ -269,6 +337,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
 	int page_length;
 	int ret;
 	uint64_t data_ptr = args->data_ptr;
+	int do_bit17_swizzling;
 
 	remain = args->size;
 
@@ -286,13 +355,15 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
 
 	down_read(&mm->mmap_sem);
 	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
-				      num_pages, 0, 0, user_pages, NULL);
+				      num_pages, 1, 0, user_pages, NULL);
 	up_read(&mm->mmap_sem);
 	if (pinned_pages < num_pages) {
 		ret = -EFAULT;
 		goto fail_put_user_pages;
 	}
 
+	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
 	mutex_lock(&dev->struct_mutex);
 
 	ret = i915_gem_object_get_pages(obj);
@@ -327,11 +398,20 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
 		if ((data_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - data_page_offset;
 
-		ret = slow_shmem_copy(user_pages[data_page_index],
-				      data_page_offset,
-				      obj_priv->pages[shmem_page_index],
-				      shmem_page_offset,
-				      page_length);
+		if (do_bit17_swizzling) {
+			ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
+						    shmem_page_offset,
+						    user_pages[data_page_index],
+						    data_page_offset,
+						    page_length,
+						    1);
+		} else {
+			ret = slow_shmem_copy(user_pages[data_page_index],
+					      data_page_offset,
+					      obj_priv->pages[shmem_page_index],
+					      shmem_page_offset,
+					      page_length);
+		}
 		if (ret)
 			goto fail_put_pages;
 
@@ -383,9 +463,14 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 		return -EINVAL;
 	}
 
-	ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv);
-	if (ret != 0)
+	if (i915_gem_object_needs_bit17_swizzle(obj)) {
 		ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv);
+	} else {
+		ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv);
+		if (ret != 0)
+			ret = i915_gem_shmem_pread_slow(dev, obj, args,
+							file_priv);
+	}
 
 	drm_gem_object_unreference(obj);
 
@@ -727,6 +812,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
 	int page_length;
 	int ret;
 	uint64_t data_ptr = args->data_ptr;
+	int do_bit17_swizzling;
 
 	remain = args->size;
 
@@ -751,6 +837,8 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
 		goto fail_put_user_pages;
 	}
 
+	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
 	mutex_lock(&dev->struct_mutex);
 
 	ret = i915_gem_object_get_pages(obj);
@@ -785,11 +873,20 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
 		if ((data_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - data_page_offset;
 
-		ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
-				      shmem_page_offset,
-				      user_pages[data_page_index],
-				      data_page_offset,
-				      page_length);
+		if (do_bit17_swizzling) {
+			ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
+						    shmem_page_offset,
+						    user_pages[data_page_index],
+						    data_page_offset,
+						    page_length,
+						    0);
+		} else {
+			ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
+					      shmem_page_offset,
+					      user_pages[data_page_index],
+					      data_page_offset,
+					      page_length);
+		}
 		if (ret)
 			goto fail_put_pages;
 
@@ -854,6 +951,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
 						       file_priv);
 		}
+	} else if (i915_gem_object_needs_bit17_swizzle(obj)) {
+		ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file_priv);
 	} else {
 		ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv);
 		if (ret == -EFAULT) {
@@ -1285,7 +1384,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 	return 0;
 }
 
-static void
+void
 i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1297,6 +1396,9 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
 	if (--obj_priv->pages_refcount != 0)
 		return;
 
+	if (obj_priv->tiling_mode != I915_TILING_NONE)
+		i915_gem_object_save_bit_17_swizzle(obj);
+
 	for (i = 0; i < page_count; i++)
 		if (obj_priv->pages[i] != NULL) {
 			if (obj_priv->dirty)
@@ -1494,8 +1596,19 @@ i915_gem_retire_request(struct drm_device *dev,
 
 		if (obj->write_domain != 0)
 			i915_gem_object_move_to_flushing(obj);
-		else
+		else {
+			/* Take a reference on the object so it won't be
+			 * freed while the spinlock is held.  The list
+			 * protection for this spinlock is safe when breaking
+			 * the lock like this since the next thing we do
+			 * is just get the head of the list again.
+			 */
+			drm_gem_object_reference(obj);
 			i915_gem_object_move_to_inactive(obj);
+			spin_unlock(&dev_priv->mm.active_list_lock);
+			drm_gem_object_unreference(obj);
+			spin_lock(&dev_priv->mm.active_list_lock);
+		}
 	}
 out:
 	spin_unlock(&dev_priv->mm.active_list_lock);
@@ -1884,7 +1997,7 @@ i915_gem_evict_everything(struct drm_device *dev)
 	return ret;
 }
 
-static int
+int
 i915_gem_object_get_pages(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1922,6 +2035,10 @@ i915_gem_object_get_pages(struct drm_gem_object *obj)
 		}
 		obj_priv->pages[i] = page;
 	}
+
+	if (obj_priv->tiling_mode != I915_TILING_NONE)
+		i915_gem_object_do_bit_17_swizzle(obj);
+
 	return 0;
 }
 
@@ -3002,13 +3119,13 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
 			drm_free(*relocs, reloc_count * sizeof(**relocs),
 				 DRM_MEM_DRIVER);
 			*relocs = NULL;
-			return ret;
+			return -EFAULT;
 		}
 
 		reloc_index += exec_list[i].relocation_count;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int
@@ -3017,23 +3134,28 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list,
 			    struct drm_i915_gem_relocation_entry *relocs)
 {
 	uint32_t reloc_count = 0, i;
-	int ret;
+	int ret = 0;
 
 	for (i = 0; i < buffer_count; i++) {
 		struct drm_i915_gem_relocation_entry __user *user_relocs;
+		int unwritten;
 
 		user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
 
-		if (ret == 0) {
-			ret = copy_to_user(user_relocs,
-					   &relocs[reloc_count],
-					   exec_list[i].relocation_count *
-					   sizeof(*relocs));
+		unwritten = copy_to_user(user_relocs,
+					 &relocs[reloc_count],
+					 exec_list[i].relocation_count *
+					 sizeof(*relocs));
+
+		if (unwritten) {
+			ret = -EFAULT;
+			goto err;
 		}
 
 		reloc_count += exec_list[i].relocation_count;
 	}
 
+err:
 	drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER);
 
 	return ret;
@@ -3243,7 +3365,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 	exec_offset = exec_list[args->buffer_count - 1].offset;
 
 #if WATCH_EXEC
-	i915_gem_dump_object(object_list[args->buffer_count - 1],
+	i915_gem_dump_object(batch_obj,
 			      args->batch_len,
 			      __func__,
 			      ~0);
@@ -3308,10 +3430,12 @@ err:
 				   (uintptr_t) args->buffers_ptr,
 				   exec_list,
 				   sizeof(*exec_list) * args->buffer_count);
-		if (ret)
+		if (ret) {
+			ret = -EFAULT;
 			DRM_ERROR("failed to copy %d exec entries "
 				  "back to user (%d)\n",
 				  args->buffer_count, ret);
+		}
 	}
 
 	/* Copy the updated relocations out regardless of current error
@@ -3593,6 +3717,7 @@ void i915_gem_free_object(struct drm_gem_object *obj)
 	i915_gem_free_mmap_offset(obj);
 
 	drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
+	kfree(obj_priv->bit_17);
 	drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
 }
 
@@ -3962,8 +4087,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
 	dev_priv->mm.suspended = 0;
 
 	ret = i915_gem_init_ringbuffer(dev);
-	if (ret != 0)
+	if (ret != 0) {
+		mutex_unlock(&dev->struct_mutex);
 		return ret;
+	}
 
 	spin_lock(&dev_priv->mm.active_list_lock);
 	BUG_ON(!list_empty(&dev_priv->mm.active_list));
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
index a1ac0c5e7307..986f1082c596 100644
--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c
@@ -234,6 +234,96 @@ static int i915_hws_info(struct seq_file *m, void *data)
 	return 0;
 }
 
+static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
+{
+	int page, i;
+	uint32_t *mem;
+
+	for (page = 0; page < page_count; page++) {
+		mem = kmap(pages[page]);
+		for (i = 0; i < PAGE_SIZE; i += 4)
+			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
+		kunmap(pages[page]);
+	}
+}
+
+static int i915_batchbuffer_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
+	int ret;
+
+	spin_lock(&dev_priv->mm.active_list_lock);
+
+	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+		obj = obj_priv->obj;
+		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
+		    ret = i915_gem_object_get_pages(obj);
+		    if (ret) {
+			    DRM_ERROR("Failed to get pages: %d\n", ret);
+			    spin_unlock(&dev_priv->mm.active_list_lock);
+			    return ret;
+		    }
+
+		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
+		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
+
+		    i915_gem_object_put_pages(obj);
+		}
+	}
+
+	spin_unlock(&dev_priv->mm.active_list_lock);
+
+	return 0;
+}
+
+static int i915_ringbuffer_data(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	u8 *virt;
+	uint32_t *ptr, off;
+
+	if (!dev_priv->ring.ring_obj) {
+		seq_printf(m, "No ringbuffer setup\n");
+		return 0;
+	}
+
+	virt = dev_priv->ring.virtual_start;
+
+	for (off = 0; off < dev_priv->ring.Size; off += 4) {
+		ptr = (uint32_t *)(virt + off);
+		seq_printf(m, "%08x :  %08x\n", off, *ptr);
+	}
+
+	return 0;
+}
+
+static int i915_ringbuffer_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	unsigned int head, tail, mask;
+
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
+	mask = dev_priv->ring.tail_mask;
+
+	seq_printf(m, "RingHead :  %08x\n", head);
+	seq_printf(m, "RingTail :  %08x\n", tail);
+	seq_printf(m, "RingMask :  %08x\n", mask);
+	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
+	seq_printf(m, "Acthd :  %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
+
+	return 0;
+}
+
+
 static struct drm_info_list i915_gem_debugfs_list[] = {
 	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
 	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
@@ -243,6 +333,9 @@ static struct drm_info_list i915_gem_debugfs_list[] = {
 	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
 	{"i915_gem_interrupt", i915_interrupt_info, 0},
 	{"i915_gem_hws", i915_hws_info, 0},
+	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
+	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
+	{"i915_batchbuffers", i915_batchbuffer_info, 0},
 };
 #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
 
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 6be3f927c86a..52a059354e83 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -25,6 +25,8 @@
  *
  */
 
+#include "linux/string.h"
+#include "linux/bitops.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -127,8 +129,8 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
 				swizzle_y = I915_BIT_6_SWIZZLE_9_11;
 			} else {
 				/* Bit 17 swizzling by the CPU in addition. */
-				swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-				swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_17;
 			}
 			break;
 		}
@@ -281,13 +283,25 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 	mutex_lock(&dev->struct_mutex);
 
 	if (args->tiling_mode == I915_TILING_NONE) {
-		obj_priv->tiling_mode = I915_TILING_NONE;
 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
 	} else {
 		if (args->tiling_mode == I915_TILING_X)
 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
 		else
 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+
+		/* Hide bit 17 swizzling from the user.  This prevents old Mesa
+		 * from aborting the application on sw fallbacks to bit 17,
+		 * and we use the pread/pwrite bit17 paths to swizzle for it.
+		 * If there was a user that was relying on the swizzle
+		 * information for drm_intel_bo_map()ed reads/writes this would
+		 * break it, but we don't have any of those.
+		 */
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
 		/* If we can't handle the swizzling, make it untiled. */
 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
 			args->tiling_mode = I915_TILING_NONE;
@@ -354,8 +368,100 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
 		DRM_ERROR("unknown tiling mode\n");
 	}
 
+	/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
 	drm_gem_object_unreference(obj);
 	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
 }
+
+/**
+ * Swap every 64 bytes of this page around, to account for it having a new
+ * bit 17 of its physical address and therefore being interpreted differently
+ * by the GPU.
+ */
+static int
+i915_gem_swizzle_page(struct page *page)
+{
+	char *vaddr;
+	int i;
+	char temp[64];
+
+	vaddr = kmap(page);
+	if (vaddr == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < PAGE_SIZE; i += 128) {
+		memcpy(temp, &vaddr[i], 64);
+		memcpy(&vaddr[i], &vaddr[i + 64], 64);
+		memcpy(&vaddr[i + 64], temp, 64);
+	}
+
+	kunmap(page);
+
+	return 0;
+}
+
+void
+i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	int page_count = obj->size >> PAGE_SHIFT;
+	int i;
+
+	if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
+		return;
+
+	if (obj_priv->bit_17 == NULL)
+		return;
+
+	for (i = 0; i < page_count; i++) {
+		char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17;
+		if ((new_bit_17 & 0x1) !=
+		    (test_bit(i, obj_priv->bit_17) != 0)) {
+			int ret = i915_gem_swizzle_page(obj_priv->pages[i]);
+			if (ret != 0) {
+				DRM_ERROR("Failed to swizzle page\n");
+				return;
+			}
+			set_page_dirty(obj_priv->pages[i]);
+		}
+	}
+}
+
+void
+i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	int page_count = obj->size >> PAGE_SHIFT;
+	int i;
+
+	if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
+		return;
+
+	if (obj_priv->bit_17 == NULL) {
+		obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
+					   sizeof(long), GFP_KERNEL);
+		if (obj_priv->bit_17 == NULL) {
+			DRM_ERROR("Failed to allocate memory for bit 17 "
+				  "record\n");
+			return;
+		}
+	}
+
+	for (i = 0; i < page_count; i++) {
+		if (page_to_phys(obj_priv->pages[i]) & (1 << 17))
+			__set_bit(i, obj_priv->bit_17);
+		else
+			__clear_bit(i, obj_priv->bit_17);
+	}
+}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index ee7ce7b78cf7..98bb4c878c4e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -406,7 +406,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
 	drm_i915_irq_emit_t *emit = data;
 	int result;
 
-	if (!dev_priv) {
+	if (!dev_priv || !dev_priv->ring.virtual_start) {
 		DRM_ERROR("called with no initialization\n");
 		return -EINVAL;
 	}
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 69427722d20e..dc425e74a268 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -370,11 +370,8 @@ int intel_opregion_init(struct drm_device *dev, int resume)
 	if (mboxes & MBOX_ACPI) {
 		DRM_DEBUG("Public ACPI methods supported\n");
 		opregion->acpi = base + OPREGION_ACPI_OFFSET;
-		if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		if (drm_core_check_feature(dev, DRIVER_MODESET))
 			intel_didl_outputs(dev);
-			if (!resume)
-				acpi_video_register();
-		}
 	} else {
 		DRM_DEBUG("Public ACPI methods not supported\n");
 		err = -ENOTSUPP;
@@ -389,8 +386,13 @@ int intel_opregion_init(struct drm_device *dev, int resume)
 	if (mboxes & MBOX_ASLE) {
 		DRM_DEBUG("ASLE supported\n");
 		opregion->asle = base + OPREGION_ASLE_OFFSET;
+		opregion_enable_asle(dev);
 	}
 
+	if (!resume)
+		acpi_video_register();
+
+
 	/* Notify BIOS we are ready to handle ACPI video ext notifs.
 	 * Right now, all the events are handled by the ACPI video module.
 	 * We don't actually need to do anything with them. */
@@ -408,7 +410,7 @@ err_out:
 	return err;
 }
 
-void intel_opregion_free(struct drm_device *dev)
+void intel_opregion_free(struct drm_device *dev, int suspend)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
@@ -416,6 +418,9 @@ void intel_opregion_free(struct drm_device *dev)
 	if (!opregion->enabled)
 		return;
 
+	if (!suspend)
+		acpi_video_exit();
+
 	opregion->acpi->drdy = 0;
 
 	system_opregion = NULL;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e805b590ae71..521194732266 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1446,6 +1446,7 @@
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+#define   DISPPLANE_TILED			(1<<10)
 #define DSPAADDR		0x70184
 #define DSPASTRIDE		0x70188
 #define DSPAPOS			0x7018C /* reserved */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 64773ce52964..bdcda36953b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -367,6 +367,7 @@ static const intel_limit_t intel_limits[] = {
         .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
+	.find_pll = intel_find_best_PLL,
     },
     { /* INTEL_LIMIT_IGD_LVDS */
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
@@ -380,6 +381,7 @@ static const intel_limit_t intel_limits[] = {
 	/* IGD only supports single-channel mode. */
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
+	.find_pll = intel_find_best_PLL,
     },
 
 };
@@ -655,6 +657,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
 	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+	int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
 	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 	u32 dspcntr, alignment;
 	int ret;
@@ -731,6 +734,13 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
+	if (IS_I965G(dev)) {
+		if (obj_priv->tiling_mode != I915_TILING_NONE)
+			dspcntr |= DISPPLANE_TILED;
+		else
+			dspcntr &= ~DISPPLANE_TILED;
+	}
+
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	Start = obj_priv->gtt_offset;
@@ -743,6 +753,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		I915_READ(dspbase);
 		I915_WRITE(dspsurf, Start);
 		I915_READ(dspsurf);
+		I915_WRITE(dsptileoff, (y << 16) | x);
 	} else {
 		I915_WRITE(dspbase, Start + Offset);
 		I915_READ(dspbase);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index b7f0ebe9f810..3e094beecb99 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -864,8 +864,8 @@ static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
 
 static struct sysrq_key_op sysrq_intelfb_restore_op = {
         .handler = intelfb_sysrq,
-        .help_msg = "force fb",
-        .action_msg = "force restore of fb console",
+        .help_msg = "force-fb(G)",
+        .action_msg = "Restore framebuffer console",
 };
 
 int intelfb_probe(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index b06a4a3ff08d..550374225388 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -38,7 +38,7 @@
 struct intel_hdmi_priv {
 	u32 sdvox_reg;
 	u32 save_SDVOX;
-	int has_hdmi_sink;
+	bool has_hdmi_sink;
 };
 
 static void intel_hdmi_mode_set(struct drm_encoder *encoder,
@@ -128,6 +128,22 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 	return true;
 }
 
+static void
+intel_hdmi_sink_detect(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct edid *edid = NULL;
+
+	edid = drm_get_edid(&intel_output->base,
+			    &intel_output->ddc_bus->adapter);
+	if (edid != NULL) {
+		hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+		kfree(edid);
+		intel_output->base.display_info.raw_edid = NULL;
+	}
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
@@ -158,9 +174,10 @@ intel_hdmi_detect(struct drm_connector *connector)
 		return connector_status_unknown;
 	}
 
-	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0)
+	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) {
+		intel_hdmi_sink_detect(connector);
 		return connector_status_connected;
-	else
+	} else
 		return connector_status_disconnected;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 7b31f55f55c8..9913651c1e17 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1357,6 +1357,23 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
 	intel_sdvo_read_response(intel_output, &response, 2);
 }
 
+static void
+intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct edid *edid = NULL;
+
+	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+	edid = drm_get_edid(&intel_output->base,
+			    &intel_output->ddc_bus->adapter);
+	if (edid != NULL) {
+		sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
+		kfree(edid);
+		intel_output->base.display_info.raw_edid = NULL;
+	}
+}
+
 static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
 {
 	u8 response[2];
@@ -1371,9 +1388,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return connector_status_unknown;
 
-	if ((response[0] != 0) || (response[1] != 0))
+	if ((response[0] != 0) || (response[1] != 0)) {
+		intel_sdvo_hdmi_sink_detect(connector);
 		return connector_status_connected;
-	else
+	} else
 		return connector_status_disconnected;
 }
 
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c
index 7a339dba6a69..bfb92d283260 100644
--- a/drivers/gpu/drm/via/via_dma.c
+++ b/drivers/gpu/drm/via/via_dma.c
@@ -481,11 +481,13 @@ static int via_wait_idle(drm_via_private_t * dev_priv)
 {
 	int count = 10000000;
 
-	while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--);
+	while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && --count)
+		;
 
-	while (count-- && (VIA_READ(VIA_REG_STATUS) &
+	while (count && (VIA_READ(VIA_REG_STATUS) &
 			   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
-			    VIA_3D_ENG_BUSY))) ;
+			    VIA_3D_ENG_BUSY)))
+		--count;
 	return count;
 }
 
@@ -705,7 +707,7 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
 	switch (d_siz->func) {
 	case VIA_CMDBUF_SPACE:
 		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
-		       && count--) {
+		       && --count) {
 			if (!d_siz->wait) {
 				break;
 			}
@@ -717,7 +719,7 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
 		break;
 	case VIA_CMDBUF_LAG:
 		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
-		       && count--) {
+		       && --count) {
 			if (!d_siz->wait) {
 				break;
 			}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0e8a9185f676..d73f5f473e38 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -692,6 +692,16 @@ config SENSORS_PCF8591
 	  These devices are hard to detect and rarely found on mainstream
 	  hardware.  If unsure, say N.
 
+config SENSORS_SHT15
+	tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
+	depends on GENERIC_GPIO
+	help
+	  If you say yes here you get support for the Sensiron SHT10, SHT11,
+	  SHT15, SHT71, SHT75 humidity and temperature sensors.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called sht15.
+
 config SENSORS_SIS5595
 	tristate "Silicon Integrated Systems Corp. SiS5595"
 	depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 1d3757837b4f..0ae26984ba45 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_SHT15)	+= sht15.o
 obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 55d3dc565be6..abca7e9f953b 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -34,7 +34,6 @@
 #include <linux/wait.h>
 #include <linux/poll.h>
 #include <linux/freezer.h>
-#include <linux/version.h>
 #include <linux/uaccess.h>
 #include <linux/leds.h>
 #include <acpi/acpi_drivers.h>
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
new file mode 100644
index 000000000000..6cbdc2fea734
--- /dev/null
+++ b/drivers/hwmon/sht15.c
@@ -0,0 +1,692 @@
+/*
+ * sht15.c - support for the SHT15 Temperature and Humidity Sensor
+ *
+ * Copyright (c) 2009 Jonathan Cameron
+ *
+ * Copyright (c) 2007 Wouter Horre
+ *
+ * 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.
+ *
+ * Currently ignoring checksum on readings.
+ * Default resolution only (14bit temp, 12bit humidity)
+ * Ignoring battery status.
+ * Heater not enabled.
+ * Timings are all conservative.
+ *
+ * Data sheet available (1/2009) at
+ * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf
+ *
+ * Regulator supply name = vcc
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include <linux/sht15.h>
+#include <linux/regulator/consumer.h>
+#include <asm/atomic.h>
+
+#define SHT15_MEASURE_TEMP	3
+#define SHT15_MEASURE_RH	5
+
+#define SHT15_READING_NOTHING	0
+#define SHT15_READING_TEMP	1
+#define SHT15_READING_HUMID	2
+
+/* Min timings in nsecs */
+#define SHT15_TSCKL		100	/* clock low */
+#define SHT15_TSCKH		100	/* clock high */
+#define SHT15_TSU		150	/* data setup time */
+
+/**
+ * struct sht15_temppair - elements of voltage dependant temp calc
+ * @vdd:	supply voltage in microvolts
+ * @d1:		see data sheet
+ */
+struct sht15_temppair {
+	int vdd; /* microvolts */
+	int d1;
+};
+
+/* Table 9 from data sheet - relates temperature calculation
+ * to supply voltage.
+ */
+static const struct sht15_temppair temppoints[] = {
+	{ 2500000, -39400 },
+	{ 3000000, -39600 },
+	{ 3500000, -39700 },
+	{ 4000000, -39800 },
+	{ 5000000, -40100 },
+};
+
+/**
+ * struct sht15_data - device instance specific data
+ * @pdata:	platform data (gpio's etc)
+ * @read_work:	bh of interrupt handler
+ * @wait_queue:	wait queue for getting values from device
+ * @val_temp:	last temperature value read from device
+ * @val_humid: 	last humidity value read from device
+ * @flag:	status flag used to identify what the last request was
+ * @valid:	are the current stored values valid (start condition)
+ * @last_updat:	time of last update
+ * @read_lock:	mutex to ensure only one read in progress
+ *		at a time.
+ * @dev:	associate device structure
+ * @hwmon_dev:	device associated with hwmon subsystem
+ * @reg:	associated regulator (if specified)
+ * @nb:		notifier block to handle notifications of voltage changes
+ * @supply_uV:	local copy of supply voltage used to allow
+ *		use of regulator consumer if available
+ * @supply_uV_valid:   indicates that an updated value has not yet
+ *		been obtained from the regulator and so any calculations
+ *		based upon it will be invalid.
+ * @update_supply_work:	work struct that is used to update the supply_uV
+ * @interrupt_handled:	flag used to indicate a hander has been scheduled
+ */
+struct sht15_data {
+	struct sht15_platform_data	*pdata;
+	struct work_struct		read_work;
+	wait_queue_head_t		wait_queue;
+	uint16_t			val_temp;
+	uint16_t			val_humid;
+	u8				flag;
+	u8				valid;
+	unsigned long			last_updat;
+	struct mutex			read_lock;
+	struct device			*dev;
+	struct device			*hwmon_dev;
+	struct regulator		*reg;
+	struct notifier_block		nb;
+	int				supply_uV;
+	int				supply_uV_valid;
+	struct work_struct		update_supply_work;
+	atomic_t			interrupt_handled;
+};
+
+/**
+ * sht15_connection_reset() - reset the comms interface
+ * @data:	sht15 specific data
+ *
+ * This implements section 3.4 of the data sheet
+ */
+static void sht15_connection_reset(struct sht15_data *data)
+{
+	int i;
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	for (i = 0; i < 9; ++i) {
+		gpio_set_value(data->pdata->gpio_sck, 1);
+		ndelay(SHT15_TSCKH);
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		ndelay(SHT15_TSCKL);
+	}
+}
+/**
+ * sht15_send_bit() - send an individual bit to the device
+ * @data:	device state data
+ * @val:	value of bit to be sent
+ **/
+static inline void sht15_send_bit(struct sht15_data *data, int val)
+{
+
+	gpio_set_value(data->pdata->gpio_data, val);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL); /* clock low time */
+}
+
+/**
+ * sht15_transmission_start() - specific sequence for new transmission
+ *
+ * @data:	device state data
+ * Timings for this are not documented on the data sheet, so very
+ * conservative ones used in implementation. This implements
+ * figure 12 on the data sheet.
+ **/
+static void sht15_transmission_start(struct sht15_data *data)
+{
+	/* ensure data is high and output */
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_data, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+}
+/**
+ * sht15_send_byte() - send a single byte to the device
+ * @data:	device state
+ * @byte:	value to be sent
+ **/
+static void sht15_send_byte(struct sht15_data *data, u8 byte)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		sht15_send_bit(data, !!(byte & 0x80));
+		byte <<= 1;
+	}
+}
+/**
+ * sht15_wait_for_response() - checks for ack from device
+ * @data:	device state
+ **/
+static int sht15_wait_for_response(struct sht15_data *data)
+{
+	gpio_direction_input(data->pdata->gpio_data);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	if (gpio_get_value(data->pdata->gpio_data)) {
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		dev_err(data->dev, "Command not acknowledged\n");
+		sht15_connection_reset(data);
+		return -EIO;
+	}
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	return 0;
+}
+
+/**
+ * sht15_send_cmd() - Sends a command to the device.
+ * @data:	device state
+ * @cmd:	command byte to be sent
+ *
+ * On entry, sck is output low, data is output pull high
+ * and the interrupt disabled.
+ **/
+static int sht15_send_cmd(struct sht15_data *data, u8 cmd)
+{
+	int ret = 0;
+	sht15_transmission_start(data);
+	sht15_send_byte(data, cmd);
+	ret = sht15_wait_for_response(data);
+	return ret;
+}
+/**
+ * sht15_update_single_val() - get a new value from device
+ * @data:		device instance specific data
+ * @command:		command sent to request value
+ * @timeout_msecs:	timeout after which comms are assumed
+ *			to have failed are reset.
+ **/
+static inline int sht15_update_single_val(struct sht15_data *data,
+					  int command,
+					  int timeout_msecs)
+{
+	int ret;
+	ret = sht15_send_cmd(data, command);
+	if (ret)
+		return ret;
+
+	gpio_direction_input(data->pdata->gpio_data);
+	atomic_set(&data->interrupt_handled, 0);
+
+	enable_irq(gpio_to_irq(data->pdata->gpio_data));
+	if (gpio_get_value(data->pdata->gpio_data) == 0) {
+		disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+		/* Only relevant if the interrupt hasn't occured. */
+		if (!atomic_read(&data->interrupt_handled))
+			schedule_work(&data->read_work);
+	}
+	ret = wait_event_timeout(data->wait_queue,
+				 (data->flag == SHT15_READING_NOTHING),
+				 msecs_to_jiffies(timeout_msecs));
+	if (ret == 0) {/* timeout occurred */
+		disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));;
+		sht15_connection_reset(data);
+		return -ETIME;
+	}
+	return 0;
+}
+
+/**
+ * sht15_update_vals() - get updated readings from device if too old
+ * @data:	device state
+ **/
+static int sht15_update_vals(struct sht15_data *data)
+{
+	int ret = 0;
+	int timeout = HZ;
+
+	mutex_lock(&data->read_lock);
+	if (time_after(jiffies, data->last_updat + timeout)
+	    || !data->valid) {
+		data->flag = SHT15_READING_HUMID;
+		ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160);
+		if (ret)
+			goto error_ret;
+		data->flag = SHT15_READING_TEMP;
+		ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400);
+		if (ret)
+			goto error_ret;
+		data->valid = 1;
+		data->last_updat = jiffies;
+	}
+error_ret:
+	mutex_unlock(&data->read_lock);
+
+	return ret;
+}
+
+/**
+ * sht15_calc_temp() - convert the raw reading to a temperature
+ * @data:	device state
+ *
+ * As per section 4.3 of the data sheet.
+ **/
+static inline int sht15_calc_temp(struct sht15_data *data)
+{
+	int d1 = 0;
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++)
+		/* Find pointer to interpolate */
+		if (data->supply_uV > temppoints[i - 1].vdd) {
+			d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+				* (temppoints[i].d1 - temppoints[i - 1].d1)
+				/ (temppoints[i].vdd - temppoints[i - 1].vdd)
+				+ temppoints[i - 1].d1;
+			break;
+		}
+
+	return data->val_temp*10 + d1;
+}
+
+/**
+ * sht15_calc_humid() - using last temperature convert raw to humid
+ * @data:	device state
+ *
+ * This is the temperature compensated version as per section 4.2 of
+ * the data sheet.
+ **/
+static inline int sht15_calc_humid(struct sht15_data *data)
+{
+	int RHlinear; /* milli percent */
+	int temp = sht15_calc_temp(data);
+
+	const int c1 = -4;
+	const int c2 = 40500; /* x 10 ^ -6 */
+	const int c3 = 2800; /* x10 ^ -9 */
+
+	RHlinear = c1*1000
+		+ c2 * data->val_humid/1000
+		+ (data->val_humid * data->val_humid * c3)/1000000;
+	return (temp - 25000) * (10000 + 800 * data->val_humid)
+		/ 1000000 + RHlinear;
+}
+
+static ssize_t sht15_show_temp(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+
+	/* Technically no need to read humidity as well */
+	ret = sht15_update_vals(data);
+
+	return ret ? ret : sprintf(buf, "%d\n",
+				   sht15_calc_temp(data));
+}
+
+static ssize_t sht15_show_humidity(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+
+	ret = sht15_update_vals(data);
+
+	return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data));
+
+};
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr,
+			 char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	return sprintf(buf, "%s\n", pdev->name);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input,
+			  S_IRUGO, sht15_show_temp,
+			  NULL, 0);
+static SENSOR_DEVICE_ATTR(humidity1_input,
+			  S_IRUGO, sht15_show_humidity,
+			  NULL, 0);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static struct attribute *sht15_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_humidity1_input.dev_attr.attr,
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group sht15_attr_group = {
+	.attrs = sht15_attrs,
+};
+
+static irqreturn_t sht15_interrupt_fired(int irq, void *d)
+{
+	struct sht15_data *data = d;
+	/* First disable the interrupt */
+	disable_irq_nosync(irq);
+	atomic_inc(&data->interrupt_handled);
+	/* Then schedule a reading work struct */
+	if (data->flag != SHT15_READING_NOTHING)
+		schedule_work(&data->read_work);
+	return IRQ_HANDLED;
+}
+
+/* Each byte of data is acknowledged by pulling the data line
+ * low for one clock pulse.
+ */
+static void sht15_ack(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_data, 1);
+
+	gpio_direction_input(data->pdata->gpio_data);
+}
+/**
+ * sht15_end_transmission() - notify device of end of transmission
+ * @data:	device state
+ *
+ * This is basically a NAK. (single clock pulse, data high)
+ **/
+static void sht15_end_transmission(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+}
+
+static void sht15_bh_read_data(struct work_struct *work_s)
+{
+	int i;
+	uint16_t val = 0;
+	struct sht15_data *data
+		= container_of(work_s, struct sht15_data,
+			       read_work);
+	/* Firstly, verify the line is low */
+	if (gpio_get_value(data->pdata->gpio_data)) {
+		/* If not, then start the interrupt again - care
+		   here as could have gone low in meantime so verify
+		   it hasn't!
+		*/
+		atomic_set(&data->interrupt_handled, 0);
+		enable_irq(gpio_to_irq(data->pdata->gpio_data));
+		/* If still not occured or another handler has been scheduled */
+		if (gpio_get_value(data->pdata->gpio_data)
+		    || atomic_read(&data->interrupt_handled))
+			return;
+	}
+	/* Read the data back from the device */
+	for (i = 0; i < 16; ++i) {
+		val <<= 1;
+		gpio_set_value(data->pdata->gpio_sck, 1);
+		ndelay(SHT15_TSCKH);
+		val |= !!gpio_get_value(data->pdata->gpio_data);
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		ndelay(SHT15_TSCKL);
+		if (i == 7)
+			sht15_ack(data);
+	}
+	/* Tell the device we are done */
+	sht15_end_transmission(data);
+
+	switch (data->flag) {
+	case SHT15_READING_TEMP:
+		data->val_temp = val;
+		break;
+	case SHT15_READING_HUMID:
+		data->val_humid = val;
+		break;
+	}
+
+	data->flag = SHT15_READING_NOTHING;
+	wake_up(&data->wait_queue);
+}
+
+static void sht15_update_voltage(struct work_struct *work_s)
+{
+	struct sht15_data *data
+		= container_of(work_s, struct sht15_data,
+			       update_supply_work);
+	data->supply_uV = regulator_get_voltage(data->reg);
+}
+
+/**
+ * sht15_invalidate_voltage() - mark supply voltage invalid when notified by reg
+ * @nb:		associated notification structure
+ * @event:	voltage regulator state change event code
+ * @ignored:	function parameter - ignored here
+ *
+ * Note that as the notification code holds the regulator lock, we have
+ * to schedule an update of the supply voltage rather than getting it directly.
+ **/
+static int sht15_invalidate_voltage(struct notifier_block *nb,
+				unsigned long event,
+				void *ignored)
+{
+	struct sht15_data *data = container_of(nb, struct sht15_data, nb);
+
+	if (event == REGULATOR_EVENT_VOLTAGE_CHANGE)
+		data->supply_uV_valid = false;
+	schedule_work(&data->update_supply_work);
+
+	return NOTIFY_OK;
+}
+
+static int __devinit sht15_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+
+	if (!data) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "kzalloc failed");
+		goto error_ret;
+	}
+
+	INIT_WORK(&data->read_work, sht15_bh_read_data);
+	INIT_WORK(&data->update_supply_work, sht15_update_voltage);
+	platform_set_drvdata(pdev, data);
+	mutex_init(&data->read_lock);
+	data->dev = &pdev->dev;
+	init_waitqueue_head(&data->wait_queue);
+
+	if (pdev->dev.platform_data == NULL) {
+		dev_err(&pdev->dev, "no platform data supplied");
+		goto err_free_data;
+	}
+	data->pdata = pdev->dev.platform_data;
+	data->supply_uV = data->pdata->supply_mv*1000;
+
+/* If a regulator is available, query what the supply voltage actually is!*/
+	data->reg = regulator_get(data->dev, "vcc");
+	if (!IS_ERR(data->reg)) {
+		data->supply_uV = regulator_get_voltage(data->reg);
+		regulator_enable(data->reg);
+		/* setup a notifier block to update this if another device
+		 *  causes the voltage to change */
+		data->nb.notifier_call = &sht15_invalidate_voltage;
+		ret = regulator_register_notifier(data->reg, &data->nb);
+	}
+/* Try requesting the GPIOs */
+	ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
+	if (ret) {
+		dev_err(&pdev->dev, "gpio request failed");
+		goto err_free_data;
+	}
+	gpio_direction_output(data->pdata->gpio_sck, 0);
+	ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
+	if (ret) {
+		dev_err(&pdev->dev, "gpio request failed");
+		goto err_release_gpio_sck;
+	}
+	ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
+	if (ret) {
+		dev_err(&pdev->dev, "sysfs create failed");
+		goto err_free_data;
+	}
+
+	ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
+			  sht15_interrupt_fired,
+			  IRQF_TRIGGER_FALLING,
+			  "sht15 data",
+			  data);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to get irq for data line");
+		goto err_release_gpio_data;
+	}
+	disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+	sht15_connection_reset(data);
+	sht15_send_cmd(data, 0x1E);
+
+	data->hwmon_dev = hwmon_device_register(data->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto err_release_gpio_data;
+	}
+	return 0;
+
+err_release_gpio_data:
+	gpio_free(data->pdata->gpio_data);
+err_release_gpio_sck:
+	gpio_free(data->pdata->gpio_sck);
+err_free_data:
+	kfree(data);
+error_ret:
+
+	return ret;
+}
+
+static int __devexit sht15_remove(struct platform_device *pdev)
+{
+	struct sht15_data *data = platform_get_drvdata(pdev);
+
+	/* Make sure any reads from the device are done and
+	 * prevent new ones beginnning */
+	mutex_lock(&data->read_lock);
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
+	if (!IS_ERR(data->reg)) {
+		regulator_unregister_notifier(data->reg, &data->nb);
+		regulator_disable(data->reg);
+		regulator_put(data->reg);
+	}
+
+	free_irq(gpio_to_irq(data->pdata->gpio_data), data);
+	gpio_free(data->pdata->gpio_data);
+	gpio_free(data->pdata->gpio_sck);
+	mutex_unlock(&data->read_lock);
+	kfree(data);
+	return 0;
+}
+
+
+static struct platform_driver sht_drivers[] = {
+	{
+		.driver = {
+			.name = "sht10",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht11",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht15",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht71",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht75",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	},
+};
+
+
+static int __init sht15_init(void)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) {
+		ret = platform_driver_register(&sht_drivers[i]);
+		if (ret)
+			goto error_unreg;
+	}
+
+	return 0;
+
+error_unreg:
+	while (--i >= 0)
+		platform_driver_unregister(&sht_drivers[i]);
+
+	return ret;
+}
+module_init(sht15_init);
+
+static void __exit sht15_exit(void)
+{
+	int i;
+	for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--)
+		platform_driver_unregister(&sht_drivers[i]);
+}
+module_exit(sht15_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index f68e5f8e23ee..6318f7ddc1d4 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -190,7 +190,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 	int completed = 1;
 	unsigned long timeout = jiffies + i2c_adap->timeout;
 
-	while (pca_status(adap) != 0xf8) {
+	while ((state = pca_status(adap)) != 0xf8) {
 		if (time_before(jiffies, timeout)) {
 			msleep(10);
 		} else {
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 94eae5c3cbc7..a48c8aee0218 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -604,12 +604,14 @@ comment "Graphics adapter I2C/DDC channel drivers"
 	depends on PCI
 
 config I2C_VOODOO3
-	tristate "Voodoo 3"
+	tristate "Voodoo 3 (DEPRECATED)"
 	depends on PCI
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the
-	  Voodoo 3 I2C interface.
+	  Voodoo 3 I2C interface. This driver is deprecated and you should
+	  use the tdfxfb driver instead, which additionally provides
+	  framebuffer support.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-voodoo3.
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b6f3a0de6ca2..85e2e919d1cd 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -716,8 +716,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 
 	/* new style driver methods can't mix with legacy ones */
 	if (is_newstyle_driver(driver)) {
-		if (driver->attach_adapter || driver->detach_adapter
-				|| driver->detach_client) {
+		if (driver->detach_adapter || driver->detach_client) {
 			printk(KERN_WARNING
 					"i2c-core: driver [%s] is confused\n",
 					driver->driver.name);
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index 8eda552326e9..403d0e4265db 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -20,7 +20,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/clk.h>
@@ -175,90 +174,6 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 	leave_16bit(chipselect, mode);
 }
 
-static u8 ide_mm_inb(unsigned long port)
-{
-	return readb((void __iomem *) port);
-}
-
-static void ide_mm_outb(u8 value, unsigned long port)
-{
-	writeb(value, (void __iomem *) port);
-}
-
-static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		ide_mm_outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
-		ide_mm_outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
-		ide_mm_outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
-		ide_mm_outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
-		ide_mm_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
-}
-
-static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-
-	/* be sure we're looking at the low order bits */
-	ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
-		tf->error  = ide_mm_inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = ide_mm_inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = ide_mm_inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = ide_mm_inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = ide_mm_inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = ide_mm_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = ide_mm_inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = ide_mm_inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = ide_mm_inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = ide_mm_inb(io_ports->lbah_addr);
-	}
-}
-
 static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 	struct ide_timing *timing;
@@ -284,8 +199,8 @@ static const struct ide_tp_ops at91_ide_tp_ops = {
 	.write_devctl	= ide_write_devctl,
 
 	.dev_select	= ide_dev_select,
-	.tf_load	= at91_ide_tf_load,
-	.tf_read	= at91_ide_tf_read,
+	.tf_load	= ide_tf_load,
+	.tf_read	= ide_tf_read,
 
 	.input_data	= at91_ide_input_data,
 	.output_data	= at91_ide_output_data,
@@ -300,7 +215,7 @@ static const struct ide_port_info at91_ide_port_info __initdata = {
 	.tp_ops		= &at91_ide_tp_ops,
 	.host_flags 	= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
 			  IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
-	.pio_mask 	= ATA_PIO5,
+	.pio_mask 	= ATA_PIO6,
 };
 
 /*
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index 353a35bbba63..0332a95eefd4 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -236,6 +236,7 @@ static const struct ide_dma_ops cs5536_dma_ops = {
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
 	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
+	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_port_info cs5536_info = {
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index afa2af9a362b..0e2df6755ec9 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -20,6 +20,7 @@
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
 #include <asm/atari_stdma.h>
+#include <asm/ide.h>
 
 #define DRV_NAME "falconide"
 
@@ -67,8 +68,10 @@ static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
-		return insw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_insw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
 	raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
@@ -78,8 +81,10 @@ static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
-		return outsw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
 	raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index a0eb87f59134..0feb66c720e1 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -3,7 +3,7 @@
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2003		Red Hat Inc
  * Portions Copyright (C) 2007		Bartlomiej Zolnierkiewicz
- * Portions Copyright (C) 2005-2008	MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009	MontaVista Software, Inc.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
  * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -114,6 +114,8 @@
  *   the register setting lists into the table indexed by the clock selected
  * - set the correct hwif->ultra_mask for each individual chip
  * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
+ * - stop resetting HPT370's state machine before each DMA transfer as that has
+ *   caused more harm than good
  *	Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
  */
 
@@ -133,7 +135,7 @@
 #define DRV_NAME "hpt366"
 
 /* various tuning parameters */
-#define HPT_RESET_STATE_ENGINE
+#undef	HPT_RESET_STATE_ENGINE
 #undef	HPT_DELAY_INTERRUPT
 
 static const char *quirk_drives[] = {
@@ -808,7 +810,7 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
 	/* get DMA command mode */
 	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
 	/* stop DMA */
-	outb(dma_cmd & ~0x1, hwif->dma_base + ATA_DMA_CMD);
+	outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
 	hpt370_clear_engine(drive);
 }
 
@@ -825,11 +827,11 @@ static int hpt370_dma_end(ide_drive_t *drive)
 	ide_hwif_t *hwif	= drive->hwif;
 	u8  dma_stat		= inb(hwif->dma_base + ATA_DMA_STATUS);
 
-	if (dma_stat & 0x01) {
+	if (dma_stat & ATA_DMA_ACTIVE) {
 		/* wait a little */
 		udelay(20);
 		dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
-		if (dma_stat & 0x01)
+		if (dma_stat & ATA_DMA_ACTIVE)
 			hpt370_irq_timeout(drive);
 	}
 	return ide_dma_end(drive);
@@ -851,7 +853,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive)
 
 	dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
 	/* return 1 if INTR asserted */
-	if (dma_stat & 4)
+	if (dma_stat & ATA_DMA_INTR)
 		return 1;
 
 	return 0;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 12f436951bff..77f79d26b264 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -318,8 +318,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
 
 		/* convert GTF to taskfile */
 		memset(&cmd, 0, sizeof(cmd));
-		memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF);
-		cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+		memcpy(&cmd.tf.feature, gtf, REGS_PER_GTF);
+		cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+		cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 		err = ide_no_data_taskfile(drive, &cmd);
 		if (err) {
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 3e43b889dd64..7201b176d75b 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -254,16 +254,13 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
 
 void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
 {
-	struct ide_cmd cmd;
+	struct ide_taskfile tf;
 
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
-		       IDE_TFLAG_IN_NSECT;
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT |
+				     IDE_VALID_LBAM | IDE_VALID_LBAH);
 
-	drive->hwif->tp_ops->tf_read(drive, &cmd);
-
-	*bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam;
-	*ireason = cmd.tf.nsect & 3;
+	*bcount = (tf.lbah << 8) | tf.lbam;
+	*ireason = tf.nsect & 3;
 }
 EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
 
@@ -439,12 +436,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
 	return ide_started;
 }
 
-static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf,
 				u16 bcount, u8 dma)
 {
-	cmd->protocol  = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
-	cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
-			 IDE_TFLAG_OUT_FEATURE | tf_flags;
+	cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+	cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM |
+			    IDE_VALID_FEATURE | valid_tf;
 	cmd->tf.command = ATA_CMD_PACKET;
 	cmd->tf.feature = dma;		/* Use PIO/DMA */
 	cmd->tf.lbam    = bcount & 0xff;
@@ -453,14 +450,11 @@ static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
 
 static u8 ide_read_ireason(ide_drive_t *drive)
 {
-	struct ide_cmd cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_IN_NSECT;
+	struct ide_taskfile tf;
 
-	drive->hwif->tp_ops->tf_read(drive, &cmd);
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT);
 
-	return cmd.tf.nsect & 3;
+	return tf.nsect & 3;
 }
 
 static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -588,12 +582,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
 	ide_expiry_t *expiry = NULL;
 	struct request *rq = hwif->rq;
 	unsigned int timeout;
-	u32 tf_flags;
 	u16 bcount;
+	u8 valid_tf;
 	u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
 
 	if (dev_is_idecd(drive)) {
-		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
+		valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL;
 		bcount = ide_cd_get_xferlen(rq);
 		expiry = ide_cd_expiry;
 		timeout = ATAPI_WAIT_PC;
@@ -607,7 +601,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
 		pc->xferred = 0;
 		pc->cur_pos = pc->buf;
 
-		tf_flags = IDE_TFLAG_OUT_DEVICE;
+		valid_tf = IDE_VALID_DEVICE;
 		bcount = ((drive->media == ide_tape) ?
 				pc->req_xfer :
 				min(pc->req_xfer, 63 * 1024));
@@ -627,7 +621,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
 						       : WAIT_TAPE_CMD;
 	}
 
-	ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma);
+	ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma);
 
 	(void)do_rw_taskfile(drive, cmd);
 
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 35729a47f797..3d4e09969763 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -265,35 +265,62 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
 		cdrom_analyze_sense_data(drive, NULL, sense);
 }
 
+
 /*
+ * Allow the drive 5 seconds to recover; some devices will return NOT_READY
+ * while flushing data from cache.
+ *
+ * returns: 0 failed (write timeout expired)
+ *	    1 success
+ */
+static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
+{
+
+	struct cdrom_info *info = drive->driver_data;
+
+	if (!rq->errors)
+		info->write_timeout = jiffies +	ATAPI_WAIT_WRITE_BUSY;
+
+	rq->errors = 1;
+
+	if (time_after(jiffies, info->write_timeout))
+		return 0;
+	else {
+		struct request_queue *q = drive->queue;
+		unsigned long flags;
+
+		/*
+		 * take a breather relying on the unplug timer to kick us again
+		 */
+
+		spin_lock_irqsave(q->queue_lock, flags);
+		blk_plug_device(q);
+		spin_unlock_irqrestore(q->queue_lock, flags);
+
+		return 1;
+	}
+}
+
+/**
  * Returns:
  * 0: if the request should be continued.
  * 1: if the request will be going through error recovery.
  * 2: if the request should be ended.
  */
-static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
+static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq = hwif->rq;
-	int stat, err, sense_key;
-
-	/* check for errors */
-	stat = hwif->tp_ops->read_status(hwif);
-
-	if (stat_ret)
-		*stat_ret = stat;
-
-	if (OK_STAT(stat, good_stat, BAD_R_STAT))
-		return 0;
+	int err, sense_key, do_end_request = 0;
+	u8 quiet = rq->cmd_flags & REQ_QUIET;
 
 	/* get the IDE error register */
 	err = ide_read_error(drive);
 	sense_key = err >> 4;
 
-	ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
-				  "rq->cmd_type: 0x%x, err: 0x%x",
-				  stat, good_stat, rq->cmd[0], rq->cmd_type,
-				  err);
+	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, "
+				  "stat 0x%x",
+				  rq->cmd[0], rq->cmd_type, err, stat);
 
 	if (blk_sense_request(rq)) {
 		/*
@@ -303,151 +330,108 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 		 */
 		rq->cmd_flags |= REQ_FAILED;
 		return 2;
-	} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
-		/* All other functions, except for READ. */
+	}
 
-		/*
-		 * if we have an error, pass back CHECK_CONDITION as the
-		 * scsi status byte
-		 */
-		if (blk_pc_request(rq) && !rq->errors)
-			rq->errors = SAM_STAT_CHECK_CONDITION;
+	/* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
+	if (blk_pc_request(rq) && !rq->errors)
+		rq->errors = SAM_STAT_CHECK_CONDITION;
 
-		/* check for tray open */
-		if (sense_key == NOT_READY) {
-			cdrom_saw_media_change(drive);
-		} else if (sense_key == UNIT_ATTENTION) {
-			/* check for media change */
+	if (blk_noretry_request(rq))
+		do_end_request = 1;
+
+	switch (sense_key) {
+	case NOT_READY:
+		if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
+			if (ide_cd_breathe(drive, rq))
+				return 1;
+		} else {
 			cdrom_saw_media_change(drive);
-			return 0;
-		} else if (sense_key == ILLEGAL_REQUEST &&
-			   rq->cmd[0] == GPCMD_START_STOP_UNIT) {
-			/*
-			 * Don't print error message for this condition--
-			 * SFF8090i indicates that 5/24/00 is the correct
-			 * response to a request to close the tray if the
-			 * drive doesn't have that capability.
-			 * cdrom_log_sense() knows this!
-			 */
-		} else if (!(rq->cmd_flags & REQ_QUIET)) {
-			/* otherwise, print an error */
-			ide_dump_status(drive, "packet command error", stat);
+
+			if (blk_fs_request(rq) && !quiet)
+				printk(KERN_ERR PFX "%s: tray open\n",
+					drive->name);
 		}
+		do_end_request = 1;
+		break;
+	case UNIT_ATTENTION:
+		cdrom_saw_media_change(drive);
 
-		rq->cmd_flags |= REQ_FAILED;
+		if (blk_fs_request(rq) == 0)
+			return 0;
 
 		/*
-		 * instead of playing games with moving completions around,
-		 * remove failed request completely and end it when the
-		 * request sense has completed
+		 * Arrange to retry the request but be sure to give up if we've
+		 * retried too many times.
 		 */
-		goto end_request;
-
-	} else if (blk_fs_request(rq)) {
-		int do_end_request = 0;
-
-		/* handle errors from READ and WRITE requests */
-
-		if (blk_noretry_request(rq))
+		if (++rq->errors > ERROR_MAX)
 			do_end_request = 1;
-
-		if (sense_key == NOT_READY) {
-			/* tray open */
-			if (rq_data_dir(rq) == READ) {
-				cdrom_saw_media_change(drive);
-
-				/* fail the request */
-				printk(KERN_ERR PFX "%s: tray open\n",
-						drive->name);
-				do_end_request = 1;
-			} else {
-				struct cdrom_info *info = drive->driver_data;
-
-				/*
-				 * Allow the drive 5 seconds to recover, some
-				 * devices will return this error while flushing
-				 * data from cache.
-				 */
-				if (!rq->errors)
-					info->write_timeout = jiffies +
-							ATAPI_WAIT_WRITE_BUSY;
-				rq->errors = 1;
-				if (time_after(jiffies, info->write_timeout))
-					do_end_request = 1;
-				else {
-					struct request_queue *q = drive->queue;
-					unsigned long flags;
-
-					/*
-					 * take a breather relying on the unplug
-					 * timer to kick us again
-					 */
-					spin_lock_irqsave(q->queue_lock, flags);
-					blk_plug_device(q);
-					spin_unlock_irqrestore(q->queue_lock, flags);
-
-					return 1;
-				}
-			}
-		} else if (sense_key == UNIT_ATTENTION) {
-			/* media change */
-			cdrom_saw_media_change(drive);
-
-			/*
-			 * Arrange to retry the request but be sure to give up
-			 * if we've retried too many times.
-			 */
-			if (++rq->errors > ERROR_MAX)
-				do_end_request = 1;
-		} else if (sense_key == ILLEGAL_REQUEST ||
-			   sense_key == DATA_PROTECT) {
-			/*
-			 * No point in retrying after an illegal request or data
-			 * protect error.
-			 */
+		break;
+	case ILLEGAL_REQUEST:
+		/*
+		 * Don't print error message for this condition -- SFF8090i
+		 * indicates that 5/24/00 is the correct response to a request
+		 * to close the tray if the drive doesn't have that capability.
+		 *
+		 * cdrom_log_sense() knows this!
+		 */
+		if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
+			break;
+		/* fall-through */
+	case DATA_PROTECT:
+		/*
+		 * No point in retrying after an illegal request or data
+		 * protect error.
+		 */
+		if (!quiet)
 			ide_dump_status(drive, "command error", stat);
-			do_end_request = 1;
-		} else if (sense_key == MEDIUM_ERROR) {
-			/*
-			 * No point in re-trying a zillion times on a bad
-			 * sector. If we got here the error is not correctable.
-			 */
-			ide_dump_status(drive, "media error (bad sector)",
+		do_end_request = 1;
+		break;
+	case MEDIUM_ERROR:
+		/*
+		 * No point in re-trying a zillion times on a bad sector.
+		 * If we got here the error is not correctable.
+		 */
+		if (!quiet)
+			ide_dump_status(drive, "media error "
+					"(bad sector)", stat);
+		do_end_request = 1;
+		break;
+	case BLANK_CHECK:
+		/* disk appears blank? */
+		if (!quiet)
+			ide_dump_status(drive, "media error (blank)",
 					stat);
-			do_end_request = 1;
-		} else if (sense_key == BLANK_CHECK) {
-			/* disk appears blank ?? */
-			ide_dump_status(drive, "media error (blank)", stat);
-			do_end_request = 1;
-		} else if ((err & ~ATA_ABORTED) != 0) {
+		do_end_request = 1;
+		break;
+	default:
+		if (blk_fs_request(rq) == 0)
+			break;
+		if (err & ~ATA_ABORTED) {
 			/* go to the default handler for other errors */
 			ide_error(drive, "cdrom_decode_status", stat);
 			return 1;
-		} else if ((++rq->errors > ERROR_MAX)) {
+		} else if (++rq->errors > ERROR_MAX)
 			/* we've racked up too many retries, abort */
 			do_end_request = 1;
-		}
-
-		/*
-		 * End a request through request sense analysis when we have
-		 * sense data. We need this in order to perform end of media
-		 * processing.
-		 */
-		if (do_end_request)
-			goto end_request;
+	}
 
-		/*
-		 * If we got a CHECK_CONDITION status, queue
-		 * a request sense command.
-		 */
-		if (stat & ATA_ERR)
-			cdrom_queue_request_sense(drive, NULL, NULL);
-		return 1;
-	} else {
-		blk_dump_rq_flags(rq, PFX "bad rq");
-		return 2;
+	if (blk_fs_request(rq) == 0) {
+		rq->cmd_flags |= REQ_FAILED;
+		do_end_request = 1;
 	}
 
+	/*
+	 * End a request through request sense analysis when we have sense data.
+	 * We need this in order to perform end of media processing.
+	 */
+	if (do_end_request)
+		goto end_request;
+
+	/* if we got a CHECK_CONDITION status, queue a request sense command */
+	if (stat & ATA_ERR)
+		cdrom_queue_request_sense(drive, NULL, NULL);
+	return 1;
+
 end_request:
 	if (stat & ATA_ERR) {
 		struct request_queue *q = drive->queue;
@@ -624,15 +608,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 	struct ide_cmd *cmd = &hwif->cmd;
 	struct request *rq = hwif->rq;
 	ide_expiry_t *expiry = NULL;
-	int dma_error = 0, dma, stat, thislen, uptodate = 0;
-	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+	int dma_error = 0, dma, thislen, uptodate = 0;
+	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
 	int sense = blk_sense_request(rq);
 	unsigned int timeout;
 	u16 len;
-	u8 ireason;
+	u8 ireason, stat;
 
-	ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x",
-				  rq->cmd[0], write);
+	ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write);
 
 	/* check for errors */
 	dma = drive->dma;
@@ -648,11 +631,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 		}
 	}
 
-	rc = cdrom_decode_status(drive, 0, &stat);
-	if (rc) {
-		if (rc == 2)
-			goto out_end;
-		return ide_stopped;
+	/* check status */
+	stat = hwif->tp_ops->read_status(hwif);
+
+	if (!OK_STAT(stat, 0, BAD_R_STAT)) {
+		rc = cdrom_decode_status(drive, stat);
+		if (rc) {
+			if (rc == 2)
+				goto out_end;
+			return ide_stopped;
+		}
 	}
 
 	/* using dma, transfer is complete now */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index c998cf8e971a..a9fbe2c31210 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -97,35 +97,38 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 	}
 
 	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	if (drive->dev_flags & IDE_DFLAG_LBA) {
 		if (lba48) {
 			pr_debug("%s: LBA=0x%012llx\n", drive->name,
 					(unsigned long long)block);
 
-			tf->hob_nsect = (nsectors >> 8) & 0xff;
-			tf->hob_lbal  = (u8)(block >> 24);
-			if (sizeof(block) != 4) {
-				tf->hob_lbam = (u8)((u64)block >> 32);
-				tf->hob_lbah = (u8)((u64)block >> 40);
-			}
-
 			tf->nsect  = nsectors & 0xff;
 			tf->lbal   = (u8) block;
 			tf->lbam   = (u8)(block >>  8);
 			tf->lbah   = (u8)(block >> 16);
+			tf->device = ATA_LBA;
 
-			cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+			tf = &cmd.hob;
+			tf->nsect = (nsectors >> 8) & 0xff;
+			tf->lbal  = (u8)(block >> 24);
+			if (sizeof(block) != 4) {
+				tf->lbam = (u8)((u64)block >> 32);
+				tf->lbah = (u8)((u64)block >> 40);
+			}
+
+			cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+			cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+			cmd.tf_flags |= IDE_TFLAG_LBA48;
 		} else {
 			tf->nsect  = nsectors & 0xff;
 			tf->lbal   = block;
 			tf->lbam   = block >>= 8;
 			tf->lbah   = block >>= 8;
-			tf->device = (block >> 8) & 0xf;
+			tf->device = ((block >> 8) & 0xf) | ATA_LBA;
 		}
-
-		tf->device |= ATA_LBA;
 	} else {
 		unsigned int sect, head, cyl, track;
 
@@ -220,15 +223,19 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
 		tf->command = ATA_CMD_READ_NATIVE_MAX;
 	tf->device  = ATA_LBA;
 
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	if (lba48)
-		cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	if (lba48) {
+		cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+		cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	}
 
 	ide_no_data_taskfile(drive, &cmd);
 
 	/* if OK, compute maximum address value */
 	if (!(tf->status & ATA_ERR))
-		addr = ide_get_lba_addr(tf, lba48) + 1;
+		addr = ide_get_lba_addr(&cmd, lba48) + 1;
 
 	return addr;
 }
@@ -250,9 +257,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
 	tf->lbam     = (addr_req >>= 8) & 0xff;
 	tf->lbah     = (addr_req >>= 8) & 0xff;
 	if (lba48) {
-		tf->hob_lbal = (addr_req >>= 8) & 0xff;
-		tf->hob_lbam = (addr_req >>= 8) & 0xff;
-		tf->hob_lbah = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbal = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbam = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbah = (addr_req >>= 8) & 0xff;
 		tf->command  = ATA_CMD_SET_MAX_EXT;
 	} else {
 		tf->device   = (addr_req >>= 8) & 0x0f;
@@ -260,15 +267,19 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
 	}
 	tf->device |= ATA_LBA;
 
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	if (lba48)
-		cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	if (lba48) {
+		cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+		cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	}
 
 	ide_no_data_taskfile(drive, &cmd);
 
 	/* if OK, compute maximum address value */
 	if (!(tf->status & ATA_ERR))
-		addr_set = ide_get_lba_addr(tf, lba48) + 1;
+		addr_set = ide_get_lba_addr(&cmd, lba48) + 1;
 
 	return addr_set;
 }
@@ -395,8 +406,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
 		cmd->tf.command = ATA_CMD_FLUSH_EXT;
 	else
 		cmd->tf.command = ATA_CMD_FLUSH;
-	cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
-			IDE_TFLAG_DYN;
+	cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd->tf_flags = IDE_TFLAG_DYN;
 	cmd->protocol = ATA_PROT_NODATA;
 
 	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
@@ -457,7 +468,8 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
 	cmd.tf.feature = feature;
 	cmd.tf.nsect   = nsect;
 	cmd.tf.command = ATA_CMD_SET_FEATURES;
-	cmd.tf_flags   = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	return ide_no_data_taskfile(drive, &cmd);
 }
@@ -533,7 +545,8 @@ static int do_idedisk_flushcache(ide_drive_t *drive)
 		cmd.tf.command = ATA_CMD_FLUSH_EXT;
 	else
 		cmd.tf.command = ATA_CMD_FLUSH;
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	return ide_no_data_taskfile(drive, &cmd);
 }
@@ -715,7 +728,8 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
-	cmd.tf_flags   = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	ret = ide_no_data_taskfile(drive, &cmd);
 
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index eaea3bef2073..19f263bf0a9e 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -13,7 +13,8 @@ static int smart_enable(ide_drive_t *drive)
 	tf->lbam    = ATA_SMART_LBAM_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->command = ATA_CMD_SMART;
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	return ide_no_data_taskfile(drive, &cmd);
 }
@@ -29,7 +30,8 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 	tf->lbam    = ATA_SMART_LBAM_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->command = ATA_CMD_SMART;
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 	cmd.protocol = ATA_PROT_PIO;
 
 	return ide_raw_taskfile(drive, &cmd, buf, 1);
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 16fc46edc32d..e4cdf78cc3e9 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -277,8 +277,6 @@ void ide_dma_start(ide_drive_t *drive)
 		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
 		outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
 	}
-
-	wmb();
 }
 EXPORT_SYMBOL_GPL(ide_dma_start);
 
@@ -286,7 +284,7 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
 int ide_dma_end(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	u8 dma_stat = 0, dma_cmd = 0, mask;
+	u8 dma_stat = 0, dma_cmd = 0;
 
 	/* stop DMA */
 	if (hwif->host_flags & IDE_HFLAG_MMIO) {
@@ -304,11 +302,10 @@ int ide_dma_end(ide_drive_t *drive)
 	/* clear INTR & ERROR bits */
 	ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
 
-	wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
 
 	/* verify good DMA status */
-	mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
-	if ((dma_stat & mask) != ATA_DMA_INTR)
+	if ((dma_stat & CHECK_DMA_MASK) != ATA_DMA_INTR)
 		return 0x10 | dma_stat;
 	return 0;
 }
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 1aebdf1a4f58..4b6b71e2cdf5 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -7,6 +7,7 @@
 #include <linux/mutex.h>
 #include <linux/ide.h>
 #include <linux/hdreg.h>
+#include <linux/dmi.h>
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define IDE_DISK_MINORS		(1 << PARTN_BITS)
@@ -99,6 +100,19 @@ static void ide_gd_resume(ide_drive_t *drive)
 		(void)drive->disk_ops->get_capacity(drive);
 }
 
+static const struct dmi_system_id ide_coldreboot_table[] = {
+	{
+		/* Acer TravelMate 66x cuts power during reboot */
+		.ident   = "Acer TravelMate 660",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+		},
+	},
+
+	{ }	/* terminate list */
+};
+
 static void ide_gd_shutdown(ide_drive_t *drive)
 {
 #ifdef	CONFIG_ALPHA
@@ -115,7 +129,8 @@ static void ide_gd_shutdown(ide_drive_t *drive)
 	   the disk to expire its write cache. */
 	if (system_state != SYSTEM_POWER_OFF) {
 #else
-	if (system_state == SYSTEM_RESTART) {
+	if (system_state == SYSTEM_RESTART &&
+		!dmi_check_system(ide_coldreboot_table)) {
 #endif
 		drive->disk_ops->flush(drive);
 		return;
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index dac9a6d44963..c06ebdc4a130 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -22,103 +22,6 @@
 	(r);				\
 })
 
-static void mm_outw(u16 d, unsigned long a)
-{
-	__asm__("mov.b %w0,r2h\n\t"
-		"mov.b %x0,r2l\n\t"
-		"mov.w r2,@%1"
-		:
-		:"r"(d),"r"(a)
-		:"er2");
-}
-
-static u16 mm_inw(unsigned long a)
-{
-	register u16 r __asm__("er0");
-	__asm__("mov.w @%1,r2\n\t"
-		"mov.b r2l,%x0\n\t"
-		"mov.b r2h,%w0"
-		:"=r"(r)
-		:"r"(a)
-		:"er2");
-	return r;
-}
-
-static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
-		outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
-		outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
-		outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
-		outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		outb((tf->device & HIHI) | drive->select,
-		     io_ports->device_addr);
-}
-
-static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-
-	/* be sure we're looking at the low order bits */
-	outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
-		tf->error  = inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = inb(io_ports->lbah_addr);
-	}
-}
-
 static void mm_outsw(unsigned long addr, void *buf, u32 len)
 {
 	unsigned short *bp = (unsigned short *)buf;
@@ -152,8 +55,8 @@ static const struct ide_tp_ops h8300_tp_ops = {
 	.write_devctl		= ide_write_devctl,
 
 	.dev_select		= ide_dev_select,
-	.tf_load		= h8300_tf_load,
-	.tf_read		= h8300_tf_read,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= h8300_input_data,
 	.output_data		= h8300_output_data,
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 9cac281d82c4..46721c454518 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -85,98 +85,57 @@ void ide_dev_select(ide_drive_t *drive)
 }
 EXPORT_SYMBOL_GPL(ide_dev_select);
 
-void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
 	void (*tf_outb)(u8 addr, unsigned long port);
 	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-	u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
 
 	if (mmio)
 		tf_outb = ide_mm_outb;
 	else
 		tf_outb = ide_outb;
 
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tf_outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tf_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tf_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tf_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+	if (valid & IDE_VALID_FEATURE)
 		tf_outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		tf_outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf_outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf_outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tf_outb((tf->device & HIHI) | drive->select,
-			 io_ports->device_addr);
+	if (valid & IDE_VALID_DEVICE)
+		tf_outb(tf->device, io_ports->device_addr);
 }
 EXPORT_SYMBOL_GPL(ide_tf_load);
 
-void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	void (*tf_outb)(u8 addr, unsigned long port);
 	u8 (*tf_inb)(unsigned long port);
 	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
 
-	if (mmio) {
-		tf_outb = ide_mm_outb;
+	if (mmio)
 		tf_inb  = ide_mm_inb;
-	} else {
-		tf_outb = ide_outb;
+	else
 		tf_inb  = ide_inb;
-	}
-
-	/* be sure we're looking at the low order bits */
-	tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
 
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+	if (valid & IDE_VALID_ERROR)
 		tf->error  = tf_inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		tf->nsect  = tf_inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf->lbal   = tf_inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf->lbam   = tf_inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf->lbah   = tf_inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+	if (valid & IDE_VALID_DEVICE)
 		tf->device = tf_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = tf_inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = tf_inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = tf_inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = tf_inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = tf_inb(io_ports->lbah_addr);
-	}
 }
 EXPORT_SYMBOL_GPL(ide_tf_read);
 
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 1deb6d29b186..35dc38d3b2c5 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -86,27 +86,30 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
 
 		tp_ops->input_data(drive, cmd, data, 2);
 
-		tf->data = data[0];
-		tf->hob_data = data[1];
+		cmd->tf.data  = data[0];
+		cmd->hob.data = data[1];
 	}
 
-	tp_ops->tf_read(drive, cmd);
+	ide_tf_readback(drive, cmd);
 
 	if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
 	    tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
 		if (tf->lbal != 0xc4) {
 			printk(KERN_ERR "%s: head unload failed!\n",
 			       drive->name);
-			ide_tf_dump(drive->name, tf);
+			ide_tf_dump(drive->name, cmd);
 		} else
 			drive->dev_flags |= IDE_DFLAG_PARKED;
 	}
 
-	if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
-		memcpy(rq->special, cmd, sizeof(*cmd));
+	if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+		struct ide_cmd *orig_cmd = rq->special;
 
-	if (cmd->tf_flags & IDE_TFLAG_DYN)
-		kfree(cmd);
+		if (cmd->tf_flags & IDE_TFLAG_DYN)
+			kfree(orig_cmd);
+		else
+			memcpy(orig_cmd, cmd, sizeof(*cmd));
+	}
 }
 
 /* obsolete, blk_rq_bytes() should be used instead */
@@ -205,8 +208,9 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
 		return ide_stopped;
 	}
 
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
-		       IDE_TFLAG_CUSTOM_HANDLER;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER;
 
 	do_rw_taskfile(drive, &cmd);
 
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 770142767437..c1c25ebbaa1f 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -141,11 +141,12 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
 		tf->lbal  = args[1];
 		tf->lbam  = 0x4f;
 		tf->lbah  = 0xc2;
-		cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+		cmd.valid.out.tf = IDE_VALID_OUT_TF;
+		cmd.valid.in.tf  = IDE_VALID_NSECT;
 	} else {
 		tf->nsect = args[1];
-		cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
-			       IDE_TFLAG_IN_NSECT;
+		cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+		cmd.valid.in.tf  = IDE_VALID_NSECT;
 	}
 	tf->command = args[0];
 	cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
@@ -205,14 +206,15 @@ static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
 		return -EFAULT;
 
 	memset(&cmd, 0, sizeof(cmd));
-	memcpy(&cmd.tf_array[7], &args[1], 6);
+	memcpy(&cmd.tf.feature, &args[1], 6);
 	cmd.tf.command = args[0];
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	err = ide_no_data_taskfile(drive, &cmd);
 
 	args[0] = cmd.tf.command;
-	memcpy(&args[1], &cmd.tf_array[7], 6);
+	memcpy(&args[1], &cmd.tf.feature, 6);
 
 	if (copy_to_user(p, args, 7))
 		err = -EFAULT;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 27bb70ddd459..c19a221b1e18 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -37,14 +37,11 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
 
 u8 ide_read_error(ide_drive_t *drive)
 {
-	struct ide_cmd cmd;
+	struct ide_taskfile tf;
 
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_IN_ERROR;
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR);
 
-	drive->hwif->tp_ops->tf_read(drive, &cmd);
-
-	return cmd.tf.error;
+	return tf.error;
 }
 EXPORT_SYMBOL_GPL(ide_read_error);
 
@@ -312,10 +309,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+	struct ide_taskfile tf;
 	u16 *id = drive->id, i;
 	int error = 0;
 	u8 stat;
-	struct ide_cmd cmd;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_ops)	/* check if host supports DMA */
@@ -347,12 +344,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 	udelay(1);
 	tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
 
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
-	cmd.tf.feature = SETFEATURES_XFER;
-	cmd.tf.nsect   = speed;
+	memset(&tf, 0, sizeof(tf));
+	tf.feature = SETFEATURES_XFER;
+	tf.nsect   = speed;
 
-	tp_ops->tf_load(drive, &cmd);
+	tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT);
 
 	tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
 
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 217b7fdf2b17..56ff8c46c7d1 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -49,16 +49,17 @@ static void ide_dump_opcode(ide_drive_t *drive)
 		printk(KERN_CONT "0x%02x\n", cmd->tf.command);
 }
 
-u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
+u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48)
 {
+	struct ide_taskfile *tf = &cmd->tf;
 	u32 high, low;
 
-	if (lba48)
-		high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) |
-			tf->hob_lbal;
-	else
-		high = tf->device & 0xf;
 	low  = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+	if (lba48) {
+		tf = &cmd->hob;
+		high = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+	} else
+		high = tf->device & 0xf;
 
 	return ((u64)high << 24) | low;
 }
@@ -71,17 +72,18 @@ static void ide_dump_sector(ide_drive_t *drive)
 	u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
 
 	memset(&cmd, 0, sizeof(cmd));
-	if (lba48)
-		cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
-				IDE_TFLAG_LBA48;
-	else
-		cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+	if (lba48) {
+		cmd.valid.in.tf  = IDE_VALID_LBA;
+		cmd.valid.in.hob = IDE_VALID_LBA;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	} else
+		cmd.valid.in.tf  = IDE_VALID_LBA | IDE_VALID_DEVICE;
 
-	drive->hwif->tp_ops->tf_read(drive, &cmd);
+	ide_tf_readback(drive, &cmd);
 
 	if (lba48 || (tf->device & ATA_LBA))
 		printk(KERN_CONT ", LBAsect=%llu",
-			(unsigned long long)ide_get_lba_addr(tf, lba48));
+			(unsigned long long)ide_get_lba_addr(&cmd, lba48));
 	else
 		printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam,
 			tf->device & 0xf, tf->lbal);
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 9490b446519f..310d03f2b5b7 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -74,7 +74,8 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
 		tf->lbal = 0x4c;
 		tf->lbam = 0x4e;
 		tf->lbah = 0x55;
-		cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+		cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+		cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 	} else		/* cmd == REQ_UNPARK_HEADS */
 		tf->command = ATA_CMD_CHK_POWER;
 
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index bb7858ebb7d1..0d8a151c0a01 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -163,7 +163,8 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
 	return ide_stopped;
 
 out_do_tf:
-	cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd->valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 	cmd->protocol = ATA_PROT_NODATA;
 
 	return do_rw_taskfile(drive, cmd);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index d8c1c3e735bb..7f264ed1141b 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -283,13 +283,11 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
 	 * identify command to be sure of reply
 	 */
 	if (cmd == ATA_CMD_ID_ATAPI) {
-		struct ide_cmd cmd;
+		struct ide_taskfile tf;
 
-		memset(&cmd, 0, sizeof(cmd));
+		memset(&tf, 0, sizeof(tf));
 		/* disable DMA & overlap */
-		cmd.tf_flags = IDE_TFLAG_OUT_FEATURE;
-
-		tp_ops->tf_load(drive, &cmd);
+		tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE);
 	}
 
 	/* ask drive for ID */
@@ -337,14 +335,11 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
 
 static u8 ide_read_device(ide_drive_t *drive)
 {
-	struct ide_cmd cmd;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.tf_flags = IDE_TFLAG_IN_DEVICE;
+	struct ide_taskfile tf;
 
-	drive->hwif->tp_ops->tf_read(drive, &cmd);
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE);
 
-	return cmd.tf.device;
+	return tf.device;
 }
 
 /**
@@ -1314,6 +1309,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
 		host->get_lock     = d->get_lock;
 		host->release_lock = d->release_lock;
 		host->host_flags = d->host_flags;
+		host->irq_flags = d->irq_flags;
 	}
 
 	return host;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 10a88bf3eefa..3242698832a4 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -204,8 +204,8 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
 	cmd.tf.command = ATA_CMD_SET_FEATURES;
 	cmd.tf.feature = SETFEATURES_XFER;
 	cmd.tf.nsect   = (u8)arg;
-	cmd.tf_flags   = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
-			 IDE_TFLAG_IN_NSECT;
+	cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+	cmd.valid.in.tf  = IDE_VALID_NSECT;
 
 	err = ide_no_data_taskfile(drive, &cmd);
 
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 243421ce40d0..4aa6223c11be 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -23,17 +23,33 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-void ide_tf_dump(const char *s, struct ide_taskfile *tf)
+void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+
+	/* Be sure we're looking at the low order bytes */
+	tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+
+	tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
+
+	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+		tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
+
+		tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
+	}
+}
+
+void ide_tf_dump(const char *s, struct ide_cmd *cmd)
 {
 #ifdef DEBUG
 	printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
 		"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
-		s, tf->feature, tf->nsect, tf->lbal,
-		tf->lbam, tf->lbah, tf->device, tf->command);
-	printk("%s: hob: nsect 0x%02x lbal 0x%02x "
-		"lbam 0x%02x lbah 0x%02x\n",
-		s, tf->hob_nsect, tf->hob_lbal,
-		tf->hob_lbam, tf->hob_lbah);
+	       s, cmd->tf.feature, cmd->tf.nsect,
+	       cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
+	       cmd->tf.device, cmd->tf.command);
+	printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n",
+	       s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
 #endif
 }
 
@@ -47,7 +63,8 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
 		cmd.tf.command = ATA_CMD_ID_ATA;
 	else
 		cmd.tf.command = ATA_CMD_ID_ATAPI;
-	cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 	cmd.protocol = ATA_PROT_PIO;
 
 	return ide_raw_taskfile(drive, &cmd, buf, 1);
@@ -79,16 +96,27 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
 	memcpy(cmd, orig_cmd, sizeof(*cmd));
 
 	if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
-		ide_tf_dump(drive->name, tf);
+		ide_tf_dump(drive->name, cmd);
 		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 		SELECT_MASK(drive, 0);
 
 		if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
-			u8 data[2] = { tf->data, tf->hob_data };
+			u8 data[2] = { cmd->tf.data, cmd->hob.data };
 
 			tp_ops->output_data(drive, cmd, data, 2);
 		}
-		tp_ops->tf_load(drive, cmd);
+
+		if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
+			u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
+				  0xE0 : 0xEF;
+
+			if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
+				cmd->tf.device &= HIHI;
+			cmd->tf.device |= drive->select;
+		}
+
+		tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
+		tp_ops->tf_load(drive, &cmd->tf,  cmd->valid.out.tf);
 	}
 
 	switch (cmd->protocol) {
@@ -489,16 +517,17 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 
 	memset(&cmd, 0, sizeof(cmd));
 
-	memcpy(&cmd.tf_array[0], req_task->hob_ports,
-	       HDIO_DRIVE_HOB_HDR_SIZE - 2);
-	memcpy(&cmd.tf_array[6], req_task->io_ports,
-	       HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+	memcpy(&cmd.tf,  req_task->io_ports,  HDIO_DRIVE_TASK_HDR_SIZE);
 
-	cmd.tf_flags   = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
-			 IDE_TFLAG_IN_TF;
+	cmd.valid.out.tf = IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_DEVICE | IDE_VALID_IN_TF;
+	cmd.tf_flags = IDE_TFLAG_IO_16BIT;
 
-	if (drive->dev_flags & IDE_DFLAG_LBA48)
-		cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+	if (drive->dev_flags & IDE_DFLAG_LBA48) {
+		cmd.tf_flags |= IDE_TFLAG_LBA48;
+		cmd.valid.in.hob = IDE_VALID_IN_HOB;
+	}
 
 	if (req_task->out_flags.all) {
 		cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
@@ -507,28 +536,28 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 			cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
 
 		if (req_task->out_flags.b.nsector_hob)
-			cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+			cmd.valid.out.hob |= IDE_VALID_NSECT;
 		if (req_task->out_flags.b.sector_hob)
-			cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+			cmd.valid.out.hob |= IDE_VALID_LBAL;
 		if (req_task->out_flags.b.lcyl_hob)
-			cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+			cmd.valid.out.hob |= IDE_VALID_LBAM;
 		if (req_task->out_flags.b.hcyl_hob)
-			cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+			cmd.valid.out.hob |= IDE_VALID_LBAH;
 
 		if (req_task->out_flags.b.error_feature)
-			cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+			cmd.valid.out.tf  |= IDE_VALID_FEATURE;
 		if (req_task->out_flags.b.nsector)
-			cmd.tf_flags |= IDE_TFLAG_OUT_NSECT;
+			cmd.valid.out.tf  |= IDE_VALID_NSECT;
 		if (req_task->out_flags.b.sector)
-			cmd.tf_flags |= IDE_TFLAG_OUT_LBAL;
+			cmd.valid.out.tf  |= IDE_VALID_LBAL;
 		if (req_task->out_flags.b.lcyl)
-			cmd.tf_flags |= IDE_TFLAG_OUT_LBAM;
+			cmd.valid.out.tf  |= IDE_VALID_LBAM;
 		if (req_task->out_flags.b.hcyl)
-			cmd.tf_flags |= IDE_TFLAG_OUT_LBAH;
+			cmd.valid.out.tf  |= IDE_VALID_LBAH;
 	} else {
-		cmd.tf_flags |= IDE_TFLAG_OUT_TF;
+		cmd.valid.out.tf |= IDE_VALID_OUT_TF;
 		if (cmd.tf_flags & IDE_TFLAG_LBA48)
-			cmd.tf_flags |= IDE_TFLAG_OUT_HOB;
+			cmd.valid.out.hob |= IDE_VALID_OUT_HOB;
 	}
 
 	if (req_task->in_flags.b.data)
@@ -594,7 +623,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 	if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
 		nsect = 0;
 	else if (!nsect) {
-		nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect;
+		nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
 
 		if (!nsect) {
 			printk(KERN_ERR "%s: in/out command without data\n",
@@ -606,10 +635,8 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 
 	err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
 
-	memcpy(req_task->hob_ports, &cmd.tf_array[0],
-	       HDIO_DRIVE_HOB_HDR_SIZE - 2);
-	memcpy(req_task->io_ports, &cmd.tf_array[6],
-	       HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+	memcpy(req_task->io_ports,  &cmd.tf,  HDIO_DRIVE_TASK_HDR_SIZE);
 
 	if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
 	    req_task->in_flags.all == 0) {
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 71a39fb3856f..95327a2c2422 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -61,41 +61,23 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
 	return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
 }
 
-static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+static void superio_tf_read(ide_drive_t *drive, struct ide_taskfile *tf,
+			    u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
 
-	/* be sure we're looking at the low order bits */
-	outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+	if (valid & IDE_VALID_ERROR)
 		tf->error  = inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		tf->nsect  = inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf->lbal   = inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf->lbam   = inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf->lbah   = inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+	if (valid & IDE_VALID_DEVICE)
 		tf->device = superio_ide_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = inb(io_ports->lbah_addr);
-	}
 }
 
 static void ns87415_dev_select(ide_drive_t *drive);
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index c7acca0b8733..09d813d313f4 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -39,27 +39,12 @@
 /* Primary Control Offset */
 #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
 
-/*
- * PalmChip 3710 IDE Controller UDMA timing structure Definition
- */
-struct palm_bk3710_udmatiming {
-	unsigned int rptime;	/* Ready to pause time  */
-	unsigned int cycletime;	/* Cycle Time           */
-};
-
 #define BK3710_BMICP		0x00
 #define BK3710_BMISP		0x02
 #define BK3710_BMIDTP		0x04
-#define BK3710_BMICS		0x08
-#define BK3710_BMISS		0x0A
-#define BK3710_BMIDTS		0x0C
 #define BK3710_IDETIMP		0x40
-#define BK3710_IDETIMS		0x42
-#define BK3710_SIDETIM		0x44
-#define BK3710_SLEWCTL		0x45
 #define BK3710_IDESTATUS	0x47
 #define BK3710_UDMACTL		0x48
-#define BK3710_UDMATIM		0x4A
 #define BK3710_MISCCTL		0x50
 #define BK3710_REGSTB		0x54
 #define BK3710_REGRCVR		0x58
@@ -71,17 +56,22 @@ struct palm_bk3710_udmatiming {
 #define BK3710_UDMATRP		0x70
 #define BK3710_UDMAENV		0x74
 #define BK3710_IORDYTMP		0x78
-#define BK3710_IORDYTMS		0x7C
 
 static unsigned ideclk_period; /* in nanoseconds */
 
+struct palm_bk3710_udmatiming {
+	unsigned int rptime;	/* tRP -- Ready to pause time (nsec) */
+	unsigned int cycletime;	/* tCYCTYP2/2 -- avg Cycle Time (nsec) */
+				/* tENV is always a minimum of 20 nsec */
+};
+
 static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
-	{160, 240},		/* UDMA Mode 0 */
-	{125, 160},		/* UDMA Mode 1 */
-	{100, 120},		/* UDMA Mode 2 */
-	{100, 90},		/* UDMA Mode 3 */
-	{100, 60},		/* UDMA Mode 4 */
-	{85,  40},		/* UDMA Mode 5 */
+	{ 160, 240 / 2 },	/* UDMA Mode 0 */
+	{ 125, 160 / 2 },	/* UDMA Mode 1 */
+	{ 100, 120 / 2 },	/* UDMA Mode 2 */
+	{ 100,  90 / 2 },	/* UDMA Mode 3 */
+	{ 100,  60 / 2 },	/* UDMA Mode 4 */
+	{  85,  40 / 2 },	/* UDMA Mode 5 */
 };
 
 static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
@@ -98,11 +88,6 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
 	trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
 			   ideclk_period) - 1;
 
-	/* udmatim Register */
-	val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
-	val16 |= (mode << (dev ? 4 : 0));
-	writew(val16, base + BK3710_UDMATIM);
-
 	/* udmastb Ultra DMA Access Strobe Width */
 	val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
 	val32 |= (t0 << (dev ? 8 : 0));
@@ -163,10 +148,11 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
 	u32 val32;
 	struct ide_timing *t;
 
+	t = ide_timing_find_mode(XFER_PIO_0 + mode);
+
 	/* PIO Data Setup */
 	t0 = DIV_ROUND_UP(cycletime, ideclk_period);
-	t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
-			  ideclk_period);
+	t2 = DIV_ROUND_UP(t->active, ideclk_period);
 
 	t2i = t0 - t2 - 1;
 	t2 -= 1;
@@ -187,7 +173,6 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
 	}
 
 	/* TASKFILE Setup */
-	t = ide_timing_find_mode(XFER_PIO_0 + mode);
 	t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
 	t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
 
@@ -236,42 +221,23 @@ static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
 static void __devinit palm_bk3710_chipinit(void __iomem *base)
 {
 	/*
-	 * enable the reset_en of ATA controller so that when ata signals
-	 * are brought out, by writing into device config. at that
-	 * time por_n signal should not be 'Z' and have a stable value.
+	 * REVISIT:  the ATA reset signal needs to be managed through a
+	 * GPIO, which means it should come from platform_data.  Until
+	 * we get and use such information, we have to trust that things
+	 * have been reset before we get here.
 	 */
-	writel(0x0300, base + BK3710_MISCCTL);
-
-	/* wait for some time and deassert the reset of ATA Device. */
-	mdelay(100);
-
-	/* Deassert the Reset */
-	writel(0x0200, base + BK3710_MISCCTL);
 
 	/*
 	 * Program the IDETIMP Register Value based on the following assumptions
 	 *
 	 * (ATA_IDETIMP_IDEEN		, ENABLE ) |
-	 * (ATA_IDETIMP_SLVTIMEN	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSMPL		, 70NS)    |
-	 * (ATA_IDETIMP_RDYRCVRY	, 50NS)    |
-	 * (ATA_IDETIMP_DMAFTIM1	, PIOCOMP) |
 	 * (ATA_IDETIMP_PREPOST1	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSEN1		, DISABLE) |
-	 * (ATA_IDETIMP_PIOFTIM1	, DISABLE) |
-	 * (ATA_IDETIMP_DMAFTIM0	, PIOCOMP) |
 	 * (ATA_IDETIMP_PREPOST0	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSEN0		, DISABLE) |
-	 * (ATA_IDETIMP_PIOFTIM0	, DISABLE)
-	 */
-	writew(0xB388, base + BK3710_IDETIMP);
-
-	/*
-	 * Configure  SIDETIM  Register
-	 * (ATA_SIDETIM_RDYSMPS1	,120NS ) |
-	 * (ATA_SIDETIM_RDYRCYS1	,120NS )
+	 *
+	 * DM6446 silicon rev 2.1 and earlier have no observed net benefit
+	 * from enabling prefetch/postwrite.
 	 */
-	writeb(0, base + BK3710_SIDETIM);
+	writew(BIT(15), base + BK3710_IDETIMP);
 
 	/*
 	 * UDMACTL Ultra-ATA DMA Control
@@ -283,11 +249,11 @@ static void __devinit palm_bk3710_chipinit(void __iomem *base)
 
 	/*
 	 * MISCCTL Miscellaneous Conrol Register
-	 * (ATA_MISCCTL_RSTMODEP	, 1) |
-	 * (ATA_MISCCTL_RESETP		, 0) |
+	 * (ATA_MISCCTL_HWNHLD1P	, 1 cycle)
+	 * (ATA_MISCCTL_HWNHLD0P	, 1 cycle)
 	 * (ATA_MISCCTL_TIMORIDE	, 1)
 	 */
-	writel(0x201, base + BK3710_MISCCTL);
+	writel(0x001, base + BK3710_MISCCTL);
 
 	/*
 	 * IORDYTMP IORDY Timer for Primary Register
@@ -357,10 +323,9 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
 
 	clk_enable(clk);
 	rate = clk_get_rate(clk);
-	ideclk_period = 1000000000UL / rate;
 
-	/* Register the IDE interface with Linux ATA Interface */
-	memset(&hw, 0, sizeof(hw));
+	/* NOTE:  round *down* to meet minimum timings; we count in clocks */
+	ideclk_period = 1000000000UL / rate;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (mem == NULL) {
@@ -390,6 +355,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
 	/* Configure the Palm Chip controller */
 	palm_bk3710_chipinit(base);
 
+	memset(&hw, 0, sizeof(hw));
 	for (i = 0; i < IDE_NR_PORTS - 2; i++)
 		hw.io_ports_array[i] = (unsigned long)
 				(base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
@@ -402,6 +368,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
 	palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
 							     ATA_UDMA5;
 
+	/* Register the IDE interface with Linux */
 	rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
 	if (rc)
 		goto out;
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 052b9bf1f8fb..f76e4e6b408f 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -1682,7 +1682,7 @@ static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
 	 * The +2 is +1 for the stop command and +1 to allow for
 	 * aligning the start address to a multiple of 16 bytes.
 	 */
-	pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
+	pmif->dma_table_cpu = pci_alloc_consistent(
 		dev,
 		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
 		&hwif->dmatable_dma);
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index d007e7f66598..c79346679244 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -16,6 +16,8 @@
 #include <linux/blkdev.h>
 #include <linux/ide.h>
 
+#include <asm/ide.h>
+
     /*
      *  Bases of the IDE interfaces
      */
@@ -77,8 +79,10 @@ static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
-		return insw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_insw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
 	raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
@@ -88,8 +92,10 @@ static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
-		return outsw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
 	raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 6d8dbd9c10bc..5be41f25204f 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -337,7 +337,6 @@ static void scc_dma_start(ide_drive_t *drive)
 
 	/* start DMA */
 	scc_ide_outb(dma_cmd | 1, hwif->dma_base);
-	wmb();
 }
 
 static int __scc_dma_end(ide_drive_t *drive)
@@ -354,7 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
 	/* clear the INTR & ERROR bits */
 	scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
 	/* verify good DMA status */
-	wmb();
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
 }
 
@@ -647,77 +645,40 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
 	return rc;
 }
 
-static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+
+	if (valid & IDE_VALID_FEATURE)
 		scc_ide_outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		scc_ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		scc_ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		scc_ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		scc_ide_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		scc_ide_outb((tf->device & HIHI) | drive->select,
-			     io_ports->device_addr);
+	if (valid & IDE_VALID_DEVICE)
+		scc_ide_outb(tf->device, io_ports->device_addr);
 }
 
-static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-
-	/* be sure we're looking at the low order bits */
-	scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
 
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+	if (valid & IDE_VALID_ERROR)
 		tf->error  = scc_ide_inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		tf->nsect  = scc_ide_inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf->lbal   = scc_ide_inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf->lbam   = scc_ide_inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf->lbah   = scc_ide_inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+	if (valid & IDE_VALID_DEVICE)
 		tf->device = scc_ide_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = scc_ide_inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = scc_ide_inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = scc_ide_inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = scc_ide_inb(io_ports->lbah_addr);
-	}
 }
 
 static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index 4cb79c4c2604..e33d764e2945 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -72,91 +72,6 @@ static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 #ifdef __BIG_ENDIAN
 
 /* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4938ide_inb(unsigned long port)
-{
-	return __raw_readb((void __iomem *)port);
-}
-
-static void tx4938ide_outb(u8 value, unsigned long port)
-{
-	__raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		tx4938ide_outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
-		tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
-		tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
-		tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
-		tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tx4938ide_outb((tf->device & HIHI) | drive->select,
-			       io_ports->device_addr);
-}
-
-static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-
-	/* be sure we're looking at the low order bits */
-	tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
-		tf->error  = tx4938ide_inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = tx4938ide_inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = tx4938ide_inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = tx4938ide_inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = tx4938ide_inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = tx4938ide_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = tx4938ide_inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = tx4938ide_inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = tx4938ide_inb(io_ports->lbah_addr);
-	}
-}
-
 static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
@@ -190,8 +105,8 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
 	.write_devctl		= ide_write_devctl,
 
 	.dev_select		= ide_dev_select,
-	.tf_load		= tx4938ide_tf_load,
-	.tf_read		= tx4938ide_tf_read,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= tx4938ide_input_data_swap,
 	.output_data		= tx4938ide_output_data_swap,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 0040a9a3e26e..564422d23976 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -327,15 +327,15 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
 	/* read and clear the INTR & ERROR bits */
 	dma_stat = tx4939ide_clear_dma_status(base);
 
-	wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
 
 	/* verify good DMA status */
-	if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
+	if ((dma_stat & CHECK_DMA_MASK) == 0 &&
 	    (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
 	    (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
 		/* INT_IDE lost... bug? */
 		return 0;
-	return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) !=
+	return ((dma_stat & CHECK_DMA_MASK) !=
 		ATA_DMA_INTR) ? 0x10 | dma_stat : 0;
 }
 
@@ -434,97 +434,19 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
 	tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
 }
 
-#ifdef __BIG_ENDIAN
-
-/* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4939ide_inb(unsigned long port)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf,
+			      u8 valid)
 {
-	return __raw_readb((void __iomem *)port);
-}
+	ide_tf_load(drive, tf, valid);
 
-static void tx4939ide_outb(u8 value, unsigned long port)
-{
-	__raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-	u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
-	if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		tx4939ide_outb(tf->feature, io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
-		tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
-		tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
-		tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
-		tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) {
-		tx4939ide_outb((tf->device & HIHI) | drive->select,
-			       io_ports->device_addr);
+	if (valid & IDE_VALID_DEVICE)
 		tx4939ide_tf_load_fixup(drive);
-	}
 }
 
-static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &cmd->tf;
-
-	/* be sure we're looking at the low order bits */
-	tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
-		tf->error  = tx4939ide_inb(io_ports->feature_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = tx4939ide_inb(io_ports->nsect_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = tx4939ide_inb(io_ports->lbal_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = tx4939ide_inb(io_ports->lbam_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = tx4939ide_inb(io_ports->lbah_addr);
-	if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = tx4939ide_inb(io_ports->device_addr);
-
-	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
-		tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
-			tf->hob_error =	tx4939ide_inb(io_ports->feature_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal  = tx4939ide_inb(io_ports->lbal_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam  = tx4939ide_inb(io_ports->lbam_addr);
-		if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah  = tx4939ide_inb(io_ports->lbah_addr);
-	}
-}
+#ifdef __BIG_ENDIAN
 
-static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+/* custom iops (independent from SWAP_IO_SPACE) */
+static void tx4939ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -536,7 +458,7 @@ static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
 	__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
 }
 
-static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4939ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -558,7 +480,7 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
 
 	.dev_select		= ide_dev_select,
 	.tf_load		= tx4939ide_tf_load,
-	.tf_read		= tx4939ide_tf_read,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= tx4939ide_input_data_swap,
 	.output_data		= tx4939ide_output_data_swap,
@@ -566,14 +488,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
 
 #else	/* __LITTLE_ENDIAN */
 
-static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-	ide_tf_load(drive, cmd);
-
-	if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tx4939ide_tf_load_fixup(drive);
-}
-
 static const struct ide_tp_ops tx4939ide_tp_ops = {
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 2a2e50871b40..851de83ff455 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
 	id_priv->cma_dev = NULL;
 }
 
-static int cma_set_qkey(struct ib_device *device, u8 port_num,
-			enum rdma_port_space ps,
-			struct rdma_dev_addr *dev_addr, u32 *qkey)
+static int cma_set_qkey(struct rdma_id_private *id_priv)
 {
 	struct ib_sa_mcmember_rec rec;
 	int ret = 0;
 
-	switch (ps) {
+	if (id_priv->qkey)
+		return 0;
+
+	switch (id_priv->id.ps) {
 	case RDMA_PS_UDP:
-		*qkey = RDMA_UDP_QKEY;
+		id_priv->qkey = RDMA_UDP_QKEY;
 		break;
 	case RDMA_PS_IPOIB:
-		ib_addr_get_mgid(dev_addr, &rec.mgid);
-		ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
-		*qkey = be32_to_cpu(rec.qkey);
+		ib_addr_get_mgid(&id_priv->id.route.addr.dev_addr, &rec.mgid);
+		ret = ib_sa_get_mcmember_rec(id_priv->id.device,
+					     id_priv->id.port_num, &rec.mgid,
+					     &rec);
+		if (!ret)
+			id_priv->qkey = be32_to_cpu(rec.qkey);
 		break;
 	default:
 		break;
@@ -341,12 +345,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
 		ret = ib_find_cached_gid(cma_dev->device, &gid,
 					 &id_priv->id.port_num, NULL);
 		if (!ret) {
-			ret = cma_set_qkey(cma_dev->device,
-					   id_priv->id.port_num,
-					   id_priv->id.ps, dev_addr,
-					   &id_priv->qkey);
-			if (!ret)
-				cma_attach_to_dev(id_priv, cma_dev);
+			cma_attach_to_dev(id_priv, cma_dev);
 			break;
 		}
 	}
@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
 	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
 	if (cma_is_ud_ps(id_priv->id.ps)) {
+		ret = cma_set_qkey(id_priv);
+		if (ret)
+			return ret;
+
 		qp_attr->qkey = id_priv->qkey;
 		*qp_attr_mask |= IB_QP_QKEY;
 	} else {
@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
 			event.status = ib_event->param.sidr_rep_rcvd.status;
 			break;
 		}
+		ret = cma_set_qkey(id_priv);
+		if (ret) {
+			event.event = RDMA_CM_EVENT_ADDR_ERROR;
+			event.status = -EINVAL;
+			break;
+		}
 		if (id_priv->qkey != rep->qkey) {
 			event.event = RDMA_CM_EVENT_UNREACHABLE;
 			event.status = -EINVAL;
@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
 			     const void *private_data, int private_data_len)
 {
 	struct ib_cm_sidr_rep_param rep;
+	int ret;
 
 	memset(&rep, 0, sizeof rep);
 	rep.status = status;
 	if (status == IB_SIDR_SUCCESS) {
+		ret = cma_set_qkey(id_priv);
+		if (ret)
+			return ret;
 		rep.qp_num = id_priv->qp_num;
 		rep.qkey = id_priv->qkey;
 	}
@@ -2713,6 +2726,10 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
 		    IB_SA_MCMEMBER_REC_FLOW_LABEL |
 		    IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
 
+	if (id_priv->id.ps == RDMA_PS_IPOIB)
+		comp_mask |= IB_SA_MCMEMBER_REC_RATE |
+			     IB_SA_MCMEMBER_REC_RATE_SELECTOR;
+
 	mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
 						id_priv->id.port_num, &rec,
 						comp_mask, GFP_KERNEL,
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index a4a82bff7100..8d71086f5a1c 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid)
 	sge_cmd = qpid << 8 | 3;
 	wqe->sge_cmd = cpu_to_be64(sge_cmd);
 	skb->priority = CPL_PRIORITY_CONTROL;
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 }
 
 int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
@@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
 	     (unsigned long long) rdev_p->ctrl_qp.dma_addr,
 	     rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
 	skb->priority = CPL_PRIORITY_CONTROL;
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 err:
 	kfree_skb(skb);
 	return err;
@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
 	u32 stag_idx;
 	u32 wptr;
 
-	if (rdev_p->flags)
+	if (cxio_fatal_error(rdev_p))
 		return -EIO;
 
 	stag_state = stag_state > 0;
@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
 	wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
 	wqe->irs = cpu_to_be32(attr->irs);
 	skb->priority = 0;	/* 0=>ToeQ; 1=>CtrlQ */
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 }
 
 void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb)
@@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p)
 		cxio_hal_pblpool_destroy(rdev_p);
 		cxio_hal_rqtpool_destroy(rdev_p);
 		list_del(&rdev_p->entry);
-		rdev_p->t3cdev_p->ulp = NULL;
 		cxio_hal_destroy_ctrl_qp(rdev_p);
 		cxio_hal_destroy_resource(rdev_p->rscp);
+		rdev_p->t3cdev_p->ulp = NULL;
 	}
 }
 
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 094a66d1480c..bfd03bf8be54 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -115,6 +115,11 @@ struct cxio_rdev {
 #define	CXIO_ERROR_FATAL	1
 };
 
+static inline int cxio_fatal_error(struct cxio_rdev *rdev_p)
+{
+	return rdev_p->flags & CXIO_ERROR_FATAL;
+}
+
 static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
 {
 	return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
 void cxio_flush_hw_cq(struct t3_cq *cq);
 int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
 		     u8 *cqe_flushed, u64 *cookie, u32 *credit);
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb);
 
 #define MOD "iw_cxgb3: "
 #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args)
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 37a4fc264a07..26fc0a4eaa74 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev)
 static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
 {
 	struct cxio_rdev *rdev = tdev->ulp;
+	struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev);
+	struct ib_event event;
 
-	if (status == OFFLOAD_STATUS_DOWN)
+	if (status == OFFLOAD_STATUS_DOWN) {
 		rdev->flags = CXIO_ERROR_FATAL;
 
-	return;
+		event.device = &rnicp->ibdev;
+		event.event  = IB_EVENT_DEVICE_FATAL;
+		event.element.port_num = 0;
+		ib_dispatch_event(&event);
+	}
 
+	return;
 }
 
 static int __init iwch_init_module(void)
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 3773453b2cf0..84735506333f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev)
 	return container_of(ibdev, struct iwch_dev, ibdev);
 }
 
+static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev)
+{
+	return container_of(rdev, struct iwch_dev, rdev);
+}
+
 static inline int t3b_device(const struct iwch_dev *rhp)
 {
 	return rhp->rdev.t3cdev_p->type == T3B;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 8699947aaf6c..52d7bb0c2a12 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep)
 	put_ep(&ep->com);
 }
 
+int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e)
+{
+	int	error = 0;
+	struct cxio_rdev *rdev;
+
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		kfree_skb(skb);
+		return -EIO;
+	}
+	error = l2t_send(tdev, skb, l2e);
+	if (error)
+		kfree_skb(skb);
+	return error;
+}
+
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
+{
+	int	error = 0;
+	struct cxio_rdev *rdev;
+
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		kfree_skb(skb);
+		return -EIO;
+	}
+	error = cxgb3_ofld_send(tdev, skb);
+	if (error)
+		kfree_skb(skb);
+	return error;
+}
+
 static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
 {
 	struct cpl_tid_release *req;
@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
 	skb->priority = CPL_PRIORITY_SETUP;
-	cxgb3_ofld_send(tdev, skb);
+	iwch_cxgb3_ofld_send(tdev, skb);
 	return;
 }
 
@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
 	req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
 
 	skb->priority = CPL_PRIORITY_DATA;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 int iwch_resume_tid(struct iwch_ep *ep)
@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
 	req->val = 0;
 
 	skb->priority = CPL_PRIORITY_DATA;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static void set_emss(struct iwch_ep *ep, u16 opt)
@@ -252,18 +282,22 @@ static void *alloc_ep(int size, gfp_t gfp)
 
 void __free_ep(struct kref *kref)
 {
-	struct iwch_ep_common *epc;
-	epc = container_of(kref, struct iwch_ep_common, kref);
-	PDBG("%s ep %p state %s\n", __func__, epc, states[state_read(epc)]);
-	kfree(epc);
+	struct iwch_ep *ep;
+	ep = container_of(container_of(kref, struct iwch_ep_common, kref),
+			  struct iwch_ep, com);
+	PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
+	if (ep->com.flags & RELEASE_RESOURCES) {
+		cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
+		dst_release(ep->dst);
+		l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+	}
+	kfree(ep);
 }
 
 static void release_ep_resources(struct iwch_ep *ep)
 {
 	PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid);
-	cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
-	dst_release(ep->dst);
-	l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+	ep->com.flags |= RELEASE_RESOURCES;
 	put_ep(&ep->com);
 }
 
@@ -382,7 +416,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
 
 	PDBG("%s t3cdev %p\n", __func__, dev);
 	req->cmd = CPL_ABORT_NO_RST;
-	cxgb3_ofld_send(dev, skb);
+	iwch_cxgb3_ofld_send(dev, skb);
 }
 
 static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
@@ -402,8 +436,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
 	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
@@ -424,8 +457,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
 	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
 	req->cmd = CPL_ABORT_SEND_RST;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_connect(struct iwch_ep *ep)
@@ -469,8 +501,7 @@ static int send_connect(struct iwch_ep *ep)
 	req->opt0l = htonl(opt0l);
 	req->params = 0;
 	req->opt2 = htonl(opt2);
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
@@ -527,7 +558,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
 	req->sndseq = htonl(ep->snd_seq);
 	BUG_ON(ep->mpa_skb);
 	ep->mpa_skb = skb;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
+	iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 	start_ep_timer(ep);
 	state_set(&ep->com, MPA_REQ_SENT);
 	return;
@@ -578,8 +609,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
 	req->sndseq = htonl(ep->snd_seq);
 	BUG_ON(ep->mpa_skb);
 	ep->mpa_skb = skb;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
@@ -630,8 +660,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
 	req->sndseq = htonl(ep->snd_seq);
 	ep->mpa_skb = skb;
 	state_set(&ep->com, MPA_REP_SENT);
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -795,7 +824,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits)
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
 	req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
 	skb->priority = CPL_PRIORITY_ACK;
-	cxgb3_ofld_send(ep->com.tdev, skb);
+	iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 	return credits;
 }
 
@@ -1127,8 +1156,8 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 	 * We get 2 abort replies from the HW.  The first one must
 	 * be ignored except for scribbling that we need one more.
 	 */
-	if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) {
-		ep->flags |= ABORT_REQ_IN_PROGRESS;
+	if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) {
+		ep->com.flags |= ABORT_REQ_IN_PROGRESS;
 		return CPL_RET_BUF_DONE;
 	}
 
@@ -1203,8 +1232,7 @@ static int listen_start(struct iwch_listen_ep *ep)
 	req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
 
 	skb->priority = 1;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -1237,8 +1265,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
 	req->cpu_idx = 0;
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
 	skb->priority = 1;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb,
@@ -1286,7 +1313,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb)
 	rpl->opt2 = htonl(opt2);
 	rpl->rsvd = rpl->opt2;	/* workaround for HW bug */
 	skb->priority = CPL_PRIORITY_SETUP;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
+	iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 
 	return;
 }
@@ -1315,7 +1342,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
 		rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
 		rpl->opt2 = 0;
 		rpl->rsvd = rpl->opt2;
-		cxgb3_ofld_send(tdev, skb);
+		iwch_cxgb3_ofld_send(tdev, skb);
 	}
 }
 
@@ -1534,8 +1561,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 	 * We get 2 peer aborts from the HW.  The first one must
 	 * be ignored except for scribbling that we need one more.
 	 */
-	if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) {
-		ep->flags |= PEER_ABORT_IN_PROGRESS;
+	if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) {
+		ep->com.flags |= PEER_ABORT_IN_PROGRESS;
 		return CPL_RET_BUF_DONE;
 	}
 
@@ -1613,7 +1640,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 	rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
 	rpl->cmd = CPL_ABORT_NO_RST;
-	cxgb3_ofld_send(ep->com.tdev, rpl_skb);
+	iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb);
 out:
 	if (release)
 		release_ep_resources(ep);
@@ -1803,6 +1830,10 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	ep->com.rpl_err = 0;
 	ep->ird = conn_param->ird;
 	ep->ord = conn_param->ord;
+
+	if (peer2peer && ep->ird == 0)
+		ep->ird = 1;
+
 	PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);
 
 	get_ep(&ep->com);
@@ -1888,6 +1919,10 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		       conn_param->private_data, ep->plen);
 	ep->ird = conn_param->ird;
 	ep->ord = conn_param->ord;
+
+	if (peer2peer && ep->ord == 0)
+		ep->ord = 1;
+
 	ep->com.tdev = h->rdev.t3cdev_p;
 
 	cm_id->add_ref(cm_id);
@@ -2017,8 +2052,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id)
 	ep->com.rpl_done = 0;
 	ep->com.rpl_err = 0;
 	err = listen_stop(ep);
+	if (err)
+		goto done;
 	wait_event(ep->com.waitq, ep->com.rpl_done);
 	cxgb3_free_stid(ep->com.tdev, ep->stid);
+done:
 	err = ep->com.rpl_err;
 	cm_id->rem_ref(cm_id);
 	put_ep(&ep->com);
@@ -2030,12 +2068,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
 	int ret=0;
 	unsigned long flags;
 	int close = 0;
+	int fatal = 0;
+	struct t3cdev *tdev;
+	struct cxio_rdev *rdev;
 
 	spin_lock_irqsave(&ep->com.lock, flags);
 
 	PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
 	     states[ep->com.state], abrupt);
 
+	tdev = (struct t3cdev *)ep->com.tdev;
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		fatal = 1;
+		close_complete_upcall(ep);
+		ep->com.state = DEAD;
+	}
 	switch (ep->com.state) {
 	case MPA_REQ_WAIT:
 	case MPA_REQ_SENT:
@@ -2075,7 +2123,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
 			ret = send_abort(ep, NULL, gfp);
 		else
 			ret = send_halfclose(ep, gfp);
+		if (ret)
+			fatal = 1;
 	}
+	if (fatal)
+		release_ep_resources(ep);
 	return ret;
 }
 
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index d7c7e09f0996..43c0aea7eadc 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -147,6 +147,7 @@ enum iwch_ep_state {
 enum iwch_ep_flags {
 	PEER_ABORT_IN_PROGRESS	= (1 << 0),
 	ABORT_REQ_IN_PROGRESS	= (1 << 1),
+	RELEASE_RESOURCES	= (1 << 2),
 };
 
 struct iwch_ep_common {
@@ -161,6 +162,7 @@ struct iwch_ep_common {
 	wait_queue_head_t waitq;
 	int rpl_done;
 	int rpl_err;
+	u32 flags;
 };
 
 struct iwch_listen_ep {
@@ -188,7 +190,6 @@ struct iwch_ep {
 	u16 plen;
 	u32 ird;
 	u32 ord;
-	u32 flags;
 };
 
 static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index c758fbd58478..27bbdc8e773a 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp)
 	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
 						V_FW_RIWR_LEN(flit_cnt));
 	skb->priority = CPL_PRIORITY_DATA;
-	return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+	return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
 }
 
 /*
@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
 			 V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
 	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
 	skb->priority = CPL_PRIORITY_DATA;
-	return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+	return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
 }
 
 /*
@@ -1069,7 +1069,6 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
 			goto out;
 		}
 		qhp->attr.state = IWCH_QP_STATE_IDLE;
-		memset(&qhp->attr, 0, sizeof(qhp->attr));
 		break;
 	case IWCH_QP_STATE_TERMINATE:
 		if (!internal) {
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 2ccb9d31771f..ae3d7590346e 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -394,8 +394,7 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 				       PAGE_SIZE, vma->vm_page_prot))
 			return -EAGAIN;
 	} else if (vma->vm_pgoff == 1 && dev->dev->caps.bf_reg_size != 0) {
-		/* FIXME want pgprot_writecombine() for BlueFlame pages */
-		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
 		if (io_remap_pfn_range(vma, vma->vm_start,
 				       to_mucontext(context)->uar.pfn +
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index c33e1c53c799..6d55f9d748f6 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -157,13 +157,15 @@ enum {
 enum {
 	CMD_TIME_CLASS_A = (HZ + 999) / 1000 + 1,
 	CMD_TIME_CLASS_B = (HZ +  99) /  100 + 1,
-	CMD_TIME_CLASS_C = (HZ +   9) /   10 + 1
+	CMD_TIME_CLASS_C = (HZ +   9) /   10 + 1,
+	CMD_TIME_CLASS_D = 60 * HZ
 };
 #else
 enum {
 	CMD_TIME_CLASS_A = 60 * HZ,
 	CMD_TIME_CLASS_B = 60 * HZ,
-	CMD_TIME_CLASS_C = 60 * HZ
+	CMD_TIME_CLASS_C = 60 * HZ,
+	CMD_TIME_CLASS_D = 60 * HZ
 };
 #endif
 
@@ -598,7 +600,7 @@ int mthca_SYS_EN(struct mthca_dev *dev, u8 *status)
 	u64 out;
 	int ret;
 
-	ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, HZ, status);
+	ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D, status);
 
 	if (*status == MTHCA_CMD_STAT_DDR_MEM_ERR)
 		mthca_warn(dev, "SYS_EN DDR error: syn=%x, sock=%d, "
@@ -611,7 +613,7 @@ int mthca_SYS_EN(struct mthca_dev *dev, u8 *status)
 
 int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status)
 {
-	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, HZ, status);
+	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, CMD_TIME_CLASS_C, status);
 }
 
 static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
@@ -1390,7 +1392,7 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
 		MTHCA_PUT(inbox, param->uarc_base,   INIT_HCA_UAR_CTX_BASE_OFFSET);
 	}
 
-	err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, HZ, status);
+	err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, CMD_TIME_CLASS_D, status);
 
 	mthca_free_mailbox(dev, mailbox);
 	return err;
@@ -1450,12 +1452,12 @@ int mthca_INIT_IB(struct mthca_dev *dev,
 
 int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status)
 {
-	return mthca_cmd(dev, 0, port, 0, CMD_CLOSE_IB, HZ, status);
+	return mthca_cmd(dev, 0, port, 0, CMD_CLOSE_IB, CMD_TIME_CLASS_A, status);
 }
 
 int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status)
 {
-	return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, HZ, status);
+	return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, CMD_TIME_CLASS_C, status);
 }
 
 int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 04b12ad23390..bf1720f7f35f 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -56,10 +56,8 @@
 
 #define QUEUE_DISCONNECTS
 
-#define DRV_BUILD   "1"
-
 #define DRV_NAME    "iw_nes"
-#define DRV_VERSION "1.0 KO Build " DRV_BUILD
+#define DRV_VERSION "1.5.0.0"
 #define PFX         DRV_NAME ": "
 
 /*
@@ -289,8 +287,8 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
 static inline void
 set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
 {
-	wqe_words[index]     = cpu_to_le32((u32) ((unsigned long)value));
-	wqe_words[index + 1] = cpu_to_le32((u32)(upper_32_bits((unsigned long)value)));
+	wqe_words[index]     = cpu_to_le32((u32) value);
+	wqe_words[index + 1] = cpu_to_le32(upper_32_bits(value));
 }
 
 static inline void
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 52425154acd4..11c7d6642014 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -56,6 +56,7 @@
 #include <net/neighbour.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
+#include <net/tcp.h>
 
 #include "nes.h"
 
@@ -426,6 +427,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	if (type == NES_TIMER_TYPE_CLOSE) {
 		new_send->timetosend += (HZ/10);
 		if (cm_node->recv_entry) {
+			kfree(new_send);
 			WARN_ON(1);
 			return -EINVAL;
 		}
@@ -445,8 +447,8 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		if (ret != NETDEV_TX_OK) {
 			nes_debug(NES_DBG_CM, "Error sending packet %p "
 				"(jiffies = %lu)\n", new_send, jiffies);
-			atomic_dec(&new_send->skb->users);
 			new_send->timetosend = jiffies;
+			ret = NETDEV_TX_OK;
 		} else {
 			cm_packets_sent++;
 			if (!send_retrans) {
@@ -539,6 +541,7 @@ static void nes_cm_timer_tick(unsigned long pass)
 	struct list_head *list_node;
 	struct nes_cm_core *cm_core = g_cm_core;
 	u32 settimer = 0;
+	unsigned long timetosend;
 	int ret = NETDEV_TX_OK;
 
 	struct list_head timer_list;
@@ -630,7 +633,6 @@ static void nes_cm_timer_tick(unsigned long pass)
 				nes_debug(NES_DBG_CM, "rexmit failed for "
 					"node=%p\n", cm_node);
 				cm_packets_bounced++;
-				atomic_dec(&send_entry->skb->users);
 				send_entry->retrycount--;
 				nexttimeout = jiffies + NES_SHORT_TIME;
 				settimer = 1;
@@ -644,8 +646,11 @@ static void nes_cm_timer_tick(unsigned long pass)
 				send_entry->retrycount);
 			if (send_entry->send_retrans) {
 				send_entry->retranscount--;
+				timetosend = (NES_RETRY_TIMEOUT <<
+					(NES_DEFAULT_RETRANS - send_entry->retranscount));
+
 				send_entry->timetosend = jiffies +
-					NES_RETRY_TIMEOUT;
+					min(timetosend, NES_MAX_TIMEOUT);
 				if (nexttimeout > send_entry->timetosend ||
 					!settimer) {
 					nexttimeout = send_entry->timetosend;
@@ -666,11 +671,6 @@ static void nes_cm_timer_tick(unsigned long pass)
 
 		spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
 		rem_ref_cm_node(cm_node->cm_core, cm_node);
-		if (ret != NETDEV_TX_OK) {
-			nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
-				cm_node);
-			break;
-		}
 	}
 
 	if (settimer) {
@@ -859,7 +859,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
 {
 	unsigned long flags;
 	struct nes_cm_listener *listen_node;
-	__be32 tmp_addr = cpu_to_be32(dst_addr);
 
 	/* walk list and find cm_node associated with this session ID */
 	spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -876,9 +875,6 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
 	}
 	spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 
-	nes_debug(NES_DBG_CM, "Unable to find listener for %pI4:%x\n",
-		  &tmp_addr, dst_port);
-
 	/* no listener */
 	return NULL;
 }
@@ -1262,7 +1258,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
 		cm_node->nesqp = NULL;
 	}
 
-	cm_node->freed = 1;
 	kfree(cm_node);
 	return 0;
 }
@@ -1331,18 +1326,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node)
 	nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
 		"refcnt=%d\n", cm_node, cm_node->state,
 		atomic_read(&cm_node->ref_count));
-	cm_node->tcp_cntxt.rcv_nxt++;
-	cleanup_retrans_entry(cm_node);
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_RCVD:
 	case NES_CM_STATE_SYN_SENT:
 	case NES_CM_STATE_ESTABLISHED:
 	case NES_CM_STATE_MPAREQ_SENT:
 	case NES_CM_STATE_MPAREJ_RCVD:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_LAST_ACK;
 		send_fin(cm_node, NULL);
 		break;
 	case NES_CM_STATE_FIN_WAIT1:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSING;
 		send_ack(cm_node, NULL);
 		/* Wait for ACK as this is simultanous close..
@@ -1350,11 +1347,15 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node)
 		* Just rm the node.. Done.. */
 		break;
 	case NES_CM_STATE_FIN_WAIT2:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_TIME_WAIT;
 		send_ack(cm_node, NULL);
 		schedule_nes_timer(cm_node, NULL,  NES_TIMER_TYPE_CLOSE, 1, 0);
 		break;
 	case NES_CM_STATE_TIME_WAIT:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
 		rem_ref_cm_node(cm_node->cm_core, cm_node);
 		break;
@@ -1390,7 +1391,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		passive_state = atomic_add_return(1, &cm_node->passive_state);
 		if (passive_state ==  NES_SEND_RESET_EVENT)
 			create_event(cm_node, NES_CM_EVENT_RESET);
-		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
 		dev_kfree_skb_any(skb);
 		break;
@@ -1404,17 +1404,16 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		active_open_err(cm_node, skb, reset);
 		break;
 	case NES_CM_STATE_CLOSED:
-		cleanup_retrans_entry(cm_node);
 		drop_packet(skb);
 		break;
+	case NES_CM_STATE_LAST_ACK:
+		cm_node->cm_id->rem_ref(cm_node->cm_id);
 	case NES_CM_STATE_TIME_WAIT:
-		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
 		rem_ref_cm_node(cm_node->cm_core, cm_node);
 		drop_packet(skb);
 		break;
 	case NES_CM_STATE_FIN_WAIT1:
-		cleanup_retrans_entry(cm_node);
 		nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
 	default:
 		drop_packet(skb);
@@ -1461,6 +1460,7 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
 				NES_PASSIVE_STATE_INDICATED);
 		break;
 	case NES_CM_STATE_MPAREQ_SENT:
+		cleanup_retrans_entry(cm_node);
 		if (res_type == NES_MPA_REQUEST_REJECT) {
 			type = NES_CM_EVENT_MPA_REJECT;
 			cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
@@ -1524,7 +1524,7 @@ static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph,
 	rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
 	if (ack_seq != loc_seq_num)
 		err = 1;
-	else if ((seq + rcv_wnd) < rcv_nxt)
+	else if (!between(seq, rcv_nxt, (rcv_nxt+rcv_wnd)))
 		err = 1;
 	if (err) {
 		nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
@@ -1658,49 +1658,39 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	}
 }
 
-static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
+static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	struct tcphdr *tcph)
 {
 	int datasize = 0;
 	u32 inc_sequence;
 	u32 rem_seq_ack;
 	u32 rem_seq;
-	int ret;
+	int ret = 0;
 	int optionsize;
 	optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
 
 	if (check_seq(cm_node, tcph, skb))
-		return;
+		return -EINVAL;
 
 	skb_pull(skb, tcph->doff << 2);
 	inc_sequence = ntohl(tcph->seq);
 	rem_seq = ntohl(tcph->seq);
 	rem_seq_ack =  ntohl(tcph->ack_seq);
 	datasize = skb->len;
-	cleanup_retrans_entry(cm_node);
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_RCVD:
 		/* Passive OPEN */
+		cleanup_retrans_entry(cm_node);
 		ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1);
 		if (ret)
 			break;
 		cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
-		if (cm_node->tcp_cntxt.rem_ack_num !=
-		    cm_node->tcp_cntxt.loc_seq_num) {
-			nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
-			cleanup_retrans_entry(cm_node);
-			send_reset(cm_node, skb);
-			return;
-		}
 		cm_node->state = NES_CM_STATE_ESTABLISHED;
-		cleanup_retrans_entry(cm_node);
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
 			handle_rcv_mpa(cm_node, skb);
-		} else { /* rcvd ACK only */
+		} else  /* rcvd ACK only */
 			dev_kfree_skb_any(skb);
-			cleanup_retrans_entry(cm_node);
-		 }
 		break;
 	case NES_CM_STATE_ESTABLISHED:
 		/* Passive OPEN */
@@ -1712,15 +1702,12 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 			drop_packet(skb);
 		break;
 	case NES_CM_STATE_MPAREQ_SENT:
-		cleanup_retrans_entry(cm_node);
 		cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
 			handle_rcv_mpa(cm_node, skb);
-		} else { /* Could be just an ack pkt.. */
-			cleanup_retrans_entry(cm_node);
+		} else  /* Could be just an ack pkt.. */
 			dev_kfree_skb_any(skb);
-		}
 		break;
 	case NES_CM_STATE_LISTENING:
 	case NES_CM_STATE_CLOSED:
@@ -1728,11 +1715,10 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		send_reset(cm_node, skb);
 		break;
 	case NES_CM_STATE_LAST_ACK:
+	case NES_CM_STATE_CLOSING:
 		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
 		cm_node->cm_id->rem_ref(cm_node->cm_id);
-	case NES_CM_STATE_CLOSING:
-		cleanup_retrans_entry(cm_node);
 		rem_ref_cm_node(cm_node->cm_core, cm_node);
 		drop_packet(skb);
 		break;
@@ -1747,9 +1733,11 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	case NES_CM_STATE_MPAREQ_RCVD:
 	case NES_CM_STATE_UNKNOWN:
 	default:
+		cleanup_retrans_entry(cm_node);
 		drop_packet(skb);
 		break;
 	}
+	return ret;
 }
 
 
@@ -1855,6 +1843,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	enum nes_tcpip_pkt_type	pkt_type = NES_PKT_TYPE_UNKNOWN;
 	struct tcphdr *tcph = tcp_hdr(skb);
 	u32     fin_set = 0;
+	int ret = 0;
 	skb_pull(skb, ip_hdr(skb)->ihl << 2);
 
 	nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
@@ -1880,17 +1869,17 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		handle_synack_pkt(cm_node, skb, tcph);
 		break;
 	case NES_PKT_TYPE_ACK:
-		handle_ack_pkt(cm_node, skb, tcph);
-		if (fin_set)
+		ret = handle_ack_pkt(cm_node, skb, tcph);
+		if (fin_set && !ret)
 			handle_fin_pkt(cm_node);
 		break;
 	case NES_PKT_TYPE_RST:
 		handle_rst_pkt(cm_node, skb, tcph);
 		break;
 	default:
-		drop_packet(skb);
-		if (fin_set)
+		if ((fin_set) && (!check_seq(cm_node, tcph, skb)))
 			handle_fin_pkt(cm_node);
+		drop_packet(skb);
 		break;
 	}
 }
@@ -1999,13 +1988,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
 		if (loopbackremotelistener == NULL) {
 			create_event(cm_node, NES_CM_EVENT_ABORTED);
 		} else {
-			atomic_inc(&cm_loopbacks);
 			loopback_cm_info = *cm_info;
 			loopback_cm_info.loc_port = cm_info->rem_port;
 			loopback_cm_info.rem_port = cm_info->loc_port;
 			loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
 			loopbackremotenode = make_cm_node(cm_core, nesvnic,
 				&loopback_cm_info, loopbackremotelistener);
+			if (!loopbackremotenode) {
+				rem_ref_cm_node(cm_node->cm_core, cm_node);
+				return NULL;
+			}
+			atomic_inc(&cm_loopbacks);
 			loopbackremotenode->loopbackpartner = cm_node;
 			loopbackremotenode->tcp_cntxt.rcv_wscale =
 				NES_CM_DEFAULT_RCV_WND_SCALE;
@@ -2690,6 +2683,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	struct ib_mr *ibmr = NULL;
 	struct ib_phys_buf ibphysbuf;
 	struct nes_pd *nespd;
+	u64 tagged_offset;
 
 
 
@@ -2711,7 +2705,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	/* associate the node with the QP */
 	nesqp->cm_node = (void *)cm_node;
 	cm_node->nesqp = nesqp;
-	nes_add_ref(&nesqp->ibqp);
 
 	nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
 		nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
@@ -2755,14 +2748,18 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		ibphysbuf.addr = nesqp->ietf_frame_pbase;
 		ibphysbuf.size = conn_param->private_data_len +
 					sizeof(struct ietf_mpa_frame);
+		tagged_offset = (u64)(unsigned long)nesqp->ietf_frame;
 		ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
 						&ibphysbuf, 1,
 						IB_ACCESS_LOCAL_WRITE,
-						(u64 *)&nesqp->ietf_frame);
+						&tagged_offset);
 		if (!ibmr) {
 			nes_debug(NES_DBG_CM, "Unable to register memory region"
 					"for lSMM for cm_node = %p \n",
 					cm_node);
+			pci_free_consistent(nesdev->pcidev,
+				nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
+				nesqp->ietf_frame, nesqp->ietf_frame_pbase);
 			return -ENOMEM;
 		}
 
@@ -2782,7 +2779,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 			sizeof(struct ietf_mpa_frame));
 		set_wqe_64bit_value(wqe->wqe_words,
 					NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
-					(u64)nesqp->ietf_frame);
+					(u64)(unsigned long)nesqp->ietf_frame);
 		wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
 			cpu_to_le32(conn_param->private_data_len +
 			sizeof(struct ietf_mpa_frame));
@@ -2879,6 +2876,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 
 	/* notify OF layer that accept event was successful */
 	cm_id->add_ref(cm_id);
+	nes_add_ref(&nesqp->ibqp);
 
 	cm_event.event = IW_CM_EVENT_ESTABLISHED;
 	cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
@@ -2959,6 +2957,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	struct nes_device *nesdev;
 	struct nes_cm_node *cm_node;
 	struct nes_cm_info cm_info;
+	int apbvt_set = 0;
 
 	ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
 	if (!ibqp)
@@ -2996,9 +2995,11 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		conn_param->private_data_len);
 
 	if (cm_id->local_addr.sin_addr.s_addr !=
-		cm_id->remote_addr.sin_addr.s_addr)
+		cm_id->remote_addr.sin_addr.s_addr) {
 		nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
 			PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
+		apbvt_set = 1;
+	}
 
 	/* set up the connection params for the node */
 	cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr);
@@ -3015,8 +3016,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		conn_param->private_data_len, (void *)conn_param->private_data,
 		&cm_info);
 	if (!cm_node) {
-		if (cm_id->local_addr.sin_addr.s_addr !=
-				cm_id->remote_addr.sin_addr.s_addr)
+		if (apbvt_set)
 			nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
 				PCI_FUNC(nesdev->pcidev->devfn),
 				NES_MANAGE_APBVT_DEL);
@@ -3025,7 +3025,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		return -ENOMEM;
 	}
 
-	cm_node->apbvt_set = 1;
+	cm_node->apbvt_set = apbvt_set;
 	nesqp->cm_node = cm_node;
 	cm_node->nesqp = nesqp;
 	nes_add_ref(&nesqp->ibqp);
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index d5f778202eb7..8b7e7c0e496e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -149,6 +149,7 @@ struct nes_timer_entry {
 #endif
 #define NES_SHORT_TIME      (10)
 #define NES_LONG_TIME       (2000*HZ/1000)
+#define NES_MAX_TIMEOUT     ((unsigned long) (12*HZ))
 
 #define NES_CM_HASHTABLE_SIZE         1024
 #define NES_CM_TCP_TIMER_INTERVAL     3000
@@ -298,7 +299,6 @@ struct nes_cm_node {
 	struct nes_vnic           *nesvnic;
 	int                       apbvt_set;
 	int                       accept_pend;
-	int			freed;
 	struct list_head	timer_entry;
 	struct list_head	reset_entry;
 	struct nes_qp		*nesqp;
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 52e734042b8e..b832a7b814a2 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -46,6 +46,10 @@ static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
 module_param(nes_lro_max_aggr, uint, 0444);
 MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
 
+static int wide_ppm_offset;
+module_param(wide_ppm_offset, int, 0644);
+MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
+
 static u32 crit_err_count;
 u32 int_mod_timer_init;
 u32 int_mod_cq_depth_256;
@@ -547,7 +551,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
 		}
 		if (int_cnt > 1) {
 			spin_lock_irqsave(&nesadapter->phy_lock, flags);
-			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
 			mh_detected++;
 			reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
 			reset_value |= 0x0000003d;
@@ -572,7 +576,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
 					if (++ext_cnt > int_cnt) {
 						spin_lock_irqsave(&nesadapter->phy_lock, flags);
 						nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1,
-								0x0000F0C8);
+								0x0000F088);
 						mh_detected++;
 						reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
 						reset_value |= 0x0000003d;
@@ -736,38 +740,50 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
 {
 	int i;
 	u32 u32temp;
-	u32 serdes_common_control;
+	u32 sds;
 
 	if (hw_rev != NE020_REV) {
 		/* init serdes 0 */
+		if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4))
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA);
+		else
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
 
-		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
 		if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
-			serdes_common_control = nes_read_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL0);
-			serdes_common_control |= 0x000000100;
-			nes_write_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL0,
-					serdes_common_control);
-		} else if (!OneG_Mode) {
-			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
+			sds |= 0x00000100;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds);
 		}
-		if (((port_count > 1) &&
-			(nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
-			((port_count > 2) &&
-			(nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
-			/* init serdes 1 */
+		if (!OneG_Mode)
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+
+		if (port_count < 2)
+			return 0;
+
+		/* init serdes 1 */
+		if (!(OneG_Mode && (nesadapter->phy_type[1] != NES_PHY_TYPE_PUMA_1G)))
 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
-			if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
-				serdes_common_control = nes_read_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL1);
-				serdes_common_control |= 0x000000100;
-				nes_write_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL1,
-					serdes_common_control);
-			} else if (!OneG_Mode) {
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
-			}
+
+		switch (nesadapter->phy_type[1]) {
+		case NES_PHY_TYPE_ARGUS:
+		case NES_PHY_TYPE_SFP_D:
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
+			break;
+		case NES_PHY_TYPE_CX4:
+			if (wide_ppm_offset)
+				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA);
+			break;
+		case NES_PHY_TYPE_PUMA_1G:
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+			sds |= 0x000000100;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
+		}
+		if (!OneG_Mode) {
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+			sds &= 0xFFFFFFBF;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
 		}
 	} else {
 		/* init serdes 0 */
@@ -896,6 +912,12 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou
 		u32temp &= 0x7fffffff;
 		u32temp |= 0x7fff0010;
 		nes_write_indexed(nesdev, 0x000021f8, u32temp);
+		if (port_count > 1) {
+			u32temp = nes_read_indexed(nesdev, 0x000023f8);
+			u32temp &= 0x7fffffff;
+			u32temp |= 0x7fff0010;
+			nes_write_indexed(nesdev, 0x000023f8, u32temp);
+		}
 	}
 }
 
@@ -1259,203 +1281,163 @@ int nes_init_phy(struct nes_device *nesdev)
 {
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
 	u32 counter = 0;
-	u32 sds_common_control0;
+	u32 sds;
 	u32 mac_index = nesdev->mac_index;
 	u32 tx_config = 0;
 	u16 phy_data;
 	u32 temp_phy_data = 0;
 	u32 temp_phy_data2 = 0;
-	u32 i = 0;
+	u8  phy_type = nesadapter->phy_type[mac_index];
+	u8  phy_index = nesadapter->phy_index[mac_index];
 
 	if ((nesadapter->OneG_Mode) &&
-	    (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
+	    (phy_type != NES_PHY_TYPE_PUMA_1G)) {
 		nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
-		if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
-			printk(PFX "%s: Programming mdc config for 1G\n", __func__);
+		if (phy_type == NES_PHY_TYPE_1G) {
 			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
 			tx_config &= 0xFFFFFFE3;
 			tx_config |= 0x04;
 			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
 		}
 
-		nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
-				nesadapter->phy_index[mac_index], phy_data);
-		nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
+		nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
 
 		/* Reset the PHY */
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
 		udelay(100);
 		counter = 0;
 		do {
-			nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-			nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
-			if (counter++ > 100) break;
+			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+			if (counter++ > 100)
+				break;
 		} while (phy_data & 0x8000);
 
 		/* Setting no phy loopback */
 		phy_data &= 0xbfff;
 		phy_data |= 0x1140;
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index],  phy_data);
-		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
-
-		nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
-
-		nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index,  phy_data);
+		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data);
 
 		/* Setting the interrupt mask */
-		nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
-		nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
-
-		nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee);
+		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
 
 		/* turning on flow control */
-		nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
-		nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
-				(phy_data & ~(0x03E0)) | 0xc00);
-		/* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
-				phy_data | 0xc00); */
-		nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
-
-		nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
-		/* Clear Half duplex */
-		nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
-				phy_data & ~(0x0100));
-		nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
+		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00);
+		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
 
-		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
-	} else {
-		if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
-		    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
-			/* setup 10G MDIO operation */
-			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
-			tx_config &= 0xFFFFFFE3;
-			tx_config |= 0x15;
-			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
-		}
-		if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
-			nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-
-			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-			mdelay(10);
-			nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-			temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		/* Clear Half duplex */
+		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100));
+		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
 
-			/*
-			 * if firmware is already running (like from a
-			 * driver un-load/load, don't do anything.
-			 */
-			if (temp_phy_data == temp_phy_data2) {
-				/* configure QT2505 AMCC PHY */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
+		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
 
-				/*
-				 * remove micro from reset; chip boots from ROM,
-				 * uploads EEPROM f/w image, uC executes f/w
-				 */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
+		return 0;
+	}
 
-				/*
-				 * wait for heart beat to start to
-				 * know loading is done
-				 */
-				counter = 0;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-					temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
-						break;
-					}
-					mdelay(100);
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-					temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-				} while ((temp_phy_data2 == temp_phy_data));
+	if ((phy_type == NES_PHY_TYPE_IRIS) ||
+	    (phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		/* setup 10G MDIO operation */
+		tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
+		tx_config &= 0xFFFFFFE3;
+		tx_config |= 0x15;
+		nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
+	}
+	if ((phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		/* Check firmware heartbeat */
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		udelay(1500);
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+		temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+
+		if (temp_phy_data != temp_phy_data2)
+			return 0;
 
-				/*
-				 * wait for tracking to start to know
-				 * f/w is good to go
-				 */
-				counter = 0;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
-					temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
-						break;
-					}
-					mdelay(1000);
-					/*
-					 * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
-					 *			temp_phy_data);
-					 */
-				} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
-
-				/* set LOS Control invert RXLOSB_I_PADINV */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
-				/* set LOS Control to mask of RXLOSB_I */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
-				/* set LED1 to input mode (LED1 and LED2 share same LED) */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
-				/* set LED2 to RX link_status and activity */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
-				/* set LED3 to RX link_status */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
+		/* no heartbeat, configure the PHY */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
+		if (phy_type == NES_PHY_TYPE_ARGUS) {
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001);
+		} else {
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013);
+		}
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
 
-				/*
-				 * reset the res-calibration on t2
-				 * serdes; ensures it is stable after
-				 * the amcc phy is stable
-				 */
+		/* setup LEDs */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009);
 
-				sds_common_control0  = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
-				sds_common_control0 |= 0x1;
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
 
-				/* release the res-calibration reset */
-				sds_common_control0 &= 0xfffffffe;
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+		/* Bring PHY out of reset */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
 
-				i = 0;
-				while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
-						&& (i++ < 5000)) {
-					/* mdelay(1); */
-				}
+		/* Check for heartbeat */
+		counter = 0;
+		mdelay(690);
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		do {
+			if (counter++ > 150) {
+				nes_debug(NES_DBG_PHY, "No PHY heartbeat\n");
+				break;
+			}
+			mdelay(1);
+			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+			temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		} while ((temp_phy_data2 == temp_phy_data));
 
-				/*
-				 * wait for link train done before moving on,
-				 * or will get an interupt storm
-				 */
-				counter = 0;
-				do {
-					temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
-								(0x200 * (nesdev->mac_index & 1)));
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
-						break;
-					}
-					mdelay(1);
-				} while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
+		/* wait for tracking */
+		counter = 0;
+		do {
+			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
+			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+			if (counter++ > 300) {
+				nes_debug(NES_DBG_PHY, "PHY did not track\n");
+				break;
 			}
-		}
+			mdelay(10);
+		} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
+
+		/* setup signal integrity */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063);
+
+		/* reset serdes */
+		sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				       mac_index * 0x200);
+		sds |= 0x1;
+		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				  mac_index * 0x200, sds);
+		sds &= 0xfffffffe;
+		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				  mac_index * 0x200, sds);
+
+		counter = 0;
+		while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
+				&& (counter++ < 5000))
+			;
 	}
 	return 0;
 }
@@ -2359,6 +2341,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
 	u16 temp_phy_data;
 	u32 pcs_val  = 0x0f0f0000;
 	u32 pcs_mask = 0x0f1f0000;
+	u32 cdr_ctrl;
 
 	spin_lock_irqsave(&nesadapter->phy_lock, flags);
 	if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2473,6 +2456,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
 				break;
 
 			case NES_PHY_TYPE_ARGUS:
+			case NES_PHY_TYPE_SFP_D:
 				/* clear the alarms */
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
@@ -2483,19 +2467,18 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
 				/* check link status */
-				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
 				temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-				u32temp = 100;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
 
-					phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if ((phy_data == temp_phy_data) || (!(--u32temp)))
-						break;
-					temp_phy_data = phy_data;
-				} while (1);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+				nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+				phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+
+				phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
+
 				nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
-					__func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
+					__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
 				break;
 
 			case NES_PHY_TYPE_PUMA_1G:
@@ -2511,6 +2494,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
 		}
 
 		if (phy_data & 0x0004) {
+			if (wide_ppm_offset &&
+			    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+			    (nesadapter->hw_rev != NE020_REV)) {
+				cdr_ctrl = nes_read_indexed(nesdev,
+							    NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+							    mac_index * 0x200);
+				nes_write_indexed(nesdev,
+						  NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+						  mac_index * 0x200,
+						  cdr_ctrl | 0x000F0000);
+			}
 			nesadapter->mac_link_down[mac_index] = 0;
 			list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
 				nes_debug(NES_DBG_PHY, "The Link is UP!!.  linkup was %d\n",
@@ -2525,6 +2519,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
 				}
 			}
 		} else {
+			if (wide_ppm_offset &&
+			    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+			    (nesadapter->hw_rev != NE020_REV)) {
+				cdr_ctrl = nes_read_indexed(nesdev,
+							    NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+							    mac_index * 0x200);
+				nes_write_indexed(nesdev,
+						  NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+						  mac_index * 0x200,
+						  cdr_ctrl & 0xFFF0FFFF);
+			}
 			nesadapter->mac_link_down[mac_index] = 1;
 			list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
 				nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index f41a8710d2a8..c3654c6383fe 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -35,12 +35,14 @@
 
 #include <linux/inet_lro.h>
 
+#define NES_PHY_TYPE_CX4       1
 #define NES_PHY_TYPE_1G        2
 #define NES_PHY_TYPE_IRIS      3
 #define NES_PHY_TYPE_ARGUS     4
 #define NES_PHY_TYPE_PUMA_1G   5
 #define NES_PHY_TYPE_PUMA_10G  6
 #define NES_PHY_TYPE_GLADIUS   7
+#define NES_PHY_TYPE_SFP_D     8
 
 #define NES_MULTICAST_PF_MAX 8
 
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index ecb1f6fd6276..c6e6611d3016 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1426,49 +1426,55 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
 	struct nes_vnic *nesvnic = netdev_priv(netdev);
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
+	u32 mac_index = nesdev->mac_index;
+	u8 phy_type = nesadapter->phy_type[mac_index];
+	u8 phy_index = nesadapter->phy_index[mac_index];
 	u16 phy_data;
 
 	et_cmd->duplex = DUPLEX_FULL;
 	et_cmd->port   = PORT_MII;
+	et_cmd->maxtxpkt = 511;
+	et_cmd->maxrxpkt = 511;
 
 	if (nesadapter->OneG_Mode) {
 		et_cmd->speed = SPEED_1000;
-		if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
+		if (phy_type == NES_PHY_TYPE_PUMA_1G) {
 			et_cmd->supported   = SUPPORTED_1000baseT_Full;
 			et_cmd->advertising = ADVERTISED_1000baseT_Full;
 			et_cmd->autoneg     = AUTONEG_DISABLE;
 			et_cmd->transceiver = XCVR_INTERNAL;
-			et_cmd->phy_address = nesdev->mac_index;
+			et_cmd->phy_address = mac_index;
 		} else {
-			et_cmd->supported   = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
-			et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
-			nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
+			et_cmd->supported   = SUPPORTED_1000baseT_Full
+					    | SUPPORTED_Autoneg;
+			et_cmd->advertising = ADVERTISED_1000baseT_Full
+					    | ADVERTISED_Autoneg;
+			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
 			if (phy_data & 0x1000)
 				et_cmd->autoneg = AUTONEG_ENABLE;
 			else
 				et_cmd->autoneg = AUTONEG_DISABLE;
 			et_cmd->transceiver = XCVR_EXTERNAL;
-			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
+			et_cmd->phy_address = phy_index;
 		}
+		return 0;
+	}
+	if ((phy_type == NES_PHY_TYPE_IRIS) ||
+	    (phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		et_cmd->transceiver = XCVR_EXTERNAL;
+		et_cmd->port        = PORT_FIBRE;
+		et_cmd->supported   = SUPPORTED_FIBRE;
+		et_cmd->advertising = ADVERTISED_FIBRE;
+		et_cmd->phy_address = phy_index;
 	} else {
-		if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
-		    (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
-			et_cmd->transceiver = XCVR_EXTERNAL;
-			et_cmd->port        = PORT_FIBRE;
-			et_cmd->supported   = SUPPORTED_FIBRE;
-			et_cmd->advertising = ADVERTISED_FIBRE;
-			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
-		} else {
-			et_cmd->transceiver = XCVR_INTERNAL;
-			et_cmd->supported   = SUPPORTED_10000baseT_Full;
-			et_cmd->advertising = ADVERTISED_10000baseT_Full;
-			et_cmd->phy_address = nesdev->mac_index;
-		}
-		et_cmd->speed = SPEED_10000;
-		et_cmd->autoneg = AUTONEG_DISABLE;
+		et_cmd->transceiver = XCVR_INTERNAL;
+		et_cmd->supported   = SUPPORTED_10000baseT_Full;
+		et_cmd->advertising = ADVERTISED_10000baseT_Full;
+		et_cmd->phy_address = mac_index;
 	}
-	et_cmd->maxtxpkt = 511;
-	et_cmd->maxrxpkt = 511;
+	et_cmd->speed = SPEED_10000;
+	et_cmd->autoneg = AUTONEG_DISABLE;
 	return 0;
 }
 
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 7e5b5ba13a74..64d5cfd8f380 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1627,6 +1627,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 				nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff;
 			else
 				nescq->hw_cq.cq_number = nesvnic->mcrq_qp_id + nes_ucontext->mcrqf-1;
+			nescq->mcrqf = nes_ucontext->mcrqf;
 			nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		}
 		nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n",
@@ -1682,6 +1683,12 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 		if (!context)
 			pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 					nescq->hw_cq.cq_pbase);
+		else {
+			pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+					    nespbl->pbl_vbase, nespbl->pbl_pbase);
+			kfree(nespbl);
+		}
+
 		nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		kfree(nescq);
 		return ERR_PTR(-ENOMEM);
@@ -1705,6 +1712,11 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 				if (!context)
 					pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 							nescq->hw_cq.cq_pbase);
+				else {
+					pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+							    nespbl->pbl_vbase, nespbl->pbl_pbase);
+					kfree(nespbl);
+				}
 				nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 				kfree(nescq);
 				return ERR_PTR(-ENOMEM);
@@ -1722,6 +1734,11 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 				if (!context)
 					pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 							nescq->hw_cq.cq_pbase);
+				else {
+					pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+							    nespbl->pbl_vbase, nespbl->pbl_pbase);
+					kfree(nespbl);
+				}
 				nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 				kfree(nescq);
 				return ERR_PTR(-ENOMEM);
@@ -1774,6 +1791,11 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
 		if (!context)
 			pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 					nescq->hw_cq.cq_pbase);
+		else {
+			pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+					    nespbl->pbl_vbase, nespbl->pbl_pbase);
+			kfree(nespbl);
+		}
 		nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		kfree(nescq);
 		return ERR_PTR(-EIO);
@@ -1855,7 +1877,9 @@ static int nes_destroy_cq(struct ib_cq *ib_cq)
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode);
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
 		(nescq->hw_cq.cq_number | ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 16)));
-	nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number);
+	if (!nescq->mcrqf)
+		nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number);
+
 	atomic_set(&cqp_request->refcount, 2);
 	nes_post_cqp_request(nesdev, cqp_request);
 
@@ -1895,8 +1919,7 @@ static int nes_destroy_cq(struct ib_cq *ib_cq)
 static u32 root_256(struct nes_device *nesdev,
 		    struct nes_root_vpbl *root_vpbl,
 		    struct nes_root_vpbl *new_root,
-		    u16 pbl_count_4k,
-		    u16 pbl_count_256)
+		    u16 pbl_count_4k)
 {
 	u64 leaf_pbl;
 	int i, j, k;
@@ -1952,7 +1975,7 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
 	int ret;
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
 	uint pg_cnt = 0;
-	u16 pbl_count_256;
+	u16 pbl_count_256 = 0;
 	u16 pbl_count = 0;
 	u8  use_256_pbls = 0;
 	u8  use_4k_pbls = 0;
@@ -2012,7 +2035,7 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
 	}
 
 	if (use_256_pbls && use_two_level) {
-		if (root_256(nesdev, root_vpbl, &new_root, pbl_count_4k, pbl_count_256) == 1) {
+		if (root_256(nesdev, root_vpbl, &new_root, pbl_count_4k) == 1) {
 			if (new_root.pbl_pbase != 0)
 				root_vpbl = &new_root;
 		} else {
@@ -2122,6 +2145,7 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 	struct nes_root_vpbl root_vpbl;
 	u32 stag;
 	u32 i;
+	unsigned long mask;
 	u32 stag_index = 0;
 	u32 next_stag_index = 0;
 	u32 driver_key = 0;
@@ -2150,6 +2174,9 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 		return ERR_PTR(-E2BIG);
 	}
 
+	if ((buffer_list[0].addr ^ *iova_start) & ~PAGE_MASK)
+		return ERR_PTR(-EINVAL);
+
 	err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, nesadapter->max_mr,
 			&stag_index, &next_stag_index);
 	if (err) {
@@ -2215,19 +2242,16 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 			root_pbl_index++;
 			cur_pbl_index = 0;
 		}
-		if (buffer_list[i].addr & ~PAGE_MASK) {
-			/* TODO: Unwind allocated buffers */
-			nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-			nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n",
-					(unsigned int) buffer_list[i].addr);
-			ibmr = ERR_PTR(-EINVAL);
-			kfree(nesmr);
-			goto reg_phys_err;
-		}
 
-		if (!buffer_list[i].size) {
+		mask = !buffer_list[i].size;
+		if (i != 0)
+			mask |= buffer_list[i].addr;
+		if (i != num_phys_buf - 1)
+			mask |= buffer_list[i].addr + buffer_list[i].size;
+
+		if (mask & ~PAGE_MASK) {
 			nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-			nes_debug(NES_DBG_MR, "Invalid Buffer Size\n");
+			nes_debug(NES_DBG_MR, "Invalid buffer addr or size\n");
 			ibmr = ERR_PTR(-EINVAL);
 			kfree(nesmr);
 			goto reg_phys_err;
@@ -2238,7 +2262,7 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 			if ((buffer_list[i-1].addr+PAGE_SIZE) != buffer_list[i].addr)
 				single_page = 0;
 		}
-		vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr);
+		vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr & PAGE_MASK);
 		vpbl.pbl_vbase[cur_pbl_index++].pa_high =
 				cpu_to_le32((u32)((((u64)buffer_list[i].addr) >> 32)));
 	}
@@ -2251,8 +2275,6 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
 			" length = 0x%016lX, index = 0x%08X\n",
 			stag, (unsigned long)*iova_start, (unsigned long)region_length, stag_index);
 
-	region_length -= (*iova_start)&PAGE_MASK;
-
 	/* Make the leaf PBL the root if only one PBL */
 	if (root_pbl_index == 1) {
 		root_vpbl.pbl_pbase = vpbl.pbl_pbase;
@@ -2786,10 +2808,9 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
 
 	nes_debug(NES_DBG_INIT, "\n");
-	return sprintf(buf, "%x.%x.%x\n",
-			(int)(nesvnic->nesdev->nesadapter->fw_ver >> 32),
-			(int)(nesvnic->nesdev->nesadapter->fw_ver >> 16) & 0xffff,
-			(int)(nesvnic->nesdev->nesadapter->fw_ver & 0xffff));
+	return sprintf(buf, "%u.%u\n",
+		(nesvnic->nesdev->nesadapter->firmware_version >> 16),
+		(nesvnic->nesdev->nesadapter->firmware_version & 0x000000ff));
 }
 
 
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index 5e48f67fbe8d..41c07f29f7c9 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -112,6 +112,7 @@ struct nes_cq {
 	spinlock_t       lock;
 	u8               virtual_cq;
 	u8               pad[3];
+	u32		 mcrqf;
 };
 
 struct nes_wq {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index da6082739839..e7e5adf84e84 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -685,7 +685,8 @@ int ipoib_ib_dev_open(struct net_device *dev)
 	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
 			   round_jiffies_relative(HZ));
 
-	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_enable(&priv->napi);
 
 	return 0;
 }
@@ -804,7 +805,8 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 	struct ipoib_tx_buf *tx_req;
 	int i;
 
-	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_disable(&priv->napi);
 
 	ipoib_cm_dev_stop(dev);
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 421a6640c9bd..ab2c192c76bc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -106,8 +106,7 @@ int ipoib_open(struct net_device *dev)
 
 	ipoib_dbg(priv, "bringing up interface\n");
 
-	if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
-		napi_enable(&priv->napi);
+	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	if (ipoib_pkey_dev_delay_open(dev))
 		return 0;
@@ -143,7 +142,6 @@ err_stop:
 	ipoib_ib_dev_stop(dev, 1);
 
 err_disable:
-	napi_disable(&priv->napi);
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	return -EINVAL;
@@ -156,7 +154,6 @@ static int ipoib_stop(struct net_device *dev)
 	ipoib_dbg(priv, "stopping interface\n");
 
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
-	napi_disable(&priv->napi);
 
 	netif_stop_queue(dev);
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 5a76a5510350..4c57f329dd50 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 	 */
 	if (ppriv->pkey == pkey) {
 		result = -ENOTUNIQ;
+		priv = NULL;
 		goto err;
 	}
 
 	list_for_each_entry(priv, &ppriv->child_intfs, list) {
 		if (priv->pkey == pkey) {
 			result = -ENOTUNIQ;
+			priv = NULL;
 			goto err;
 		}
 	}
@@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 
 	result = ipoib_set_dev_features(priv, ppriv->ca);
 	if (result)
-		goto device_init_failed;
+		goto err;
 
 	priv->pkey = pkey;
 
@@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 		ipoib_warn(ppriv, "failed to initialize subinterface: "
 			   "device %s, port %d",
 			   ppriv->ca->name, ppriv->port);
-		goto device_init_failed;
+		goto err;
 	}
 
 	result = register_netdevice(priv->dev);
@@ -146,19 +148,19 @@ sysfs_failed:
 register_failed:
 	ipoib_dev_cleanup(priv->dev);
 
-device_init_failed:
-	free_netdev(priv->dev);
-
 err:
 	mutex_unlock(&ppriv->vlan_mutex);
 	rtnl_unlock();
+	if (priv)
+		free_netdev(priv->dev);
+
 	return result;
 }
 
 int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 {
 	struct ipoib_dev_priv *ppriv, *priv, *tpriv;
-	int ret = -ENOENT;
+	struct net_device *dev = NULL;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 			unregister_netdevice(priv->dev);
 			ipoib_dev_cleanup(priv->dev);
 			list_del(&priv->list);
-			free_netdev(priv->dev);
-
-			ret = 0;
+			dev = priv->dev;
 			break;
 		}
 	}
 	mutex_unlock(&ppriv->vlan_mutex);
 	rtnl_unlock();
 
-	return ret;
+	if (dev) {
+		free_netdev(dev);
+		return 0;
+	}
+
+	return -ENODEV;
 }
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index ebf4be5b7c4e..2d175b5928ff 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list);
 
 static struct bus_type gameport_bus;
 
-static void gameport_add_driver(struct gameport_driver *drv);
 static void gameport_add_port(struct gameport *gameport);
-static void gameport_destroy_port(struct gameport *gameport);
+static void gameport_attach_driver(struct gameport_driver *drv);
 static void gameport_reconnect_port(struct gameport *gameport);
 static void gameport_disconnect_port(struct gameport *gameport);
 
@@ -230,7 +229,6 @@ static void gameport_find_driver(struct gameport *gameport)
 
 enum gameport_event_type {
 	GAMEPORT_REGISTER_PORT,
-	GAMEPORT_REGISTER_DRIVER,
 	GAMEPORT_ATTACH_DRIVER,
 };
 
@@ -374,8 +372,8 @@ static void gameport_handle_event(void)
 				gameport_add_port(event->object);
 				break;
 
-			case GAMEPORT_REGISTER_DRIVER:
-				gameport_add_driver(event->object);
+			case GAMEPORT_ATTACH_DRIVER:
+				gameport_attach_driver(event->object);
 				break;
 
 			default:
@@ -706,14 +704,14 @@ static int gameport_driver_remove(struct device *dev)
 	return 0;
 }
 
-static void gameport_add_driver(struct gameport_driver *drv)
+static void gameport_attach_driver(struct gameport_driver *drv)
 {
 	int error;
 
-	error = driver_register(&drv->driver);
+	error = driver_attach(&drv->driver);
 	if (error)
 		printk(KERN_ERR
-			"gameport: driver_register() failed for %s, error: %d\n",
+			"gameport: driver_attach() failed for %s, error: %d\n",
 			drv->driver.name, error);
 }
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ec3db3ade118..935a1835de2d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
 	}
 }
 
+static void input_stop_autorepeat(struct input_dev *dev)
+{
+	del_timer(&dev->timer);
+}
+
 #define INPUT_IGNORE_EVENT	0
 #define INPUT_PASS_TO_HANDLERS	1
 #define INPUT_PASS_TO_DEVICE	2
@@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev,
 				__change_bit(code, dev->key);
 				if (value)
 					input_start_autorepeat(dev, code);
+				else
+					input_stop_autorepeat(dev);
 			}
 
 			disposition = INPUT_PASS_TO_HANDLERS;
@@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void)
 
 static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
 {
-	int state = input_devices_state;
-
 	poll_wait(file, &input_devices_poll_wait, wait);
-	if (state != input_devices_state)
+	if (file->f_version != input_devices_state) {
+		file->f_version = input_devices_state;
 		return POLLIN | POLLRDNORM;
+	}
 
 	return 0;
 }
@@ -1542,7 +1549,6 @@ int input_register_handle(struct input_handle *handle)
 		return error;
 	list_add_tail_rcu(&handle->d_node, &dev->h_list);
 	mutex_unlock(&dev->mutex);
-	synchronize_rcu();
 
 	/*
 	 * Since we are supposed to be called from ->connect()
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 45470f18d7e9..444dec07e5d8 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -229,7 +229,8 @@ struct atkbd {
 /*
  * System-specific ketymap fixup routine
  */
-static void (*atkbd_platform_fixup)(struct atkbd *);
+static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
+static void *atkbd_platform_fixup_data;
 
 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
 				ssize_t (*handler)(struct atkbd *, char *));
@@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio)
 }
 
 /*
- * Most special keys (Fn+F?) on Dell laptops do not generate release
- * events so we have to do it ourselves.
+ * generate release events for the keycodes given in data
  */
-static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
+						const void *data)
 {
-	static const unsigned int forced_release_keys[] = {
-		0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
-	};
-	int i;
+	const unsigned int *keys = data;
+	unsigned int i;
 
 	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
+		for (i = 0; keys[i] != -1U; i++)
+			__set_bit(keys[i], atkbd->force_release_mask);
 }
 
 /*
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+static unsigned int atkbd_dell_laptop_forced_release_keys[] = {
+	0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U
+};
+
+/*
  * Perform fixup for HP system that doesn't generate release
  * for its video switch
  */
-static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
-{
-	static const unsigned int forced_release_keys[] = {
-		0x94,
-	};
-	int i;
-
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-					atkbd->force_release_mask);
-}
+static unsigned int atkbd_hp_forced_release_keys[] = {
+	0x94, -1U
+};
 
 /*
  * Inventec system with broken key release on volume keys
  */
-static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0xae, 0xb0,
-	};
-	int i;
-
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
-}
+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 void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0xae, 0xb0,
-	};
-	int i;
-
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-					atkbd->force_release_mask);
-}
+static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
+	0xae, 0xb0, -1U
+};
 
 /*
- * Samsung NC10 with Fn+F? key release not working
+ * Samsung NC10,NC20 with Fn+F? key release not working
  */
-static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,
-	};
-	int i;
+static unsigned int atkbd_samsung_forced_release_keys[] = {
+	0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
+};
 
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
-}
+/*
+ * 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
+};
 
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
@@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
  * Perform additional fixups
  */
 	if (atkbd_platform_fixup)
-		atkbd_platform_fixup(atkbd);
+		atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);
 }
 
 /*
@@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
 	return sprintf(buf, "%lu\n", atkbd->err_count);
 }
 
-static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
+static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
 {
-	atkbd_platform_fixup = id->driver_data;
+	atkbd_platform_fixup = atkbd_apply_forced_release_keylist;
+	atkbd_platform_fixup_data = id->driver_data;
+
 	return 0;
 }
 
@@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_dell_laptop_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
 		.ident = "Dell Laptop",
@@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_dell_laptop_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
 		.ident = "HP 2133",
@@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_hp_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_hp_forced_release_keys,
 	},
 	{
 		.ident = "HP Pavilion ZV6100",
@@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_hp_zv6100_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_hp_zv6100_forced_release_keys,
 	},
 	{
 		.ident = "Inventec Symphony",
@@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_inventec_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_inventec_forced_release_keys,
 	},
 	{
 		.ident = "Samsung NC10",
@@ -1550,8 +1530,35 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_samsung_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Samsung NC20",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "NC20"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Samsung SQ45S70S",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Fujitsu Amilo PA 1510",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_amilo_pa1510_forced_release_keys,
 	},
 	{ }
 };
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index ee855c5202e8..d427f322e207 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 
 	if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
 	    !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
-		printk(KERN_ERR DRV_NAME
-			": Invalid Debounce/Columdrive Time from pdata\n");
+		printk(KERN_WARNING DRV_NAME
+			": Invalid Debounce/Columndrive Time in platform data\n");
 		bfin_write_KPAD_MSEL(0xFF0);	/* Default MSEL	*/
 	} else {
 		bfin_write_KPAD_MSEL(
@@ -252,7 +252,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 	}
 
 	error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
-				 IRQF_SAMPLE_RANDOM, DRV_NAME, pdev);
+				0, DRV_NAME, pdev);
 	if (error) {
 		printk(KERN_ERR DRV_NAME
 			": unable to claim irq %d; error %d\n",
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index aacf71f3cd44..e9d639ec283d 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
 }
 
 
-/* initialise HIL */
-static int __init
-hil_keyb_init(void)
+/* initialize HIL */
+static int __devinit hil_keyb_init(void)
 {
 	unsigned char c;
 	unsigned int i, kbid;
 	wait_queue_head_t hil_wait;
 	int err;
 
-	if (hil_dev.dev) {
+	if (hil_dev.dev)
 		return -ENODEV; /* already initialized */
-	}
 
+	init_waitqueue_head(&hil_wait);
 	spin_lock_init(&hil_dev.lock);
+
 	hil_dev.dev = input_allocate_device();
 	if (!hil_dev.dev)
 		return -ENOMEM;
 
-#if defined(CONFIG_HP300)
-	if (!MACH_IS_HP300) {
-		err = -ENODEV;
-		goto err1;
-	}
-	if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
-		printk(KERN_ERR "HIL: hardware register was not found\n");
-		err = -ENODEV;
-		goto err1;
-	}
-	if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
-		printk(KERN_ERR "HIL: IOPORT region already used\n");
-		err = -EIO;
-		goto err1;
-	}
-#endif
-
 	err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
 	if (err) {
 		printk(KERN_ERR "HIL: Can't get IRQ\n");
-		goto err2;
+		goto err1;
 	}
 
 	/* Turn on interrupts */
@@ -246,11 +229,9 @@ hil_keyb_init(void)
 	hil_dev.valid = 0;	/* clear any pending data */
 	hil_do(HIL_READKBDSADR, NULL, 0);
 
-	init_waitqueue_head(&hil_wait);
-	wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
-	if (!hil_dev.valid) {
+	wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);
+	if (!hil_dev.valid)
 		printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
-	}
 
 	c = hil_dev.c;
 	hil_dev.valid = 0;
@@ -268,7 +249,7 @@ hil_keyb_init(void)
 
 	for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
 		if (hphilkeyb_keycode[i] != KEY_RESERVED)
-			set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+			__set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
 
 	hil_dev.dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	hil_dev.dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
@@ -287,34 +268,45 @@ hil_keyb_init(void)
 	err = input_register_device(hil_dev.dev);
 	if (err) {
 		printk(KERN_ERR "HIL: Can't register device\n");
-		goto err3;
+		goto err2;
 	}
+
 	printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
 	       hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
 
 	return 0;
 
-err3:
+err2:
 	hil_do(HIL_INTOFF, NULL, 0);
-	disable_irq(HIL_IRQ);
 	free_irq(HIL_IRQ, hil_dev.dev_id);
-err2:
-#if defined(CONFIG_HP300)
-	release_region(HILBASE + HIL_DATA, 2);
 err1:
-#endif
 	input_free_device(hil_dev.dev);
 	hil_dev.dev = NULL;
 	return err;
 }
 
+static void __devexit hil_keyb_exit(void)
+{
+	if (HIL_IRQ)
+		free_irq(HIL_IRQ, hil_dev.dev_id);
+
+	/* Turn off interrupts */
+	hil_do(HIL_INTOFF, NULL, 0);
+
+	input_unregister_device(hil_dev.dev);
+	hil_dev.dev = NULL;
+}
 
 #if defined(CONFIG_PARISC)
-static int __init
-hil_init_chip(struct parisc_device *dev)
+static int __devinit hil_probe_chip(struct parisc_device *dev)
 {
+	/* Only allow one HIL keyboard */
+	if (hil_dev.dev)
+		return -ENODEV;
+
 	if (!dev->irq) {
-		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
+		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",
+			(void *)dev->hpa.start);
 		return -ENODEV;
 	}
 
@@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev)
 	return hil_keyb_init();
 }
 
+static int __devexit hil_remove_chip(struct parisc_device *dev)
+{
+	hil_keyb_exit();
+
+	return 0;
+}
+
 static struct parisc_device_id hil_tbl[] = {
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
 	{ 0, }
 };
 
+#if 0
+/* Disabled to avoid conflicts with the HP SDC HIL drivers */
 MODULE_DEVICE_TABLE(parisc, hil_tbl);
+#endif
 
 static struct parisc_driver hil_driver = {
-	.name =		"hil",
-	.id_table =	hil_tbl,
-	.probe =	hil_init_chip,
+	.name		= "hil",
+	.id_table	= hil_tbl,
+	.probe		= hil_probe_chip,
+	.remove		= __devexit_p(hil_remove_chip),
 };
-#endif /* CONFIG_PARISC */
-
 
 static int __init hil_init(void)
 {
-#if defined(CONFIG_PARISC)
 	return register_parisc_driver(&hil_driver);
-#else
-	return hil_keyb_init();
-#endif
 }
 
-
 static void __exit hil_exit(void)
 {
-	if (HIL_IRQ) {
-		disable_irq(HIL_IRQ);
-		free_irq(HIL_IRQ, hil_dev.dev_id);
+	unregister_parisc_driver(&hil_driver);
+}
+
+#else /* !CONFIG_PARISC */
+
+static int __init hil_init(void)
+{
+	int error;
+
+	/* Only allow one HIL keyboard */
+	if (hil_dev.dev)
+		return -EBUSY;
+
+	if (!MACH_IS_HP300)
+		return -ENODEV;
+
+	if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
+		printk(KERN_ERR "HIL: hardware register was not found\n");
+		return -ENODEV;
 	}
 
-	/* Turn off interrupts */
-	hil_do(HIL_INTOFF, NULL, 0);
+	if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
+		printk(KERN_ERR "HIL: IOPORT region already used\n");
+		return -EIO;
+	}
 
-	input_unregister_device(hil_dev.dev);
+	error = hil_keyb_init();
+	if (error) {
+		release_region(HILBASE + HIL_DATA, 2);
+		return error;
+	}
 
-	hil_dev.dev = NULL;
+	return 0;
+}
 
-#if defined(CONFIG_PARISC)
-	unregister_parisc_driver(&hil_driver);
-#else
-	release_region(HILBASE+HIL_DATA, 2);
-#endif
+static void __exit hil_exit(void)
+{
+	hil_keyb_exit();
+	release_region(HILBASE + HIL_DATA, 2);
 }
 
+#endif /* CONFIG_PARISC */
+
 module_init(hil_init);
 module_exit(hil_exit);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 67e5553f699a..5c0a631d1455 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -214,7 +214,7 @@ config INPUT_SGI_BTNS
 
 config HP_SDC_RTC
 	tristate "HP SDC Real Time Clock"
-	depends on GSC || HP300
+	depends on (GSC || HP300) && SERIO
 	select HP_SDC
 	help
 	  Say Y here if you want to support the built-in real time clock
@@ -227,4 +227,27 @@ config INPUT_PCF50633_PMU
 	 Say Y to include support for delivering  PMU events via  input
 	 layer on NXP PCF50633.
 
+config INPUT_GPIO_ROTARY_ENCODER
+	tristate "Rotary encoders connected to GPIO pins"
+	depends on GPIOLIB && GENERIC_GPIO
+	help
+	  Say Y here to add support for rotary encoders connected to GPIO lines.
+	  Check file:Documentation/incput/rotary_encoder.txt for more
+	  information.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rotary_encoder.
+
+config INPUT_RB532_BUTTON
+	tristate "Mikrotik Routerboard 532 button interface"
+	depends on MIKROTIK_RB532
+	depends on GPIOLIB && GENERIC_GPIO
+	select INPUT_POLLDEV
+	help
+	  Say Y here if you want support for the S1 button built into
+	  Mikrotik's Routerboard 532.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rb532_button.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index bb62e6efacf3..eb3f407baedf 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,21 +4,23 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
-obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
-obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
-obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
-obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
-obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
+obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
 obj-$(CONFIG_INPUT_ATI_REMOTE)		+= ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
-obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
-obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
-obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
+obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
 obj-$(CONFIG_INPUT_CM109)		+= cm109.o
+obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
-obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
-obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
+obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)	+= pcf50633-input.o
+obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
+obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
+obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
+obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
+obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
+obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
+obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
+obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 3c9988dc0e9f..922c05141585 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -31,12 +31,73 @@ MODULE_LICENSE("GPL");
  * newly configured "channel".
  */
 
-static unsigned int channel_mask = 0xFFFF;
-module_param(channel_mask, uint, 0644);
+enum {
+	ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF,
+	ATI_REMOTE2_MAX_MODE_MASK = 0x1F,
+};
+
+static int ati_remote2_set_mask(const char *val,
+				struct kernel_param *kp, unsigned int max)
+{
+	unsigned long mask;
+	int ret;
+
+	if (!val)
+		return -EINVAL;
+
+	ret = strict_strtoul(val, 0, &mask);
+	if (ret)
+		return ret;
+
+	if (mask & ~max)
+		return -EINVAL;
+
+	*(unsigned int *)kp->arg = mask;
+
+	return 0;
+}
+
+static int ati_remote2_set_channel_mask(const char *val,
+					struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
+}
+
+static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
+}
+
+static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
+}
+
+static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg);
+}
+
+static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
+#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_channel_mask ati_remote2_set_channel_mask
+#define param_get_channel_mask ati_remote2_get_channel_mask
+module_param(channel_mask, channel_mask, 0644);
 MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
 
-static unsigned int mode_mask = 0x1F;
-module_param(mode_mask, uint, 0644);
+static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
+#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_mode_mask ati_remote2_set_mode_mask
+#define param_get_mode_mask ati_remote2_get_mode_mask
+module_param(mode_mask, mode_mask, 0644);
 MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
 
 static struct usb_device_id ati_remote2_id_table[] = {
@@ -133,12 +194,18 @@ struct ati_remote2 {
 	u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
 
 	unsigned int flags;
+
+	unsigned int channel_mask;
+	unsigned int mode_mask;
 };
 
 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
 static void ati_remote2_disconnect(struct usb_interface *interface);
 static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
 static int ati_remote2_resume(struct usb_interface *interface);
+static int ati_remote2_reset_resume(struct usb_interface *interface);
+static int ati_remote2_pre_reset(struct usb_interface *interface);
+static int ati_remote2_post_reset(struct usb_interface *interface);
 
 static struct usb_driver ati_remote2_driver = {
 	.name       = "ati_remote2",
@@ -147,6 +214,9 @@ static struct usb_driver ati_remote2_driver = {
 	.id_table   = ati_remote2_id_table,
 	.suspend    = ati_remote2_suspend,
 	.resume     = ati_remote2_resume,
+	.reset_resume = ati_remote2_reset_resume,
+	.pre_reset  = ati_remote2_pre_reset,
+	.post_reset = ati_remote2_post_reset,
 	.supports_autosuspend = 1,
 };
 
@@ -238,7 +308,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
 
 	channel = data[0] >> 4;
 
-	if (!((1 << channel) & channel_mask))
+	if (!((1 << channel) & ar2->channel_mask))
 		return;
 
 	mode = data[0] & 0x0F;
@@ -250,7 +320,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
 		return;
 	}
 
-	if (!((1 << mode) & mode_mask))
+	if (!((1 << mode) & ar2->mode_mask))
 		return;
 
 	input_event(idev, EV_REL, REL_X, (s8) data[1]);
@@ -277,7 +347,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
 
 	channel = data[0] >> 4;
 
-	if (!((1 << channel) & channel_mask))
+	if (!((1 << channel) & ar2->channel_mask))
 		return;
 
 	mode = data[0] & 0x0F;
@@ -305,7 +375,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
 			ar2->mode = mode;
 	}
 
-	if (!((1 << mode) & mode_mask))
+	if (!((1 << mode) & ar2->mode_mask))
 		return;
 
 	index = ati_remote2_lookup(hw_code);
@@ -410,7 +480,7 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
 	int index, mode;
 
 	mode = scancode >> 8;
-	if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
 		return -EINVAL;
 
 	index = ati_remote2_lookup(scancode & 0xFF);
@@ -427,7 +497,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
 	int index, mode, old_keycode;
 
 	mode = scancode >> 8;
-	if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
 		return -EINVAL;
 
 	index = ati_remote2_lookup(scancode & 0xFF);
@@ -550,7 +620,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
 	}
 }
 
-static int ati_remote2_setup(struct ati_remote2 *ar2)
+static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask)
 {
 	int r, i, channel;
 
@@ -565,8 +635,8 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
 
 	channel = 0;
 	for (i = 0; i < 16; i++) {
-		if ((1 << i) & channel_mask) {
-			if (!(~(1 << i) & 0xFFFF & channel_mask))
+		if ((1 << i) & ch_mask) {
+			if (!(~(1 << i) & ch_mask))
 				channel = i + 1;
 			break;
 		}
@@ -585,6 +655,99 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
 	return 0;
 }
 
+static ssize_t ati_remote2_show_channel_mask(struct device *dev,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+	return sprintf(buf, "0x%04x\n", ar2->channel_mask);
+}
+
+static ssize_t ati_remote2_store_channel_mask(struct device *dev,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+	unsigned long mask;
+	int r;
+
+	if (strict_strtoul(buf, 0, &mask))
+		return -EINVAL;
+
+	if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK)
+		return -EINVAL;
+
+	r = usb_autopm_get_interface(ar2->intf[0]);
+	if (r) {
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): usb_autopm_get_interface() = %d\n", __func__, r);
+		return r;
+	}
+
+	mutex_lock(&ati_remote2_mutex);
+
+	if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))
+		ar2->channel_mask = mask;
+
+	mutex_unlock(&ati_remote2_mutex);
+
+	usb_autopm_put_interface(ar2->intf[0]);
+
+	return count;
+}
+
+static ssize_t ati_remote2_show_mode_mask(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+	return sprintf(buf, "0x%02x\n", ar2->mode_mask);
+}
+
+static ssize_t ati_remote2_store_mode_mask(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+	unsigned long mask;
+
+	if (strict_strtoul(buf, 0, &mask))
+		return -EINVAL;
+
+	if (mask & ~ATI_REMOTE2_MAX_MODE_MASK)
+		return -EINVAL;
+
+	ar2->mode_mask = mask;
+
+	return count;
+}
+
+static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask,
+		   ati_remote2_store_channel_mask);
+
+static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask,
+		   ati_remote2_store_mode_mask);
+
+static struct attribute *ati_remote2_attrs[] = {
+	&dev_attr_channel_mask.attr,
+	&dev_attr_mode_mask.attr,
+	NULL,
+};
+
+static struct attribute_group ati_remote2_attr_group = {
+	.attrs = ati_remote2_attrs,
+};
+
 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(interface);
@@ -615,7 +778,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
 	if (r)
 		goto fail2;
 
-	r = ati_remote2_setup(ar2);
+	ar2->channel_mask = channel_mask;
+	ar2->mode_mask = mode_mask;
+
+	r = ati_remote2_setup(ar2, ar2->channel_mask);
 	if (r)
 		goto fail2;
 
@@ -624,19 +790,24 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
 
 	strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
 
-	r = ati_remote2_input_init(ar2);
+	r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
 	if (r)
 		goto fail2;
 
+	r = ati_remote2_input_init(ar2);
+	if (r)
+		goto fail3;
+
 	usb_set_intfdata(interface, ar2);
 
 	interface->needs_remote_wakeup = 1;
 
 	return 0;
 
+ fail3:
+	sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
  fail2:
 	ati_remote2_urb_cleanup(ar2);
-
 	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
  fail1:
 	kfree(ar2);
@@ -657,6 +828,8 @@ static void ati_remote2_disconnect(struct usb_interface *interface)
 
 	input_unregister_device(ar2->idev);
 
+	sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group);
+
 	ati_remote2_urb_cleanup(ar2);
 
 	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
@@ -715,6 +888,78 @@ static int ati_remote2_resume(struct usb_interface *interface)
 	return r;
 }
 
+static int ati_remote2_reset_resume(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	int r = 0;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	mutex_lock(&ati_remote2_mutex);
+
+	r = ati_remote2_setup(ar2, ar2->channel_mask);
+	if (r)
+		goto out;
+
+	if (ar2->flags & ATI_REMOTE2_OPENED)
+		r = ati_remote2_submit_urbs(ar2);
+
+	if (!r)
+		ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
+
+ out:
+	mutex_unlock(&ati_remote2_mutex);
+
+	return r;
+}
+
+static int ati_remote2_pre_reset(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	mutex_lock(&ati_remote2_mutex);
+
+	if (ar2->flags == ATI_REMOTE2_OPENED)
+		ati_remote2_kill_urbs(ar2);
+
+	return 0;
+}
+
+static int ati_remote2_post_reset(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	int r = 0;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	if (ar2->flags == ATI_REMOTE2_OPENED)
+		r = ati_remote2_submit_urbs(ar2);
+
+	mutex_unlock(&ati_remote2_mutex);
+
+	return r;
+}
+
 static int __init ati_remote2_init(void)
 {
 	int r;
diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c
new file mode 100644
index 000000000000..e2c7f622a0b5
--- /dev/null
+++ b/drivers/input/misc/rb532_button.c
@@ -0,0 +1,120 @@
+/*
+ * Support for the S1 button on Routerboard 532
+ *
+ * Copyright (C) 2009  Phil Sutter <n0-1@freewrt.org>
+ */
+
+#include <linux/input-polldev.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+#define DRV_NAME "rb532-button"
+
+#define RB532_BTN_RATE 100 /* msec */
+#define RB532_BTN_KSYM BTN_0
+
+/* The S1 button state is provided by GPIO pin 1. But as this
+ * pin is also used for uart input as alternate function, the
+ * operational modes must be switched first:
+ * 1) disable uart using set_latch_u5()
+ * 2) turn off alternate function implicitly through
+ *    gpio_direction_input()
+ * 3) read the GPIO's current value
+ * 4) undo step 2 by enabling alternate function (in this
+ *    mode the GPIO direction is fixed, so no change needed)
+ * 5) turn on uart again
+ * The GPIO value occurs to be inverted, so pin high means
+ * button is not pressed.
+ */
+static bool rb532_button_pressed(void)
+{
+	int val;
+
+	set_latch_u5(0, LO_FOFF);
+	gpio_direction_input(GPIO_BTN_S1);
+
+	val = gpio_get_value(GPIO_BTN_S1);
+
+	rb532_gpio_set_func(GPIO_BTN_S1);
+	set_latch_u5(LO_FOFF, 0);
+
+	return !val;
+}
+
+static void rb532_button_poll(struct input_polled_dev *poll_dev)
+{
+	input_report_key(poll_dev->input, RB532_BTN_KSYM,
+			 rb532_button_pressed());
+	input_sync(poll_dev->input);
+}
+
+static int __devinit rb532_button_probe(struct platform_device *pdev)
+{
+	struct input_polled_dev *poll_dev;
+	int error;
+
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev)
+		return -ENOMEM;
+
+	poll_dev->poll = rb532_button_poll;
+	poll_dev->poll_interval = RB532_BTN_RATE;
+
+	poll_dev->input->name = "rb532 button";
+	poll_dev->input->phys = "rb532/button0";
+	poll_dev->input->id.bustype = BUS_HOST;
+	poll_dev->input->dev.parent = &pdev->dev;
+
+	dev_set_drvdata(&pdev->dev, poll_dev);
+
+	input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);
+
+	error = input_register_polled_device(poll_dev);
+	if (error) {
+		input_free_polled_device(poll_dev);
+		return error;
+	}
+
+	return 0;
+}
+
+static int __devexit rb532_button_remove(struct platform_device *pdev)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev);
+
+	input_unregister_polled_device(poll_dev);
+	input_free_polled_device(poll_dev);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver rb532_button_driver = {
+	.probe = rb532_button_probe,
+	.remove = __devexit_p(rb532_button_remove),
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init rb532_button_init(void)
+{
+	return platform_driver_register(&rb532_button_driver);
+}
+
+static void __exit rb532_button_exit(void)
+{
+	platform_driver_unregister(&rb532_button_driver);
+}
+
+module_init(rb532_button_init);
+module_exit(rb532_button_exit);
+
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Support for S1 button on Routerboard 532");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
new file mode 100644
index 000000000000..5bb3ab51b8c6
--- /dev/null
+++ b/drivers/input/misc/rotary_encoder.c
@@ -0,0 +1,221 @@
+/*
+ * rotary_encoder.c
+ *
+ * (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * state machine code inspired by code from Tim Ruetz
+ *
+ * A generic driver for rotary encoders connected to GPIO lines.
+ * See file:Documentation/input/rotary_encoder.txt for more information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/rotary_encoder.h>
+
+#define DRV_NAME "rotary-encoder"
+
+struct rotary_encoder {
+	unsigned int irq_a;
+	unsigned int irq_b;
+	unsigned int pos;
+	unsigned int armed;
+	unsigned int dir;
+	struct input_dev *input;
+	struct rotary_encoder_platform_data *pdata;
+};
+
+static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
+{
+	struct rotary_encoder *encoder = dev_id;
+	struct rotary_encoder_platform_data *pdata = encoder->pdata;
+	int a = !!gpio_get_value(pdata->gpio_a);
+	int b = !!gpio_get_value(pdata->gpio_b);
+	int state;
+
+	a ^= pdata->inverted_a;
+	b ^= pdata->inverted_b;
+	state = (a << 1) | b;
+
+	switch (state) {
+
+	case 0x0:
+		if (!encoder->armed)
+			break;
+
+		if (encoder->dir) {
+			/* turning counter-clockwise */
+			encoder->pos += pdata->steps;
+			encoder->pos--;
+			encoder->pos %= pdata->steps;
+		} else {
+			/* turning clockwise */
+			encoder->pos++;
+			encoder->pos %= pdata->steps;
+		}
+
+		input_report_abs(encoder->input, pdata->axis, encoder->pos);
+		input_sync(encoder->input);
+
+		encoder->armed = 0;
+		break;
+
+	case 0x1:
+	case 0x2:
+		if (encoder->armed)
+			encoder->dir = state - 1;
+		break;
+
+	case 0x3:
+		encoder->armed = 1;
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit rotary_encoder_probe(struct platform_device *pdev)
+{
+	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+	struct rotary_encoder *encoder;
+	struct input_dev *input;
+	int err;
+
+	if (!pdata || !pdata->steps) {
+		dev_err(&pdev->dev, "invalid platform data\n");
+		return -ENOENT;
+	}
+
+	encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
+	input = input_allocate_device();
+	if (!encoder || !input) {
+		dev_err(&pdev->dev, "failed to allocate memory for device\n");
+		err = -ENOMEM;
+		goto exit_free_mem;
+	}
+
+	encoder->input = input;
+	encoder->pdata = pdata;
+	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
+	encoder->irq_b = gpio_to_irq(pdata->gpio_b);
+
+	/* create and register the input driver */
+	input->name = pdev->name;
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &pdev->dev;
+	input->evbit[0] = BIT_MASK(EV_ABS);
+	input_set_abs_params(encoder->input,
+			     pdata->axis, 0, pdata->steps, 0, 1);
+
+	err = input_register_device(input);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		goto exit_free_mem;
+	}
+
+	/* request the GPIOs */
+	err = gpio_request(pdata->gpio_a, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request GPIO %d\n",
+			pdata->gpio_a);
+		goto exit_unregister_input;
+	}
+
+	err = gpio_request(pdata->gpio_b, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request GPIO %d\n",
+			pdata->gpio_b);
+		goto exit_free_gpio_a;
+	}
+
+	/* request the IRQs */
+	err = request_irq(encoder->irq_a, &rotary_encoder_irq,
+			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+			  DRV_NAME, encoder);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request IRQ %d\n",
+			encoder->irq_a);
+		goto exit_free_gpio_b;
+	}
+
+	err = request_irq(encoder->irq_b, &rotary_encoder_irq,
+			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+			  DRV_NAME, encoder);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request IRQ %d\n",
+			encoder->irq_b);
+		goto exit_free_irq_a;
+	}
+
+	platform_set_drvdata(pdev, encoder);
+
+	return 0;
+
+exit_free_irq_a:
+	free_irq(encoder->irq_a, encoder);
+exit_free_gpio_b:
+	gpio_free(pdata->gpio_b);
+exit_free_gpio_a:
+	gpio_free(pdata->gpio_a);
+exit_unregister_input:
+	input_unregister_device(input);
+	input = NULL; /* so we don't try to free it */
+exit_free_mem:
+	input_free_device(input);
+	kfree(encoder);
+	return err;
+}
+
+static int __devexit rotary_encoder_remove(struct platform_device *pdev)
+{
+	struct rotary_encoder *encoder = platform_get_drvdata(pdev);
+	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+
+	free_irq(encoder->irq_a, encoder);
+	free_irq(encoder->irq_b, encoder);
+	gpio_free(pdata->gpio_a);
+	gpio_free(pdata->gpio_b);
+	input_unregister_device(encoder->input);
+	platform_set_drvdata(pdev, NULL);
+	kfree(encoder);
+
+	return 0;
+}
+
+static struct platform_driver rotary_encoder_driver = {
+	.probe		= rotary_encoder_probe,
+	.remove		= __devexit_p(rotary_encoder_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init rotary_encoder_init(void)
+{
+	return platform_driver_register(&rotary_encoder_driver);
+}
+
+static void __exit rotary_encoder_exit(void)
+{
+	platform_driver_unregister(&rotary_encoder_driver);
+}
+
+module_init(rotary_encoder_init);
+module_exit(rotary_encoder_exit);
+
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DESCRIPTION("GPIO rotary encoder driver");
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 4f38e6f7dfdd..c66cc3d08c2f 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -292,4 +292,15 @@ config MOUSE_PXA930_TRKBALL
 	help
 	  Say Y here to support PXA930 Trackball mouse.
 
+config MOUSE_MAPLE
+	tristate "Maple mouse (for the Dreamcast)"
+	depends on MAPLE
+	help
+	  This driver supports the Maple mouse on the SEGA Dreamcast.
+
+	  Most Dreamcast users, who have a mouse, will say Y here.
+
+	  To compile this driver as a module choose M here: the module will be
+	  called maplemouse.
+
 endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 8c8a1f236e28..472189468d67 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -6,18 +6,19 @@
 
 obj-$(CONFIG_MOUSE_AMIGA)		+= amimouse.o
 obj-$(CONFIG_MOUSE_APPLETOUCH)		+= appletouch.o
-obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
 obj-$(CONFIG_MOUSE_ATARI)		+= atarimouse.o
-obj-$(CONFIG_MOUSE_RISCPC)		+= rpcmouse.o
+obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
+obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
+obj-$(CONFIG_MOUSE_HIL)			+= hil_ptr.o
 obj-$(CONFIG_MOUSE_INPORT)		+= inport.o
 obj-$(CONFIG_MOUSE_LOGIBM)		+= logibm.o
+obj-$(CONFIG_MOUSE_MAPLE)		+= maplemouse.o
 obj-$(CONFIG_MOUSE_PC110PAD)		+= pc110pad.o
 obj-$(CONFIG_MOUSE_PS2)			+= psmouse.o
 obj-$(CONFIG_MOUSE_PXA930_TRKBALL)	+= pxa930_trkball.o
+obj-$(CONFIG_MOUSE_RISCPC)		+= rpcmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)		+= sermouse.o
-obj-$(CONFIG_MOUSE_HIL)			+= hil_ptr.o
 obj-$(CONFIG_MOUSE_VSXXXAA)		+= vsxxxaa.o
-obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
 
 psmouse-objs := psmouse-base.o synaptics.o
 
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 55cd0fa68339..a1ad2f1a7bb3 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -472,7 +472,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
 		return -EIO;
 	}
 
-	hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
+	hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]);
 
 	/* HGPK signature: 0x67, 0x00, 0x<model> */
 	if (param[0] != 0x67 || param[1] != 0x00)
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
new file mode 100644
index 000000000000..5f278176eb9b
--- /dev/null
+++ b/drivers/input/mouse/maplemouse.c
@@ -0,0 +1,150 @@
+/*
+ *	SEGA Dreamcast mouse driver
+ *	Based on drivers/usb/usbmouse.c
+ *
+ *	Copyright (c) Yaegashi Takeshi, 2001
+ *	Copyright (c) Adrian McMenamin, 2008 - 2009
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/maple.h>
+
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
+MODULE_DESCRIPTION("SEGA Dreamcast mouse driver");
+MODULE_LICENSE("GPL");
+
+struct dc_mouse {
+	struct input_dev *dev;
+	struct maple_device *mdev;
+};
+
+static void dc_mouse_callback(struct mapleq *mq)
+{
+	int buttons, relx, rely, relz;
+	struct maple_device *mapledev = mq->dev;
+	struct dc_mouse *mse = maple_get_drvdata(mapledev);
+	struct input_dev *dev = mse->dev;
+	unsigned char *res = mq->recvbuf->buf;
+
+	buttons = ~res[8];
+	relx = *(unsigned short *)(res + 12) - 512;
+	rely = *(unsigned short *)(res + 14) - 512;
+	relz = *(unsigned short *)(res + 16) - 512;
+
+	input_report_key(dev, BTN_LEFT,   buttons & 4);
+	input_report_key(dev, BTN_MIDDLE, buttons & 9);
+	input_report_key(dev, BTN_RIGHT,  buttons & 2);
+	input_report_rel(dev, REL_X,      relx);
+	input_report_rel(dev, REL_Y,      rely);
+	input_report_rel(dev, REL_WHEEL,  relz);
+	input_sync(dev);
+}
+
+static int dc_mouse_open(struct input_dev *dev)
+{
+	struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
+
+	maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50,
+		MAPLE_FUNC_MOUSE);
+
+	return 0;
+}
+
+static void dc_mouse_close(struct input_dev *dev)
+{
+	struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
+
+	maple_getcond_callback(mse->mdev, dc_mouse_callback, 0,
+		MAPLE_FUNC_MOUSE);
+}
+
+/* allow the mouse to be used */
+static int __devinit probe_maple_mouse(struct device *dev)
+{
+	struct maple_device *mdev = to_maple_dev(dev);
+	struct maple_driver *mdrv = to_maple_driver(dev->driver);
+	int error;
+	struct input_dev *input_dev;
+	struct dc_mouse *mse;
+
+	mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL);
+	if (!mse) {
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		error = -ENOMEM;
+		goto fail_nomem;
+	}
+
+	mse->dev = input_dev;
+	mse->mdev = mdev;
+
+	input_set_drvdata(input_dev, mse);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
+		BIT_MASK(REL_WHEEL);
+	input_dev->open = dc_mouse_open;
+	input_dev->close = dc_mouse_close;
+	input_dev->name = mdev->product_name;
+	input_dev->id.bustype = BUS_HOST;
+	error =	input_register_device(input_dev);
+	if (error)
+		goto fail_register;
+
+	mdev->driver = mdrv;
+	maple_set_drvdata(mdev, mse);
+
+	return error;
+
+fail_register:
+	input_free_device(input_dev);
+fail_nomem:
+	kfree(mse);
+fail:
+	return error;
+}
+
+static int __devexit remove_maple_mouse(struct device *dev)
+{
+	struct maple_device *mdev = to_maple_dev(dev);
+	struct dc_mouse *mse = maple_get_drvdata(mdev);
+
+	mdev->callback = NULL;
+	input_unregister_device(mse->dev);
+	maple_set_drvdata(mdev, NULL);
+	kfree(mse);
+
+	return 0;
+}
+
+static struct maple_driver dc_mouse_driver = {
+	.function =	MAPLE_FUNC_MOUSE,
+	.drv = {
+		.name = "Dreamcast_mouse",
+		.probe = probe_maple_mouse,
+		.remove = __devexit_p(remove_maple_mouse),
+	},
+};
+
+static int __init dc_mouse_init(void)
+{
+	return maple_driver_register(&dc_mouse_driver);
+}
+
+static void __exit dc_mouse_exit(void)
+{
+	maple_driver_unregister(&dc_mouse_driver);
+}
+
+module_init(dc_mouse_init);
+module_exit(dc_mouse_exit);
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index fd09c8df81f2..3941f97cfa60 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -108,14 +108,10 @@ static int pc110pad_open(struct input_dev *dev)
  */
 static int __init pc110pad_init(void)
 {
-	struct pci_dev *dev;
 	int err;
 
-	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (dev) {
-		pci_dev_put(dev);
+	if (!no_pci_devices())
 		return -ENODEV;
-	}
 
 	if (!request_region(pc110pad_io, 4, "pc110pad")) {
 		printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n",
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index bfe49243f38b..1c9410d1822c 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -819,6 +819,7 @@ static const struct parisc_device_id hp_sdc_tbl[] = {
 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
 
 static int __init hp_sdc_init_hppa(struct parisc_device *d);
+static struct delayed_work moduleloader_work;
 
 static struct parisc_driver hp_sdc_driver = {
 	.name =		"hp_sdc",
@@ -930,8 +931,15 @@ static int __init hp_sdc_init(void)
 
 #if defined(__hppa__)
 
+static void request_module_delayed(struct work_struct *work)
+{
+	request_module("hp_sdc_mlc");
+}
+
 static int __init hp_sdc_init_hppa(struct parisc_device *d)
 {
+	int ret;
+
 	if (!d)
 		return 1;
 	if (hp_sdc.dev != NULL)
@@ -944,13 +952,26 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d)
 	hp_sdc.data_io		= d->hpa.start + 0x800;
 	hp_sdc.status_io	= d->hpa.start + 0x801;
 
-	return hp_sdc_init();
+	INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed);
+
+	ret = hp_sdc_init();
+	/* after sucessfull initialization give SDC some time to settle
+	 * and then load the hp_sdc_mlc upper layer driver */
+	if (!ret)
+		schedule_delayed_work(&moduleloader_work,
+			msecs_to_jiffies(2000));
+
+	return ret;
 }
 
 #endif /* __hppa__ */
 
 static void hp_sdc_exit(void)
 {
+	/* do nothing if we don't have a SDC */
+	if (!hp_sdc.dev)
+		return;
+
 	write_lock_irq(&hp_sdc.lock);
 
 	/* Turn off all maskable "sub-function" irq's. */
@@ -969,6 +990,7 @@ static void hp_sdc_exit(void)
 	tasklet_kill(&hp_sdc.task);
 
 #if defined(__hppa__)
+	cancel_delayed_work_sync(&moduleloader_work);
 	if (unregister_parisc_driver(&hp_sdc_driver))
 		printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
 #endif
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 6fa2deff7446..fb8a3cd3ffd0 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -151,6 +151,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
 			DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
 		},
 	},
+	{
+		.ident = "HP DV9700",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+		},
+	},
 	{ }
 };
 
@@ -369,6 +377,24 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
 	{ }
 };
 
+static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+	{
+		.ident = "MSI Wind U-100",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+		},
+	},
+	{
+		.ident = "LG Electronics X110",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "X110"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+		},
+	},
+	{ }
+};
+
 #ifdef CONFIG_PNP
 static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 	{
@@ -378,6 +404,13 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
 		},
 	},
+	{
+		.ident = "MSI Wind U-100",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+		},
+	},
 	{ }
 };
 #endif
@@ -690,6 +723,9 @@ static int __init i8042_platform_init(void)
 #endif
 
 #ifdef CONFIG_X86
+	if (dmi_check_system(i8042_dmi_reset_table))
+		i8042_reset = 1;
+
 	if (dmi_check_system(i8042_dmi_noloop_table))
 		i8042_noloop = 1;
 
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 170f71ee5772..3cffb704e374 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -712,22 +712,43 @@ static int i8042_controller_check(void)
 static int i8042_controller_selftest(void)
 {
 	unsigned char param;
+	int i = 0;
 
 	if (!i8042_reset)
 		return 0;
 
-	if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
-		printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-		return -ENODEV;
-	}
+	/*
+	 * We try this 5 times; on some really fragile systems this does not
+	 * take the first time...
+	 */
+	do {
+
+		if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+			printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+			return -ENODEV;
+		}
+
+		if (param == I8042_RET_CTL_TEST)
+			return 0;
 
-	if (param != I8042_RET_CTL_TEST) {
 		printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
-			 param, I8042_RET_CTL_TEST);
-		return -EIO;
-	}
+			param, I8042_RET_CTL_TEST);
+		msleep(50);
+	} while (i++ < 5);
 
+#ifdef CONFIG_X86
+	/*
+	 * On x86, we don't fail entire i8042 initialization if controller
+	 * reset fails in hopes that keyboard port will still be functional
+	 * and user will still get a working keyboard. This is especially
+	 * important on netbooks. On other arches we trust hardware more.
+	 */
+	printk(KERN_INFO
+		"i8042: giving up on controller selftest, continuing anyway...\n");
 	return 0;
+#else
+	return -EIO;
+#endif
 }
 
 /*
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index bb6486a8c070..b01fd61dadcc 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -29,6 +29,51 @@ config TOUCHSCREEN_ADS7846
 	  To compile this driver as a module, choose M here: the
 	  module will be called ads7846.
 
+config TOUCHSCREEN_AD7877
+	tristate "AD7877 based touchscreens"
+	depends on SPI_MASTER
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7877 controller, and your board-specific initialization
+	  code includes that in its table of SPI devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7877.
+
+config TOUCHSCREEN_AD7879_I2C
+	tristate "AD7879 based touchscreens: AD7879-1 I2C Interface"
+	depends on I2C
+	select TOUCHSCREEN_AD7879
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7879-1 controller, and your board-specific initialization
+	  code includes that in its table of I2C devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879_SPI
+	tristate "AD7879 based touchscreens: AD7879 SPI Interface"
+	depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n
+	select TOUCHSCREEN_AD7879
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7879 controller, and your board-specific initialization
+	  code includes that in its table of SPI devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879
+	tristate
+	default n
+
 config TOUCHSCREEN_BITSY
 	tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
 	depends on SA1100_BITSY
@@ -308,6 +353,19 @@ config TOUCHSCREEN_WM97XX_MAINSTONE
 	  To compile this driver as a module, choose M here: the
 	  module will be called mainstone-wm97xx.
 
+config TOUCHSCREEN_WM97XX_ZYLONITE
+	tristate "Zylonite accelerated touch"
+	depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE
+	select TOUCHSCREEN_WM9713
+	help
+	  Say Y here for support for streaming mode with the touchscreen
+	  on Zylonite systems.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called zylonite-wm97xx.
+
 config TOUCHSCREEN_USB_COMPOSITE
 	tristate "USB Touchscreen Driver"
 	depends on USB_ARCH_HAS_HCD
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d3375aff46fe..6700f7b9d165 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,8 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
+obj-$(CONFIG_TOUCHSCREEN_AD7877)	+= ad7877.o
+obj-$(CONFIG_TOUCHSCREEN_AD7879)	+= ad7879.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
@@ -34,3 +36,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705)	+= wm9705.o
 wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712)	+= wm9712.o
 wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713)	+= wm9713.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
+obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
new file mode 100644
index 000000000000..ecaeb7e8e75e
--- /dev/null
+++ b/drivers/input/touchscreen/ad7877.c
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:	AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver
+ * Based on:	ads7846.c
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *	Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *	Copyright (C) 2002 MontaVista Software
+ *	Copyright (C) 2004 Texas Instruments
+ *	Copyright (C) 2005 Dirk Behme
+ */
+
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ad7877.h>
+#include <asm/irq.h>
+
+#define	TS_PEN_UP_TIMEOUT	msecs_to_jiffies(50)
+
+#define MAX_SPI_FREQ_HZ			20000000
+#define	MAX_12BIT			((1<<12)-1)
+
+#define AD7877_REG_ZEROS			0
+#define AD7877_REG_CTRL1			1
+#define AD7877_REG_CTRL2			2
+#define AD7877_REG_ALERT			3
+#define AD7877_REG_AUX1HIGH			4
+#define AD7877_REG_AUX1LOW			5
+#define AD7877_REG_BAT1HIGH			6
+#define AD7877_REG_BAT1LOW			7
+#define AD7877_REG_BAT2HIGH			8
+#define AD7877_REG_BAT2LOW			9
+#define AD7877_REG_TEMP1HIGH			10
+#define AD7877_REG_TEMP1LOW			11
+#define AD7877_REG_SEQ0				12
+#define AD7877_REG_SEQ1				13
+#define AD7877_REG_DAC				14
+#define AD7877_REG_NONE1			15
+#define AD7877_REG_EXTWRITE			15
+#define AD7877_REG_XPLUS			16
+#define AD7877_REG_YPLUS			17
+#define AD7877_REG_Z2				18
+#define AD7877_REG_aux1				19
+#define AD7877_REG_aux2				20
+#define AD7877_REG_aux3				21
+#define AD7877_REG_bat1				22
+#define AD7877_REG_bat2				23
+#define AD7877_REG_temp1			24
+#define AD7877_REG_temp2			25
+#define AD7877_REG_Z1				26
+#define AD7877_REG_GPIOCTRL1			27
+#define AD7877_REG_GPIOCTRL2			28
+#define AD7877_REG_GPIODATA			29
+#define AD7877_REG_NONE2			30
+#define AD7877_REG_NONE3			31
+
+#define AD7877_SEQ_YPLUS_BIT			(1<<11)
+#define AD7877_SEQ_XPLUS_BIT			(1<<10)
+#define AD7877_SEQ_Z2_BIT			(1<<9)
+#define AD7877_SEQ_AUX1_BIT			(1<<8)
+#define AD7877_SEQ_AUX2_BIT			(1<<7)
+#define AD7877_SEQ_AUX3_BIT			(1<<6)
+#define AD7877_SEQ_BAT1_BIT			(1<<5)
+#define AD7877_SEQ_BAT2_BIT			(1<<4)
+#define AD7877_SEQ_TEMP1_BIT			(1<<3)
+#define AD7877_SEQ_TEMP2_BIT			(1<<2)
+#define AD7877_SEQ_Z1_BIT			(1<<1)
+
+enum {
+	AD7877_SEQ_YPOS  = 0,
+	AD7877_SEQ_XPOS  = 1,
+	AD7877_SEQ_Z2    = 2,
+	AD7877_SEQ_AUX1  = 3,
+	AD7877_SEQ_AUX2  = 4,
+	AD7877_SEQ_AUX3  = 5,
+	AD7877_SEQ_BAT1  = 6,
+	AD7877_SEQ_BAT2  = 7,
+	AD7877_SEQ_TEMP1 = 8,
+	AD7877_SEQ_TEMP2 = 9,
+	AD7877_SEQ_Z1    = 10,
+	AD7877_NR_SENSE  = 11,
+};
+
+/* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */
+#define AD7877_DAC_CONF			0x1
+
+/* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */
+#define AD7877_EXTW_GPIO_3_CONF		0x1C4
+#define AD7877_EXTW_GPIO_DATA		0x200
+
+/* Control REG 2 */
+#define AD7877_TMR(x)			((x & 0x3) << 0)
+#define AD7877_REF(x)			((x & 0x1) << 2)
+#define AD7877_POL(x)			((x & 0x1) << 3)
+#define AD7877_FCD(x)			((x & 0x3) << 4)
+#define AD7877_PM(x)			((x & 0x3) << 6)
+#define AD7877_ACQ(x)			((x & 0x3) << 8)
+#define AD7877_AVG(x)			((x & 0x3) << 10)
+
+/* Control REG 1 */
+#define	AD7877_SER			(1 << 11)	/* non-differential */
+#define	AD7877_DFR			(0 << 11)	/* differential */
+
+#define AD7877_MODE_NOC  (0)	/* Do not convert */
+#define AD7877_MODE_SCC  (1)	/* Single channel conversion */
+#define AD7877_MODE_SEQ0 (2)	/* Sequence 0 in Slave Mode */
+#define AD7877_MODE_SEQ1 (3)	/* Sequence 1 in Master Mode */
+
+#define AD7877_CHANADD(x)		((x&0xF)<<7)
+#define AD7877_READADD(x)		((x)<<2)
+#define AD7877_WRITEADD(x)		((x)<<12)
+
+#define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \
+		AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \
+		AD7877_READADD(AD7877_REG_ ## x))
+
+#define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \
+		AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT)
+
+/*
+ * Non-touchscreen sensors only use single-ended conversions.
+ */
+
+struct ser_req {
+	u16			reset;
+	u16			ref_on;
+	u16			command;
+	u16			sample;
+	struct spi_message	msg;
+	struct spi_transfer	xfer[6];
+};
+
+struct ad7877 {
+	struct input_dev	*input;
+	char			phys[32];
+
+	struct spi_device	*spi;
+	u16			model;
+	u16			vref_delay_usecs;
+	u16			x_plate_ohms;
+	u16			pressure_max;
+
+	u16			cmd_crtl1;
+	u16			cmd_crtl2;
+	u16			cmd_dummy;
+	u16			dac;
+
+	u8			stopacq_polarity;
+	u8			first_conversion_delay;
+	u8			acquisition_time;
+	u8			averaging;
+	u8			pen_down_acc_interval;
+
+	u16			conversion_data[AD7877_NR_SENSE];
+
+	struct spi_transfer	xfer[AD7877_NR_SENSE + 2];
+	struct spi_message	msg;
+
+	struct mutex		mutex;
+	unsigned		disabled:1;	/* P: mutex */
+	unsigned		gpio3:1;	/* P: mutex */
+	unsigned		gpio4:1;	/* P: mutex */
+
+	spinlock_t		lock;
+	struct timer_list	timer;		/* P: lock */
+	unsigned		pending:1;	/* P: lock */
+};
+
+static int gpio3;
+module_param(gpio3, int, 0);
+MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3");
+
+/*
+ * ad7877_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done using spi_async() in the interrupt handler.
+ */
+
+static int ad7877_read(struct spi_device *spi, u16 reg)
+{
+	struct ser_req *req;
+	int status, ret;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) |
+			AD7877_READADD(reg));
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].rx_buf = &req->sample;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	ret = status ? : req->sample;
+
+	kfree(req);
+
+	return ret;
+}
+
+static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
+{
+	struct ser_req *req;
+	int status;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) (AD7877_WRITEADD(reg) | (val & MAX_12BIT));
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+
+	kfree(req);
+
+	return status;
+}
+
+static int ad7877_read_adc(struct spi_device *spi, unsigned command)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+	struct ser_req *req;
+	int status;
+	int sample;
+	int i;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	/* activate reference, so it has time to settle; */
+	req->ref_on = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+			 AD7877_POL(ts->stopacq_polarity) |
+			 AD7877_AVG(0) | AD7877_PM(2) | AD7877_TMR(0) |
+			 AD7877_ACQ(ts->acquisition_time) | AD7877_FCD(0);
+
+	req->reset = AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_MODE_NOC;
+
+	req->command = (u16) command;
+
+	req->xfer[0].tx_buf = &req->reset;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].tx_buf = &req->ref_on;
+	req->xfer[1].len = 2;
+	req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+
+	req->xfer[2].tx_buf = &req->command;
+	req->xfer[2].len = 2;
+	req->xfer[2].delay_usecs = ts->vref_delay_usecs;
+
+	req->xfer[3].rx_buf = &req->sample;
+	req->xfer[3].len = 2;
+
+	req->xfer[4].tx_buf = &ts->cmd_crtl2;	/*REF OFF*/
+	req->xfer[4].len = 2;
+
+	req->xfer[5].tx_buf = &ts->cmd_crtl1;	/*DEFAULT*/
+	req->xfer[5].len = 2;
+
+	/* group all the transfers together, so we can't interfere with
+	 * reading touchscreen state; disable penirq while sampling
+	 */
+	for (i = 0; i < 6; i++)
+		spi_message_add_tail(&req->xfer[i], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	sample = req->sample;
+
+	kfree(req);
+
+	return status ? : sample;
+}
+
+static void ad7877_rx(struct ad7877 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+	unsigned Rt;
+	u16 x, y, z1, z2;
+
+	x = ts->conversion_data[AD7877_SEQ_XPOS] & MAX_12BIT;
+	y = ts->conversion_data[AD7877_SEQ_YPOS] & MAX_12BIT;
+	z1 = ts->conversion_data[AD7877_SEQ_Z1] & MAX_12BIT;
+	z2 = ts->conversion_data[AD7877_SEQ_Z2] & MAX_12BIT;
+
+	/*
+	 * The samples processed here are already preprocessed by the AD7877.
+	 * The preprocessing function consists of an averaging filter.
+	 * The combination of 'first conversion delay' and averaging provides a robust solution,
+	 * discarding the spurious noise in the signal and keeping only the data of interest.
+	 * The size of the averaging filter is programmable. (dev.platform_data, see linux/spi/ad7877.h)
+	 * Other user-programmable conversion controls include variable acquisition time,
+	 * and first conversion delay. Up to 16 averages can be taken per conversion.
+	 */
+
+	if (likely(x && z1)) {
+		/* compute touch pressure resistance using equation #1 */
+		Rt = (z2 - z1) * x * ts->x_plate_ohms;
+		Rt /= z1;
+		Rt = (Rt + 2047) >> 12;
+
+		input_report_abs(input_dev, ABS_X, x);
+		input_report_abs(input_dev, ABS_Y, y);
+		input_report_abs(input_dev, ABS_PRESSURE, Rt);
+		input_sync(input_dev);
+	}
+}
+
+static inline void ad7877_ts_event_release(struct ad7877 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+
+	input_report_abs(input_dev, ABS_PRESSURE, 0);
+	input_sync(input_dev);
+}
+
+static void ad7877_timer(unsigned long handle)
+{
+	struct ad7877 *ts = (void *)handle;
+
+	ad7877_ts_event_release(ts);
+}
+
+static irqreturn_t ad7877_irq(int irq, void *handle)
+{
+	struct ad7877 *ts = handle;
+	unsigned long flags;
+	int status;
+
+	/*
+	 * The repeated conversion sequencer controlled by TMR kicked off
+	 * too fast. We ignore the last and process the sample sequence
+	 * currently in the queue. It can't be older than 9.4ms, and we
+	 * need to avoid that ts->msg doesn't get issued twice while in work.
+	 */
+
+	spin_lock_irqsave(&ts->lock, flags);
+	if (!ts->pending) {
+		ts->pending = 1;
+
+		status = spi_async(ts->spi, &ts->msg);
+		if (status)
+			dev_err(&ts->spi->dev, "spi_sync --> %d\n", status);
+	}
+	spin_unlock_irqrestore(&ts->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void ad7877_callback(void *_ts)
+{
+	struct ad7877 *ts = _ts;
+
+	spin_lock_irq(&ts->lock);
+
+	ad7877_rx(ts);
+	ts->pending = 0;
+	mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+
+	spin_unlock_irq(&ts->lock);
+}
+
+static void ad7877_disable(struct ad7877 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (!ts->disabled) {
+		ts->disabled = 1;
+		disable_irq(ts->spi->irq);
+
+		/* Wait for spi_async callback */
+		while (ts->pending)
+			msleep(1);
+
+		if (del_timer_sync(&ts->timer))
+			ad7877_ts_event_release(ts);
+	}
+
+	/* we know the chip's in lowpower mode since we always
+	 * leave it that way after every request
+	 */
+
+	mutex_unlock(&ts->mutex);
+}
+
+static void ad7877_enable(struct ad7877 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (ts->disabled) {
+		ts->disabled = 0;
+		enable_irq(ts->spi->irq);
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+#define SHOW(name) static ssize_t \
+name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct ad7877	*ts = dev_get_drvdata(dev); \
+	ssize_t v = ad7877_read_adc(ts->spi, \
+			AD7877_READ_CHAN(name)); \
+	if (v < 0) \
+		return v; \
+	return sprintf(buf, "%u\n", (unsigned) v); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
+
+SHOW(aux1)
+SHOW(aux2)
+SHOW(aux3)
+SHOW(bat1)
+SHOW(bat2)
+SHOW(temp1)
+SHOW(temp2)
+
+static ssize_t ad7877_disable_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7877_disable_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val)
+		ad7877_disable(ts);
+	else
+		ad7877_enable(ts);
+
+	return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store);
+
+static ssize_t ad7877_dac_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->dac);
+}
+
+static ssize_t ad7877_dac_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->dac = val & 0xFF;
+	ad7877_write(ts->spi, AD7877_REG_DAC, (ts->dac << 4) | AD7877_DAC_CONF);
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store);
+
+static ssize_t ad7877_gpio3_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio3);
+}
+
+static ssize_t ad7877_gpio3_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->gpio3 = !!val;
+	ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+		 (ts->gpio4 << 4) | (ts->gpio3 << 5));
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store);
+
+static ssize_t ad7877_gpio4_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio4);
+}
+
+static ssize_t ad7877_gpio4_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->gpio4 = !!val;
+	ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+		     (ts->gpio4 << 4) | (ts->gpio3 << 5));
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpio4, 0664, ad7877_gpio4_show, ad7877_gpio4_store);
+
+static struct attribute *ad7877_attributes[] = {
+	&dev_attr_temp1.attr,
+	&dev_attr_temp2.attr,
+	&dev_attr_aux1.attr,
+	&dev_attr_aux2.attr,
+	&dev_attr_bat1.attr,
+	&dev_attr_bat2.attr,
+	&dev_attr_disable.attr,
+	&dev_attr_dac.attr,
+	&dev_attr_gpio4.attr,
+	NULL
+};
+
+static const struct attribute_group ad7877_attr_group = {
+	.attrs = ad7877_attributes,
+};
+
+static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
+{
+	struct spi_message *m;
+	int i;
+
+	ts->cmd_crtl2 = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+			AD7877_POL(ts->stopacq_polarity) |
+			AD7877_AVG(ts->averaging) | AD7877_PM(1) |
+			AD7877_TMR(ts->pen_down_acc_interval) |
+			AD7877_ACQ(ts->acquisition_time) |
+			AD7877_FCD(ts->first_conversion_delay);
+
+	ad7877_write(spi, AD7877_REG_CTRL2, ts->cmd_crtl2);
+
+	ts->cmd_crtl1 = AD7877_WRITEADD(AD7877_REG_CTRL1) |
+			AD7877_READADD(AD7877_REG_XPLUS-1) |
+			AD7877_MODE_SEQ1 | AD7877_DFR;
+
+	ad7877_write(spi, AD7877_REG_CTRL1, ts->cmd_crtl1);
+
+	ts->cmd_dummy = 0;
+
+	m = &ts->msg;
+
+	spi_message_init(m);
+
+	m->complete = ad7877_callback;
+	m->context = ts;
+
+	ts->xfer[0].tx_buf = &ts->cmd_crtl1;
+	ts->xfer[0].len = 2;
+
+	spi_message_add_tail(&ts->xfer[0], m);
+
+	ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */
+	ts->xfer[1].len = 2;
+
+	spi_message_add_tail(&ts->xfer[1], m);
+
+	for (i = 0; i < 11; i++) {
+		ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i];
+		ts->xfer[i + 2].len = 2;
+		spi_message_add_tail(&ts->xfer[i + 2], m);
+	}
+}
+
+static int __devinit ad7877_probe(struct spi_device *spi)
+{
+	struct ad7877			*ts;
+	struct input_dev		*input_dev;
+	struct ad7877_platform_data	*pdata = spi->dev.platform_data;
+	int				err;
+	u16				verify;
+
+	if (!spi->irq) {
+		dev_dbg(&spi->dev, "no IRQ?\n");
+		return -ENODEV;
+	}
+
+	if (!pdata) {
+		dev_dbg(&spi->dev, "no platform data?\n");
+		return -ENODEV;
+	}
+
+	/* don't exceed max specified SPI CLK frequency */
+	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+		dev_dbg(&spi->dev, "SPI CLK %d Hz?\n",spi->max_speed_hz);
+		return -EINVAL;
+	}
+
+	ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ts || !input_dev) {
+		err = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	dev_set_drvdata(&spi->dev, ts);
+	ts->spi = spi;
+	ts->input = input_dev;
+
+	setup_timer(&ts->timer, ad7877_timer, (unsigned long) ts);
+	mutex_init(&ts->mutex);
+	spin_lock_init(&ts->lock);
+
+	ts->model = pdata->model ? : 7877;
+	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
+	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+	ts->pressure_max = pdata->pressure_max ? : ~0;
+
+	ts->stopacq_polarity = pdata->stopacq_polarity;
+	ts->first_conversion_delay = pdata->first_conversion_delay;
+	ts->acquisition_time = pdata->acquisition_time;
+	ts->averaging = pdata->averaging;
+	ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
+
+	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
+
+	input_dev->name = "AD7877 Touchscreen";
+	input_dev->phys = ts->phys;
+	input_dev->dev.parent = &spi->dev;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(ABS_X, input_dev->absbit);
+	__set_bit(ABS_Y, input_dev->absbit);
+	__set_bit(ABS_PRESSURE, input_dev->absbit);
+
+	input_set_abs_params(input_dev, ABS_X,
+			pdata->x_min ? : 0,
+			pdata->x_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			pdata->y_min ? : 0,
+			pdata->y_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE,
+			pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+	ad7877_write(spi, AD7877_REG_SEQ1, AD7877_MM_SEQUENCE);
+
+	verify = ad7877_read(spi, AD7877_REG_SEQ1);
+
+	if (verify != AD7877_MM_SEQUENCE){
+		dev_err(&spi->dev, "%s: Failed to probe %s\n",
+			dev_name(&spi->dev), input_dev->name);
+		err = -ENODEV;
+		goto err_free_mem;
+	}
+
+	if (gpio3)
+		ad7877_write(spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_3_CONF);
+
+	ad7877_setup_ts_def_msg(spi, ts);
+
+	/* Request AD7877 /DAV GPIO interrupt */
+
+	err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING,
+			spi->dev.driver->name, ts);
+	if (err) {
+		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
+		goto err_free_mem;
+	}
+
+	err = sysfs_create_group(&spi->dev.kobj, &ad7877_attr_group);
+	if (err)
+		goto err_free_irq;
+
+	err = device_create_file(&spi->dev,
+				 gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+	if (err)
+		goto err_remove_attr_group;
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_remove_attr;
+
+	return 0;
+
+err_remove_attr:
+	device_remove_file(&spi->dev,
+			   gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+err_remove_attr_group:
+	sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+err_free_irq:
+	free_irq(spi->irq, ts);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(ts);
+	dev_set_drvdata(&spi->dev, NULL);
+	return err;
+}
+
+static int __devexit ad7877_remove(struct spi_device *spi)
+{
+	struct ad7877		*ts = dev_get_drvdata(&spi->dev);
+
+	sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+	device_remove_file(&spi->dev,
+			   gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+
+	ad7877_disable(ts);
+	free_irq(ts->spi->irq, ts);
+
+	input_unregister_device(ts->input);
+	kfree(ts);
+
+	dev_dbg(&spi->dev, "unregistered touchscreen\n");
+	dev_set_drvdata(&spi->dev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7877_suspend(struct spi_device *spi, pm_message_t message)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7877_disable(ts);
+
+	return 0;
+}
+
+static int ad7877_resume(struct spi_device *spi)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7877_enable(ts);
+
+	return 0;
+}
+#else
+#define ad7877_suspend NULL
+#define ad7877_resume  NULL
+#endif
+
+static struct spi_driver ad7877_driver = {
+	.driver = {
+		.name	= "ad7877",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7877_probe,
+	.remove		= __devexit_p(ad7877_remove),
+	.suspend	= ad7877_suspend,
+	.resume		= ad7877_resume,
+};
+
+static int __init ad7877_init(void)
+{
+	return spi_register_driver(&ad7877_driver);
+}
+module_init(ad7877_init);
+
+static void __exit ad7877_exit(void)
+{
+	spi_unregister_driver(&ad7877_driver);
+}
+module_exit(ad7877_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7877 touchscreen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
new file mode 100644
index 000000000000..5d8a70398807
--- /dev/null
+++ b/drivers/input/touchscreen/ad7879.c
@@ -0,0 +1,781 @@
+/*
+ * Copyright (C) 2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:	AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface)
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *	Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *	Copyright (C) 2002 MontaVista Software
+ *	Copyright (C) 2004 Texas Instruments
+ *	Copyright (C) 2005 Dirk Behme
+ *  - ad7877.c
+ *	Copyright (C) 2006-2008 Analog Devices Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+
+#include <linux/spi/ad7879.h>
+
+#define AD7879_REG_ZEROS		0
+#define AD7879_REG_CTRL1		1
+#define AD7879_REG_CTRL2		2
+#define AD7879_REG_CTRL3		3
+#define AD7879_REG_AUX1HIGH		4
+#define AD7879_REG_AUX1LOW		5
+#define AD7879_REG_TEMP1HIGH		6
+#define AD7879_REG_TEMP1LOW		7
+#define AD7879_REG_XPLUS		8
+#define AD7879_REG_YPLUS		9
+#define AD7879_REG_Z1			10
+#define AD7879_REG_Z2			11
+#define AD7879_REG_AUXVBAT		12
+#define AD7879_REG_TEMP			13
+#define AD7879_REG_REVID		14
+
+/* Control REG 1 */
+#define AD7879_TMR(x)			((x & 0xFF) << 0)
+#define AD7879_ACQ(x)			((x & 0x3) << 8)
+#define AD7879_MODE_NOC			(0 << 10)	/* Do not convert */
+#define AD7879_MODE_SCC			(1 << 10)	/* Single channel conversion */
+#define AD7879_MODE_SEQ0		(2 << 10)	/* Sequence 0 in Slave Mode */
+#define AD7879_MODE_SEQ1		(3 << 10)	/* Sequence 1 in Master Mode */
+#define AD7879_MODE_INT			(1 << 15)	/* PENIRQ disabled INT enabled */
+
+/* Control REG 2 */
+#define AD7879_FCD(x)			((x & 0x3) << 0)
+#define AD7879_RESET			(1 << 4)
+#define AD7879_MFS(x)			((x & 0x3) << 5)
+#define AD7879_AVG(x)			((x & 0x3) << 7)
+#define	AD7879_SER			(1 << 9)	/* non-differential */
+#define	AD7879_DFR			(0 << 9)	/* differential */
+#define AD7879_GPIOPOL			(1 << 10)
+#define AD7879_GPIODIR			(1 << 11)
+#define AD7879_GPIO_DATA		(1 << 12)
+#define AD7879_GPIO_EN			(1 << 13)
+#define AD7879_PM(x)			((x & 0x3) << 14)
+#define AD7879_PM_SHUTDOWN		(0)
+#define AD7879_PM_DYN			(1)
+#define AD7879_PM_FULLON		(2)
+
+/* Control REG 3 */
+#define AD7879_TEMPMASK_BIT		(1<<15)
+#define AD7879_AUXVBATMASK_BIT		(1<<14)
+#define AD7879_INTMODE_BIT		(1<<13)
+#define AD7879_GPIOALERTMASK_BIT	(1<<12)
+#define AD7879_AUXLOW_BIT		(1<<11)
+#define AD7879_AUXHIGH_BIT		(1<<10)
+#define AD7879_TEMPLOW_BIT		(1<<9)
+#define AD7879_TEMPHIGH_BIT		(1<<8)
+#define AD7879_YPLUS_BIT		(1<<7)
+#define AD7879_XPLUS_BIT		(1<<6)
+#define AD7879_Z1_BIT			(1<<5)
+#define AD7879_Z2_BIT			(1<<4)
+#define AD7879_AUX_BIT			(1<<3)
+#define AD7879_VBAT_BIT			(1<<2)
+#define AD7879_TEMP_BIT			(1<<1)
+
+enum {
+	AD7879_SEQ_XPOS  = 0,
+	AD7879_SEQ_YPOS  = 1,
+	AD7879_SEQ_Z1    = 2,
+	AD7879_SEQ_Z2    = 3,
+	AD7879_NR_SENSE  = 4,
+};
+
+#define	MAX_12BIT			((1<<12)-1)
+#define	TS_PEN_UP_TIMEOUT		msecs_to_jiffies(50)
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define AD7879_DEVID		0x7A
+typedef struct spi_device	bus_device;
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+#define AD7879_DEVID		0x79
+typedef struct i2c_client	bus_device;
+#endif
+
+struct ad7879 {
+	bus_device		*bus;
+	struct input_dev	*input;
+	struct work_struct	work;
+	struct timer_list	timer;
+
+	struct mutex		mutex;
+	unsigned		disabled:1;	/* P: mutex */
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+	struct spi_message	msg;
+	struct spi_transfer	xfer[AD7879_NR_SENSE + 1];
+	u16			cmd;
+#endif
+	u16			conversion_data[AD7879_NR_SENSE];
+	char			phys[32];
+	u8			first_conversion_delay;
+	u8			acquisition_time;
+	u8			averaging;
+	u8			pen_down_acc_interval;
+	u8			median;
+	u16			x_plate_ohms;
+	u16			pressure_max;
+	u16			gpio_init;
+	u16			cmd_crtl1;
+	u16			cmd_crtl2;
+	u16			cmd_crtl3;
+	unsigned		gpio:1;
+};
+
+static int ad7879_read(bus_device *, u8);
+static int ad7879_write(bus_device *, u8, u16);
+static void ad7879_collect(struct ad7879 *);
+
+static void ad7879_report(struct ad7879 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+	unsigned Rt;
+	u16 x, y, z1, z2;
+
+	x = ts->conversion_data[AD7879_SEQ_XPOS] & MAX_12BIT;
+	y = ts->conversion_data[AD7879_SEQ_YPOS] & MAX_12BIT;
+	z1 = ts->conversion_data[AD7879_SEQ_Z1] & MAX_12BIT;
+	z2 = ts->conversion_data[AD7879_SEQ_Z2] & MAX_12BIT;
+
+	/*
+	 * The samples processed here are already preprocessed by the AD7879.
+	 * The preprocessing function consists of a median and an averaging filter.
+	 * The combination of these two techniques provides a robust solution,
+	 * discarding the spurious noise in the signal and keeping only the data of interest.
+	 * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h)
+	 * Other user-programmable conversion controls include variable acquisition time,
+	 * and first conversion delay. Up to 16 averages can be taken per conversion.
+	 */
+
+	if (likely(x && z1)) {
+		/* compute touch pressure resistance using equation #1 */
+		Rt = (z2 - z1) * x * ts->x_plate_ohms;
+		Rt /= z1;
+		Rt = (Rt + 2047) >> 12;
+
+		input_report_abs(input_dev, ABS_X, x);
+		input_report_abs(input_dev, ABS_Y, y);
+		input_report_abs(input_dev, ABS_PRESSURE, Rt);
+		input_sync(input_dev);
+	}
+}
+
+static void ad7879_work(struct work_struct *work)
+{
+	struct ad7879 *ts = container_of(work, struct ad7879, work);
+
+	/* use keventd context to read the result registers */
+	ad7879_collect(ts);
+	ad7879_report(ts);
+	mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+}
+
+static void ad7879_ts_event_release(struct ad7879 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+
+	input_report_abs(input_dev, ABS_PRESSURE, 0);
+	input_sync(input_dev);
+}
+
+static void ad7879_timer(unsigned long handle)
+{
+	struct ad7879 *ts = (void *)handle;
+
+	ad7879_ts_event_release(ts);
+}
+
+static irqreturn_t ad7879_irq(int irq, void *handle)
+{
+	struct ad7879 *ts = handle;
+
+	/* The repeated conversion sequencer controlled by TMR kicked off too fast.
+	 * We ignore the last and process the sample sequence currently in the queue.
+	 * It can't be older than 9.4ms
+	 */
+
+	if (!work_pending(&ts->work))
+		schedule_work(&ts->work);
+
+	return IRQ_HANDLED;
+}
+
+static void ad7879_setup(struct ad7879 *ts)
+{
+	ts->cmd_crtl3 = AD7879_YPLUS_BIT |
+			AD7879_XPLUS_BIT |
+			AD7879_Z2_BIT |
+			AD7879_Z1_BIT |
+			AD7879_TEMPMASK_BIT |
+			AD7879_AUXVBATMASK_BIT |
+			AD7879_GPIOALERTMASK_BIT;
+
+	ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
+			AD7879_AVG(ts->averaging) |
+			AD7879_MFS(ts->median) |
+			AD7879_FCD(ts->first_conversion_delay) |
+			ts->gpio_init;
+
+	ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
+			AD7879_ACQ(ts->acquisition_time) |
+			AD7879_TMR(ts->pen_down_acc_interval);
+
+	ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+	ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3);
+	ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1);
+}
+
+static void ad7879_disable(struct ad7879 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (!ts->disabled) {
+
+		ts->disabled = 1;
+		disable_irq(ts->bus->irq);
+
+		cancel_work_sync(&ts->work);
+
+		if (del_timer_sync(&ts->timer))
+			ad7879_ts_event_release(ts);
+
+		ad7879_write(ts->bus, AD7879_REG_CTRL2,
+			     AD7879_PM(AD7879_PM_SHUTDOWN));
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+static void ad7879_enable(struct ad7879 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (ts->disabled) {
+		ad7879_setup(ts);
+		ts->disabled = 0;
+		enable_irq(ts->bus->irq);
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+static ssize_t ad7879_disable_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7879_disable_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val)
+		ad7879_disable(ts);
+	else
+		ad7879_enable(ts);
+
+	return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store);
+
+static ssize_t ad7879_gpio_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio);
+}
+
+static ssize_t ad7879_gpio_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->gpio = !!val;
+	error = ad7879_write(ts->bus, AD7879_REG_CTRL2,
+			   ts->gpio ?
+				ts->cmd_crtl2 & ~AD7879_GPIO_DATA :
+				ts->cmd_crtl2 | AD7879_GPIO_DATA);
+	mutex_unlock(&ts->mutex);
+
+	return error ? : count;
+}
+
+static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
+
+static struct attribute *ad7879_attributes[] = {
+	&dev_attr_disable.attr,
+	&dev_attr_gpio.attr,
+	NULL
+};
+
+static const struct attribute_group ad7879_attr_group = {
+	.attrs = ad7879_attributes,
+};
+
+static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
+{
+	struct input_dev *input_dev;
+	struct ad7879_platform_data *pdata = bus->dev.platform_data;
+	int err;
+	u16 revid;
+
+	if (!bus->irq) {
+		dev_err(&bus->dev, "no IRQ?\n");
+		return -ENODEV;
+	}
+
+	if (!pdata) {
+		dev_err(&bus->dev, "no platform data?\n");
+		return -ENODEV;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	ts->input = input_dev;
+
+	setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts);
+	INIT_WORK(&ts->work, ad7879_work);
+	mutex_init(&ts->mutex);
+
+	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+	ts->pressure_max = pdata->pressure_max ? : ~0;
+
+	ts->first_conversion_delay = pdata->first_conversion_delay;
+	ts->acquisition_time = pdata->acquisition_time;
+	ts->averaging = pdata->averaging;
+	ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
+	ts->median = pdata->median;
+
+	if (pdata->gpio_output)
+		ts->gpio_init = AD7879_GPIO_EN |
+				(pdata->gpio_default ? 0 : AD7879_GPIO_DATA);
+	else
+		ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR;
+
+	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev));
+
+	input_dev->name = "AD7879 Touchscreen";
+	input_dev->phys = ts->phys;
+	input_dev->dev.parent = &bus->dev;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(ABS_X, input_dev->absbit);
+	__set_bit(ABS_Y, input_dev->absbit);
+	__set_bit(ABS_PRESSURE, input_dev->absbit);
+
+	input_set_abs_params(input_dev, ABS_X,
+			pdata->x_min ? : 0,
+			pdata->x_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			pdata->y_min ? : 0,
+			pdata->y_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE,
+			pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+	err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET);
+
+	if (err < 0) {
+		dev_err(&bus->dev, "Failed to write %s\n", input_dev->name);
+		goto err_free_mem;
+	}
+
+	revid = ad7879_read(bus, AD7879_REG_REVID);
+
+	if ((revid & 0xFF) != AD7879_DEVID) {
+		dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name);
+		err = -ENODEV;
+		goto err_free_mem;
+	}
+
+	ad7879_setup(ts);
+
+	err = request_irq(bus->irq, ad7879_irq,
+			  IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts);
+
+	if (err) {
+		dev_err(&bus->dev, "irq %d busy?\n", bus->irq);
+		goto err_free_mem;
+	}
+
+	err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group);
+	if (err)
+		goto err_free_irq;
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_remove_attr;
+
+	dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n",
+		 revid >> 8, bus->irq);
+
+	return 0;
+
+err_remove_attr:
+	sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group);
+err_free_irq:
+	free_irq(bus->irq, ts);
+err_free_mem:
+	input_free_device(input_dev);
+
+	return err;
+}
+
+static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
+{
+	ad7879_disable(ts);
+	sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
+	free_irq(ts->bus->irq, ts);
+	input_unregister_device(ts->input);
+	dev_dbg(&bus->dev, "unregistered touchscreen\n");
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7879_suspend(bus_device *bus, pm_message_t message)
+{
+	struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+	ad7879_disable(ts);
+
+	return 0;
+}
+
+static int ad7879_resume(bus_device *bus)
+{
+	struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+	ad7879_enable(ts);
+
+	return 0;
+}
+#else
+#define ad7879_suspend NULL
+#define ad7879_resume  NULL
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define MAX_SPI_FREQ_HZ		5000000
+#define AD7879_CMD_MAGIC	0xE000
+#define AD7879_CMD_READ		(1 << 10)
+#define AD7879_WRITECMD(reg)	(AD7879_CMD_MAGIC | (reg & 0xF))
+#define AD7879_READCMD(reg)	(AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF))
+
+struct ser_req {
+	u16			command;
+	u16			data;
+	struct spi_message	msg;
+	struct spi_transfer	xfer[2];
+};
+
+/*
+ * ad7879_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done in ad7879_collect().
+ */
+
+static int ad7879_read(struct spi_device *spi, u8 reg)
+{
+	struct ser_req *req;
+	int status, ret;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) AD7879_READCMD(reg);
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].rx_buf = &req->data;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	ret = status ? : req->data;
+
+	kfree(req);
+
+	return ret;
+}
+
+static int ad7879_write(struct spi_device *spi, u8 reg, u16 val)
+{
+	struct ser_req *req;
+	int status;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) AD7879_WRITECMD(reg);
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->data = val;
+	req->xfer[1].tx_buf = &req->data;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+
+	kfree(req);
+
+	return status;
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+	int status = spi_sync(ts->bus, &ts->msg);
+
+	if (status)
+		dev_err(&ts->bus->dev, "spi_sync --> %d\n", status);
+}
+
+static void ad7879_setup_ts_def_msg(struct ad7879 *ts)
+{
+	struct spi_message *m;
+	int i;
+
+	ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS);
+
+	m = &ts->msg;
+	spi_message_init(m);
+	ts->xfer[0].tx_buf = &ts->cmd;
+	ts->xfer[0].len = 2;
+
+	spi_message_add_tail(&ts->xfer[0], m);
+
+	for (i = 0; i < AD7879_NR_SENSE; i++) {
+		ts->xfer[i + 1].rx_buf = &ts->conversion_data[i];
+		ts->xfer[i + 1].len = 2;
+		spi_message_add_tail(&ts->xfer[i + 1], m);
+	}
+}
+
+static int __devinit ad7879_probe(struct spi_device *spi)
+{
+	struct ad7879 *ts;
+	int error;
+
+	/* don't exceed max specified SPI CLK frequency */
+	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+		dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
+		return -EINVAL;
+	}
+
+	ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	dev_set_drvdata(&spi->dev, ts);
+	ts->bus = spi;
+
+	ad7879_setup_ts_def_msg(ts);
+
+	error = ad7879_construct(spi, ts);
+	if (error) {
+		dev_set_drvdata(&spi->dev, NULL);
+		kfree(ts);
+	}
+
+	return 0;
+}
+
+static int __devexit ad7879_remove(struct spi_device *spi)
+{
+	struct ad7879 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7879_destroy(spi, ts);
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(ts);
+
+	return 0;
+}
+
+static struct spi_driver ad7879_driver = {
+	.driver = {
+		.name	= "ad7879",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7879_probe,
+	.remove		= __devexit_p(ad7879_remove),
+	.suspend	= ad7879_suspend,
+	.resume		= ad7879_resume,
+};
+
+static int __init ad7879_init(void)
+{
+	return spi_register_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+	spi_unregister_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+
+/* All registers are word-sized.
+ * AD7879 uses a high-byte first convention.
+ */
+static int ad7879_read(struct i2c_client *client, u8 reg)
+{
+	return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static int ad7879_write(struct i2c_client *client, u8 reg, u16 val)
+{
+	return i2c_smbus_write_word_data(client, reg, swab16(val));
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+	int i;
+
+	for (i = 0; i < AD7879_NR_SENSE; i++)
+		ts->conversion_data[i] = ad7879_read(ts->bus,
+						     AD7879_REG_XPLUS + i);
+}
+
+static int __devinit ad7879_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct ad7879 *ts;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_WORD_DATA)) {
+		dev_err(&client->dev, "SMBUS Word Data not Supported\n");
+		return -EIO;
+	}
+
+	ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, ts);
+	ts->bus = client;
+
+	error = ad7879_construct(client, ts);
+	if (error) {
+		i2c_set_clientdata(client, NULL);
+		kfree(ts);
+	}
+
+	return 0;
+}
+
+static int __devexit ad7879_remove(struct i2c_client *client)
+{
+	struct ad7879 *ts = dev_get_drvdata(&client->dev);
+
+	ad7879_destroy(client, ts);
+	i2c_set_clientdata(client, NULL);
+	kfree(ts);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad7879_id[] = {
+	{ "ad7879", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ad7879_id);
+
+static struct i2c_driver ad7879_driver = {
+	.driver = {
+		.name	= "ad7879",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7879_probe,
+	.remove		= __devexit_p(ad7879_remove),
+	.suspend	= ad7879_suspend,
+	.resume		= ad7879_resume,
+	.id_table	= ad7879_id,
+};
+
+static int __init ad7879_init(void)
+{
+	return i2c_add_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+	i2c_del_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+#endif
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 056ac77e2cf0..2b01e56568f8 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -127,6 +127,8 @@ struct ads7846 {
 	void			(*filter_cleanup)(void *data);
 	int			(*get_pendown_state)(void);
 	int			gpio_pendown;
+
+	void			(*wait_for_sync)(void);
 };
 
 /* leave chip selected when we're done, for quicker re-select? */
@@ -511,6 +513,10 @@ static int get_pendown_state(struct ads7846 *ts)
 	return !gpio_get_value(ts->gpio_pendown);
 }
 
+static void null_wait_for_sync(void)
+{
+}
+
 /*
  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
  * to retrieve touchscreen status.
@@ -686,6 +692,7 @@ static void ads7846_rx_val(void *ads)
 	default:
 		BUG();
 	}
+	ts->wait_for_sync();
 	status = spi_async(ts->spi, m);
 	if (status)
 		dev_err(&ts->spi->dev, "spi_async --> %d\n",
@@ -723,6 +730,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
 	} else {
 		/* pen is still down, continue with the measurement */
 		ts->msg_idx = 0;
+		ts->wait_for_sync();
 		status = spi_async(ts->spi, &ts->msg[0]);
 		if (status)
 			dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
@@ -746,7 +754,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
 			 * that here.  (The "generic irq" framework may help...)
 			 */
 			ts->irq_disabled = 1;
-			disable_irq(ts->spi->irq);
+			disable_irq_nosync(ts->spi->irq);
 			ts->pending = 1;
 			hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
 					HRTIMER_MODE_REL);
@@ -947,6 +955,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 		ts->penirq_recheck_delay_usecs =
 				pdata->penirq_recheck_delay_usecs;
 
+	ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
+
 	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
 
 	input_dev->name = "ADS784x Touchscreen";
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
index fa67d782c3c3..3ffd4c4b170c 100644
--- a/drivers/input/touchscreen/da9034-ts.c
+++ b/drivers/input/touchscreen/da9034-ts.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2006-2008 Marvell International Ltd.
  *	Fengwei Yin <fengwei.yin@marvell.com>
+ *	Bin Yang  <bin.yang@marvell.com>
  *	Eric Miao <eric.miao@marvell.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -175,6 +176,16 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 			goto err_reset;
 
 		touch->state = STATE_STOP;
+
+		/* FIXME: PEN_{UP/DOWN} events are expected to be
+		 * available by stopping TSI, but this is found not
+		 * always true, delay and simulate such an event
+		 * here is more reliable
+		 */
+		mdelay(1);
+		da9034_event_handler(touch,
+				     is_pen_down(touch) ? EVENT_PEN_DOWN :
+							  EVENT_PEN_UP);
 		break;
 
 	case STATE_STOP:
@@ -189,8 +200,6 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 			report_pen_up(touch);
 			touch->state = STATE_IDLE;
 		}
-
-		input_sync(touch->input_dev);
 		break;
 
 	case STATE_WAIT:
@@ -200,8 +209,10 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 		if (is_pen_down(touch)) {
 			start_tsi(touch);
 			touch->state = STATE_BUSY;
-		} else
+		} else {
+			report_pen_up(touch);
 			touch->state = STATE_IDLE;
+		}
 		break;
 	}
 	return;
@@ -226,16 +237,12 @@ static int da9034_touch_notifier(struct notifier_block *nb,
 	struct da9034_touch *touch =
 		container_of(nb, struct da9034_touch, notifier);
 
-	if (event & DA9034_EVENT_PEN_DOWN) {
-		if (is_pen_down(touch))
-			da9034_event_handler(touch, EVENT_PEN_DOWN);
-		else
-			da9034_event_handler(touch, EVENT_PEN_UP);
-	}
-
 	if (event & DA9034_EVENT_TSI_READY)
 		da9034_event_handler(touch, EVENT_TSI_READY);
 
+	if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
+		da9034_event_handler(touch, EVENT_PEN_DOWN);
+
 	return 0;
 }
 
@@ -385,6 +392,6 @@ static void __exit da9034_touch_exit(void)
 module_exit(da9034_touch_exit);
 
 MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:da9034-touch");
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 1d11e2be9ef8..4cc047a5116e 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -111,13 +111,12 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm)
 #else
 static void wm97xx_acc_pen_up(struct wm97xx *wm)
 {
-	int count = 16;
+	unsigned int count;
+
 	schedule_timeout_uninterruptible(1);
 
-	while (count < 16) {
+	for (count = 0; count < 16; count++)
 		MODR;
-		count--;
-	}
 }
 #endif
 
@@ -162,6 +161,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm)
 		input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
 		input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
 		input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
 		input_sync(wm->input_dev);
 		reads++;
 	} while (reads < cinfo[sp_idx].reads);
@@ -245,7 +245,7 @@ static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
 	if (enable)
 		enable_irq(wm->pen_irq);
 	else
-		disable_irq(wm->pen_irq);
+		disable_irq_nosync(wm->pen_irq);
 }
 
 static struct wm97xx_mach_ops mainstone_mach_ops = {
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 54986627def0..e868264fe799 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -151,12 +151,14 @@ static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16
 	input_report_abs(idev, ABS_X, x);
 	input_report_abs(idev, ABS_Y, y);
 	input_report_abs(idev, ABS_PRESSURE, pressure);
+	input_report_key(idev, BTN_TOUCH, 1);
 	input_sync(idev);
 }
 
 static void ucb1400_ts_event_release(struct input_dev *idev)
 {
 	input_report_abs(idev, ABS_PRESSURE, 0);
+	input_report_key(idev, BTN_TOUCH, 0);
 	input_sync(idev);
 }
 
@@ -377,7 +379,8 @@ static int ucb1400_ts_probe(struct platform_device *dev)
 	ucb->ts_idev->id.product	= ucb->id;
 	ucb->ts_idev->open		= ucb1400_ts_open;
 	ucb->ts_idev->close		= ucb1400_ts_close;
-	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS);
+	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	ucb1400_adc_enable(ucb->ac97);
 	x_res = ucb1400_ts_read_xres(ucb);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index d15aa11d7056..69af8385ab14 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -370,8 +370,7 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm)
 	 * provided. */
 	BUG_ON(!wm->mach_ops->irq_enable);
 
-	if (request_irq(wm->pen_irq, wm97xx_pen_interrupt,
-			IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+	if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED,
 			"wm97xx-pen", wm)) {
 		dev_err(wm->dev,
 			"Failed to register pen down interrupt, polling");
@@ -409,6 +408,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
 			wm->pen_is_down = 0;
 			dev_dbg(wm->dev, "pen up\n");
 			input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
+			input_report_key(wm->input_dev, BTN_TOUCH, 0);
 			input_sync(wm->input_dev);
 		} else if (!(rc & RC_AGAIN)) {
 			/* We need high frequency updates only while
@@ -433,6 +433,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
 		input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
 		input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
 		input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, 1);
 		input_sync(wm->input_dev);
 		wm->pen_is_down = 1;
 		wm->ts_reader_interval = wm->ts_reader_min_interval;
@@ -628,18 +629,21 @@ static int wm97xx_probe(struct device *dev)
 	wm->input_dev->phys = "wm97xx";
 	wm->input_dev->open = wm97xx_ts_input_open;
 	wm->input_dev->close = wm97xx_ts_input_close;
-	set_bit(EV_ABS, wm->input_dev->evbit);
-	set_bit(ABS_X, wm->input_dev->absbit);
-	set_bit(ABS_Y, wm->input_dev->absbit);
-	set_bit(ABS_PRESSURE, wm->input_dev->absbit);
+
+	__set_bit(EV_ABS, wm->input_dev->evbit);
+	__set_bit(EV_KEY, wm->input_dev->evbit);
+	__set_bit(BTN_TOUCH, wm->input_dev->keybit);
+
 	input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
 			     abs_x[2], 0);
 	input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
 			     abs_y[2], 0);
 	input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
 			     abs_p[2], 0);
+
 	input_set_drvdata(wm->input_dev, wm);
 	wm->input_dev->dev.parent = dev;
+
 	ret = input_register_device(wm->input_dev);
 	if (ret < 0)
 		goto dev_alloc_err;
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c
new file mode 100644
index 000000000000..41e4359c277c
--- /dev/null
+++ b/drivers/input/touchscreen/zylonite-wm97xx.c
@@ -0,0 +1,240 @@
+/*
+ * zylonite-wm97xx.c  --  Zylonite Continuous Touch screen driver
+ *
+ * Copyright 2004, 2007, 2008 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ * Parts Copyright : Ian Molton <spyro@f2s.com>
+ *                   Andrew Zabolotny <zap@homelink.ru>
+ *
+ *  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.
+ *
+ * Notes:
+ *     This is a wm97xx extended touch driver supporting interrupt driven
+ *     and continuous operation on Marvell Zylonite development systems
+ *     (which have a WM9713 on board).
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/wm97xx.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/regs-ac97.h>
+
+struct continuous {
+	u16 id;    /* codec id */
+	u8 code;   /* continuous code */
+	u8 reads;  /* number of coord reads per read cycle */
+	u32 speed; /* number of coords per second */
+};
+
+#define WM_READS(sp) ((sp / HZ) + 1)
+
+static const struct continuous cinfo[] = {
+	{ WM9713_ID2, 0, WM_READS(94),  94  },
+	{ WM9713_ID2, 1, WM_READS(120), 120 },
+	{ WM9713_ID2, 2, WM_READS(154), 154 },
+	{ WM9713_ID2, 3, WM_READS(188), 188 },
+};
+
+/* continuous speed index */
+static int sp_idx;
+
+/*
+ * Pen sampling frequency (Hz) in continuous mode.
+ */
+static int cont_rate = 200;
+module_param(cont_rate, int, 0);
+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
+
+/*
+ * Pressure readback.
+ *
+ * Set to 1 to read back pen down pressure
+ */
+static int pressure;
+module_param(pressure, int, 0);
+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
+
+/*
+ * AC97 touch data slot.
+ *
+ * Touch screen readback data ac97 slot
+ */
+static int ac97_touch_slot = 5;
+module_param(ac97_touch_slot, int, 0);
+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
+
+
+/* flush AC97 slot 5 FIFO machines */
+static void wm97xx_acc_pen_up(struct wm97xx *wm)
+{
+	int i;
+
+	msleep(1);
+
+	for (i = 0; i < 16; i++)
+		MODR;
+}
+
+static int wm97xx_acc_pen_down(struct wm97xx *wm)
+{
+	u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
+	int reads = 0;
+	static u16 last, tries;
+
+	/* When the AC97 queue has been drained we need to allow time
+	 * to buffer up samples otherwise we end up spinning polling
+	 * for samples.  The controller can't have a suitably low
+	 * threashold set to use the notifications it gives.
+	 */
+	msleep(1);
+
+	if (tries > 5) {
+		tries = 0;
+		return RC_PENUP;
+	}
+
+	x = MODR;
+	if (x == last) {
+		tries++;
+		return RC_AGAIN;
+	}
+	last = x;
+	do {
+		if (reads)
+			x = MODR;
+		y = MODR;
+		if (pressure)
+			p = MODR;
+
+		/* are samples valid */
+		if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
+		    (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
+		    (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES)
+			goto up;
+
+		/* coordinate is good */
+		tries = 0;
+		input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
+		input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
+		input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
+		input_sync(wm->input_dev);
+		reads++;
+	} while (reads < cinfo[sp_idx].reads);
+up:
+	return RC_PENDOWN | RC_AGAIN;
+}
+
+static int wm97xx_acc_startup(struct wm97xx *wm)
+{
+	int idx;
+
+	/* check we have a codec */
+	if (wm->ac97 == NULL)
+		return -ENODEV;
+
+	/* Go you big red fire engine */
+	for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
+		if (wm->id != cinfo[idx].id)
+			continue;
+		sp_idx = idx;
+		if (cont_rate <= cinfo[idx].speed)
+			break;
+	}
+	wm->acc_rate = cinfo[sp_idx].code;
+	wm->acc_slot = ac97_touch_slot;
+	dev_info(wm->dev,
+		 "zylonite accelerated touchscreen driver, %d samples/sec\n",
+		 cinfo[sp_idx].speed);
+
+	return 0;
+}
+
+static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
+{
+	if (enable)
+		enable_irq(wm->pen_irq);
+	else
+		disable_irq_nosync(wm->pen_irq);
+}
+
+static struct wm97xx_mach_ops zylonite_mach_ops = {
+	.acc_enabled	= 1,
+	.acc_pen_up	= wm97xx_acc_pen_up,
+	.acc_pen_down	= wm97xx_acc_pen_down,
+	.acc_startup	= wm97xx_acc_startup,
+	.irq_enable	= wm97xx_irq_enable,
+	.irq_gpio	= WM97XX_GPIO_2,
+};
+
+static int zylonite_wm97xx_probe(struct platform_device *pdev)
+{
+	struct wm97xx *wm = platform_get_drvdata(pdev);
+	int gpio_touch_irq;
+
+	if (cpu_is_pxa320())
+		gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO15);
+	else
+		gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+
+	wm->pen_irq = IRQ_GPIO(gpio_touch_irq);
+	set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);
+
+	wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
+			   WM97XX_GPIO_POL_HIGH,
+			   WM97XX_GPIO_STICKY,
+			   WM97XX_GPIO_WAKE);
+	wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
+			   WM97XX_GPIO_POL_HIGH,
+			   WM97XX_GPIO_NOTSTICKY,
+			   WM97XX_GPIO_NOWAKE);
+
+	return wm97xx_register_mach_ops(wm, &zylonite_mach_ops);
+}
+
+static int zylonite_wm97xx_remove(struct platform_device *pdev)
+{
+	struct wm97xx *wm = platform_get_drvdata(pdev);
+
+	wm97xx_unregister_mach_ops(wm);
+
+	return 0;
+}
+
+static struct platform_driver zylonite_wm97xx_driver = {
+	.probe	= zylonite_wm97xx_probe,
+	.remove	= zylonite_wm97xx_remove,
+	.driver	= {
+		.name	= "wm97xx-touch",
+	},
+};
+
+static int __init zylonite_wm97xx_init(void)
+{
+	return platform_driver_register(&zylonite_wm97xx_driver);
+}
+
+static void __exit zylonite_wm97xx_exit(void)
+{
+	platform_driver_unregister(&zylonite_wm97xx_driver);
+}
+
+module_init(zylonite_wm97xx_init);
+module_exit(zylonite_wm97xx_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("wm97xx continuous touch driver for Zylonite");
+MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index ec3c0e507669..2b3a055059ea 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -149,14 +149,7 @@ static void usb_ctrl_complete(struct urb *urb)
 	if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
 	        /* Special case handling for pipe reset */
 		le16_to_cpus(&ctrl_msg->dr.wIndex);
-
-		/* toggle is reset on clear */
-		usb_settoggle(adapter->usb_dev, 
-			      ctrl_msg->dr.wIndex & ~USB_DIR_IN, 
-			      (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0,
-			      0);
-
-
+		usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex);
 	}
 	
 	if (ctrl_msg->complete)
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 102ef4a14c5f..d2109054de85 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -82,7 +82,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
 	if (!gpio_is_valid(template->gpio)) {
 		printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", 
 				template->gpio, template->name);
-		return;
+		return 0;
 	}
 
 	ret = gpio_request(template->gpio, template->name);
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index ac8a4a3741b8..af92a176697f 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -158,7 +158,8 @@ void free_interrupts(void);
 /* segments.c: */
 void setup_default_gdt_entries(struct lguest_ro_state *state);
 void setup_guest_gdt(struct lg_cpu *cpu);
-void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num);
+void load_guest_gdt_entry(struct lg_cpu *cpu, unsigned int i,
+			  u32 low, u32 hi);
 void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array);
 void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt);
 void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt);
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index 4f15439b7f12..7ede64ffeef9 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -144,18 +144,19 @@ void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt)
 			gdt[i] = cpu->arch.gdt[i];
 }
 
-/*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT).
- * We copy it from the Guest and tweak the entries. */
-void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num)
+/*H:620 This is where the Guest asks us to load a new GDT entry
+ * (LHCALL_LOAD_GDT_ENTRY).  We tweak the entry and copy it in. */
+void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi)
 {
 	/* We assume the Guest has the same number of GDT entries as the
 	 * Host, otherwise we'd have to dynamically allocate the Guest GDT. */
 	if (num > ARRAY_SIZE(cpu->arch.gdt))
 		kill_guest(cpu, "too many gdt entries %i", num);
 
-	/* We read the whole thing in, then fix it up. */
-	__lgread(cpu, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0]));
-	fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt));
+	/* Set it up, then fix it. */
+	cpu->arch.gdt[num].a = lo;
+	cpu->arch.gdt[num].b = hi;
+	fixup_gdt_table(cpu, num, num+1);
 	/* Mark that the GDT changed so the core knows it has to copy it again,
 	 * even if the Guest is run on the same CPU. */
 	cpu->changed |= CHANGED_GDT;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index a6b717644be0..1a83910f674f 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -324,6 +324,11 @@ static void rewrite_hypercall(struct lg_cpu *cpu)
 	u8 insn[3] = {0xcd, 0x1f, 0x90};
 
 	__lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
+	/* The above write might have caused a copy of that page to be made
+	 * (if it was read-only).  We need to make sure the Guest has
+	 * up-to-date pagetables.  As this doesn't happen often, we can just
+	 * drop them all. */
+	guest_pagetable_clear_all(cpu);
 }
 
 static bool is_hypercall(struct lg_cpu *cpu)
@@ -563,8 +568,8 @@ void __exit lguest_arch_host_fini(void)
 int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
 {
 	switch (args->arg0) {
-	case LHCALL_LOAD_GDT:
-		load_guest_gdt(cpu, args->arg1, args->arg2);
+	case LHCALL_LOAD_GDT_ENTRY:
+		load_guest_gdt_entry(cpu, args->arg1, args->arg2, args->arg3);
 		break;
 	case LHCALL_LOAD_IDT_ENTRY:
 		load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3);
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 173cf55c64d0..3d906833948d 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -123,7 +123,7 @@ config PMAC_APM_EMU
 
 config PMAC_MEDIABAY
 	bool "Support PowerBook hotswap media bay"
-	depends on PPC_PMAC && PPC32
+	depends on PPC_PMAC && PPC32 && BLOCK
 	help
 	  This option adds support for older PowerBook's hotswap media bay
 	  that can contains batteries, floppy drives, or IDE devices. PCI
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index d7e46d345d9e..029ad8ce8a7e 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -18,7 +18,6 @@
 #include <linux/timer.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
-#include <linux/ide.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <asm/prom.h>
@@ -447,6 +446,7 @@ int check_media_bay_by_base(unsigned long base, int what)
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(check_media_bay_by_base);
 
 int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
 			    int irq, ide_hwif_t *hwif)
@@ -486,6 +486,7 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
 #endif /* CONFIG_BLK_DEV_IDE_PMAC */
 
 static void media_bay_step(int i)
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index f8a9f7ab2cb8..1fb91edc7de2 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
 		s += blocks;
 	}
 	bitmap->last_end_sync = jiffies;
+	sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
 }
 
 static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
@@ -1589,7 +1590,7 @@ void bitmap_destroy(mddev_t *mddev)
 int bitmap_create(mddev_t *mddev)
 {
 	struct bitmap *bitmap;
-	unsigned long blocks = mddev->resync_max_sectors;
+	sector_t blocks = mddev->resync_max_sectors;
 	unsigned long chunks;
 	unsigned long pages;
 	struct file *file = mddev->bitmap_file;
@@ -1631,8 +1632,8 @@ int bitmap_create(mddev_t *mddev)
 	bitmap->chunkshift = ffz(~bitmap->chunksize);
 
 	/* now that chunksize and chunkshift are set, we can use these macros */
- 	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
-			CHUNK_BLOCK_RATIO(bitmap);
+ 	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
+			CHUNK_BLOCK_SHIFT(bitmap);
  	pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
 
 	BUG_ON(!pages);
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
deleted file mode 100644
index 345098b4ca77..000000000000
--- a/drivers/md/dm-bio-list.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2004 Red Hat UK Ltd.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_BIO_LIST_H
-#define DM_BIO_LIST_H
-
-#include <linux/bio.h>
-
-#ifdef CONFIG_BLOCK
-
-struct bio_list {
-	struct bio *head;
-	struct bio *tail;
-};
-
-static inline int bio_list_empty(const struct bio_list *bl)
-{
-	return bl->head == NULL;
-}
-
-static inline void bio_list_init(struct bio_list *bl)
-{
-	bl->head = bl->tail = NULL;
-}
-
-#define bio_list_for_each(bio, bl) \
-	for (bio = (bl)->head; bio; bio = bio->bi_next)
-
-static inline unsigned bio_list_size(const struct bio_list *bl)
-{
-	unsigned sz = 0;
-	struct bio *bio;
-
-	bio_list_for_each(bio, bl)
-		sz++;
-
-	return sz;
-}
-
-static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
-{
-	bio->bi_next = NULL;
-
-	if (bl->tail)
-		bl->tail->bi_next = bio;
-	else
-		bl->head = bio;
-
-	bl->tail = bio;
-}
-
-static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
-{
-	bio->bi_next = bl->head;
-
-	bl->head = bio;
-
-	if (!bl->tail)
-		bl->tail = bio;
-}
-
-static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
-{
-	if (!bl2->head)
-		return;
-
-	if (bl->tail)
-		bl->tail->bi_next = bl2->head;
-	else
-		bl->head = bl2->head;
-
-	bl->tail = bl2->tail;
-}
-
-static inline void bio_list_merge_head(struct bio_list *bl,
-				       struct bio_list *bl2)
-{
-	if (!bl2->head)
-		return;
-
-	if (bl->head)
-		bl2->tail->bi_next = bl->head;
-	else
-		bl->tail = bl2->tail;
-
-	bl->head = bl2->head;
-}
-
-static inline struct bio *bio_list_pop(struct bio_list *bl)
-{
-	struct bio *bio = bl->head;
-
-	if (bio) {
-		bl->head = bl->head->bi_next;
-		if (!bl->head)
-			bl->tail = NULL;
-
-		bio->bi_next = NULL;
-	}
-
-	return bio;
-}
-
-static inline struct bio *bio_list_get(struct bio_list *bl)
-{
-	struct bio *bio = bl->head;
-
-	bl->head = bl->tail = NULL;
-
-	return bio;
-}
-
-#endif /* CONFIG_BLOCK */
-#endif
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 59ee1b015d2d..559dbb52bc85 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -15,8 +15,6 @@
 
 #include <linux/device-mapper.h>
 
-#include "dm-bio-list.h"
-
 #define DM_MSG_PREFIX "delay"
 
 struct delay_c {
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index f01096549a93..823ceba6efa8 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1047,6 +1047,19 @@ static int populate_table(struct dm_table *table,
 	return dm_table_complete(table);
 }
 
+static int table_prealloc_integrity(struct dm_table *t,
+				    struct mapped_device *md)
+{
+	struct list_head *devices = dm_table_get_devices(t);
+	struct dm_dev_internal *dd;
+
+	list_for_each_entry(dd, devices, list)
+		if (bdev_get_integrity(dd->dm_dev.bdev))
+			return blk_integrity_register(dm_disk(md), NULL);
+
+	return 0;
+}
+
 static int table_load(struct dm_ioctl *param, size_t param_size)
 {
 	int r;
@@ -1068,6 +1081,14 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
 		goto out;
 	}
 
+	r = table_prealloc_integrity(t, md);
+	if (r) {
+		DMERR("%s: could not register integrity profile.",
+		      dm_device_name(md));
+		dm_table_destroy(t);
+		goto out;
+	}
+
 	down_write(&_hash_lock);
 	hc = dm_get_mdptr(md);
 	if (!hc || hc->md != md) {
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 0a225da21272..3e3fc06cb861 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -297,7 +297,8 @@ static int run_complete_job(struct kcopyd_job *job)
 	dm_kcopyd_notify_fn fn = job->fn;
 	struct dm_kcopyd_client *kc = job->kc;
 
-	kcopyd_put_pages(kc, job->pages);
+	if (job->pages)
+		kcopyd_put_pages(kc, job->pages);
 	mempool_free(job, kc->job_pool);
 	fn(read_err, write_err, context);
 
@@ -461,6 +462,7 @@ static void segment_complete(int read_err, unsigned long write_err,
 	sector_t progress = 0;
 	sector_t count = 0;
 	struct kcopyd_job *job = (struct kcopyd_job *) context;
+	struct dm_kcopyd_client *kc = job->kc;
 
 	mutex_lock(&job->lock);
 
@@ -490,7 +492,7 @@ static void segment_complete(int read_err, unsigned long write_err,
 
 	if (count) {
 		int i;
-		struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool,
+		struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool,
 							   GFP_NOIO);
 
 		*sub_job = *job;
@@ -509,13 +511,16 @@ static void segment_complete(int read_err, unsigned long write_err,
 	} else if (atomic_dec_and_test(&job->sub_jobs)) {
 
 		/*
-		 * To avoid a race we must keep the job around
-		 * until after the notify function has completed.
-		 * Otherwise the client may try and stop the job
-		 * after we've completed.
+		 * Queue the completion callback to the kcopyd thread.
+		 *
+		 * Some callers assume that all the completions are called
+		 * from a single thread and don't race with each other.
+		 *
+		 * We must not call the callback directly here because this
+		 * code may not be executing in the thread.
 		 */
-		job->fn(read_err, write_err, job->context);
-		mempool_free(job, job->kc->job_pool);
+		push(&kc->complete_jobs, job);
+		wake(kc);
 	}
 }
 
@@ -528,6 +533,8 @@ static void split_job(struct kcopyd_job *job)
 {
 	int i;
 
+	atomic_inc(&job->kc->nr_jobs);
+
 	atomic_set(&job->sub_jobs, SPLIT_COUNT);
 	for (i = 0; i < SPLIT_COUNT; i++)
 		segment_complete(0, 0u, job);
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index bfa107f59d96..79fb53e51c70 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -142,7 +142,6 @@ static struct target_type linear_target = {
 	.status = linear_status,
 	.ioctl  = linear_ioctl,
 	.merge  = linear_merge,
-	.features = DM_TARGET_SUPPORTS_BARRIERS,
 };
 
 int __init dm_linear_init(void)
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 095f77bf9681..6a386ab4f7eb 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -8,7 +8,6 @@
 #include <linux/device-mapper.h>
 
 #include "dm-path-selector.h"
-#include "dm-bio-list.h"
 #include "dm-bio-record.h"
 #include "dm-uevent.h"
 
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 536ef0bef154..076fbb4e967a 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -5,7 +5,6 @@
  * This file is released under the GPL.
  */
 
-#include "dm-bio-list.h"
 #include "dm-bio-record.h"
 
 #include <linux/init.h>
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index 59f8d9df9e1a..7b899be0b087 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -14,7 +14,6 @@
 #include <linux/vmalloc.h>
 
 #include "dm.h"
-#include "dm-bio-list.h"
 
 #define	DM_MSG_PREFIX	"region hash"
 
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 981a0413068f..d73f17fc7778 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -22,7 +22,6 @@
 #include <linux/workqueue.h>
 
 #include "dm-exception-store.h"
-#include "dm-bio-list.h"
 
 #define DM_MSG_PREFIX "snapshots"
 
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index e8361b191b9b..429b50b975d5 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -52,8 +52,6 @@ struct dm_table {
 	sector_t *highs;
 	struct dm_target *targets;
 
-	unsigned barriers_supported:1;
-
 	/*
 	 * Indicates the rw permissions for the new logical
 	 * device.  This should be a combination of FMODE_READ
@@ -243,7 +241,6 @@ int dm_table_create(struct dm_table **result, fmode_t mode,
 
 	INIT_LIST_HEAD(&t->devices);
 	atomic_set(&t->holders, 0);
-	t->barriers_supported = 1;
 
 	if (!num_targets)
 		num_targets = KEYS_PER_NODE;
@@ -751,10 +748,6 @@ int dm_table_add_target(struct dm_table *t, const char *type,
 	/* FIXME: the plan is to combine high here and then have
 	 * the merge fn apply the target level restrictions. */
 	combine_restrictions_low(&t->limits, &tgt->limits);
-
-	if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS))
-		t->barriers_supported = 0;
-
 	return 0;
 
  bad:
@@ -799,12 +792,6 @@ int dm_table_complete(struct dm_table *t)
 
 	check_for_valid_limits(&t->limits);
 
-	/*
-	 * We only support barriers if there is exactly one underlying device.
-	 */
-	if (!list_is_singular(&t->devices))
-		t->barriers_supported = 0;
-
 	/* how many indexes will the btree have ? */
 	leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
 	t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
@@ -879,6 +866,45 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
 	return &t->targets[(KEYS_PER_NODE * n) + k];
 }
 
+/*
+ * Set the integrity profile for this device if all devices used have
+ * matching profiles.
+ */
+static void dm_table_set_integrity(struct dm_table *t)
+{
+	struct list_head *devices = dm_table_get_devices(t);
+	struct dm_dev_internal *prev = NULL, *dd = NULL;
+
+	if (!blk_get_integrity(dm_disk(t->md)))
+		return;
+
+	list_for_each_entry(dd, devices, list) {
+		if (prev &&
+		    blk_integrity_compare(prev->dm_dev.bdev->bd_disk,
+					  dd->dm_dev.bdev->bd_disk) < 0) {
+			DMWARN("%s: integrity not set: %s and %s mismatch",
+			       dm_device_name(t->md),
+			       prev->dm_dev.bdev->bd_disk->disk_name,
+			       dd->dm_dev.bdev->bd_disk->disk_name);
+			goto no_integrity;
+		}
+		prev = dd;
+	}
+
+	if (!prev || !bdev_get_integrity(prev->dm_dev.bdev))
+		goto no_integrity;
+
+	blk_integrity_register(dm_disk(t->md),
+			       bdev_get_integrity(prev->dm_dev.bdev));
+
+	return;
+
+no_integrity:
+	blk_integrity_register(dm_disk(t->md), NULL);
+
+	return;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
 {
 	/*
@@ -899,6 +925,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
 	else
 		queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
 
+	dm_table_set_integrity(t);
 }
 
 unsigned int dm_table_get_num_targets(struct dm_table *t)
@@ -1019,12 +1046,6 @@ struct mapped_device *dm_table_get_md(struct dm_table *t)
 	return t->md;
 }
 
-int dm_table_barrier_ok(struct dm_table *t)
-{
-	return t->barriers_supported;
-}
-EXPORT_SYMBOL(dm_table_barrier_ok);
-
 EXPORT_SYMBOL(dm_vcalloc);
 EXPORT_SYMBOL(dm_get_device);
 EXPORT_SYMBOL(dm_put_device);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 788ba96a6256..424f7b048c30 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -6,7 +6,6 @@
  */
 
 #include "dm.h"
-#include "dm-bio-list.h"
 #include "dm-uevent.h"
 
 #include <linux/init.h>
@@ -89,12 +88,13 @@ union map_info *dm_get_mapinfo(struct bio *bio)
 /*
  * Bits for the md->flags field.
  */
-#define DMF_BLOCK_IO 0
+#define DMF_BLOCK_IO_FOR_SUSPEND 0
 #define DMF_SUSPENDED 1
 #define DMF_FROZEN 2
 #define DMF_FREEING 3
 #define DMF_DELETING 4
 #define DMF_NOFLUSH_SUSPENDING 5
+#define DMF_QUEUE_IO_TO_THREAD 6
 
 /*
  * Work processed by per-device workqueue.
@@ -124,6 +124,11 @@ struct mapped_device {
 	spinlock_t deferred_lock;
 
 	/*
+	 * An error from the barrier request currently being processed.
+	 */
+	int barrier_error;
+
+	/*
 	 * Processing queue (flush/barriers)
 	 */
 	struct workqueue_struct *wq;
@@ -424,6 +429,10 @@ static void end_io_acct(struct dm_io *io)
 	part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration);
 	part_stat_unlock();
 
+	/*
+	 * 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);
 
@@ -435,21 +444,18 @@ static void end_io_acct(struct dm_io *io)
 /*
  * Add the bio to the list of deferred io.
  */
-static int queue_io(struct mapped_device *md, struct bio *bio)
+static void queue_io(struct mapped_device *md, struct bio *bio)
 {
 	down_write(&md->io_lock);
 
-	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
-		up_write(&md->io_lock);
-		return 1;
-	}
-
 	spin_lock_irq(&md->deferred_lock);
 	bio_list_add(&md->deferred, bio);
 	spin_unlock_irq(&md->deferred_lock);
 
+	if (!test_and_set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags))
+		queue_work(md->wq, &md->work);
+
 	up_write(&md->io_lock);
-	return 0;		/* deferred successfully */
 }
 
 /*
@@ -533,25 +539,35 @@ static void dec_pending(struct dm_io *io, int error)
 			 */
 			spin_lock_irqsave(&md->deferred_lock, flags);
 			if (__noflush_suspending(md))
-				bio_list_add(&md->deferred, io->bio);
+				bio_list_add_head(&md->deferred, io->bio);
 			else
 				/* noflush suspend was interrupted. */
 				io->error = -EIO;
 			spin_unlock_irqrestore(&md->deferred_lock, flags);
 		}
 
-		end_io_acct(io);
-
 		io_error = io->error;
 		bio = io->bio;
 
-		free_io(md, io);
+		if (bio_barrier(bio)) {
+			/*
+			 * There can be just one barrier request so we use
+			 * a per-device variable for error reporting.
+			 * Note that you can't touch the bio after end_io_acct
+			 */
+			md->barrier_error = io_error;
+			end_io_acct(io);
+		} else {
+			end_io_acct(io);
 
-		if (io_error != DM_ENDIO_REQUEUE) {
-			trace_block_bio_complete(md->queue, bio);
+			if (io_error != DM_ENDIO_REQUEUE) {
+				trace_block_bio_complete(md->queue, bio);
 
-			bio_endio(bio, io_error);
+				bio_endio(bio, io_error);
+			}
 		}
+
+		free_io(md, io);
 	}
 }
 
@@ -693,13 +709,19 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
 
 	clone->bi_sector = sector;
 	clone->bi_bdev = bio->bi_bdev;
-	clone->bi_rw = bio->bi_rw;
+	clone->bi_rw = bio->bi_rw & ~(1 << BIO_RW_BARRIER);
 	clone->bi_vcnt = 1;
 	clone->bi_size = to_bytes(len);
 	clone->bi_io_vec->bv_offset = offset;
 	clone->bi_io_vec->bv_len = clone->bi_size;
 	clone->bi_flags |= 1 << BIO_CLONED;
 
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, GFP_NOIO);
+		bio_integrity_trim(clone,
+				   bio_sector_offset(bio, idx, offset), len);
+	}
+
 	return clone;
 }
 
@@ -714,6 +736,7 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
 
 	clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
 	__bio_clone(clone, bio);
+	clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
 	clone->bi_destructor = dm_bio_destructor;
 	clone->bi_sector = sector;
 	clone->bi_idx = idx;
@@ -721,6 +744,14 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
 	clone->bi_size = to_bytes(len);
 	clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, GFP_NOIO);
+
+		if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
+			bio_integrity_trim(clone,
+					   bio_sector_offset(bio, idx, 0), len);
+	}
+
 	return clone;
 }
 
@@ -834,14 +865,13 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
 
 	ci.map = dm_get_table(md);
 	if (unlikely(!ci.map)) {
-		bio_io_error(bio);
-		return;
-	}
-	if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
-		dm_table_put(ci.map);
-		bio_endio(bio, -EOPNOTSUPP);
+		if (!bio_barrier(bio))
+			bio_io_error(bio);
+		else
+			md->barrier_error = -EIO;
 		return;
 	}
+
 	ci.md = md;
 	ci.bio = bio;
 	ci.io = alloc_io(md);
@@ -918,7 +948,6 @@ out:
  */
 static int dm_request(struct request_queue *q, struct bio *bio)
 {
-	int r = -EIO;
 	int rw = bio_data_dir(bio);
 	struct mapped_device *md = q->queuedata;
 	int cpu;
@@ -931,34 +960,27 @@ static int dm_request(struct request_queue *q, struct bio *bio)
 	part_stat_unlock();
 
 	/*
-	 * If we're suspended we have to queue
-	 * this io for later.
+	 * If we're suspended or the thread is processing barriers
+	 * we have to queue this io for later.
 	 */
-	while (test_bit(DMF_BLOCK_IO, &md->flags)) {
+	if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) ||
+	    unlikely(bio_barrier(bio))) {
 		up_read(&md->io_lock);
 
-		if (bio_rw(bio) != READA)
-			r = queue_io(md, bio);
+		if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) &&
+		    bio_rw(bio) == READA) {
+			bio_io_error(bio);
+			return 0;
+		}
 
-		if (r <= 0)
-			goto out_req;
+		queue_io(md, bio);
 
-		/*
-		 * We're in a while loop, because someone could suspend
-		 * before we get to the following read lock.
-		 */
-		down_read(&md->io_lock);
+		return 0;
 	}
 
 	__split_and_process_bio(md, bio);
 	up_read(&md->io_lock);
 	return 0;
-
-out_req:
-	if (r < 0)
-		bio_io_error(bio);
-
-	return 0;
 }
 
 static void dm_unplug_all(struct request_queue *q)
@@ -978,7 +1000,7 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
 	struct mapped_device *md = congested_data;
 	struct dm_table *map;
 
-	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
+	if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
 		map = dm_get_table(md);
 		if (map) {
 			r = dm_table_any_congested(map, bdi_bits);
@@ -1193,6 +1215,7 @@ static void free_dev(struct mapped_device *md)
 	mempool_destroy(md->tio_pool);
 	mempool_destroy(md->io_pool);
 	bioset_free(md->bs);
+	blk_integrity_unregister(md->disk);
 	del_gendisk(md->disk);
 	free_minor(minor);
 
@@ -1406,6 +1429,36 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
 	return r;
 }
 
+static int dm_flush(struct mapped_device *md)
+{
+	dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
+	return 0;
+}
+
+static void process_barrier(struct mapped_device *md, struct bio *bio)
+{
+	int error = dm_flush(md);
+
+	if (unlikely(error)) {
+		bio_endio(bio, error);
+		return;
+	}
+	if (bio_empty_barrier(bio)) {
+		bio_endio(bio, 0);
+		return;
+	}
+
+	__split_and_process_bio(md, bio);
+
+	error = dm_flush(md);
+
+	if (!error && md->barrier_error)
+		error = md->barrier_error;
+
+	if (md->barrier_error != DM_ENDIO_REQUEUE)
+		bio_endio(bio, error);
+}
+
 /*
  * Process the deferred bios
  */
@@ -1417,25 +1470,34 @@ static void dm_wq_work(struct work_struct *work)
 
 	down_write(&md->io_lock);
 
-next_bio:
-	spin_lock_irq(&md->deferred_lock);
-	c = bio_list_pop(&md->deferred);
-	spin_unlock_irq(&md->deferred_lock);
+	while (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
+		spin_lock_irq(&md->deferred_lock);
+		c = bio_list_pop(&md->deferred);
+		spin_unlock_irq(&md->deferred_lock);
 
-	if (c) {
-		__split_and_process_bio(md, c);
-		goto next_bio;
-	}
+		if (!c) {
+			clear_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
+			break;
+		}
 
-	clear_bit(DMF_BLOCK_IO, &md->flags);
+		up_write(&md->io_lock);
+
+		if (bio_barrier(c))
+			process_barrier(md, c);
+		else
+			__split_and_process_bio(md, c);
+
+		down_write(&md->io_lock);
+	}
 
 	up_write(&md->io_lock);
 }
 
 static void dm_queue_flush(struct mapped_device *md)
 {
+	clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+	smp_mb__after_clear_bit();
 	queue_work(md->wq, &md->work);
-	flush_workqueue(md->wq);
 }
 
 /*
@@ -1553,20 +1615,36 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 	}
 
 	/*
-	 * First we set the BLOCK_IO flag so no more ios will be mapped.
+	 * Here we must make sure that no processes are submitting requests
+	 * to target drivers i.e. no one may be executing
+	 * __split_and_process_bio. This is called from dm_request and
+	 * dm_wq_work.
+	 *
+	 * To get all processes out of __split_and_process_bio in dm_request,
+	 * we take the write lock. To prevent any process from reentering
+	 * __split_and_process_bio from dm_request, we set
+	 * DMF_QUEUE_IO_TO_THREAD.
+	 *
+	 * To quiesce the thread (dm_wq_work), we set DMF_BLOCK_IO_FOR_SUSPEND
+	 * and call flush_workqueue(md->wq). flush_workqueue will wait until
+	 * dm_wq_work exits and DMF_BLOCK_IO_FOR_SUSPEND will prevent any
+	 * further calls to __split_and_process_bio from dm_wq_work.
 	 */
 	down_write(&md->io_lock);
-	set_bit(DMF_BLOCK_IO, &md->flags);
-
+	set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+	set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
 	up_write(&md->io_lock);
 
+	flush_workqueue(md->wq);
+
 	/*
-	 * Wait for the already-mapped ios to complete.
+	 * At this point no more requests are entering target request routines.
+	 * We call dm_wait_for_completion to wait for all existing requests
+	 * to finish.
 	 */
 	r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
 
 	down_write(&md->io_lock);
-
 	if (noflush)
 		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
 	up_write(&md->io_lock);
@@ -1579,6 +1657,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 		goto out; /* pushback list is already flushed, so skip flush */
 	}
 
+	/*
+	 * If dm_wait_for_completion returned 0, the device is completely
+	 * quiescent now. There is no request-processing activity. All new
+	 * requests are being added to md->deferred list.
+	 */
+
 	dm_table_postsuspend_targets(map);
 
 	set_bit(DMF_SUSPENDED, &md->flags);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index b48397c0abbd..a31506d93e91 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -52,7 +52,6 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits);
  * To check the return value from dm_table_find_target().
  */
 #define dm_target_is_valid(t) ((t)->table)
-int dm_table_barrier_ok(struct dm_table *t);
 
 /*-----------------------------------------------------------------
  * A registry of target types.
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ed5727c089a9..612343fdde94 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2017,6 +2017,8 @@ repeat:
 	clear_bit(MD_CHANGE_PENDING, &mddev->flags);
 	spin_unlock_irq(&mddev->write_lock);
 	wake_up(&mddev->sb_wait);
+	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 
 }
 
@@ -2086,6 +2088,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 	 *  -writemostly - clears write_mostly
 	 *  blocked - sets the Blocked flag
 	 *  -blocked - clears the Blocked flag
+	 *  insync - sets Insync providing device isn't active
 	 */
 	int err = -EINVAL;
 	if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
@@ -2118,6 +2121,9 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 		md_wakeup_thread(rdev->mddev->thread);
 
 		err = 0;
+	} else if (cmd_match(buf, "insync") && rdev->raid_disk == -1) {
+		set_bit(In_sync, &rdev->flags);
+		err = 0;
 	}
 	if (!err && rdev->sysfs_state)
 		sysfs_notify_dirent(rdev->sysfs_state);
@@ -2190,7 +2196,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 	} else if (rdev->mddev->pers) {
 		mdk_rdev_t *rdev2;
 		/* Activating a spare .. or possibly reactivating
-		 * if we every get bitmaps working here.
+		 * if we ever get bitmaps working here.
 		 */
 
 		if (rdev->raid_disk != -1)
@@ -3482,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page)
 {
 	unsigned long max_sectors, resync;
 
+	if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+		return sprintf(page, "none\n");
+
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		max_sectors = mddev->resync_max_sectors;
 	else
 		max_sectors = mddev->dev_sectors;
 
-	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
+	resync = mddev->curr_resync_completed;
 	return sprintf(page, "%lu / %lu\n", resync, max_sectors);
 }
 
@@ -6334,18 +6343,13 @@ void md_do_sync(mddev_t *mddev)
 		sector_t sectors;
 
 		skipped = 0;
-		if (j >= mddev->resync_max) {
-			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
-			wait_event(mddev->recovery_wait,
-				   mddev->resync_max > j
-				   || kthread_should_stop());
-		}
-		if (kthread_should_stop())
-			goto interrupted;
 
-		if (mddev->curr_resync > mddev->curr_resync_completed &&
-		    (mddev->curr_resync - mddev->curr_resync_completed)
-		    > (max_sectors >> 4)) {
+		if ((mddev->curr_resync > mddev->curr_resync_completed &&
+		     (mddev->curr_resync - mddev->curr_resync_completed)
+		    > (max_sectors >> 4)) ||
+		    (j - mddev->curr_resync_completed)*2
+		    >= mddev->resync_max - mddev->curr_resync_completed
+			) {
 			/* time to update curr_resync_completed */
 			blk_unplug(mddev->queue);
 			wait_event(mddev->recovery_wait,
@@ -6353,7 +6357,17 @@ void md_do_sync(mddev_t *mddev)
 			mddev->curr_resync_completed =
 				mddev->curr_resync;
 			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 		}
+
+		if (j >= mddev->resync_max)
+			wait_event(mddev->recovery_wait,
+				   mddev->resync_max > j
+				   || kthread_should_stop());
+
+		if (kthread_should_stop())
+			goto interrupted;
+
 		sectors = mddev->pers->sync_request(mddev, j, &skipped,
 						  currspeed < speed_min(mddev));
 		if (sectors == 0) {
@@ -6461,6 +6475,7 @@ void md_do_sync(mddev_t *mddev)
 
  skip:
 	mddev->curr_resync = 0;
+	mddev->curr_resync_completed = 0;
 	mddev->resync_min = 0;
 	mddev->resync_max = MaxSector;
 	sysfs_notify(&mddev->kobj, NULL, "sync_completed");
diff --git a/drivers/md/md.h b/drivers/md/md.h
index e9b7f54c24d6..8227ab909d44 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -12,10 +12,17 @@
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#ifndef _MD_K_H
-#define _MD_K_H
-
-#ifdef CONFIG_BLOCK
+#ifndef _MD_MD_H
+#define _MD_MD_H
+
+#include <linux/blkdev.h>
+#include <linux/kobject.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #define MaxSector (~(sector_t)0)
 
@@ -408,10 +415,6 @@ static inline void safe_put_page(struct page *p)
 	if (p) put_page(p);
 }
 
-#endif /* CONFIG_BLOCK */
-#endif
-
-
 extern int register_md_personality(struct mdk_personality *p);
 extern int unregister_md_personality(struct mdk_personality *p);
 extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
@@ -434,3 +437,5 @@ extern void md_new_event(mddev_t *mddev);
 extern int md_allow_write(mddev_t *mddev);
 extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
 extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
+
+#endif /* _MD_MD_H */
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 274b491a11c1..36df9109cde1 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -35,7 +35,6 @@
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
 #include "md.h"
-#include "dm-bio-list.h"
 #include "raid1.h"
 #include "bitmap.h"
 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index e293d92641ac..81a54f17417e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -22,7 +22,6 @@
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
 #include "md.h"
-#include "dm-bio-list.h"
 #include "raid10.h"
 #include "bitmap.h"
 
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 3bbc6d647044..4616bc3a6e71 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes)==0);
 		mddev->reshape_position = conf->reshape_progress;
+		mddev->curr_resync_completed = mddev->curr_resync;
 		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
 		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	}
 
 	if (mddev->delta_disks < 0) {
@@ -3938,11 +3940,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
 	 * then we need to write out the superblock.
 	 */
 	sector_nr += reshape_sectors;
-	if (sector_nr >= mddev->resync_max) {
+	if ((sector_nr - mddev->curr_resync_completed) * 2
+	    >= mddev->resync_max - mddev->curr_resync_completed) {
 		/* Cannot proceed until we've updated the superblock... */
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes) == 0);
 		mddev->reshape_position = conf->reshape_progress;
+		mddev->curr_resync_completed = mddev->curr_resync;
 		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
@@ -3953,6 +3957,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
 		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	}
 	return reshape_sectors;
 }
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 772990415f99..68eb4493f991 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -28,25 +28,12 @@ config DVB_AV7110
 	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
 	  or /lib/firmware (depending on configuration of firmware hotplug).
 
-	  Say Y if you own such a card and want to use it.
-
-config DVB_AV7110_FIRMWARE
-	bool "Compile AV7110 firmware into the driver"
-	depends on DVB_AV7110 && !STANDALONE
-	default y if DVB_AV7110=y
-	help
-	  The AV7110 firmware is normally loaded by the firmware hotplug manager.
-	  If you want to compile the firmware into the driver you need to say
-	  Y here and provide the correct path of the firmware. You need this
-	  option if you want to compile the whole driver statically into the
-	  kernel.
+	  Alternatively, you can download the file and use the kernel's
+	  EXTRA_FIRMWARE configuration option to build it into your
+	  kernel image by adding the filename to the EXTRA_FIRMWARE
+	  configuration option string.
 
-	  All other people say N.
-
-config DVB_AV7110_FIRMWARE_FILE
-	string "Full pathname of av7110 firmware file"
-	depends on DVB_AV7110_FIRMWARE
-	default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw"
+	  Say Y if you own such a card and want to use it.
 
 config DVB_AV7110_OSD
 	bool "AV7110 OSD support"
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index 71451237294c..8a4d5bb20a5b 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -19,12 +19,3 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
-
-hostprogs-y	:= fdump
-
-ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y)
-$(obj)/av7110.o: $(obj)/av7110_firm.h
-
-$(obj)/av7110_firm.h: $(obj)/fdump
-	$(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
-endif
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 4624cee93e74..d1d959ed37b7 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1518,20 +1518,6 @@ static int check_firmware(struct av7110* av7110)
 	return 0;
 }
 
-#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
-#include "av7110_firm.h"
-static void put_firmware(struct av7110* av7110)
-{
-	av7110->bin_fw = NULL;
-}
-
-static inline int get_firmware(struct av7110* av7110)
-{
-	av7110->bin_fw = dvb_ttpci_fw;
-	av7110->size_fw = sizeof(dvb_ttpci_fw);
-	return check_firmware(av7110);
-}
-#else
 static void put_firmware(struct av7110* av7110)
 {
 	vfree(av7110->bin_fw);
@@ -1580,8 +1566,6 @@ static int get_firmware(struct av7110* av7110)
 	release_firmware(fw);
 	return ret;
 }
-#endif
-
 
 static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
 {
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 3a3f5279e927..5e3f88911a1d 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -198,29 +198,10 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
 
 /* we cannot write av7110 DRAM directly, so load a bootloader into
  * the DPRAM which implements a simple boot protocol */
-static u8 bootcode[] = {
-  0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04,
-  0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04,
-  0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24,
-  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34,
-  0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55,
-  0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74,
-  0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04,
-  0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64,
-  0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02,
-  0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0,
-  0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d,
-  0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f,
-  0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0,
-  0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0,
-  0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01,
-  0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec,
-  0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00,
-  0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0
-};
-
 int av7110_bootarm(struct av7110 *av7110)
 {
+	const struct firmware *fw;
+	const char *fw_name = "av7110/bootcode.bin";
 	struct saa7146_dev *dev = av7110->dev;
 	u32 ret;
 	int i;
@@ -261,7 +242,15 @@ int av7110_bootarm(struct av7110 *av7110)
 	//saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
 	//saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
 
-	mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
+	ret = request_firmware(&fw, fw_name, &dev->pci->dev);
+	if (ret) {
+		printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
+			fw_name);
+		return ret;
+	}
+
+	mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
+	release_firmware(fw);
 	iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 
 	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
@@ -302,7 +291,7 @@ int av7110_bootarm(struct av7110 *av7110)
 	av7110->arm_ready = 1;
 	return 0;
 }
-
+MODULE_FIRMWARE("av7110/bootcode.bin");
 
 /****************************************************************************
  * DEBI command polling
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index ca99e5c1fc8a..1634aba5cb84 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -390,7 +390,8 @@ static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val,
 }
 
 /* buffer writes */
-static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count)
+static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
+			  const u8 *val, int count)
 {
 	memcpy(av7110->debi_virt, val, count);
 	av7110_debiwrite(av7110, config, addr, 0, count);
diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c
deleted file mode 100644
index c90001d35e7d..000000000000
--- a/drivers/media/dvb/ttpci/fdump.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char **argv)
-{
-    unsigned char buf[8];
-    unsigned int i, count, bytes = 0;
-    FILE *fd_in, *fd_out;
-
-    if (argc != 4) {
-	fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
-	return -1;
-    }
-
-    fd_in = fopen(argv[1], "rb");
-    if (fd_in == NULL) {
-	fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
-	return -1;
-    }
-
-    fd_out = fopen(argv[3], "w+");
-    if (fd_out == NULL) {
-	fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
-	return -1;
-    }
-
-    fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
-
-    while ((count = fread(buf, 1, 8, fd_in)) > 0) {
-	fprintf(fd_out, "\n\t");
-	for (i = 0; i < count; i++, bytes++)
-	    fprintf(fd_out, "0x%02x, ", buf[i]);
-    }
-
-    fprintf(fd_out, "\n};\n\n");
-
-    fclose(fd_in);
-    fclose(fd_out);
-
-    return 0;
-}
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 92c297796a9f..bd945d04dc90 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1200,7 +1200,7 @@ static int si470x_fops_release(struct file *file)
 			video_unregister_device(radio->videodev);
 			kfree(radio->buffer);
 			kfree(radio);
-			goto unlock;
+			goto done;
 		}
 
 		/* stop rds reception */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index d9d974a8f52a..add3395d3248 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1461,7 +1461,6 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
 		return ret;
 	}
 
-	usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
 	usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
 
 	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index f9fbe02e0f69..50b415e07eda 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -159,35 +159,67 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev);
 
 /****************************************************************************/
 
+static int _send_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, int index, void *buf, int buflen, int timeout)
+{
+	int rc;
+	void *kbuf = NULL;
+
+	if (buflen) {
+		kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+		if (kbuf == NULL)
+			return -ENOMEM;
+		memcpy(kbuf, buf, buflen);
+	}
 
-#define SendControlMsg(request, value, buflen) \
-	usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
-		request, \
-		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
-		value, \
-		pdev->vcinterface, \
-		&buf, buflen, 500)
+	rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		request,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		index,
+		kbuf, buflen, timeout);
 
-#define RecvControlMsg(request, value, buflen) \
-	usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
-		request, \
-		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
-		value, \
-		pdev->vcinterface, \
-		&buf, buflen, 500)
+	kfree(kbuf);
+	return rc;
+}
 
+static int recv_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, void *buf, int buflen)
+{
+	int rc;
+	void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+
+	if (kbuf == NULL)
+		return -ENOMEM;
+
+	rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		request,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		pdev->vcinterface,
+		kbuf, buflen, 500);
+	memcpy(buf, kbuf, buflen);
+	kfree(kbuf);
+	return rc;
+}
 
-static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
+static inline int send_video_command(struct pwc_device *pdev,
+	int index, void *buf, int buflen)
 {
-	return usb_control_msg(udev,
-		usb_sndctrlpipe(udev, 0),
+	return _send_control_msg(pdev,
 		SET_EP_STREAM_CTL,
-		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		VIDEO_OUTPUT_CONTROL_FORMATTER,
 		index,
 		buf, buflen, 1000);
 }
 
+static inline int send_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, void *buf, int buflen)
+{
+	return _send_control_msg(pdev,
+		request, value, pdev->vcinterface, buf, buflen, 500);
+}
+
 
 
 static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
@@ -224,7 +256,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
 		return -EINVAL;
 
 	memcpy(buf, pEntry->mode, 3);
-	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
+	ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
 	if (ret < 0) {
 		PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
 		return ret;
@@ -285,7 +317,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i
 	memcpy(buf, pChoose->mode, 13);
 	if (snapshot)
 		buf[0] |= 0x80;
-	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
+	ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
 	if (ret < 0)
 		return ret;
 
@@ -358,7 +390,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i
 		buf[0] |= 0x80;
 
 	/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
-	ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
+	ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
 	if (ret < 0)
 		return ret;
 
@@ -530,7 +562,8 @@ int pwc_get_brightness(struct pwc_device *pdev)
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -545,7 +578,8 @@ int pwc_set_brightness(struct pwc_device *pdev, int value)
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 9) & 0x7f;
-	return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
 }
 
 /* CONTRAST */
@@ -555,7 +589,8 @@ int pwc_get_contrast(struct pwc_device *pdev)
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -570,7 +605,8 @@ int pwc_set_contrast(struct pwc_device *pdev, int value)
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 10) & 0x3f;
-	return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
 }
 
 /* GAMMA */
@@ -580,7 +616,8 @@ int pwc_get_gamma(struct pwc_device *pdev)
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -595,7 +632,8 @@ int pwc_set_gamma(struct pwc_device *pdev, int value)
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 11) & 0x1f;
-	return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
 }
 
 
@@ -613,7 +651,8 @@ int pwc_get_saturation(struct pwc_device *pdev, int *value)
 		saturation_register = SATURATION_MODE_FORMATTER2;
 	else
 		saturation_register = SATURATION_MODE_FORMATTER1;
-	ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = (signed)buf;
@@ -636,7 +675,8 @@ int pwc_set_saturation(struct pwc_device *pdev, int value)
 		saturation_register = SATURATION_MODE_FORMATTER2;
 	else
 		saturation_register = SATURATION_MODE_FORMATTER1;
-	return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
 }
 
 /* AGC */
@@ -651,7 +691,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
 	else
 		buf = 0xff; /* fixed */
 
-	ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (!mode && ret >= 0) {
 		if (value < 0)
@@ -659,7 +700,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
 		if (value > 0xffff)
 			value = 0xffff;
 		buf = (value >> 10) & 0x3F;
-		ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+		ret = send_control_msg(pdev,
+			SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
 	}
 	if (ret < 0)
 		return ret;
@@ -671,12 +713,14 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
 	if (buf != 0) { /* fixed */
-		ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		if (buf > 0x3F)
@@ -684,7 +728,8 @@ int pwc_get_agc(struct pwc_device *pdev, int *value)
 		*value = (buf << 10);
 	}
 	else { /* auto */
-		ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		/* Gah... this value ranges from 0x00 ... 0x9F */
@@ -707,7 +752,8 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
 	else
 		buf[0] = 0xff; /* fixed */
 
-	ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (!mode && ret >= 0) {
 		if (value < 0)
@@ -726,7 +772,9 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
 			buf[0] = value >> 8;
 		}
 
-		ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
+		ret = send_control_msg(pdev,
+			SET_LUM_CTL, PRESET_SHUTTER_FORMATTER,
+			&buf, sizeof(buf));
 	}
 	return ret;
 }
@@ -737,7 +785,8 @@ int pwc_get_shutter_speed(struct pwc_device *pdev, int *value)
 	unsigned char buf[2];
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf[0] + (buf[1] << 8);
@@ -764,7 +813,9 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
 		buf = 0x00; /* active */
 	else
 		buf = 0xFF; /* power save */
-	return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 
@@ -773,20 +824,20 @@ int pwc_camera_power(struct pwc_device *pdev, int power)
 
 int pwc_restore_user(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0);
 }
 
 int pwc_save_user(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0);
 }
 
 int pwc_restore_factory(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0);
 }
 
  /* ************************************************* */
@@ -814,7 +865,8 @@ int pwc_set_awb(struct pwc_device *pdev, int mode)
 
 	buf = mode & 0x07; /* just the lowest three bits */
 
-	ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (ret < 0)
 		return ret;
@@ -826,7 +878,8 @@ int pwc_get_awb(struct pwc_device *pdev)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (ret < 0)
 		return ret;
@@ -843,7 +896,9 @@ int pwc_set_red_gain(struct pwc_device *pdev, int value)
 		value = 0xffff;
 	/* only the msb is considered */
 	buf = value >> 8;
-	return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_red_gain(struct pwc_device *pdev, int *value)
@@ -851,7 +906,9 @@ int pwc_get_red_gain(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 	    return ret;
 	*value = buf << 8;
@@ -869,7 +926,9 @@ int pwc_set_blue_gain(struct pwc_device *pdev, int value)
 		value = 0xffff;
 	/* only the msb is considered */
 	buf = value >> 8;
-	return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
@@ -877,7 +936,9 @@ int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 	    return ret;
 	*value = buf << 8;
@@ -894,7 +955,8 @@ static int pwc_read_red_gain(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 8;
@@ -906,7 +968,8 @@ static int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 8;
@@ -920,7 +983,8 @@ static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
 
 	/* useful range is 0x01..0x20 */
 	buf = speed / 0x7f0;
-	return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
@@ -928,7 +992,8 @@ static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf * 0x7f0;
@@ -942,7 +1007,8 @@ static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
 
 	/* useful range is 0x01..0x3F */
 	buf = (delay >> 10);
-	return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
@@ -950,7 +1016,8 @@ static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 10;
@@ -978,7 +1045,8 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
 	buf[0] = on_value;
 	buf[1] = off_value;
 
-	return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
@@ -992,7 +1060,8 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
 		return 0;
 	}
 
-	ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*on_value = buf[0] * 100;
@@ -1009,7 +1078,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
 		buf = 0xff; /* auto contour on */
 	else
 		buf = 0x0; /* auto contour off */
-	ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
@@ -1019,7 +1089,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour)
 		contour = 0xffff;
 
 	buf = (contour >> 10); /* contour preset is [0..3f] */
-	ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -1030,13 +1101,16 @@ int pwc_get_contour(struct pwc_device *pdev, int *contour)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
 	if (buf == 0) {
 		/* auto mode off, query current preset value */
-		ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_LUM_CTL, PRESET_CONTOUR_FORMATTER,
+			&buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		*contour = buf << 10;
@@ -1055,7 +1129,9 @@ int pwc_set_backlight(struct pwc_device *pdev, int backlight)
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
@@ -1063,7 +1139,9 @@ int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*backlight = !!buf;
@@ -1078,7 +1156,8 @@ int pwc_set_colour_mode(struct pwc_device *pdev, int colour)
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
@@ -1086,7 +1165,8 @@ int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*colour = !!buf;
@@ -1102,7 +1182,8 @@ int pwc_set_flicker(struct pwc_device *pdev, int flicker)
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
@@ -1110,7 +1191,8 @@ int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*flicker = !!buf;
@@ -1126,7 +1208,9 @@ int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise)
 	if (noise > 3)
 		noise = 3;
 	buf = noise;
-	return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
@@ -1134,7 +1218,9 @@ int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*noise = buf;
@@ -1146,7 +1232,8 @@ static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
 	unsigned char buf;
 
 	buf = flags & 0x03; // only lower two bits are currently used
-	return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_mpt_reset(struct pwc_device *pdev, int flags)
@@ -1175,7 +1262,8 @@ static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
 	buf[1] = (pan >> 8) & 0xFF;
 	buf[2] = tilt & 0xFF;
 	buf[3] = (tilt >> 8) & 0xFF;
-	return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
+	return send_control_msg(pdev,
+		SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
@@ -1211,7 +1299,8 @@ static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *st
 	int ret;
 	unsigned char buf[5];
 
-	ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
+	ret = recv_control_msg(pdev,
+		GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	status->status = buf[0] & 0x7; // 3 bits are used for reporting
@@ -1233,7 +1322,8 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
 	else
 		request = SENSOR_TYPE_FORMATTER2;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, request, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	if (pdev->type < 675)
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d0d126c69354..5d496a99e034 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -5934,7 +5934,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
 
 	/* Initalize the timer
 	 */
-	init_timer(&pCfg->timer);
+	init_timer_on_stack(&pCfg->timer);
 	pCfg->timer.data = (unsigned long) ioc;
 	pCfg->timer.function = mpt_timer_expired;
 	pCfg->wait_done = 0;
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index d184dfab9631..db39f4a52f53 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -278,7 +278,7 @@ static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
  * We only use page mode writes; the alternative is sloooow. This routine
  * writes at most one page.
  */
-static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
+static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
 		unsigned offset, size_t count)
 {
 	struct i2c_client *client;
@@ -347,8 +347,8 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
 	return -ETIMEDOUT;
 }
 
-static ssize_t at24_write(struct at24_data *at24,
-		char *buf, loff_t off, size_t count)
+static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off,
+			  size_t count)
 {
 	ssize_t retval = 0;
 
@@ -406,7 +406,7 @@ static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
 	return at24_read(at24, buf, offset, count);
 }
 
-static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf,
+static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf,
 			  off_t offset, size_t count)
 {
 	struct at24_data *at24 = container_of(macc, struct at24_data, macc);
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 6bc0dac5c1e8..b34cb5f79eea 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -140,7 +140,8 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
 
 
 static ssize_t
-at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
+at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
+	      size_t count)
 {
 	ssize_t			status = 0;
 	unsigned		written = 0;
@@ -276,7 +277,7 @@ static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
 	return at25_ee_read(at25, buf, offset, count);
 }
 
-static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf,
+static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
 			  off_t offset, size_t count)
 {
 	struct at25_data *at25 = container_of(mem, struct at25_data, mem);
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 3e6e42d2f01b..bbefe77c67a9 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -375,7 +375,7 @@ static int __init gru_init(void)
 	void *gru_start_vaddr;
 
 	if (!is_uv_system())
-		return -ENODEV;
+		return 0;
 
 #if defined CONFIG_IA64
 	gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
index 16f8dcab2da4..7896849b16dc 100644
--- a/drivers/misc/sgi-xp/xp_main.c
+++ b/drivers/misc/sgi-xp/xp_main.c
@@ -248,19 +248,19 @@ xp_init(void)
 	enum xp_retval ret;
 	int ch_number;
 
+	/* initialize the connection registration mutex */
+	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
+		mutex_init(&xpc_registrations[ch_number].mutex);
+
 	if (is_shub())
 		ret = xp_init_sn2();
 	else if (is_uv())
 		ret = xp_init_uv();
 	else
-		ret = xpUnsupported;
+		ret = 0;
 
 	if (ret != xpSuccess)
-		return -ENODEV;
-
-	/* initialize the connection registration mutex */
-	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
-		mutex_init(&xpc_registrations[ch_number].mutex);
+		return ret;
 
 	return 0;
 }
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 114444cfd496..b94d5f767703 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -90,18 +90,21 @@ struct xpc_rsvd_page {
 	short max_npartitions;	/* value of XPC_MAX_PARTITIONS */
 	u8 version;
 	u8 pad1[3];		/* align to next u64 in 1st 64-byte cacheline */
+	unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
 	union {
-		unsigned long vars_pa;	/* phys address of struct xpc_vars */
-		unsigned long activate_gru_mq_desc_gpa; /* phys addr of */
-							/* activate mq's */
-							/* gru mq descriptor */
+		struct {
+			unsigned long vars_pa;	/* phys addr */
+		} sn2;
+		struct {
+			unsigned long heartbeat_gpa; /* phys addr */
+			unsigned long activate_gru_mq_desc_gpa; /* phys addr */
+		} uv;
 	} sn;
-	unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
-	u64 pad2[10];		/* align to last u64 in 2nd 64-byte cacheline */
+	u64 pad2[9];		/* align to last u64 in 2nd 64-byte cacheline */
 	u64 SAL_nasids_size;	/* SAL: size of each nasid mask in bytes */
 };
 
-#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
+#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
 
 /*
  * Define the structures by which XPC variables can be exported to other
@@ -182,6 +185,17 @@ struct xpc_vars_part_sn2 {
 				 (XPC_RP_MACH_NASIDS(_rp) + \
 				  xpc_nasid_mask_nlongs))
 
+
+/*
+ * The following structure describes the partition's heartbeat info which
+ * will be periodically read by other partitions to determine whether this
+ * XPC is still 'alive'.
+ */
+struct xpc_heartbeat_uv {
+	unsigned long value;
+	unsigned long offline;	/* if 0, heartbeat should be changing */
+};
+
 /*
  * Info pertinent to a GRU message queue using a watch list for irq generation.
  */
@@ -198,7 +212,7 @@ struct xpc_gru_mq_uv {
 
 /*
  * The activate_mq is used to send/receive GRU messages that affect XPC's
- * heartbeat, partition active state, and channel state. This is UV only.
+ * partition active state and channel state. This is uv only.
  */
 struct xpc_activate_mq_msghdr_uv {
 	unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
@@ -210,33 +224,27 @@ struct xpc_activate_mq_msghdr_uv {
 
 /* activate_mq defined message types */
 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV		0
-#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV		1
-#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV	2
-#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV		3
 
-#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		4
-#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		5
+#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		1
+#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		2
 
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	6
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		7
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	8
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		9
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	3
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		4
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	5
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		6
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV	7
 
-#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		10
-#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		11
+#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		8
+#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		9
 
 struct xpc_activate_mq_msg_uv {
 	struct xpc_activate_mq_msghdr_uv hdr;
 };
 
-struct xpc_activate_mq_msg_heartbeat_req_uv {
-	struct xpc_activate_mq_msghdr_uv hdr;
-	u64 heartbeat;
-};
-
 struct xpc_activate_mq_msg_activate_req_uv {
 	struct xpc_activate_mq_msghdr_uv hdr;
 	unsigned long rp_gpa;
+	unsigned long heartbeat_gpa;
 	unsigned long activate_gru_mq_desc_gpa;
 };
 
@@ -271,6 +279,11 @@ struct xpc_activate_mq_msg_chctl_openreply_uv {
 	unsigned long notify_gru_mq_desc_gpa;
 };
 
+struct xpc_activate_mq_msg_chctl_opencomplete_uv {
+	struct xpc_activate_mq_msghdr_uv hdr;
+	short ch_number;
+};
+
 /*
  * Functions registered by add_timer() or called by kernel_thread() only
  * allow for a single 64-bit argument. The following macros can be used to
@@ -576,30 +589,32 @@ struct xpc_channel {
 
 #define	XPC_C_WASCONNECTED	0x00000001	/* channel was connected */
 
-#define	XPC_C_ROPENREPLY	0x00000002	/* remote open channel reply */
-#define	XPC_C_OPENREPLY		0x00000004	/* local open channel reply */
-#define	XPC_C_ROPENREQUEST	0x00000008     /* remote open channel request */
-#define	XPC_C_OPENREQUEST	0x00000010	/* local open channel request */
+#define XPC_C_ROPENCOMPLETE	0x00000002    /* remote open channel complete */
+#define XPC_C_OPENCOMPLETE	0x00000004     /* local open channel complete */
+#define	XPC_C_ROPENREPLY	0x00000008	/* remote open channel reply */
+#define	XPC_C_OPENREPLY		0x00000010	/* local open channel reply */
+#define	XPC_C_ROPENREQUEST	0x00000020     /* remote open channel request */
+#define	XPC_C_OPENREQUEST	0x00000040	/* local open channel request */
 
-#define	XPC_C_SETUP		0x00000020 /* channel's msgqueues are alloc'd */
-#define	XPC_C_CONNECTEDCALLOUT	0x00000040     /* connected callout initiated */
+#define	XPC_C_SETUP		0x00000080 /* channel's msgqueues are alloc'd */
+#define	XPC_C_CONNECTEDCALLOUT	0x00000100     /* connected callout initiated */
 #define	XPC_C_CONNECTEDCALLOUT_MADE \
-				0x00000080     /* connected callout completed */
-#define	XPC_C_CONNECTED		0x00000100	/* local channel is connected */
-#define	XPC_C_CONNECTING	0x00000200	/* channel is being connected */
+				0x00000200     /* connected callout completed */
+#define	XPC_C_CONNECTED		0x00000400	/* local channel is connected */
+#define	XPC_C_CONNECTING	0x00000800	/* channel is being connected */
 
-#define	XPC_C_RCLOSEREPLY	0x00000400	/* remote close channel reply */
-#define	XPC_C_CLOSEREPLY	0x00000800	/* local close channel reply */
-#define	XPC_C_RCLOSEREQUEST	0x00001000    /* remote close channel request */
-#define	XPC_C_CLOSEREQUEST	0x00002000     /* local close channel request */
+#define	XPC_C_RCLOSEREPLY	0x00001000	/* remote close channel reply */
+#define	XPC_C_CLOSEREPLY	0x00002000	/* local close channel reply */
+#define	XPC_C_RCLOSEREQUEST	0x00004000    /* remote close channel request */
+#define	XPC_C_CLOSEREQUEST	0x00008000     /* local close channel request */
 
-#define	XPC_C_DISCONNECTED	0x00004000	/* channel is disconnected */
-#define	XPC_C_DISCONNECTING	0x00008000   /* channel is being disconnected */
+#define	XPC_C_DISCONNECTED	0x00010000	/* channel is disconnected */
+#define	XPC_C_DISCONNECTING	0x00020000   /* channel is being disconnected */
 #define	XPC_C_DISCONNECTINGCALLOUT \
-				0x00010000 /* disconnecting callout initiated */
+				0x00040000 /* disconnecting callout initiated */
 #define	XPC_C_DISCONNECTINGCALLOUT_MADE \
-				0x00020000 /* disconnecting callout completed */
-#define	XPC_C_WDISCONNECT	0x00040000  /* waiting for channel disconnect */
+				0x00080000 /* disconnecting callout completed */
+#define	XPC_C_WDISCONNECT	0x00100000  /* waiting for channel disconnect */
 
 /*
  * The channel control flags (chctl) union consists of a 64-bit variable which
@@ -618,11 +633,13 @@ union xpc_channel_ctl_flags {
 #define	XPC_CHCTL_CLOSEREPLY	0x02
 #define	XPC_CHCTL_OPENREQUEST	0x04
 #define	XPC_CHCTL_OPENREPLY	0x08
-#define	XPC_CHCTL_MSGREQUEST	0x10
+#define XPC_CHCTL_OPENCOMPLETE	0x10
+#define	XPC_CHCTL_MSGREQUEST	0x20
 
 #define XPC_OPENCLOSE_CHCTL_FLAGS \
 			(XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
-			 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
+			 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
+			 XPC_CHCTL_OPENCOMPLETE)
 #define XPC_MSG_CHCTL_FLAGS	XPC_CHCTL_MSGREQUEST
 
 static inline int
@@ -687,6 +704,9 @@ struct xpc_partition_sn2 {
 };
 
 struct xpc_partition_uv {
+	unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
+	struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
+						  /* partition's heartbeat */
 	unsigned long activate_gru_mq_desc_gpa;	/* phys addr of parititon's */
 						/* activate mq's gru mq */
 						/* descriptor */
@@ -698,14 +718,12 @@ struct xpc_partition_uv {
 	u8 remote_act_state;	/* remote partition's act_state */
 	u8 act_state_req;	/* act_state request from remote partition */
 	enum xp_retval reason;	/* reason for deactivate act_state request */
-	u64 heartbeat;		/* incremented by remote partition */
 };
 
 /* struct xpc_partition_uv flags */
 
-#define XPC_P_HEARTBEAT_OFFLINE_UV		0x00000001
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV	0x00000001
 #define XPC_P_ENGAGED_UV			0x00000002
-#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV	0x00000004
 
 /* struct xpc_partition_uv act_state change requests */
 
@@ -762,6 +780,62 @@ struct xpc_partition {
 
 } ____cacheline_aligned;
 
+struct xpc_arch_operations {
+	int (*setup_partitions) (void);
+	void (*teardown_partitions) (void);
+	void (*process_activate_IRQ_rcvd) (void);
+	enum xp_retval (*get_partition_rsvd_page_pa)
+		(void *, u64 *, unsigned long *, size_t *);
+	int (*setup_rsvd_page) (struct xpc_rsvd_page *);
+
+	void (*allow_hb) (short);
+	void (*disallow_hb) (short);
+	void (*disallow_all_hbs) (void);
+	void (*increment_heartbeat) (void);
+	void (*offline_heartbeat) (void);
+	void (*online_heartbeat) (void);
+	void (*heartbeat_init) (void);
+	void (*heartbeat_exit) (void);
+	enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
+
+	void (*request_partition_activation) (struct xpc_rsvd_page *,
+						 unsigned long, int);
+	void (*request_partition_reactivation) (struct xpc_partition *);
+	void (*request_partition_deactivation) (struct xpc_partition *);
+	void (*cancel_partition_deactivation_request) (struct xpc_partition *);
+	enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
+	void (*teardown_ch_structures) (struct xpc_partition *);
+
+	enum xp_retval (*make_first_contact) (struct xpc_partition *);
+
+	u64 (*get_chctl_all_flags) (struct xpc_partition *);
+	void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
+	void (*process_msg_chctl_flags) (struct xpc_partition *, int);
+
+	enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
+						      unsigned long);
+
+	enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
+	void (*teardown_msg_structures) (struct xpc_channel *);
+
+	void (*indicate_partition_engaged) (struct xpc_partition *);
+	void (*indicate_partition_disengaged) (struct xpc_partition *);
+	void (*assume_partition_disengaged) (short);
+	int (*partition_engaged) (short);
+	int (*any_partition_engaged) (void);
+
+	int (*n_of_deliverable_payloads) (struct xpc_channel *);
+	enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
+					   u16, u8, xpc_notify_func, void *);
+	void *(*get_deliverable_payload) (struct xpc_channel *);
+	void (*received_payload) (struct xpc_channel *, void *);
+	void (*notify_senders_of_disconnect) (struct xpc_channel *);
+};
+
 /* struct xpc_partition act_state values (for XPC HB) */
 
 #define	XPC_P_AS_INACTIVE	0x00	/* partition is not active */
@@ -802,67 +876,17 @@ extern struct xpc_registration xpc_registrations[];
 /* found in xpc_main.c */
 extern struct device *xpc_part;
 extern struct device *xpc_chan;
+extern struct xpc_arch_operations xpc_arch_ops;
 extern int xpc_disengage_timelimit;
 extern int xpc_disengage_timedout;
 extern int xpc_activate_IRQ_rcvd;
 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
 extern wait_queue_head_t xpc_activate_IRQ_wq;
-extern void *xpc_heartbeating_to_mask;
 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
 extern void xpc_disconnect_wait(int);
-extern int (*xpc_setup_partitions_sn) (void);
-extern void (*xpc_teardown_partitions_sn) (void);
-extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
-							 unsigned long *,
-							 size_t *);
-extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
-extern void (*xpc_heartbeat_init) (void);
-extern void (*xpc_heartbeat_exit) (void);
-extern void (*xpc_increment_heartbeat) (void);
-extern void (*xpc_offline_heartbeat) (void);
-extern void (*xpc_online_heartbeat) (void);
-extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
-extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
-extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
-extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
-extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
-extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
-extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
-extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
-extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
-extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
-						 unsigned long, int);
-extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
-extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_deactivation_request) (
-							struct xpc_partition *);
-extern void (*xpc_process_activate_IRQ_rcvd) (void);
-extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
-extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
-
-extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
-extern int (*xpc_partition_engaged) (short);
-extern int (*xpc_any_partition_engaged) (void);
-extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_assume_partition_disengaged) (short);
-
-extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
-					    unsigned long *);
-extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
-					  unsigned long *);
-extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
-					   unsigned long *);
-extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-
-extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
-						      unsigned long);
-
-extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
-					   u16, u8, xpc_notify_func, void *);
-extern void (*xpc_received_payload) (struct xpc_channel *, void *);
 
 /* found in xpc_sn2.c */
 extern int xpc_init_sn2(void);
@@ -909,40 +933,6 @@ extern void xpc_disconnect_channel(const int, struct xpc_channel *,
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 
-static inline int
-xpc_hb_allowed(short partid, void *heartbeating_to_mask)
-{
-	return test_bit(partid, heartbeating_to_mask);
-}
-
-static inline int
-xpc_any_hbs_allowed(void)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
-static inline void
-xpc_allow_hb(short partid)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	set_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_hb(short partid)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	clear_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_all_hbs(void)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
 static inline void
 xpc_wakeup_channel_mgr(struct xpc_partition *part)
 {
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 99a2534c38a1..652593fc486d 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -39,34 +39,38 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
 
 	if (!(ch->flags & XPC_C_SETUP)) {
 		spin_unlock_irqrestore(&ch->lock, *irq_flags);
-		ret = xpc_setup_msg_structures(ch);
+		ret = xpc_arch_ops.setup_msg_structures(ch);
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 
 		if (ret != xpSuccess)
 			XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
+		else
+			ch->flags |= XPC_C_SETUP;
 
-		ch->flags |= XPC_C_SETUP;
-
-		if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
+		if (ch->flags & XPC_C_DISCONNECTING)
 			return;
 	}
 
 	if (!(ch->flags & XPC_C_OPENREPLY)) {
 		ch->flags |= XPC_C_OPENREPLY;
-		xpc_send_chctl_openreply(ch, irq_flags);
+		xpc_arch_ops.send_chctl_openreply(ch, irq_flags);
 	}
 
 	if (!(ch->flags & XPC_C_ROPENREPLY))
 		return;
 
-	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */
+	if (!(ch->flags & XPC_C_OPENCOMPLETE)) {
+		ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED);
+		xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags);
+	}
+
+	if (!(ch->flags & XPC_C_ROPENCOMPLETE))
+		return;
 
 	dev_info(xpc_chan, "channel %d to partition %d connected\n",
 		 ch->number, ch->partid);
 
-	spin_unlock_irqrestore(&ch->lock, *irq_flags);
-	xpc_create_kthreads(ch, 1, 0);
-	spin_lock_irqsave(&ch->lock, *irq_flags);
+	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */
 }
 
 /*
@@ -96,7 +100,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 
 	if (part->act_state == XPC_P_AS_DEACTIVATING) {
 		/* can't proceed until the other side disengages from us */
-		if (xpc_partition_engaged(ch->partid))
+		if (xpc_arch_ops.partition_engaged(ch->partid))
 			return;
 
 	} else {
@@ -108,7 +112,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 
 		if (!(ch->flags & XPC_C_CLOSEREPLY)) {
 			ch->flags |= XPC_C_CLOSEREPLY;
-			xpc_send_chctl_closereply(ch, irq_flags);
+			xpc_arch_ops.send_chctl_closereply(ch, irq_flags);
 		}
 
 		if (!(ch->flags & XPC_C_RCLOSEREPLY))
@@ -118,7 +122,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 	/* wake those waiting for notify completion */
 	if (atomic_read(&ch->n_to_notify) > 0) {
 		/* we do callout while holding ch->lock, callout can't block */
-		xpc_notify_senders_of_disconnect(ch);
+		xpc_arch_ops.notify_senders_of_disconnect(ch);
 	}
 
 	/* both sides are disconnected now */
@@ -132,7 +136,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 	DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
 
 	/* it's now safe to free the channel's message queues */
-	xpc_teardown_msg_structures(ch);
+	xpc_arch_ops.teardown_msg_structures(ch);
 
 	ch->func = NULL;
 	ch->key = NULL;
@@ -144,8 +148,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
 
 	/*
 	 * Mark the channel disconnected and clear all other flags, including
-	 * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but
-	 * not including XPC_C_WDISCONNECT (if it was set).
+	 * XPC_C_SETUP (because of call to
+	 * xpc_arch_ops.teardown_msg_structures()) but not including
+	 * XPC_C_WDISCONNECT (if it was set).
 	 */
 	ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
 
@@ -184,6 +189,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
 	struct xpc_channel *ch = &part->channels[ch_number];
 	enum xp_retval reason;
 	enum xp_retval ret;
+	int create_kthread = 0;
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
 
@@ -196,8 +202,7 @@ again:
 		 * has had a chance to see that the channel is disconnected.
 		 */
 		ch->delayed_chctl_flags |= chctl_flags;
-		spin_unlock_irqrestore(&ch->lock, irq_flags);
-		return;
+		goto out;
 	}
 
 	if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) {
@@ -239,8 +244,7 @@ again:
 					    XPC_CHCTL_CLOSEREQUEST;
 					spin_unlock(&part->chctl_lock);
 				}
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
-				return;
+				goto out;
 			}
 
 			XPC_SET_REASON(ch, 0, 0);
@@ -250,7 +254,8 @@ again:
 			ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
 		}
 
-		chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY);
+		chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY |
+		    XPC_CHCTL_OPENCOMPLETE);
 
 		/*
 		 * The meaningful CLOSEREQUEST connection state fields are:
@@ -269,8 +274,7 @@ again:
 			XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
 
 			DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		xpc_process_disconnect(ch, &irq_flags);
@@ -283,8 +287,7 @@ again:
 
 		if (ch->flags & XPC_C_DISCONNECTED) {
 			DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
@@ -299,8 +302,7 @@ again:
 				    XPC_CHCTL_CLOSEREPLY;
 				spin_unlock(&part->chctl_lock);
 			}
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		ch->flags |= XPC_C_RCLOSEREPLY;
@@ -320,14 +322,12 @@ again:
 
 		if (part->act_state == XPC_P_AS_DEACTIVATING ||
 		    (ch->flags & XPC_C_ROPENREQUEST)) {
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
 			ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 		DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
 				       XPC_C_OPENREQUEST)));
@@ -341,8 +341,7 @@ again:
 		 */
 		if (args->entry_size == 0 || args->local_nentries == 0) {
 			/* assume OPENREQUEST was delayed by mistake */
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
@@ -352,8 +351,7 @@ again:
 			if (args->entry_size != ch->entry_size) {
 				XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
 						       &irq_flags);
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
-				return;
+				goto out;
 			}
 		} else {
 			ch->entry_size = args->entry_size;
@@ -375,15 +373,13 @@ again:
 			args->local_msgqueue_pa, args->local_nentries,
 			args->remote_nentries, ch->partid, ch->number);
 
-		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
-		}
+		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+			goto out;
+
 		if (!(ch->flags & XPC_C_OPENREQUEST)) {
 			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
 					       &irq_flags);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
@@ -400,11 +396,11 @@ again:
 		DBUG_ON(args->local_nentries == 0);
 		DBUG_ON(args->remote_nentries == 0);
 
-		ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
+		ret = xpc_arch_ops.save_remote_msgqueue_pa(ch,
+						      args->local_msgqueue_pa);
 		if (ret != xpSuccess) {
 			XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 		ch->flags |= XPC_C_ROPENREPLY;
 
@@ -430,7 +426,36 @@ again:
 		xpc_process_connect(ch, &irq_flags);
 	}
 
+	if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) {
+
+		dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from "
+			"partid=%d, channel=%d\n", ch->partid, ch->number);
+
+		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+			goto out;
+
+		if (!(ch->flags & XPC_C_OPENREQUEST) ||
+		    !(ch->flags & XPC_C_OPENREPLY)) {
+			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
+					       &irq_flags);
+			goto out;
+		}
+
+		DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
+		DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY));
+		DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
+
+		ch->flags |= XPC_C_ROPENCOMPLETE;
+
+		xpc_process_connect(ch, &irq_flags);
+		create_kthread = 1;
+	}
+
+out:
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+	if (create_kthread)
+		xpc_create_kthreads(ch, 1, 0);
 }
 
 /*
@@ -508,7 +533,7 @@ xpc_connect_channel(struct xpc_channel *ch)
 	/* initiate the connection */
 
 	ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
-	xpc_send_chctl_openrequest(ch, &irq_flags);
+	xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags);
 
 	xpc_process_connect(ch, &irq_flags);
 
@@ -526,7 +551,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
 	int ch_number;
 	u32 ch_flags;
 
-	chctl.all_flags = xpc_get_chctl_all_flags(part);
+	chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part);
 
 	/*
 	 * Initiate channel connections for registered channels.
@@ -564,10 +589,6 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
 			if (!(ch_flags & XPC_C_OPENREQUEST)) {
 				DBUG_ON(ch_flags & XPC_C_SETUP);
 				(void)xpc_connect_channel(ch);
-			} else {
-				spin_lock_irqsave(&ch->lock, irq_flags);
-				xpc_process_connect(ch, &irq_flags);
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
 			}
 			continue;
 		}
@@ -579,7 +600,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
 		 */
 
 		if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
-			xpc_process_msg_chctl_flags(part, ch_number);
+			xpc_arch_ops.process_msg_chctl_flags(part, ch_number);
 	}
 }
 
@@ -755,7 +776,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
 		       XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
 		       XPC_C_CONNECTING | XPC_C_CONNECTED);
 
-	xpc_send_chctl_closerequest(ch, irq_flags);
+	xpc_arch_ops.send_chctl_closerequest(ch, irq_flags);
 
 	if (channel_was_connected)
 		ch->flags |= XPC_C_WASCONNECTED;
@@ -862,8 +883,8 @@ xpc_initiate_send(short partid, int ch_number, u32 flags, void *payload,
 	DBUG_ON(payload == NULL);
 
 	if (xpc_part_ref(part)) {
-		ret = xpc_send_payload(&part->channels[ch_number], flags,
-				       payload, payload_size, 0, NULL, NULL);
+		ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+				  flags, payload, payload_size, 0, NULL, NULL);
 		xpc_part_deref(part);
 	}
 
@@ -914,9 +935,8 @@ xpc_initiate_send_notify(short partid, int ch_number, u32 flags, void *payload,
 	DBUG_ON(func == NULL);
 
 	if (xpc_part_ref(part)) {
-		ret = xpc_send_payload(&part->channels[ch_number], flags,
-				       payload, payload_size, XPC_N_CALL, func,
-				       key);
+		ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+			  flags, payload, payload_size, XPC_N_CALL, func, key);
 		xpc_part_deref(part);
 	}
 	return ret;
@@ -930,7 +950,7 @@ xpc_deliver_payload(struct xpc_channel *ch)
 {
 	void *payload;
 
-	payload = xpc_get_deliverable_payload(ch);
+	payload = xpc_arch_ops.get_deliverable_payload(ch);
 	if (payload != NULL) {
 
 		/*
@@ -984,7 +1004,7 @@ xpc_initiate_received(short partid, int ch_number, void *payload)
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 
 	ch = &part->channels[ch_number];
-	xpc_received_payload(ch, payload);
+	xpc_arch_ops.received_payload(ch, payload);
 
 	/* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload()  */
 	xpc_msgqueue_deref(ch);
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 1ab9fda87fab..fd3688a3e23f 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -150,7 +150,6 @@ DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq);
 
 static unsigned long xpc_hb_check_timeout;
 static struct timer_list xpc_hb_timer;
-void *xpc_heartbeating_to_mask;
 
 /* notification that the xpc_hb_checker thread has exited */
 static DECLARE_COMPLETION(xpc_hb_checker_exited);
@@ -170,62 +169,7 @@ static struct notifier_block xpc_die_notifier = {
 	.notifier_call = xpc_system_die,
 };
 
-int (*xpc_setup_partitions_sn) (void);
-void (*xpc_teardown_partitions_sn) (void);
-enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
-						  unsigned long *rp_pa,
-						  size_t *len);
-int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp);
-void (*xpc_heartbeat_init) (void);
-void (*xpc_heartbeat_exit) (void);
-void (*xpc_increment_heartbeat) (void);
-void (*xpc_offline_heartbeat) (void);
-void (*xpc_online_heartbeat) (void);
-enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *part);
-
-enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
-void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
-u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *part);
-enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch);
-void (*xpc_teardown_msg_structures) (struct xpc_channel *ch);
-void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number);
-int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch);
-void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch);
-
-void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
-					  unsigned long remote_rp_pa,
-					  int nasid);
-void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
-void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
-void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
-
-void (*xpc_process_activate_IRQ_rcvd) (void);
-enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *part);
-void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *part);
-
-void (*xpc_indicate_partition_engaged) (struct xpc_partition *part);
-int (*xpc_partition_engaged) (short partid);
-int (*xpc_any_partition_engaged) (void);
-void (*xpc_indicate_partition_disengaged) (struct xpc_partition *part);
-void (*xpc_assume_partition_disengaged) (short partid);
-
-void (*xpc_send_chctl_closerequest) (struct xpc_channel *ch,
-				     unsigned long *irq_flags);
-void (*xpc_send_chctl_closereply) (struct xpc_channel *ch,
-				   unsigned long *irq_flags);
-void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch,
-				    unsigned long *irq_flags);
-void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
-				  unsigned long *irq_flags);
-
-enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
-					       unsigned long msgqueue_pa);
-
-enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
-				    void *payload, u16 payload_size,
-				    u8 notify_type, xpc_notify_func func,
-				    void *key);
-void (*xpc_received_payload) (struct xpc_channel *ch, void *payload);
+struct xpc_arch_operations xpc_arch_ops;
 
 /*
  * Timer function to enforce the timelimit on the partition disengage.
@@ -240,7 +184,7 @@ xpc_timeout_partition_disengage(unsigned long data)
 	(void)xpc_partition_disengaged(part);
 
 	DBUG_ON(part->disengage_timeout != 0);
-	DBUG_ON(xpc_partition_engaged(XPC_PARTID(part)));
+	DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
 }
 
 /*
@@ -251,7 +195,7 @@ xpc_timeout_partition_disengage(unsigned long data)
 static void
 xpc_hb_beater(unsigned long dummy)
 {
-	xpc_increment_heartbeat();
+	xpc_arch_ops.increment_heartbeat();
 
 	if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
 		wake_up_interruptible(&xpc_activate_IRQ_wq);
@@ -263,7 +207,7 @@ xpc_hb_beater(unsigned long dummy)
 static void
 xpc_start_hb_beater(void)
 {
-	xpc_heartbeat_init();
+	xpc_arch_ops.heartbeat_init();
 	init_timer(&xpc_hb_timer);
 	xpc_hb_timer.function = xpc_hb_beater;
 	xpc_hb_beater(0);
@@ -273,7 +217,7 @@ static void
 xpc_stop_hb_beater(void)
 {
 	del_timer_sync(&xpc_hb_timer);
-	xpc_heartbeat_exit();
+	xpc_arch_ops.heartbeat_exit();
 }
 
 /*
@@ -302,7 +246,7 @@ xpc_check_remote_hb(void)
 			continue;
 		}
 
-		ret = xpc_get_remote_heartbeat(part);
+		ret = xpc_arch_ops.get_remote_heartbeat(part);
 		if (ret != xpSuccess)
 			XPC_DEACTIVATE_PARTITION(part, ret);
 	}
@@ -353,7 +297,7 @@ xpc_hb_checker(void *ignore)
 			force_IRQ = 0;
 			dev_dbg(xpc_part, "processing activate IRQs "
 				"received\n");
-			xpc_process_activate_IRQ_rcvd();
+			xpc_arch_ops.process_activate_IRQ_rcvd();
 		}
 
 		/* wait for IRQ or timeout */
@@ -528,7 +472,7 @@ xpc_setup_ch_structures(struct xpc_partition *part)
 		init_waitqueue_head(&ch->idle_wq);
 	}
 
-	ret = xpc_setup_ch_structures_sn(part);
+	ret = xpc_arch_ops.setup_ch_structures(part);
 	if (ret != xpSuccess)
 		goto out_2;
 
@@ -572,7 +516,7 @@ xpc_teardown_ch_structures(struct xpc_partition *part)
 
 	/* now we can begin tearing down the infrastructure */
 
-	xpc_teardown_ch_structures_sn(part);
+	xpc_arch_ops.teardown_ch_structures(part);
 
 	kfree(part->remote_openclose_args_base);
 	part->remote_openclose_args = NULL;
@@ -620,12 +564,12 @@ xpc_activating(void *__partid)
 
 	dev_dbg(xpc_part, "activating partition %d\n", partid);
 
-	xpc_allow_hb(partid);
+	xpc_arch_ops.allow_hb(partid);
 
 	if (xpc_setup_ch_structures(part) == xpSuccess) {
 		(void)xpc_part_ref(part);	/* this will always succeed */
 
-		if (xpc_make_first_contact(part) == xpSuccess) {
+		if (xpc_arch_ops.make_first_contact(part) == xpSuccess) {
 			xpc_mark_partition_active(part);
 			xpc_channel_mgr(part);
 			/* won't return until partition is deactivating */
@@ -635,12 +579,12 @@ xpc_activating(void *__partid)
 		xpc_teardown_ch_structures(part);
 	}
 
-	xpc_disallow_hb(partid);
+	xpc_arch_ops.disallow_hb(partid);
 	xpc_mark_partition_inactive(part);
 
 	if (part->reason == xpReactivating) {
 		/* interrupting ourselves results in activating partition */
-		xpc_request_partition_reactivation(part);
+		xpc_arch_ops.request_partition_reactivation(part);
 	}
 
 	return 0;
@@ -713,10 +657,13 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed)
 static void
 xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
 {
+	int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+		xpc_arch_ops.n_of_deliverable_payloads;
+
 	do {
 		/* deliver messages to their intended recipients */
 
-		while (xpc_n_of_deliverable_payloads(ch) > 0 &&
+		while (n_of_deliverable_payloads(ch) > 0 &&
 		       !(ch->flags & XPC_C_DISCONNECTING)) {
 			xpc_deliver_payload(ch);
 		}
@@ -732,7 +679,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
 			"wait_event_interruptible_exclusive()\n");
 
 		(void)wait_event_interruptible_exclusive(ch->idle_wq,
-				(xpc_n_of_deliverable_payloads(ch) > 0 ||
+				(n_of_deliverable_payloads(ch) > 0 ||
 				 (ch->flags & XPC_C_DISCONNECTING)));
 
 		atomic_dec(&ch->kthreads_idle);
@@ -749,6 +696,8 @@ xpc_kthread_start(void *args)
 	struct xpc_channel *ch;
 	int n_needed;
 	unsigned long irq_flags;
+	int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+		xpc_arch_ops.n_of_deliverable_payloads;
 
 	dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
 		partid, ch_number);
@@ -777,7 +726,7 @@ xpc_kthread_start(void *args)
 			 * additional kthreads to help deliver them. We only
 			 * need one less than total #of messages to deliver.
 			 */
-			n_needed = xpc_n_of_deliverable_payloads(ch) - 1;
+			n_needed = n_of_deliverable_payloads(ch) - 1;
 			if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
 				xpc_activate_kthreads(ch, n_needed);
 
@@ -805,7 +754,7 @@ xpc_kthread_start(void *args)
 
 	if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
 	    atomic_dec_return(&part->nchannels_engaged) == 0) {
-		xpc_indicate_partition_disengaged(part);
+		xpc_arch_ops.indicate_partition_disengaged(part);
 	}
 
 	xpc_msgqueue_deref(ch);
@@ -837,6 +786,8 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
 	u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
 	struct task_struct *kthread;
+	void (*indicate_partition_disengaged) (struct xpc_partition *) =
+		xpc_arch_ops.indicate_partition_disengaged;
 
 	while (needed-- > 0) {
 
@@ -858,7 +809,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
 
 		} else if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
 			   atomic_inc_return(&part->nchannels_engaged) == 1) {
-				xpc_indicate_partition_engaged(part);
+			xpc_arch_ops.indicate_partition_engaged(part);
 		}
 		(void)xpc_part_ref(part);
 		xpc_msgqueue_ref(ch);
@@ -880,7 +831,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
 
 			if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
 			    atomic_dec_return(&part->nchannels_engaged) == 0) {
-				xpc_indicate_partition_disengaged(part);
+				indicate_partition_disengaged(part);
 			}
 			xpc_msgqueue_deref(ch);
 			xpc_part_deref(part);
@@ -993,13 +944,13 @@ xpc_setup_partitions(void)
 		atomic_set(&part->references, 0);
 	}
 
-	return xpc_setup_partitions_sn();
+	return xpc_arch_ops.setup_partitions();
 }
 
 static void
 xpc_teardown_partitions(void)
 {
-	xpc_teardown_partitions_sn();
+	xpc_arch_ops.teardown_partitions();
 	kfree(xpc_partitions);
 }
 
@@ -1055,7 +1006,7 @@ xpc_do_exit(enum xp_retval reason)
 				disengage_timeout = part->disengage_timeout;
 		}
 
-		if (xpc_any_partition_engaged()) {
+		if (xpc_arch_ops.any_partition_engaged()) {
 			if (time_is_before_jiffies(printmsg_time)) {
 				dev_info(xpc_part, "waiting for remote "
 					 "partitions to deactivate, timeout in "
@@ -1086,8 +1037,7 @@ xpc_do_exit(enum xp_retval reason)
 
 	} while (1);
 
-	DBUG_ON(xpc_any_partition_engaged());
-	DBUG_ON(xpc_any_hbs_allowed() != 0);
+	DBUG_ON(xpc_arch_ops.any_partition_engaged());
 
 	xpc_teardown_rsvd_page();
 
@@ -1152,15 +1102,15 @@ xpc_die_deactivate(void)
 	/* keep xpc_hb_checker thread from doing anything (just in case) */
 	xpc_exiting = 1;
 
-	xpc_disallow_all_hbs();	/*indicate we're deactivated */
+	xpc_arch_ops.disallow_all_hbs();   /*indicate we're deactivated */
 
 	for (partid = 0; partid < xp_max_npartitions; partid++) {
 		part = &xpc_partitions[partid];
 
-		if (xpc_partition_engaged(partid) ||
+		if (xpc_arch_ops.partition_engaged(partid) ||
 		    part->act_state != XPC_P_AS_INACTIVE) {
-			xpc_request_partition_deactivation(part);
-			xpc_indicate_partition_disengaged(part);
+			xpc_arch_ops.request_partition_deactivation(part);
+			xpc_arch_ops.indicate_partition_disengaged(part);
 		}
 	}
 
@@ -1177,7 +1127,7 @@ xpc_die_deactivate(void)
 	wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5;
 
 	while (1) {
-		any_engaged = xpc_any_partition_engaged();
+		any_engaged = xpc_arch_ops.any_partition_engaged();
 		if (!any_engaged) {
 			dev_info(xpc_part, "all partitions have deactivated\n");
 			break;
@@ -1186,7 +1136,7 @@ xpc_die_deactivate(void)
 		if (!keep_waiting--) {
 			for (partid = 0; partid < xp_max_npartitions;
 			     partid++) {
-				if (xpc_partition_engaged(partid)) {
+				if (xpc_arch_ops.partition_engaged(partid)) {
 					dev_info(xpc_part, "deactivate from "
 						 "remote partition %d timed "
 						 "out\n", partid);
@@ -1233,7 +1183,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
 		/* fall through */
 	case DIE_MCA_MONARCH_ENTER:
 	case DIE_INIT_MONARCH_ENTER:
-		xpc_offline_heartbeat();
+		xpc_arch_ops.offline_heartbeat();
 		break;
 
 	case DIE_KDEBUG_LEAVE:
@@ -1244,7 +1194,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
 		/* fall through */
 	case DIE_MCA_MONARCH_LEAVE:
 	case DIE_INIT_MONARCH_LEAVE:
-		xpc_online_heartbeat();
+		xpc_arch_ops.online_heartbeat();
 		break;
 	}
 #else
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 6722f6fe4dc7..65877bc5edaa 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -70,6 +70,9 @@ xpc_get_rsvd_page_pa(int nasid)
 	size_t buf_len = 0;
 	void *buf = buf;
 	void *buf_base = NULL;
+	enum xp_retval (*get_partition_rsvd_page_pa)
+		(void *, u64 *, unsigned long *, size_t *) =
+		xpc_arch_ops.get_partition_rsvd_page_pa;
 
 	while (1) {
 
@@ -79,8 +82,7 @@ xpc_get_rsvd_page_pa(int nasid)
 		 * ??? function or have two versions? Rename rp_pa for UV to
 		 * ??? rp_gpa?
 		 */
-		ret = xpc_get_partition_rsvd_page_pa(buf, &cookie, &rp_pa,
-						     &len);
+		ret = get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, &len);
 
 		dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, "
 			"address=0x%016lx, len=0x%016lx\n", ret,
@@ -172,7 +174,7 @@ xpc_setup_rsvd_page(void)
 	xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
 	xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
 
-	ret = xpc_setup_rsvd_page_sn(rp);
+	ret = xpc_arch_ops.setup_rsvd_page(rp);
 	if (ret != 0)
 		return ret;
 
@@ -264,7 +266,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
 	short partid = XPC_PARTID(part);
 	int disengaged;
 
-	disengaged = !xpc_partition_engaged(partid);
+	disengaged = !xpc_arch_ops.partition_engaged(partid);
 	if (part->disengage_timeout) {
 		if (!disengaged) {
 			if (time_is_after_jiffies(part->disengage_timeout)) {
@@ -280,7 +282,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
 			dev_info(xpc_part, "deactivate request to remote "
 				 "partition %d timed out\n", partid);
 			xpc_disengage_timedout = 1;
-			xpc_assume_partition_disengaged(partid);
+			xpc_arch_ops.assume_partition_disengaged(partid);
 			disengaged = 1;
 		}
 		part->disengage_timeout = 0;
@@ -294,7 +296,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
 		if (part->act_state != XPC_P_AS_INACTIVE)
 			xpc_wakeup_channel_mgr(part);
 
-		xpc_cancel_partition_deactivation_request(part);
+		xpc_arch_ops.cancel_partition_deactivation_request(part);
 	}
 	return disengaged;
 }
@@ -339,7 +341,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		if (reason == xpReactivating) {
 			/* we interrupt ourselves to reactivate partition */
-			xpc_request_partition_reactivation(part);
+			xpc_arch_ops.request_partition_reactivation(part);
 		}
 		return;
 	}
@@ -358,7 +360,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
 
 	/* ask remote partition to deactivate with regard to us */
-	xpc_request_partition_deactivation(part);
+	xpc_arch_ops.request_partition_deactivation(part);
 
 	/* set a timelimit on the disengage phase of the deactivation request */
 	part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
@@ -496,7 +498,7 @@ xpc_discovery(void)
 				continue;
 			}
 
-			xpc_request_partition_activation(remote_rp,
+			xpc_arch_ops.request_partition_activation(remote_rp,
 							 remote_rp_pa, nasid);
 		}
 	}
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index eaaa964942de..915a3b495da5 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -60,14 +60,14 @@ static struct xpc_vars_sn2 *xpc_vars_sn2;
 static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
 
 static int
-xpc_setup_partitions_sn_sn2(void)
+xpc_setup_partitions_sn2(void)
 {
 	/* nothing needs to be done */
 	return 0;
 }
 
 static void
-xpc_teardown_partitions_sn_sn2(void)
+xpc_teardown_partitions_sn2(void)
 {
 	/* nothing needs to be done */
 }
@@ -431,6 +431,13 @@ xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
 }
 
 static void
+xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch,
+				unsigned long *irq_flags)
+{
+	XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags);
+}
+
+static void
 xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch)
 {
 	XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL);
@@ -621,7 +628,7 @@ xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa,
 
 
 static int
-xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp)
 {
 	struct amo *amos_page;
 	int i;
@@ -629,7 +636,7 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
 
 	xpc_vars_sn2 = XPC_RP_VARS(rp);
 
-	rp->sn.vars_pa = xp_pa(xpc_vars_sn2);
+	rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2);
 
 	/* vars_part array follows immediately after vars */
 	xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
@@ -693,6 +700,33 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
 	return 0;
 }
 
+static int
+xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask)
+{
+	return test_bit(partid, heartbeating_to_mask);
+}
+
+static void
+xpc_allow_hb_sn2(short partid)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	set_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_hb_sn2(short partid)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_all_hbs_sn2(void)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions);
+}
+
 static void
 xpc_increment_heartbeat_sn2(void)
 {
@@ -719,7 +753,6 @@ xpc_heartbeat_init_sn2(void)
 	DBUG_ON(xpc_vars_sn2 == NULL);
 
 	bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
-	xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0];
 	xpc_online_heartbeat_sn2();
 }
 
@@ -751,9 +784,9 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part)
 		remote_vars->heartbeating_to_mask[0]);
 
 	if ((remote_vars->heartbeat == part->last_heartbeat &&
-	    remote_vars->heartbeat_offline == 0) ||
-	    !xpc_hb_allowed(sn_partition_id,
-			    &remote_vars->heartbeating_to_mask)) {
+	    !remote_vars->heartbeat_offline) ||
+	    !xpc_hb_allowed_sn2(sn_partition_id,
+				remote_vars->heartbeating_to_mask)) {
 		ret = xpNoHeartbeat;
 	} else {
 		part->last_heartbeat = remote_vars->heartbeat;
@@ -972,7 +1005,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
 		return;
 	}
 
-	remote_vars_pa = remote_rp->sn.vars_pa;
+	remote_vars_pa = remote_rp->sn.sn2.vars_pa;
 	remote_rp_version = remote_rp->version;
 	remote_rp_ts_jiffies = remote_rp->ts_jiffies;
 
@@ -1129,7 +1162,7 @@ xpc_process_activate_IRQ_rcvd_sn2(void)
  * Setup the channel structures that are sn2 specific.
  */
 static enum xp_retval
-xpc_setup_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_setup_ch_structures_sn2(struct xpc_partition *part)
 {
 	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	struct xpc_channel_sn2 *ch_sn2;
@@ -1251,7 +1284,7 @@ out_1:
  * Teardown the channel structures that are sn2 specific.
  */
 static void
-xpc_teardown_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_teardown_ch_structures_sn2(struct xpc_partition *part)
 {
 	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	short partid = XPC_PARTID(part);
@@ -2315,61 +2348,70 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
 		xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
 }
 
+static struct xpc_arch_operations xpc_arch_ops_sn2 = {
+	.setup_partitions = xpc_setup_partitions_sn2,
+	.teardown_partitions = xpc_teardown_partitions_sn2,
+	.process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2,
+	.get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2,
+	.setup_rsvd_page = xpc_setup_rsvd_page_sn2,
+
+	.allow_hb = xpc_allow_hb_sn2,
+	.disallow_hb = xpc_disallow_hb_sn2,
+	.disallow_all_hbs = xpc_disallow_all_hbs_sn2,
+	.increment_heartbeat = xpc_increment_heartbeat_sn2,
+	.offline_heartbeat = xpc_offline_heartbeat_sn2,
+	.online_heartbeat = xpc_online_heartbeat_sn2,
+	.heartbeat_init = xpc_heartbeat_init_sn2,
+	.heartbeat_exit = xpc_heartbeat_exit_sn2,
+	.get_remote_heartbeat = xpc_get_remote_heartbeat_sn2,
+
+	.request_partition_activation =
+		xpc_request_partition_activation_sn2,
+	.request_partition_reactivation =
+		xpc_request_partition_reactivation_sn2,
+	.request_partition_deactivation =
+		xpc_request_partition_deactivation_sn2,
+	.cancel_partition_deactivation_request =
+		xpc_cancel_partition_deactivation_request_sn2,
+
+	.setup_ch_structures = xpc_setup_ch_structures_sn2,
+	.teardown_ch_structures = xpc_teardown_ch_structures_sn2,
+
+	.make_first_contact = xpc_make_first_contact_sn2,
+
+	.get_chctl_all_flags = xpc_get_chctl_all_flags_sn2,
+	.send_chctl_closerequest = xpc_send_chctl_closerequest_sn2,
+	.send_chctl_closereply = xpc_send_chctl_closereply_sn2,
+	.send_chctl_openrequest = xpc_send_chctl_openrequest_sn2,
+	.send_chctl_openreply = xpc_send_chctl_openreply_sn2,
+	.send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2,
+	.process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2,
+
+	.save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2,
+
+	.setup_msg_structures = xpc_setup_msg_structures_sn2,
+	.teardown_msg_structures = xpc_teardown_msg_structures_sn2,
+
+	.indicate_partition_engaged = xpc_indicate_partition_engaged_sn2,
+	.indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2,
+	.partition_engaged = xpc_partition_engaged_sn2,
+	.any_partition_engaged = xpc_any_partition_engaged_sn2,
+	.assume_partition_disengaged = xpc_assume_partition_disengaged_sn2,
+
+	.n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2,
+	.send_payload = xpc_send_payload_sn2,
+	.get_deliverable_payload = xpc_get_deliverable_payload_sn2,
+	.received_payload = xpc_received_payload_sn2,
+	.notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2,
+};
+
 int
 xpc_init_sn2(void)
 {
 	int ret;
 	size_t buf_size;
 
-	xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2;
-	xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2;
-	xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
-	xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2;
-	xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
-	xpc_offline_heartbeat = xpc_offline_heartbeat_sn2;
-	xpc_online_heartbeat = xpc_online_heartbeat_sn2;
-	xpc_heartbeat_init = xpc_heartbeat_init_sn2;
-	xpc_heartbeat_exit = xpc_heartbeat_exit_sn2;
-	xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_sn2;
-
-	xpc_request_partition_activation = xpc_request_partition_activation_sn2;
-	xpc_request_partition_reactivation =
-	    xpc_request_partition_reactivation_sn2;
-	xpc_request_partition_deactivation =
-	    xpc_request_partition_deactivation_sn2;
-	xpc_cancel_partition_deactivation_request =
-	    xpc_cancel_partition_deactivation_request_sn2;
-
-	xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2;
-	xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_sn2;
-	xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_sn2;
-	xpc_make_first_contact = xpc_make_first_contact_sn2;
-
-	xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_sn2;
-	xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_sn2;
-	xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2;
-	xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2;
-	xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2;
-
-	xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2;
-
-	xpc_setup_msg_structures = xpc_setup_msg_structures_sn2;
-	xpc_teardown_msg_structures = xpc_teardown_msg_structures_sn2;
-
-	xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2;
-	xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2;
-	xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2;
-	xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2;
-
-	xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2;
-	xpc_indicate_partition_disengaged =
-	    xpc_indicate_partition_disengaged_sn2;
-	xpc_partition_engaged = xpc_partition_engaged_sn2;
-	xpc_any_partition_engaged = xpc_any_partition_engaged_sn2;
-	xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2;
-
-	xpc_send_payload = xpc_send_payload_sn2;
-	xpc_received_payload = xpc_received_payload_sn2;
+	xpc_arch_ops = xpc_arch_ops_sn2;
 
 	if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
 		dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index f7fff4727edb..9172fcdee4e2 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -46,8 +46,7 @@ struct uv_IO_APIC_route_entry {
 };
 #endif
 
-static atomic64_t xpc_heartbeat_uv;
-static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
+static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
 
 #define XPC_ACTIVATE_MSG_SIZE_UV	(1 * GRU_CACHE_LINE_BYTES)
 #define XPC_ACTIVATE_MQ_SIZE_UV		(4 * XP_MAX_NPARTITIONS_UV * \
@@ -63,7 +62,7 @@ static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
 static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
 
 static int
-xpc_setup_partitions_sn_uv(void)
+xpc_setup_partitions_uv(void)
 {
 	short partid;
 	struct xpc_partition_uv *part_uv;
@@ -79,7 +78,7 @@ xpc_setup_partitions_sn_uv(void)
 }
 
 static void
-xpc_teardown_partitions_sn_uv(void)
+xpc_teardown_partitions_uv(void)
 {
 	short partid;
 	struct xpc_partition_uv *part_uv;
@@ -423,41 +422,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
 		/* syncing of remote_act_state was just done above */
 		break;
 
-	case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-		break;
-	}
-	case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-
-		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
-		part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV;
-		spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
-		break;
-	}
-	case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-
-		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
-		part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV;
-		spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
-		break;
-	}
 	case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: {
 		struct xpc_activate_mq_msg_activate_req_uv *msg;
 
@@ -475,6 +439,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
 		part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
 		part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
 		part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
+		part_uv->heartbeat_gpa = msg->heartbeat_gpa;
 
 		if (msg->activate_gru_mq_desc_gpa !=
 		    part_uv->activate_gru_mq_desc_gpa) {
@@ -569,6 +534,17 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
 		xpc_wakeup_channel_mgr(part);
 		break;
 	}
+	case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
+		struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
+
+		msg = container_of(msg_hdr, struct
+				xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
+		spin_lock_irqsave(&part->chctl_lock, irq_flags);
+		part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE;
+		spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
+
+		xpc_wakeup_channel_mgr(part);
+	}
 	case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV:
 		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
 		part_uv->flags |= XPC_P_ENGAGED_UV;
@@ -759,7 +735,7 @@ xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req)
 
 	/*
 	 * !!! Make our side think that the remote partition sent an activate
-	 * !!! message our way by doing what the activate IRQ handler would
+	 * !!! mq message our way by doing what the activate IRQ handler would
 	 * !!! do had one really been sent.
 	 */
 
@@ -806,90 +782,82 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
 }
 
 static int
-xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp)
 {
-	rp->sn.activate_gru_mq_desc_gpa =
+	xpc_heartbeat_uv =
+	    &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat;
+	rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv);
+	rp->sn.uv.activate_gru_mq_desc_gpa =
 	    uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
 	return 0;
 }
 
 static void
-xpc_send_heartbeat_uv(int msg_type)
+xpc_allow_hb_uv(short partid)
 {
-	short partid;
-	struct xpc_partition *part;
-	struct xpc_activate_mq_msg_heartbeat_req_uv msg;
-
-	/*
-	 * !!! On uv we're broadcasting a heartbeat message every 5 seconds.
-	 * !!! Whereas on sn2 we're bte_copy'ng the heartbeat info every 20
-	 * !!! seconds. This is an increase in numalink traffic.
-	 * ??? Is this good?
-	 */
-
-	msg.heartbeat = atomic64_inc_return(&xpc_heartbeat_uv);
-
-	partid = find_first_bit(xpc_heartbeating_to_mask_uv,
-				XP_MAX_NPARTITIONS_UV);
-
-	while (partid < XP_MAX_NPARTITIONS_UV) {
-		part = &xpc_partitions[partid];
+}
 
-		xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
-					      msg_type);
+static void
+xpc_disallow_hb_uv(short partid)
+{
+}
 
-		partid = find_next_bit(xpc_heartbeating_to_mask_uv,
-				       XP_MAX_NPARTITIONS_UV, partid + 1);
-	}
+static void
+xpc_disallow_all_hbs_uv(void)
+{
 }
 
 static void
 xpc_increment_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV);
+	xpc_heartbeat_uv->value++;
 }
 
 static void
 xpc_offline_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+	xpc_increment_heartbeat_uv();
+	xpc_heartbeat_uv->offline = 1;
 }
 
 static void
 xpc_online_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV);
+	xpc_increment_heartbeat_uv();
+	xpc_heartbeat_uv->offline = 0;
 }
 
 static void
 xpc_heartbeat_init_uv(void)
 {
-	atomic64_set(&xpc_heartbeat_uv, 0);
-	bitmap_zero(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
-	xpc_heartbeating_to_mask = &xpc_heartbeating_to_mask_uv[0];
+	xpc_heartbeat_uv->value = 1;
+	xpc_heartbeat_uv->offline = 0;
 }
 
 static void
 xpc_heartbeat_exit_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+	xpc_offline_heartbeat_uv();
 }
 
 static enum xp_retval
 xpc_get_remote_heartbeat_uv(struct xpc_partition *part)
 {
 	struct xpc_partition_uv *part_uv = &part->sn.uv;
-	enum xp_retval ret = xpNoHeartbeat;
+	enum xp_retval ret;
 
-	if (part_uv->remote_act_state != XPC_P_AS_INACTIVE &&
-	    part_uv->remote_act_state != XPC_P_AS_DEACTIVATING) {
+	ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat),
+			       part_uv->heartbeat_gpa,
+			       sizeof(struct xpc_heartbeat_uv));
+	if (ret != xpSuccess)
+		return ret;
 
-		if (part_uv->heartbeat != part->last_heartbeat ||
-		    (part_uv->flags & XPC_P_HEARTBEAT_OFFLINE_UV)) {
+	if (part_uv->cached_heartbeat.value == part->last_heartbeat &&
+	    !part_uv->cached_heartbeat.offline) {
 
-			part->last_heartbeat = part_uv->heartbeat;
-			ret = xpSuccess;
-		}
+		ret = xpNoHeartbeat;
+	} else {
+		part->last_heartbeat = part_uv->cached_heartbeat.value;
 	}
 	return ret;
 }
@@ -904,8 +872,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
 
 	part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
 	part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
+	part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa;
 	part->sn.uv.activate_gru_mq_desc_gpa =
-	    remote_rp->sn.activate_gru_mq_desc_gpa;
+	    remote_rp->sn.uv.activate_gru_mq_desc_gpa;
 
 	/*
 	 * ??? Is it a good idea to make this conditional on what is
@@ -913,8 +882,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
 	 */
 	if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
 		msg.rp_gpa = uv_gpa(xpc_rsvd_page);
+		msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa;
 		msg.activate_gru_mq_desc_gpa =
-		    xpc_rsvd_page->sn.activate_gru_mq_desc_gpa;
+		    xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa;
 		xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
 					   XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
 	}
@@ -1010,7 +980,7 @@ xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head)
  * Setup the channel structures that are uv specific.
  */
 static enum xp_retval
-xpc_setup_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_setup_ch_structures_uv(struct xpc_partition *part)
 {
 	struct xpc_channel_uv *ch_uv;
 	int ch_number;
@@ -1029,7 +999,7 @@ xpc_setup_ch_structures_sn_uv(struct xpc_partition *part)
  * Teardown the channel structures that are uv specific.
  */
 static void
-xpc_teardown_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_teardown_ch_structures_uv(struct xpc_partition *part)
 {
 	/* nothing needs to be done */
 	return;
@@ -1243,6 +1213,16 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
 }
 
 static void
+xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+	struct xpc_activate_mq_msg_chctl_opencomplete_uv msg;
+
+	msg.ch_number = ch->number;
+	xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
+				    XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV);
+}
+
+static void
 xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
 {
 	unsigned long irq_flags;
@@ -1669,58 +1649,67 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
 	msg->hdr.msg_slot_number += ch->remote_nentries;
 }
 
+static struct xpc_arch_operations xpc_arch_ops_uv = {
+	.setup_partitions = xpc_setup_partitions_uv,
+	.teardown_partitions = xpc_teardown_partitions_uv,
+	.process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv,
+	.get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv,
+	.setup_rsvd_page = xpc_setup_rsvd_page_uv,
+
+	.allow_hb = xpc_allow_hb_uv,
+	.disallow_hb = xpc_disallow_hb_uv,
+	.disallow_all_hbs = xpc_disallow_all_hbs_uv,
+	.increment_heartbeat = xpc_increment_heartbeat_uv,
+	.offline_heartbeat = xpc_offline_heartbeat_uv,
+	.online_heartbeat = xpc_online_heartbeat_uv,
+	.heartbeat_init = xpc_heartbeat_init_uv,
+	.heartbeat_exit = xpc_heartbeat_exit_uv,
+	.get_remote_heartbeat = xpc_get_remote_heartbeat_uv,
+
+	.request_partition_activation =
+		xpc_request_partition_activation_uv,
+	.request_partition_reactivation =
+		xpc_request_partition_reactivation_uv,
+	.request_partition_deactivation =
+		xpc_request_partition_deactivation_uv,
+	.cancel_partition_deactivation_request =
+		xpc_cancel_partition_deactivation_request_uv,
+
+	.setup_ch_structures = xpc_setup_ch_structures_uv,
+	.teardown_ch_structures = xpc_teardown_ch_structures_uv,
+
+	.make_first_contact = xpc_make_first_contact_uv,
+
+	.get_chctl_all_flags = xpc_get_chctl_all_flags_uv,
+	.send_chctl_closerequest = xpc_send_chctl_closerequest_uv,
+	.send_chctl_closereply = xpc_send_chctl_closereply_uv,
+	.send_chctl_openrequest = xpc_send_chctl_openrequest_uv,
+	.send_chctl_openreply = xpc_send_chctl_openreply_uv,
+	.send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv,
+	.process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv,
+
+	.save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv,
+
+	.setup_msg_structures = xpc_setup_msg_structures_uv,
+	.teardown_msg_structures = xpc_teardown_msg_structures_uv,
+
+	.indicate_partition_engaged = xpc_indicate_partition_engaged_uv,
+	.indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv,
+	.assume_partition_disengaged = xpc_assume_partition_disengaged_uv,
+	.partition_engaged = xpc_partition_engaged_uv,
+	.any_partition_engaged = xpc_any_partition_engaged_uv,
+
+	.n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv,
+	.send_payload = xpc_send_payload_uv,
+	.get_deliverable_payload = xpc_get_deliverable_payload_uv,
+	.received_payload = xpc_received_payload_uv,
+	.notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
+};
+
 int
 xpc_init_uv(void)
 {
-	xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv;
-	xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv;
-	xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv;
-	xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv;
-	xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv;
-	xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
-	xpc_offline_heartbeat = xpc_offline_heartbeat_uv;
-	xpc_online_heartbeat = xpc_online_heartbeat_uv;
-	xpc_heartbeat_init = xpc_heartbeat_init_uv;
-	xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
-	xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_uv;
-
-	xpc_request_partition_activation = xpc_request_partition_activation_uv;
-	xpc_request_partition_reactivation =
-	    xpc_request_partition_reactivation_uv;
-	xpc_request_partition_deactivation =
-	    xpc_request_partition_deactivation_uv;
-	xpc_cancel_partition_deactivation_request =
-	    xpc_cancel_partition_deactivation_request_uv;
-
-	xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_uv;
-	xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_uv;
-
-	xpc_make_first_contact = xpc_make_first_contact_uv;
-
-	xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_uv;
-	xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_uv;
-	xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv;
-	xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv;
-	xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv;
-
-	xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv;
-
-	xpc_setup_msg_structures = xpc_setup_msg_structures_uv;
-	xpc_teardown_msg_structures = xpc_teardown_msg_structures_uv;
-
-	xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_uv;
-	xpc_indicate_partition_disengaged =
-	    xpc_indicate_partition_disengaged_uv;
-	xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_uv;
-	xpc_partition_engaged = xpc_partition_engaged_uv;
-	xpc_any_partition_engaged = xpc_any_partition_engaged_uv;
-
-	xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv;
-	xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv;
-	xpc_send_payload = xpc_send_payload_uv;
-	xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv;
-	xpc_get_deliverable_payload = xpc_get_deliverable_payload_uv;
-	xpc_received_payload = xpc_received_payload_uv;
+	xpc_arch_ops = xpc_arch_ops_uv;
 
 	if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
 		dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n",
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c232d11a7ed4..06084dbf1277 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -208,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 	}
 
 	ext_csd_struct = ext_csd[EXT_CSD_REV];
-	if (ext_csd_struct > 2) {
+	if (ext_csd_struct > 3) {
 		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
 			"version %d\n", mmc_hostname(card->host),
 			ext_csd_struct);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 26fc098d77cd..cd81c395e164 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -363,15 +363,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 		goto err;
 
 	/*
-	 * For SPI, enable CRC as appropriate.
-	 */
-	if (mmc_host_is_spi(host)) {
-		err = mmc_spi_set_crc(host, use_spi_crc);
-		if (err)
-			goto err;
-	}
-
-	/*
 	 * Fetch CID from card.
 	 */
 	if (mmc_host_is_spi(host))
@@ -458,6 +449,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	}
 
 	/*
+	 * For SPI, enable CRC as appropriate.
+	 * This CRC enable is located AFTER the reading of the
+	 * card registers because some SDHC cards are not able
+	 * to provide valid CRCs for non-512-byte blocks.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_set_crc(host, use_spi_crc);
+		if (err)
+			goto free_card;
+	}
+
+	/*
 	 * Attempt to change to high-speed (if supported)
 	 */
 	err = mmc_switch_hs(card);
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index eb29b1d933ac..e0be21a4a696 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -307,13 +307,6 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
 
 	wmb();
 
-	if (host->actual_bus_width == MMC_BUS_WIDTH_4)
-		BLR(host->dma) = 0;	/* burst 64 byte read / 64 bytes write */
-	else
-		BLR(host->dma) = 16;	/* burst 16 byte read / 16 bytes write */
-
-	RSSR(host->dma) = DMA_REQ_SDHC;
-
 	set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
 	clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
 
@@ -818,9 +811,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	if (ios->bus_width == MMC_BUS_WIDTH_4) {
 		host->actual_bus_width = MMC_BUS_WIDTH_4;
 		imx_gpio_mode(PB11_PF_SD_DAT3);
+		BLR(host->dma) = 0;	/* burst 64 byte read/write */
 	} else {
 		host->actual_bus_width = MMC_BUS_WIDTH_1;
 		imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
+		BLR(host->dma) = 16;	/* burst 16 byte read/write */
 	}
 
 	if (host->power_mode != ios->power_mode) {
@@ -938,7 +933,7 @@ static void imxmci_check_status(unsigned long data)
 	mod_timer(&host->timer, jiffies + (HZ>>1));
 }
 
-static int imxmci_probe(struct platform_device *pdev)
+static int __init imxmci_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
 	struct imxmci_host *host = NULL;
@@ -1034,6 +1029,7 @@ static int imxmci_probe(struct platform_device *pdev)
 	}
 	host->dma_allocated = 1;
 	imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
+	RSSR(host->dma) = DMA_REQ_SDHC;
 
 	tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
 	host->status_reg=0;
@@ -1079,7 +1075,7 @@ out:
 	return ret;
 }
 
-static int imxmci_remove(struct platform_device *pdev)
+static int __exit imxmci_remove(struct platform_device *pdev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
@@ -1145,8 +1141,7 @@ static int imxmci_resume(struct platform_device *dev)
 #endif /* CONFIG_PM */
 
 static struct platform_driver imxmci_driver = {
-	.probe		= imxmci_probe,
-	.remove		= imxmci_remove,
+	.remove		= __exit_p(imxmci_remove),
 	.suspend	= imxmci_suspend,
 	.resume		= imxmci_resume,
 	.driver		= {
@@ -1157,7 +1152,7 @@ static struct platform_driver imxmci_driver = {
 
 static int __init imxmci_init(void)
 {
-	return platform_driver_register(&imxmci_driver);
+	return platform_driver_probe(&imxmci_driver, imxmci_probe);
 }
 
 static void __exit imxmci_exit(void)
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 72f8bde4877a..f48349d18c92 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/hrtimer.h>
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/bio.h>
 #include <linux/dma-mapping.h>
@@ -95,7 +95,7 @@
  * reads which takes nowhere near that long.  Older cards may be able to use
  * shorter timeouts ... but why bother?
  */
-#define r1b_timeout		ktime_set(3, 0)
+#define r1b_timeout		(HZ * 3)
 
 
 /****************************************************************************/
@@ -183,12 +183,11 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
 	return status;
 }
 
-static int
-mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
+static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
+			unsigned n, u8 byte)
 {
 	u8		*cp = host->data->status;
-
-	timeout = ktime_add(timeout, ktime_get());
+	unsigned long start = jiffies;
 
 	while (1) {
 		int		status;
@@ -203,22 +202,26 @@ mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
 				return cp[i];
 		}
 
-		/* REVISIT investigate msleep() to avoid busy-wait I/O
-		 * in at least some cases.
-		 */
-		if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
+		if (time_is_before_jiffies(start + timeout))
 			break;
+
+		/* If we need long timeouts, we may release the CPU.
+		 * We use jiffies here because we want to have a relation
+		 * between elapsed time and the blocking of the scheduler.
+		 */
+		if (time_is_before_jiffies(start+1))
+			schedule();
 	}
 	return -ETIMEDOUT;
 }
 
 static inline int
-mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
+mmc_spi_wait_unbusy(struct mmc_spi_host *host, unsigned long timeout)
 {
 	return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
 }
 
-static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)
+static int mmc_spi_readtoken(struct mmc_spi_host *host, unsigned long timeout)
 {
 	return mmc_spi_skip(host, timeout, 1, 0xff);
 }
@@ -251,6 +254,10 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
 	u8	*cp = host->data->status;
 	u8	*end = cp + host->t.len;
 	int	value = 0;
+	int	bitshift;
+	u8 	leftover = 0;
+	unsigned short rotator;
+	int 	i;
 	char	tag[32];
 
 	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
@@ -268,9 +275,8 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
 
 	/* Data block reads (R1 response types) may need more data... */
 	if (cp == end) {
-		unsigned	i;
-
 		cp = host->data->status;
+		end = cp+1;
 
 		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
 		 * status byte ... and we already scanned 2 bytes.
@@ -295,20 +301,34 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
 	}
 
 checkstatus:
-	if (*cp & 0x80) {
-		dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
-					tag, *cp);
-		value = -EBADR;
-		goto done;
+	bitshift = 0;
+	if (*cp & 0x80)	{
+		/* Houston, we have an ugly card with a bit-shifted response */
+		rotator = *cp++ << 8;
+		/* read the next byte */
+		if (cp == end) {
+			value = mmc_spi_readbytes(host, 1);
+			if (value < 0)
+				goto done;
+			cp = host->data->status;
+			end = cp+1;
+		}
+		rotator |= *cp++;
+		while (rotator & 0x8000) {
+			bitshift++;
+			rotator <<= 1;
+		}
+		cmd->resp[0] = rotator >> 8;
+		leftover = rotator;
+	} else {
+		cmd->resp[0] = *cp++;
 	}
-
-	cmd->resp[0] = *cp++;
 	cmd->error = 0;
 
 	/* Status byte: the entire seven-bit R1 response.  */
 	if (cmd->resp[0] != 0) {
 		if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
-					| R1_SPI_ILLEGAL_COMMAND)
+				      | R1_SPI_ILLEGAL_COMMAND)
 				& cmd->resp[0])
 			value = -EINVAL;
 		else if (R1_SPI_COM_CRC & cmd->resp[0])
@@ -336,12 +356,45 @@ checkstatus:
 	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
 	 */
 	case MMC_RSP_SPI_R2:
-		cmd->resp[0] |= *cp << 8;
+		/* read the next byte */
+		if (cp == end) {
+			value = mmc_spi_readbytes(host, 1);
+			if (value < 0)
+				goto done;
+			cp = host->data->status;
+			end = cp+1;
+		}
+		if (bitshift) {
+			rotator = leftover << 8;
+			rotator |= *cp << bitshift;
+			cmd->resp[0] |= (rotator & 0xFF00);
+		} else {
+			cmd->resp[0] |= *cp << 8;
+		}
 		break;
 
 	/* SPI R3, R4, or R7 == R1 + 4 bytes */
 	case MMC_RSP_SPI_R3:
-		cmd->resp[1] = get_unaligned_be32(cp);
+		rotator = leftover << 8;
+		cmd->resp[1] = 0;
+		for (i = 0; i < 4; i++) {
+			cmd->resp[1] <<= 8;
+			/* read the next byte */
+			if (cp == end) {
+				value = mmc_spi_readbytes(host, 1);
+				if (value < 0)
+					goto done;
+				cp = host->data->status;
+				end = cp+1;
+			}
+			if (bitshift) {
+				rotator |= *cp++ << bitshift;
+				cmd->resp[1] |= (rotator >> 8);
+				rotator <<= 8;
+			} else {
+				cmd->resp[1] |= *cp++;
+			}
+		}
 		break;
 
 	/* SPI R1 == just one status byte */
@@ -607,7 +660,7 @@ mmc_spi_setup_data_message(
  */
 static int
 mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
-	ktime_t timeout)
+	unsigned long timeout)
 {
 	struct spi_device	*spi = host->spi;
 	int			status, i;
@@ -717,11 +770,13 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
  */
 static int
 mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
-	ktime_t timeout)
+	unsigned long timeout)
 {
 	struct spi_device	*spi = host->spi;
 	int			status;
 	struct scratch		*scratch = host->data;
+	unsigned int 		bitshift;
+	u8			leftover;
 
 	/* At least one SD card sends an all-zeroes byte when N(CX)
 	 * applies, before the all-ones bytes ... just cope with that.
@@ -733,38 +788,60 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
 	if (status == 0xff || status == 0)
 		status = mmc_spi_readtoken(host, timeout);
 
-	if (status == SPI_TOKEN_SINGLE) {
-		if (host->dma_dev) {
-			dma_sync_single_for_device(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-			dma_sync_single_for_device(host->dma_dev,
-					t->rx_dma, t->len,
-					DMA_FROM_DEVICE);
-		}
+	if (status < 0) {
+		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+		return status;
+	}
 
-		status = spi_sync(spi, &host->m);
+	/* The token may be bit-shifted...
+	 * the first 0-bit precedes the data stream.
+	 */
+	bitshift = 7;
+	while (status & 0x80) {
+		status <<= 1;
+		bitshift--;
+	}
+	leftover = status << 1;
 
-		if (host->dma_dev) {
-			dma_sync_single_for_cpu(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-			dma_sync_single_for_cpu(host->dma_dev,
-					t->rx_dma, t->len,
-					DMA_FROM_DEVICE);
-		}
+	if (host->dma_dev) {
+		dma_sync_single_for_device(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+		dma_sync_single_for_device(host->dma_dev,
+				t->rx_dma, t->len,
+				DMA_FROM_DEVICE);
+	}
 
-	} else {
-		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+	status = spi_sync(spi, &host->m);
 
-		/* we've read extra garbage, timed out, etc */
-		if (status < 0)
-			return status;
+	if (host->dma_dev) {
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+		dma_sync_single_for_cpu(host->dma_dev,
+				t->rx_dma, t->len,
+				DMA_FROM_DEVICE);
+	}
 
-		/* low four bits are an R2 subset, fifth seems to be
-		 * vendor specific ... map them all to generic error..
+	if (bitshift) {
+		/* Walk through the data and the crc and do
+		 * all the magic to get byte-aligned data.
 		 */
-		return -EIO;
+		u8 *cp = t->rx_buf;
+		unsigned int len;
+		unsigned int bitright = 8 - bitshift;
+		u8 temp;
+		for (len = t->len; len; len--) {
+			temp = *cp;
+			*cp++ = leftover | (temp >> bitshift);
+			leftover = temp << bitright;
+		}
+		cp = (u8 *) &scratch->crc_val;
+		temp = *cp;
+		*cp++ = leftover | (temp >> bitshift);
+		leftover = temp << bitright;
+		temp = *cp;
+		*cp = leftover | (temp >> bitshift);
 	}
 
 	if (host->mmc->use_spi_crc) {
@@ -803,7 +880,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 	unsigned		n_sg;
 	int			multiple = (data->blocks > 1);
 	u32			clock_rate;
-	ktime_t			timeout;
+	unsigned long		timeout;
 
 	if (data->flags & MMC_DATA_READ)
 		direction = DMA_FROM_DEVICE;
@@ -817,8 +894,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 	else
 		clock_rate = spi->max_speed_hz;
 
-	timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns +
-			data->timeout_clks * 1000000 / clock_rate);
+	timeout = data->timeout_ns +
+		  data->timeout_clks * 1000000 / clock_rate;
+	timeout = usecs_to_jiffies((unsigned int)(timeout / 1000)) + 1;
 
 	/* Handle scatterlist segments one at a time, with synch for
 	 * each 512-byte block
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d183be6f2a5f..e62a22a7f00c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -298,7 +298,6 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 		struct mmc_request *mrq = host->mrq;
 
 		host->mrq = NULL;
-		mmc_omap_fclk_lazy_disable(host);
 		mmc_request_done(host->mmc, mrq);
 		return;
 	}
@@ -434,6 +433,8 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 	if (host->mrq == NULL) {
 		OMAP_HSMMC_WRITE(host->base, STAT,
 			OMAP_HSMMC_READ(host->base, STAT));
+		/* Flush posted write */
+		OMAP_HSMMC_READ(host->base, STAT);
 		return IRQ_HANDLED;
 	}
 
@@ -489,8 +490,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 	}
 
 	OMAP_HSMMC_WRITE(host->base, STAT, status);
+	/* Flush posted write */
+	OMAP_HSMMC_READ(host->base, STAT);
 
-	if (end_cmd || (status & CC))
+	if (end_cmd || ((status & CC) && host->cmd))
 		mmc_omap_cmd_done(host, host->cmd);
 	if (end_trans || (status & TC))
 		mmc_omap_xfer_done(host, data);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index c5b316e22371..cd37962ec44f 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -729,6 +729,6 @@ static void __exit sdhci_drv_exit(void)
 module_init(sdhci_drv_init);
 module_exit(sdhci_drv_exit);
 
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 30d8e3d4e6fd..9234be2226e7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1935,7 +1935,7 @@ module_exit(sdhci_drv_exit);
 
 module_param(debug_quirks, uint, 0444);
 
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index adda37952032..89bf8cd25cac 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -2036,7 +2036,7 @@ module_param_named(irq, param_irq, uint, 0444);
 module_param_named(dma, param_dma, int, 0444);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
 
 #ifdef CONFIG_PNP
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 7c5b257ce8e4..29acd06b1c39 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -332,7 +332,7 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr)
 		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
 }
 
-static int cafe_nand_interrupt(int irq, void *id)
+static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 {
 	struct mtd_info *mtd = id;
 	struct cafe_priv *cafe = mtd->priv;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 29df398b7727..1fc45431a620 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1383,6 +1383,11 @@ static void rtl8139_hw_start (struct net_device *dev)
 	RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
 	RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
 
+	tp->cur_rx = 0;
+
+	/* init Rx ring buffer DMA address */
+	RTL_W32_F (RxBuf, tp->rx_ring_dma);
+
 	/* Must enable Tx/Rx before setting transfer thresholds! */
 	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
@@ -1390,8 +1395,6 @@ static void rtl8139_hw_start (struct net_device *dev)
 	RTL_W32 (RxConfig, tp->rx_config);
 	RTL_W32 (TxConfig, rtl8139_tx_config);
 
-	tp->cur_rx = 0;
-
 	rtl_check_media (dev, 1);
 
 	if (tp->chipset >= CH_8139B) {
@@ -1406,9 +1409,6 @@ static void rtl8139_hw_start (struct net_device *dev)
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
 
-	/* init Rx ring buffer DMA address */
-	RTL_W32_F (RxBuf, tp->rx_ring_dma);
-
 	/* init Tx buffer DMA addresses */
 	for (i = 0; i < NUM_TX_DESC; i++)
 		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9e7baec45720..214a92d1ef75 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -28,9 +28,9 @@ if NETDEVICES
 
 config COMPAT_NET_DEV_OPS
        default y
-       bool "Enable older network device API compatiablity"
+       bool "Enable older network device API compatibility"
        ---help---
-          This option enables kernel compatiability with older network devices
+          This option enables kernel compatibility with older network devices
           that do not use net_device_ops interface.
 
 	  If unsure, say Y.
@@ -977,6 +977,8 @@ config ETHOC
 	depends on NET_ETHERNET && HAS_IOMEM
 	select MII
 	select PHYLIB
+	select CRC32
+	select BITREVERSE
 	help
 	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
 
@@ -2056,6 +2058,27 @@ config IGB_DCA
 	  driver.  DCA is a method for warming the CPU cache before data
 	  is used, with the intent of lessening the impact of cache misses.
 
+config IGBVF
+       tristate "Intel(R) 82576 Virtual Function Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) 82576 virtual functions.  For more
+         information on how to identify your adapter, go to the Adapter &
+         Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called igbvf.
+
 source "drivers/net/ixp2000/Kconfig"
 
 config MYRI_SBUS
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index edc9a0d6171d..1fc4602a6ff2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_E1000) += e1000/
 obj-$(CONFIG_E1000E) += e1000e/
 obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
 obj-$(CONFIG_IGB) += igb/
+obj-$(CONFIG_IGBVF) += igbvf/
 obj-$(CONFIG_IXGBE) += ixgbe/
 obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_IP1000) += ipg.o
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index d0d0c2fee054..02f64d578641 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -692,6 +692,17 @@ static struct zorro_driver a2065_driver = {
 	.remove		= __devexit_p(a2065_remove_one),
 };
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_set_multicast_list	= lance_set_multicast,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit a2065_init_one(struct zorro_dev *z,
 				    const struct zorro_device_id *ent)
 {
@@ -753,12 +764,8 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
 	priv->rx_ring_mod_mask = RX_RING_MOD_MASK;
 	priv->tx_ring_mod_mask = TX_RING_MOD_MASK;
 
-	dev->open = &lance_open;
-	dev->stop = &lance_close;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->tx_timeout = &lance_tx_timeout;
+	dev->netdev_ops = &lance_netdev_ops;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &lance_set_multicast;
 	dev->dma = 0;
 
 	init_timer(&priv->multicast_timer);
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index e1d72e06f3e1..58e8d522e5bc 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -155,6 +155,18 @@ static struct zorro_driver ariadne_driver = {
     .remove	= __devexit_p(ariadne_remove_one),
 };
 
+static const struct net_device_ops ariadne_netdev_ops = {
+	.ndo_open		= ariadne_open,
+	.ndo_stop		= ariadne_close,
+	.ndo_start_xmit		= ariadne_start_xmit,
+	.ndo_tx_timeout		= ariadne_tx_timeout,
+	.ndo_get_stats		= ariadne_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit ariadne_init_one(struct zorro_dev *z,
 				      const struct zorro_device_id *ent)
 {
@@ -197,13 +209,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z,
     dev->mem_start = ZTWO_VADDR(mem_start);
     dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE;
 
-    dev->open = &ariadne_open;
-    dev->stop = &ariadne_close;
-    dev->hard_start_xmit = &ariadne_start_xmit;
-    dev->tx_timeout = &ariadne_tx_timeout;
+    dev->netdev_ops = &ariadne_netdev_ops;
     dev->watchdog_timeo = 5*HZ;
-    dev->get_stats = &ariadne_get_stats;
-    dev->set_multicast_list = &set_multicast_list;
 
     err = register_netdev(dev);
     if (err) {
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 4bc6901b3819..627bc75da17d 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -665,6 +665,20 @@ static void __init am79c961_banner(void)
 	if (net_debug && version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 }
+static const struct net_device_ops am79c961_netdev_ops = {
+	.ndo_open		= am79c961_open,
+	.ndo_stop		= am79c961_close,
+	.ndo_start_xmit		= am79c961_sendpacket,
+	.ndo_get_stats		= am79c961_getstats,
+	.ndo_set_multicast_list	= am79c961_setmulticastlist,
+	.ndo_tx_timeout		= am79c961_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= am79c961_poll_controller,
+#endif
+};
 
 static int __init am79c961_probe(struct platform_device *pdev)
 {
@@ -732,15 +746,7 @@ static int __init am79c961_probe(struct platform_device *pdev)
 	if (am79c961_hw_init(dev))
 		goto release;
 
-	dev->open		= am79c961_open;
-	dev->stop		= am79c961_close;
-	dev->hard_start_xmit	= am79c961_sendpacket;
-	dev->get_stats		= am79c961_getstats;
-	dev->set_multicast_list	= am79c961_setmulticastlist;
-	dev->tx_timeout		= am79c961_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller	= am79c961_poll_controller;
-#endif
+	dev->netdev_ops = &am79c961_netdev_ops;
 
 	ret = register_netdev(dev);
 	if (ret == 0) {
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 442938d50380..7f4bc8ae5462 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -577,7 +577,7 @@ static void at91ether_sethashtable(struct net_device *dev)
 /*
  * Enable/Disable promiscuous and multicast modes.
  */
-static void at91ether_set_rx_mode(struct net_device *dev)
+static void at91ether_set_multicast_list(struct net_device *dev)
 {
 	unsigned long cfg;
 
@@ -808,7 +808,7 @@ static int at91ether_close(struct net_device *dev)
 /*
  * Transmit packet.
  */
-static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
+static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct at91_private *lp = netdev_priv(dev);
 
@@ -828,7 +828,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
 
 		dev->trans_start = jiffies;
 	} else {
-		printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
+		printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
 		return 1;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
 				on this skb, he also reports -ENETDOWN and printk's, so either
 				we free and return(0) or don't free and return 1 */
@@ -965,6 +965,21 @@ static void at91ether_poll_controller(struct net_device *dev)
 }
 #endif
 
+static const struct net_device_ops at91ether_netdev_ops = {
+	.ndo_open		= at91ether_open,
+	.ndo_stop		= at91ether_close,
+	.ndo_start_xmit		= at91ether_start_xmit,
+	.ndo_get_stats		= at91ether_stats,
+	.ndo_set_multicast_list	= at91ether_set_multicast_list,
+	.ndo_set_mac_address	= set_mac_address,
+	.ndo_do_ioctl		= at91ether_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= at91ether_poll_controller,
+#endif
+};
+
 /*
  * Initialize the ethernet interface
  */
@@ -1005,17 +1020,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
 	spin_lock_init(&lp->lock);
 
 	ether_setup(dev);
-	dev->open = at91ether_open;
-	dev->stop = at91ether_close;
-	dev->hard_start_xmit = at91ether_tx;
-	dev->get_stats = at91ether_stats;
-	dev->set_multicast_list = at91ether_set_rx_mode;
-	dev->set_mac_address = set_mac_address;
+	dev->netdev_ops = &at91ether_netdev_ops;
 	dev->ethtool_ops = &at91ether_ethtool_ops;
-	dev->do_ioctl = at91ether_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = at91ether_poll_controller;
-#endif
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index cc7708775da0..b72b3d639f6e 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -153,7 +153,7 @@ struct ep93xx_descs
 struct ep93xx_priv
 {
 	struct resource		*res;
-	void			*base_addr;
+	void __iomem		*base_addr;
 	int			irq;
 
 	struct ep93xx_descs	*descs;
@@ -770,7 +770,18 @@ static struct ethtool_ops ep93xx_ethtool_ops = {
 	.get_link		= ep93xx_get_link,
 };
 
-struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
+static const struct net_device_ops ep93xx_netdev_ops = {
+	.ndo_open		= ep93xx_open,
+	.ndo_stop		= ep93xx_close,
+	.ndo_start_xmit		= ep93xx_xmit,
+	.ndo_get_stats		= ep93xx_get_stats,
+	.ndo_do_ioctl		= ep93xx_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
+static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
 {
 	struct net_device *dev;
 
@@ -780,12 +791,8 @@ struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
 
 	memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN);
 
-	dev->get_stats = ep93xx_get_stats;
 	dev->ethtool_ops = &ep93xx_ethtool_ops;
-	dev->hard_start_xmit = ep93xx_xmit;
-	dev->open = ep93xx_open;
-	dev->stop = ep93xx_close;
-	dev->do_ioctl = ep93xx_ioctl;
+	dev->netdev_ops = &ep93xx_netdev_ops;
 
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index e380de454463..edf770f639fa 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -991,6 +991,18 @@ static void __devinit ether1_banner(void)
 		printk(KERN_INFO "%s", version);
 }
 
+static const struct net_device_ops ether1_netdev_ops = {
+	.ndo_open		= ether1_open,
+	.ndo_stop		= ether1_close,
+	.ndo_start_xmit		= ether1_sendpacket,
+	.ndo_get_stats		= ether1_getstats,
+	.ndo_set_multicast_list	= ether1_setmulticastlist,
+	.ndo_tx_timeout		= ether1_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit
 ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
@@ -1031,12 +1043,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto free;
 	}
 
-	dev->open		= ether1_open;
-	dev->stop		= ether1_close;
-	dev->hard_start_xmit    = ether1_sendpacket;
-	dev->get_stats		= ether1_getstats;
-	dev->set_multicast_list = ether1_setmulticastlist;
-	dev->tx_timeout		= ether1_timeout;
+	dev->netdev_ops		= &ether1_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 
 	ret = register_netdev(dev);
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 21a7bef12d3b..ec8a1ae1e887 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -770,6 +770,18 @@ static void __devinit ether3_banner(void)
 		printk(KERN_INFO "%s", version);
 }
 
+static const struct net_device_ops ether3_netdev_ops = {
+	.ndo_open		= ether3_open,
+	.ndo_stop		= ether3_close,
+	.ndo_start_xmit		= ether3_sendpacket,
+	.ndo_get_stats		= ether3_getstats,
+	.ndo_set_multicast_list	= ether3_setmulticastlist,
+	.ndo_tx_timeout		= ether3_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit
 ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
@@ -846,12 +858,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto free;
 	}
 
-	dev->open		= ether3_open;
-	dev->stop		= ether3_close;
-	dev->hard_start_xmit	= ether3_sendpacket;
-	dev->get_stats		= ether3_getstats;
-	dev->set_multicast_list	= ether3_setmulticastlist;
-	dev->tx_timeout		= ether3_timeout;
+	dev->netdev_ops		= &ether3_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 
 	ret = register_netdev(dev);
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 2d81f6afcb58..5425ab0c38c0 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -453,6 +453,16 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag,
 	return( ret );
 }
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_set_mac_address	= lance_set_mac_address,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
 
 static unsigned long __init lance_probe1( struct net_device *dev,
 					   struct lance_addr *init_rec )
@@ -623,15 +633,9 @@ static unsigned long __init lance_probe1( struct net_device *dev,
 	if (did_version++ == 0)
 		DPRINTK( 1, ( version ));
 
-	/* The LANCE-specific entries in the device structure. */
-	dev->open = &lance_open;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->stop = &lance_close;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = &lance_set_mac_address;
+	dev->netdev_ops = &lance_netdev_ops;
 
 	/* XXX MSch */
-	dev->tx_timeout = lance_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	return( 1 );
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index deb7b53167ee..83a12125b94e 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -2532,8 +2532,8 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
 	 * various kernel subsystems to support the mechanics required by a
 	 * fixed-high-32-bit system.
 	 */
-	if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
-	    (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+	if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+	    (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
 		dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
 		goto err_dma;
 	}
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 4274e4ac963b..d58c105fc779 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -1004,12 +1004,12 @@ static void au1000_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static void set_rx_mode(struct net_device *dev)
+static void au1000_multicast_list(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
 	if (au1000_debug > 4)
-		printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
+		printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags);
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
@@ -1047,6 +1047,18 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
 }
 
+static const struct net_device_ops au1000_netdev_ops = {
+	.ndo_open		= au1000_open,
+	.ndo_stop		= au1000_close,
+	.ndo_start_xmit		= au1000_tx,
+	.ndo_set_multicast_list	= au1000_multicast_list,
+	.ndo_do_ioctl		= au1000_ioctl,
+	.ndo_tx_timeout		= au1000_tx_timeout,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static struct net_device * au1000_probe(int port_num)
 {
 	static unsigned version_printed = 0;
@@ -1197,13 +1209,8 @@ static struct net_device * au1000_probe(int port_num)
 
 	dev->base_addr = base;
 	dev->irq = irq;
-	dev->open = au1000_open;
-	dev->hard_start_xmit = au1000_tx;
-	dev->stop = au1000_close;
-	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &au1000_ioctl;
+	dev->netdev_ops = &au1000_netdev_ops;
 	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
-	dev->tx_timeout = au1000_tx_timeout;
 	dev->watchdog_timeo = ETH_TX_TIMEOUT;
 
 	/*
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 04f4b73fa8d8..9592f22e4c8c 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -319,7 +319,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 
 	be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause,
 		&ecmd->rx_pause);
-	ecmd->autoneg = AUTONEG_ENABLE;
+	ecmd->autoneg = 0;
 }
 
 static int
@@ -328,7 +328,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 	struct be_adapter *adapter = netdev_priv(netdev);
 	int status;
 
-	if (ecmd->autoneg != AUTONEG_ENABLE)
+	if (ecmd->autoneg != 0)
 		return -EINVAL;
 
 	status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9b75aa630062..30d0c81c989e 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1821,11 +1821,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
 
 	be_msix_enable(adapter);
 
-	status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!status) {
 		netdev->features |= NETIF_F_HIGHDMA;
 	} else {
-		status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (status) {
 			dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
 			goto free_netdev;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 9afe8092dfc4..9f971ed6b58d 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -979,6 +979,20 @@ static int bfin_mac_open(struct net_device *dev)
 	return 0;
 }
 
+static const struct net_device_ops bfin_mac_netdev_ops = {
+	.ndo_open		= bfin_mac_open,
+	.ndo_stop		= bfin_mac_close,
+	.ndo_start_xmit		= bfin_mac_hard_start_xmit,
+	.ndo_set_mac_address	= bfin_mac_set_mac_address,
+	.ndo_tx_timeout		= bfin_mac_timeout,
+	.ndo_set_multicast_list	= bfin_mac_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= bfin_mac_poll,
+#endif
+};
+
 /*
  *
  * this makes the board clean up everything that it can
@@ -1086,15 +1100,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 	/* Fill in the fields of the device structure with ethernet values. */
 	ether_setup(ndev);
 
-	ndev->open = bfin_mac_open;
-	ndev->stop = bfin_mac_close;
-	ndev->hard_start_xmit = bfin_mac_hard_start_xmit;
-	ndev->set_mac_address = bfin_mac_set_mac_address;
-	ndev->tx_timeout = bfin_mac_timeout;
-	ndev->set_multicast_list = bfin_mac_set_multicast_list;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	ndev->poll_controller = bfin_mac_poll;
-#endif
+	ndev->netdev_ops = &bfin_mac_netdev_ops;
 	ndev->ethtool_ops = &bfin_mac_ethtool_ops;
 
 	spin_lock_init(&lp->lock);
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 9d268be0b670..d47839184a06 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -3427,8 +3427,8 @@ static int __devinit
 bnx2_request_firmware(struct bnx2 *bp)
 {
 	const char *mips_fw_file, *rv2p_fw_file;
-	const struct bnx2_mips_fw_file *mips;
-	const struct bnx2_rv2p_fw_file *rv2p;
+	const struct bnx2_mips_fw_file *mips_fw;
+	const struct bnx2_rv2p_fw_file *rv2p_fw;
 	int rc;
 
 	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
@@ -3452,21 +3452,21 @@ bnx2_request_firmware(struct bnx2 *bp)
 		       rv2p_fw_file);
 		return rc;
 	}
-	mips = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
-	rv2p = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
-	if (bp->mips_firmware->size < sizeof(*mips) ||
-	    check_mips_fw_entry(bp->mips_firmware, &mips->com) ||
-	    check_mips_fw_entry(bp->mips_firmware, &mips->cp) ||
-	    check_mips_fw_entry(bp->mips_firmware, &mips->rxp) ||
-	    check_mips_fw_entry(bp->mips_firmware, &mips->tpat) ||
-	    check_mips_fw_entry(bp->mips_firmware, &mips->txp)) {
+	mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+	rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+	if (bp->mips_firmware->size < sizeof(*mips_fw) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->com) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->cp) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->rxp) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
 		printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
 		       mips_fw_file);
 		return -EINVAL;
 	}
-	if (bp->rv2p_firmware->size < sizeof(*rv2p) ||
-	    check_fw_section(bp->rv2p_firmware, &rv2p->proc1.rv2p, 8, true) ||
-	    check_fw_section(bp->rv2p_firmware, &rv2p->proc2.rv2p, 8, true)) {
+	if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
+	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
+	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
 		printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
 		       rv2p_fw_file);
 		return -EINVAL;
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 8dc6fbb9a41e..553a89919778 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -370,8 +370,6 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
 
 	if (arp->op_code == htons(ARPOP_REPLY)) {
 		/* update rx hash table for this ARP */
-		printk("rar: update orig %s bond_dev %s\n", orig_dev->name,
-		       bond_dev->name);
 		bond = netdev_priv(bond_dev);
 		rlb_update_entry_from_arp(bond, arp);
 		pr_debug("Server received an ARP Reply from client\n");
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 99610f358c40..63369b6b14d4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2570,7 +2570,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
 		if (!targets[i])
-			continue;
+			break;
 		pr_debug("basa: target %x\n", targets[i]);
 		if (list_empty(&bond->vlan_list)) {
 			pr_debug("basa: empty vlan: arp_send\n");
@@ -2677,7 +2677,6 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
 	int i;
 	__be32 *targets = bond->params.arp_targets;
 
-	targets = bond->params.arp_targets;
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
 		pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n",
 			&sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip));
@@ -3303,7 +3302,7 @@ static void bond_info_show_master(struct seq_file *seq)
 
 		for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
 			if (!bond->params.arp_targets[i])
-				continue;
+				break;
 			if (printed)
 				seq_printf(seq, ",");
 			seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 18cf4787874c..d28731535226 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -684,17 +684,15 @@ static ssize_t bonding_store_arp_targets(struct device *d,
 			goto out;
 		}
 		/* look for an empty slot to put the target in, and check for dupes */
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
 			if (targets[i] == newtarget) { /* duplicate */
 				printk(KERN_ERR DRV_NAME
 				       ": %s: ARP target %pI4 is already present\n",
 				       bond->dev->name, &newtarget);
-				if (done)
-					targets[i] = 0;
 				ret = -EINVAL;
 				goto out;
 			}
-			if (targets[i] == 0 && !done) {
+			if (targets[i] == 0) {
 				printk(KERN_INFO DRV_NAME
 				       ": %s: adding ARP target %pI4.\n",
 				       bond->dev->name, &newtarget);
@@ -720,12 +718,16 @@ static ssize_t bonding_store_arp_targets(struct device *d,
 			goto out;
 		}
 
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
 			if (targets[i] == newtarget) {
+				int j;
 				printk(KERN_INFO DRV_NAME
 				       ": %s: removing ARP target %pI4.\n",
 				       bond->dev->name, &newtarget);
-				targets[i] = 0;
+				for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
+					targets[j] = targets[j+1];
+
+				targets[j] = 0;
 				done = 1;
 			}
 		}
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index c9806c58b2fd..7a18dc7e5c7f 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -257,6 +257,23 @@ struct transceiver_ops transceivers[] =
 
 struct transceiver_ops* transceiver = &transceivers[0];
 
+static const struct net_device_ops e100_netdev_ops = {
+	.ndo_open		= e100_open,
+	.ndo_stop		= e100_close,
+	.ndo_start_xmit		= e100_send_packet,
+	.ndo_tx_timeout		= e100_tx_timeout,
+	.ndo_get_stats		= e100_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_do_ioctl		= e100_ioctl,
+	.ndo_set_mac_address	= e100_set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_config		= e100_set_config,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= e100_netpoll,
+#endif
+};
+
 #define tx_done(dev) (*R_DMA_CH0_CMD == 0)
 
 /*
@@ -300,19 +317,8 @@ etrax_ethernet_init(void)
 
 	/* fill in our handlers so the network layer can talk to us in the future */
 
-	dev->open               = e100_open;
-	dev->hard_start_xmit    = e100_send_packet;
-	dev->stop               = e100_close;
-	dev->get_stats          = e100_get_stats;
-	dev->set_multicast_list = set_multicast_list;
-	dev->set_mac_address    = e100_set_mac_address;
 	dev->ethtool_ops	= &e100_ethtool_ops;
-	dev->do_ioctl           = e100_ioctl;
-	dev->set_config		= e100_set_config;
-	dev->tx_timeout         = e100_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = e100_netpoll;
-#endif
+	dev->netdev_ops		= &e100_netdev_ops;
 
 	spin_lock_init(&np->lock);
 	spin_lock_init(&np->led_lock);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index ab0e5febef83..7ea48414c6cb 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1117,8 +1117,8 @@ static void cxgb_down(struct adapter *adapter)
 	spin_unlock_irq(&adapter->work_lock);
 
 	free_irq_resources(adapter);
-	flush_workqueue(cxgb3_wq);	/* wait for external IRQ handler */
 	quiesce_rx(adapter);
+	flush_workqueue(cxgb3_wq);	/* wait for external IRQ handler */
 }
 
 static void schedule_chk_task(struct adapter *adap)
@@ -1187,6 +1187,9 @@ static int offload_close(struct t3cdev *tdev)
 
 	sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
 
+	/* Flush work scheduled while releasing TIDs */
+	flush_scheduled_work();
+
 	tdev->lldev = NULL;
 	cxgb3_set_dummy_ops(tdev);
 	t3_tp_set_offload_mode(adapter, 0);
@@ -1232,6 +1235,10 @@ static int cxgb_close(struct net_device *dev)
 	struct port_info *pi = netdev_priv(dev);
 	struct adapter *adapter = pi->adapter;
 
+	
+	if (!adapter->open_device_map)
+		return 0;
+
 	/* Stop link fault interrupts */
 	t3_xgm_intr_disable(adapter, pi->port_id);
 	t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
@@ -1247,8 +1254,7 @@ static int cxgb_close(struct net_device *dev)
 	spin_unlock_irq(&adapter->work_lock);
 
 	if (!(adapter->open_device_map & PORT_MASK))
-		cancel_rearming_delayed_workqueue(cxgb3_wq,
-						  &adapter->adap_check_task);
+		cancel_delayed_work_sync(&adapter->adap_check_task);
 
 	if (!adapter->open_device_map)
 		cxgb_down(adapter);
@@ -2493,6 +2499,7 @@ static void check_link_status(struct adapter *adapter)
 
 		spin_lock_irq(&adapter->work_lock);
 		if (p->link_fault) {
+			t3_link_fault(adapter, i);
 			spin_unlock_irq(&adapter->work_lock);
 			continue;
 		}
@@ -2554,9 +2561,7 @@ static void t3_adap_check_task(struct work_struct *work)
 
 	adapter->check_task_cnt++;
 
-	/* Check link status for PHYs without interrupts */
-	if (p->linkpoll_period)
-		check_link_status(adapter);
+	check_link_status(adapter);
 
 	/* Accumulate MAC stats if needed */
 	if (!p->linkpoll_period ||
@@ -2680,21 +2685,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
 	spin_unlock(&adapter->work_lock);
 }
 
-static void link_fault_task(struct work_struct *work)
-{
-	struct adapter *adapter = container_of(work, struct adapter,
-					       link_fault_handler_task);
-	int i;
-
-	for_each_port(adapter, i) {
-		struct net_device *netdev = adapter->port[i];
-		struct port_info *pi = netdev_priv(netdev);
-
-		if (pi->link_fault)
-			t3_link_fault(adapter, i);
-	}
-}
-
 void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
 {
 	struct net_device *netdev = adapter->port[port_id];
@@ -2702,7 +2692,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
 
 	spin_lock(&adapter->work_lock);
 	pi->link_fault = 1;
-	queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
 	spin_unlock(&adapter->work_lock);
 }
 
@@ -2838,6 +2827,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
 	struct adapter *adapter = pci_get_drvdata(pdev);
 	int ret;
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	ret = t3_adapter_error(adapter, 0);
 
 	/* Request a slot reset. */
@@ -2932,8 +2924,13 @@ static int __devinit cxgb_enable_msix(struct adapter *adap)
 	while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
 		vectors = err;
 
-	if (!err && vectors < (adap->params.nports + 1))
+	if (err < 0)
+		pci_disable_msix(adap->pdev);
+
+	if (!err && vectors < (adap->params.nports + 1)) {
+		pci_disable_msix(adap->pdev);
 		err = -1;
+	}
 
 	if (!err) {
 		for (i = 0; i < vectors; ++i)
@@ -3082,7 +3079,6 @@ static int __devinit init_one(struct pci_dev *pdev,
 
 	INIT_LIST_HEAD(&adapter->adapter_list);
 	INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
-	INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
 	INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
 	INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
 
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 31ed31a3428b..e1bd690ff831 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1202,7 +1202,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
 	struct cphy *phy = &pi->phy;
 	struct cmac *mac = &pi->mac;
 	struct link_config *lc = &pi->link_config;
-	int force_link_down = 0;
 
 	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
@@ -1218,14 +1217,9 @@ void t3_link_changed(struct adapter *adapter, int port_id)
 		status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
 		if (status & F_LINKFAULTCHANGE) {
 			mac->stats.link_faults++;
-			force_link_down = 1;
+			pi->link_fault = 1;
 		}
 		t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
-
-		if (force_link_down) {
-			t3_os_link_fault_handler(adapter, port_id);
-			return;
-		}
 	}
 
 	if (lc->requested_fc & PAUSE_AUTONEG)
@@ -1292,9 +1286,6 @@ void t3_link_fault(struct adapter *adapter, int port_id)
 		/* Account link faults only when the phy reports a link up */
 		if (link_ok)
 			mac->stats.link_faults++;
-
-		msleep(1000);
-		t3_os_link_fault_handler(adapter, port_id);
 	} else {
 		if (link_ok)
 			t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 861c867fca87..b62405a69180 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1010,6 +1010,17 @@ static void lance_set_multicast_retry(unsigned long _opaque)
 	lance_set_multicast(dev);
 }
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_set_multicast_list	= lance_set_multicast,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init dec_lance_probe(struct device *bdev, const int type)
 {
 	static unsigned version_printed;
@@ -1223,12 +1234,8 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
 
 	printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq);
 
-	dev->open = &lance_open;
-	dev->stop = &lance_close;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->tx_timeout = &lance_tx_timeout;
+	dev->netdev_ops = &lance_netdev_ops;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &lance_set_multicast;
 
 	/* lp->ll is the location of the registers for lance card */
 	lp->ll = ll;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ddc5c533e89c..6a46ceed9436 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -156,8 +156,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 static int e1000_resume(struct pci_dev *pdev);
 #endif
 static void e1000_shutdown(struct pci_dev *pdev);
@@ -3834,7 +3834,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
 	unsigned int count = 0;
-	bool cleaned;
 	unsigned int total_tx_bytes=0, total_tx_packets=0;
 
 	i = tx_ring->next_to_clean;
@@ -3843,7 +3842,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
-		for (cleaned = false; !cleaned; count++) {
+		bool cleaned = false;
+		for ( ; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
@@ -3871,7 +3871,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+	if (unlikely(count && netif_carrier_ok(netdev) &&
 		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
@@ -4601,7 +4601,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 	return 0;
 }
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4664,22 +4664,18 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 		ew32(WUC, E1000_WUC_PME_EN);
 		ew32(WUFC, wufc);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
 	} else {
 		ew32(WUC, 0);
 		ew32(WUFC, 0);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
 	e1000_release_manageability(adapter);
 
+	*enable_wake = !!wufc;
+
 	/* make sure adapter isn't asleep if manageability is enabled */
-	if (adapter->en_mng_pt) {
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	}
+	if (adapter->en_mng_pt)
+		*enable_wake = true;
 
 	if (hw->phy_type == e1000_phy_igp_3)
 		e1000_phy_powerdown_workaround(hw);
@@ -4693,12 +4689,29 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	pci_disable_device(pdev);
 
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
 	return 0;
 }
 
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __e1000_shutdown(pdev, &wake);
+	if (retval)
+		return retval;
+
+	if (wake) {
+		pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
+	return 0;
+}
+
 static int e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4753,7 +4766,14 @@ static int e1000_resume(struct pci_dev *pdev)
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-	e1000_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+
+	__e1000_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, wake);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 409b58cad0e5..ca82f19a7ed1 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -621,7 +621,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
 	unsigned int count = 0;
-	bool cleaned;
 	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 
 	i = tx_ring->next_to_clean;
@@ -630,7 +629,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
-		for (cleaned = 0; !cleaned; count++) {
+		bool cleaned = false;
+		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
@@ -661,8 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-	if (cleaned && netif_carrier_ok(netdev) &&
-		     e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+	if (count && netif_carrier_ok(netdev) &&
+	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
 		 */
@@ -4346,7 +4346,7 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 	}
 }
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4409,20 +4409,16 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 		ew32(WUC, E1000_WUC_PME_EN);
 		ew32(WUFC, wufc);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
 	} else {
 		ew32(WUC, 0);
 		ew32(WUFC, 0);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
+	*enable_wake = !!wufc;
+
 	/* make sure adapter isn't asleep if manageability is enabled */
-	if (adapter->flags & FLAG_MNG_PT_ENABLED) {
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	}
+	if (adapter->flags & FLAG_MNG_PT_ENABLED)
+		*enable_wake = true;
 
 	if (adapter->hw.phy.type == e1000_phy_igp_3)
 		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
@@ -4435,6 +4431,26 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	pci_disable_device(pdev);
 
+	return 0;
+}
+
+static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
+{
+	if (sleep && wake) {
+		pci_prepare_to_sleep(pdev);
+		return;
+	}
+
+	pci_wake_from_d3(pdev, wake);
+	pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
+                                    bool wake)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+
 	/*
 	 * The pci-e switch on some quad port adapters will report a
 	 * correctable error when the MAC transitions from D0 to D3.  To
@@ -4450,14 +4466,12 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
 		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
 
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		e1000_power_off(pdev, sleep, wake);
 
 		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
 	} else {
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		e1000_power_off(pdev, sleep, wake);
 	}
-
-	return 0;
 }
 
 static void e1000e_disable_l1aspm(struct pci_dev *pdev)
@@ -4486,6 +4500,18 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __e1000_shutdown(pdev, &wake);
+	if (!retval)
+		e1000_complete_shutdown(pdev, true, wake);
+
+	return retval;
+}
+
 static int e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4549,7 +4575,12 @@ static int e1000_resume(struct pci_dev *pdev)
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-	e1000_suspend(pdev, PMSG_SUSPEND);
+	bool wake = false;
+
+	__e1000_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF)
+		e1000_complete_shutdown(pdev, false, wake);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index ac0c5b438e0a..604c844d0769 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3080,7 +3080,8 @@ static const struct net_device_ops ehea_netdev_ops = {
 	.ndo_change_mtu		= ehea_change_mtu,
 	.ndo_vlan_rx_register	= ehea_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= ehea_vlan_rx_add_vid,
-	.ndo_vlan_rx_kill_vid	= ehea_vlan_rx_kill_vid
+	.ndo_vlan_rx_kill_vid	= ehea_vlan_rx_kill_vid,
+	.ndo_tx_timeout		= ehea_tx_watchdog,
 };
 
 struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
@@ -3142,7 +3143,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 		      | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
 		      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
 		      | NETIF_F_LLTX;
-	dev->tx_timeout = &ehea_tx_watchdog;
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
 	INIT_WORK(&port->reset_task, ehea_reset_port);
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 51ead7941f83..5210bb1027cc 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -542,6 +542,8 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
 	}
 	spin_unlock_bh(&eql->queue.lock);
 
+	dev_put(slave_dev);
+
 	return ret;
 }
 
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index a515acccc61f..682e7f0b5581 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1240,6 +1240,7 @@ static void __inline__ fec_phy_ack_intr(void)
 	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
 	*icrp = 0x0d000000;
 }
+#endif
 
 #ifdef CONFIG_M5272
 static void __inline__ fec_get_mac(struct net_device *dev)
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d37465020bcc..11d5db16ed9c 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3745,14 +3745,14 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
 			mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
 		}
 		spin_unlock_irqrestore(&np->lock, flags);
-		__napi_complete(napi);
+		napi_complete(napi);
 		return rx_work;
 	}
 
 	if (rx_work < budget) {
 		/* re-enable interrupts
 		   (msix not enabled in napi) */
-		__napi_complete(napi);
+		napi_complete(napi);
 
 		writel(np->irqmask, base + NvRegIrqMask);
 	}
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index b037ce9857bf..a9cbc3191a2a 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1019,6 +1019,22 @@ out_put_phy:
 #define IS_FEC(match) 0
 #endif
 
+static const struct net_device_ops fs_enet_netdev_ops = {
+	.ndo_open		= fs_enet_open,
+	.ndo_stop		= fs_enet_close,
+	.ndo_get_stats		= fs_enet_get_stats,
+	.ndo_start_xmit		= fs_enet_start_xmit,
+	.ndo_tx_timeout		= fs_timeout,
+	.ndo_set_multicast_list	= fs_set_multicast_list,
+	.ndo_do_ioctl		= fs_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= fs_enet_netpoll,
+#endif
+};
+
 static int __devinit fs_enet_probe(struct of_device *ofdev,
                                    const struct of_device_id *match)
 {
@@ -1093,22 +1109,13 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
 	fep->tx_ring = fpi->tx_ring;
 	fep->rx_ring = fpi->rx_ring;
 
-	ndev->open = fs_enet_open;
-	ndev->hard_start_xmit = fs_enet_start_xmit;
-	ndev->tx_timeout = fs_timeout;
+	ndev->netdev_ops = &fs_enet_netdev_ops;
 	ndev->watchdog_timeo = 2 * HZ;
-	ndev->stop = fs_enet_close;
-	ndev->get_stats = fs_enet_get_stats;
-	ndev->set_multicast_list = fs_set_multicast_list;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	ndev->poll_controller = fs_enet_netpoll;
-#endif
 	if (fpi->use_napi)
 		netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi,
 		               fpi->napi_weight);
 
 	ndev->ethtool_ops = &fs_ethtool_ops;
-	ndev->do_ioctl = fs_ioctl;
 
 	init_timer(&fep->phy_timer_list);
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 65f55877be95..b2c49679bba7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1583,8 +1583,10 @@ static void gfar_reset_task(struct work_struct *work)
 	struct net_device *dev = priv->ndev;
 
 	if (dev->flags & IFF_UP) {
+		netif_stop_queue(dev);
 		stop_gfar(dev);
 		startup_gfar(dev);
+		netif_start_queue(dev);
 	}
 
 	netif_tx_schedule_all(dev);
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 77e4b5b52fc8..806533c831c7 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2686,6 +2686,32 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	return 0;
 }
 
+static const struct net_device_ops emac_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_close,
+	.ndo_get_stats		= emac_stats,
+	.ndo_set_multicast_list	= emac_set_multicast_list,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_tx_timeout		= emac_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_start_xmit		= emac_start_xmit,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
+static const struct net_device_ops emac_gige_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_close,
+	.ndo_get_stats		= emac_stats,
+	.ndo_set_multicast_list	= emac_set_multicast_list,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_tx_timeout		= emac_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_start_xmit		= emac_start_xmit_sg,
+	.ndo_change_mtu		= emac_change_mtu,
+};
+
 static int __devinit emac_probe(struct of_device *ofdev,
 				const struct of_device_id *match)
 {
@@ -2827,23 +2853,14 @@ static int __devinit emac_probe(struct of_device *ofdev,
 	if (err != 0)
 		goto err_detach_tah;
 
-	/* Fill in the driver function table */
-	ndev->open = &emac_open;
 	if (dev->tah_dev)
 		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-	ndev->tx_timeout = &emac_tx_timeout;
 	ndev->watchdog_timeo = 5 * HZ;
-	ndev->stop = &emac_close;
-	ndev->get_stats = &emac_stats;
-	ndev->set_multicast_list = &emac_set_multicast_list;
-	ndev->do_ioctl = &emac_ioctl;
 	if (emac_phy_supports_gige(dev->phy_mode)) {
-		ndev->hard_start_xmit = &emac_start_xmit_sg;
-		ndev->change_mtu = &emac_change_mtu;
+		ndev->netdev_ops = &emac_gige_netdev_ops;
 		dev->commac.ops = &emac_commac_sg_ops;
-	} else {
-		ndev->hard_start_xmit = &emac_start_xmit;
-	}
+	} else
+		ndev->netdev_ops = &emac_netdev_ops;
 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 
 	netif_carrier_off(ndev);
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index f4c315b5a900..472f3f124840 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -111,7 +111,7 @@ void igb_clear_vfta(struct e1000_hw *hw)
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 {
 	array_wr32(E1000_VFTA, offset, value);
 	wrfl();
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index a34de5269637..1d690b4c9ae4 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -66,7 +66,6 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 s32  igb_check_alt_mac_addr(struct e1000_hw *hw);
 void igb_reset_adaptive(struct e1000_hw *hw);
 void igb_update_adaptive(struct e1000_hw *hw);
-void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
 
 bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
 
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index fe71c7ddaa05..840782fb5736 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -188,7 +188,7 @@ out:
  *  returns SUCCESS if it successfully received a message notification and
  *  copied it into the receive buffer.
  **/
-s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
 {
 	struct e1000_mbx_info *mbx = &hw->mbx;
 	s32 ret_val = -E1000_ERR_MBX;
@@ -214,7 +214,7 @@ out:
  *  returns SUCCESS if it successfully copied message into the buffer and
  *  received an ack to that message within delay * timeout period
  **/
-s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
 {
 	struct e1000_mbx_info *mbx = &hw->mbx;
 	s32 ret_val = 0;
@@ -232,19 +232,6 @@ out:
 	return ret_val;
 }
 
-/**
- *  e1000_init_mbx_ops_generic - Initialize NVM function pointers
- *  @hw: pointer to the HW structure
- *
- *  Setups up the function pointers to no-op functions
- **/
-void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
-{
-	struct e1000_mbx_info *mbx = &hw->mbx;
-	mbx->ops.read_posted = igb_read_posted_mbx;
-	mbx->ops.write_posted = igb_write_posted_mbx;
-}
-
 static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
 {
 	u32 mbvficr = rd32(E1000_MBVFICR);
diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h
index 6ec9890a8f7a..ebc02ea3f198 100644
--- a/drivers/net/igb/e1000_mbx.h
+++ b/drivers/net/igb/e1000_mbx.h
@@ -67,8 +67,6 @@
 
 s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16);
 s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 igb_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
-s32 igb_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
 s32 igb_check_for_msg(struct e1000_hw *, u16);
 s32 igb_check_for_ack(struct e1000_hw *, u16);
 s32 igb_check_for_rst(struct e1000_hw *, u16);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 6b0697c565b9..08c801490c72 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -152,14 +152,13 @@ static struct notifier_block dca_notifier = {
 /* for netdump / net console */
 static void igb_netpoll(struct net_device *);
 #endif
-
 #ifdef CONFIG_PCI_IOV
-static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *,
-                               const char *, size_t);
-static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *,
-                               char *);
-DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs);
-#endif
+static unsigned int max_vfs = 0;
+module_param(max_vfs, uint, 0);
+MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
+                 "per physical function");
+#endif /* CONFIG_PCI_IOV */
+
 static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
 		     pci_channel_state_t);
 static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
@@ -671,6 +670,21 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
 
 	/* If we can't do MSI-X, try MSI */
 msi_only:
+#ifdef CONFIG_PCI_IOV
+	/* disable SR-IOV for non MSI-X configurations */
+	if (adapter->vf_data) {
+		struct e1000_hw *hw = &adapter->hw;
+		/* disable iov and allow time for transactions to clear */
+		pci_disable_sriov(adapter->pdev);
+		msleep(500);
+
+		kfree(adapter->vf_data);
+		adapter->vf_data = NULL;
+		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+		msleep(100);
+		dev_info(&adapter->pdev->dev, "IOV Disabled\n");
+	}
+#endif
 	adapter->num_rx_queues = 1;
 	adapter->num_tx_queues = 1;
 	if (!pci_enable_msi(adapter->pdev))
@@ -1238,6 +1252,46 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	if (err)
 		goto err_sw_init;
 
+#ifdef CONFIG_PCI_IOV
+	/* since iov functionality isn't critical to base device function we
+	 * can accept failure.  If it fails we don't allow iov to be enabled */
+	if (hw->mac.type == e1000_82576) {
+		/* 82576 supports a maximum of 7 VFs in addition to the PF */
+		unsigned int num_vfs = (max_vfs > 7) ? 7 : max_vfs;
+		int i;
+		unsigned char mac_addr[ETH_ALEN];
+
+		if (num_vfs) {
+			adapter->vf_data = kcalloc(num_vfs,
+						sizeof(struct vf_data_storage),
+						GFP_KERNEL);
+			if (!adapter->vf_data) {
+				dev_err(&pdev->dev,
+				        "Could not allocate VF private data - "
+					"IOV enable failed\n");
+			} else {
+				err = pci_enable_sriov(pdev, num_vfs);
+				if (!err) {
+					adapter->vfs_allocated_count = num_vfs;
+					dev_info(&pdev->dev,
+					         "%d vfs allocated\n",
+					         num_vfs);
+					for (i = 0;
+					     i < adapter->vfs_allocated_count;
+					     i++) {
+						random_ether_addr(mac_addr);
+						igb_set_vf_mac(adapter, i,
+						               mac_addr);
+					}
+				} else {
+					kfree(adapter->vf_data);
+					adapter->vf_data = NULL;
+				}
+			}
+		}
+	}
+
+#endif
 	/* setup the private structure */
 	err = igb_sw_init(adapter);
 	if (err)
@@ -1397,19 +1451,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	if (err)
 		goto err_register;
 
-#ifdef CONFIG_PCI_IOV
-	/* since iov functionality isn't critical to base device function we
-	 * can accept failure.  If it fails we don't allow iov to be enabled */
-	if (hw->mac.type == e1000_82576) {
-		err = pci_enable_sriov(pdev, 0);
-		if (!err)
-			err = device_create_file(&netdev->dev,
-			                         &dev_attr_num_vfs);
-		if (err)
-			dev_err(&pdev->dev, "Failed to initialize IOV\n");
-	}
-
-#endif
 #ifdef CONFIG_IGB_DCA
 	if (dca_add_requester(&pdev->dev) == 0) {
 		adapter->flags |= IGB_FLAG_DCA_ENABLED;
@@ -5422,89 +5463,4 @@ static void igb_vmm_control(struct igb_adapter *adapter)
 	igb_vmdq_set_replication_pf(hw, true);
 }
 
-#ifdef CONFIG_PCI_IOV
-static ssize_t igb_show_num_vfs(struct device *dev,
-                                struct device_attribute *attr, char *buf)
-{
-	struct igb_adapter *adapter = netdev_priv(to_net_dev(dev));
-
-	return sprintf(buf, "%d\n", adapter->vfs_allocated_count);
-}
-
-static ssize_t igb_set_num_vfs(struct device *dev,
-                               struct device_attribute *attr,
-                               const char *buf, size_t count)
-{
-	struct net_device *netdev = to_net_dev(dev);
-	struct igb_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
-	struct pci_dev *pdev = adapter->pdev;
-	unsigned int num_vfs, i;
-	unsigned char mac_addr[ETH_ALEN];
-	int err;
-
-	sscanf(buf, "%u", &num_vfs);
-
-	if (num_vfs > 7)
-		num_vfs = 7;
-
-	/* value unchanged do nothing */
-	if (num_vfs == adapter->vfs_allocated_count)
-		return count;
-
-	if (netdev->flags & IFF_UP)
-		igb_close(netdev);
-
-	igb_reset_interrupt_capability(adapter);
-	igb_free_queues(adapter);
-	adapter->tx_ring = NULL;
-	adapter->rx_ring = NULL;
-	adapter->vfs_allocated_count = 0;
-
-	/* reclaim resources allocated to VFs since we are changing count */
-	if (adapter->vf_data) {
-		/* disable iov and allow time for transactions to clear */
-		pci_disable_sriov(pdev);
-		msleep(500);
-
-		kfree(adapter->vf_data);
-		adapter->vf_data = NULL;
-		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
-		msleep(100);
-		dev_info(&pdev->dev, "IOV Disabled\n");
-	}
-
-	if (num_vfs) {
-		adapter->vf_data = kcalloc(num_vfs,
-		                           sizeof(struct vf_data_storage),
-		                           GFP_KERNEL);
-		if (!adapter->vf_data) {
-			dev_err(&pdev->dev, "Could not allocate VF private "
-				"data - IOV enable failed\n");
-		} else {
-			err = pci_enable_sriov(pdev, num_vfs);
-			if (!err) {
-				adapter->vfs_allocated_count = num_vfs;
-				dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs);
-				for (i = 0; i < adapter->vfs_allocated_count; i++) {
-					random_ether_addr(mac_addr);
-					igb_set_vf_mac(adapter, i, mac_addr);
-				}
-			} else {
-				kfree(adapter->vf_data);
-				adapter->vf_data = NULL;
-			}
-		}
-	}
-
-	igb_set_interrupt_capability(adapter);
-	igb_alloc_queues(adapter);
-	igb_reset(adapter);
-
-	if (netdev->flags & IFF_UP)
-		igb_open(netdev);
-
-	return count;
-}
-#endif /* CONFIG_PCI_IOV */
 /* igb_main.c */
diff --git a/drivers/net/igbvf/Makefile b/drivers/net/igbvf/Makefile
new file mode 100644
index 000000000000..c2f150d8f2d9
--- /dev/null
+++ b/drivers/net/igbvf/Makefile
@@ -0,0 +1,38 @@
+################################################################################
+#
+# Intel(R) 82576 Virtual Function Linux driver
+# Copyright(c) 2009 Intel Corporation.
+#
+# 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".
+#
+# Contact Information:
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+################################################################################
+
+#
+# Makefile for the Intel(R) 82576 VF ethernet driver
+#
+
+obj-$(CONFIG_IGBVF) += igbvf.o
+
+igbvf-objs := vf.o \
+              mbx.o \
+              ethtool.o \
+              netdev.o
+
diff --git a/drivers/net/igbvf/defines.h b/drivers/net/igbvf/defines.h
new file mode 100644
index 000000000000..88a47537518a
--- /dev/null
+++ b/drivers/net/igbvf/defines.h
@@ -0,0 +1,125 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 1999 - 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_DEFINES_H_
+#define _E1000_DEFINES_H_
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* IVAR valid bit */
+#define E1000_IVAR_VALID        0x80
+
+/* Receive Descriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
+#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
+#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+
+#define E1000_RXDEXT_STATERR_CE    0x01000000
+#define E1000_RXDEXT_STATERR_SE    0x02000000
+#define E1000_RXDEXT_STATERR_SEQ   0x04000000
+#define E1000_RXDEXT_STATERR_CXE   0x10000000
+#define E1000_RXDEXT_STATERR_TCPE  0x20000000
+#define E1000_RXDEXT_STATERR_IPE   0x40000000
+#define E1000_RXDEXT_STATERR_RXE   0x80000000
+
+
+/* Same mask, but for extended and packet split descriptors */
+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
+    E1000_RXDEXT_STATERR_CE  |            \
+    E1000_RXDEXT_STATERR_SE  |            \
+    E1000_RXDEXT_STATERR_SEQ |            \
+    E1000_RXDEXT_STATERR_CXE |            \
+    E1000_RXDEXT_STATERR_RXE)
+
+/* Device Control */
+#define E1000_CTRL_RST      0x04000000  /* Global reset */
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
+#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
+
+#define MAX_JUMBO_FRAME_SIZE    0x3F00
+
+/* 802.1q VLAN Packet Size */
+#define VLAN_TAG_SIZE              4    /* 802.3ac tag (not DMA'd) */
+
+/* Error Codes */
+#define E1000_SUCCESS      0
+#define E1000_ERR_CONFIG   3
+#define E1000_ERR_MAC_INIT 5
+#define E1000_ERR_MBX      15
+
+#ifndef ETH_ADDR_LEN
+#define ETH_ADDR_LEN                 6
+#endif
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK                  0x00000F00
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000
+#define E1000_SRRCTL_DESCTYPE_MASK                      0x0E000000
+#define E1000_SRRCTL_DROP_EN                            0x80000000
+
+#define E1000_SRRCTL_BSIZEPKT_MASK      0x0000007F
+#define E1000_SRRCTL_BSIZEHDR_MASK      0x00003F00
+
+/* Additional Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */
+#define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */
+
+/* Direct Cache Access (DCA) definitions */
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+
+#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
+
+#endif /* _E1000_DEFINES_H_ */
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
new file mode 100644
index 000000000000..1dcaa6905312
--- /dev/null
+++ b/drivers/net/igbvf/ethtool.c
@@ -0,0 +1,540 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* ethtool support for igbvf */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include "igbvf.h"
+#include <linux/if_vlan.h>
+
+
+struct igbvf_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+	int base_stat_offset;
+};
+
+#define IGBVF_STAT(current, base) \
+		sizeof(((struct igbvf_adapter *)0)->current), \
+		offsetof(struct igbvf_adapter, current), \
+		offsetof(struct igbvf_adapter, base)
+
+static const struct igbvf_stats igbvf_gstrings_stats[] = {
+	{ "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) },
+	{ "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) },
+	{ "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+	{ "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) },
+	{ "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) },
+	{ "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
+	{ "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
+	{ "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
+	{ "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+	{ "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
+	{ "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },
+	{ "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) },
+	{ "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) },
+};
+
+#define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats)
+
+static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Link test   (on/offline)"
+};
+
+#define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test)
+
+static int igbvf_get_settings(struct net_device *netdev,
+                              struct ethtool_cmd *ecmd)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 status;
+
+	ecmd->supported   = SUPPORTED_1000baseT_Full;
+
+	ecmd->advertising = ADVERTISED_1000baseT_Full;
+
+	ecmd->port = -1;
+	ecmd->transceiver = XCVR_DUMMY1;
+
+	status = er32(STATUS);
+	if (status & E1000_STATUS_LU) {
+		if (status & E1000_STATUS_SPEED_1000)
+			ecmd->speed = 1000;
+		else if (status & E1000_STATUS_SPEED_100)
+			ecmd->speed = 100;
+		else
+			ecmd->speed = 10;
+
+		if (status & E1000_STATUS_FD)
+			ecmd->duplex = DUPLEX_FULL;
+		else
+			ecmd->duplex = DUPLEX_HALF;
+	} else {
+		ecmd->speed = -1;
+		ecmd->duplex = -1;
+	}
+
+	ecmd->autoneg = AUTONEG_DISABLE;
+
+	return 0;
+}
+
+static u32 igbvf_get_link(struct net_device *netdev)
+{
+	return netif_carrier_ok(netdev);
+}
+
+static int igbvf_set_settings(struct net_device *netdev,
+                              struct ethtool_cmd *ecmd)
+{
+	return -EOPNOTSUPP;
+}
+
+static void igbvf_get_pauseparam(struct net_device *netdev,
+                                 struct ethtool_pauseparam *pause)
+{
+	return;
+}
+
+static int igbvf_set_pauseparam(struct net_device *netdev,
+                                struct ethtool_pauseparam *pause)
+{
+	return -EOPNOTSUPP;
+}
+
+static u32 igbvf_get_tx_csum(struct net_device *netdev)
+{
+	return ((netdev->features & NETIF_F_IP_CSUM) != 0);
+}
+
+static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
+{
+	if (data)
+		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+	else
+		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+	return 0;
+}
+
+static int igbvf_set_tso(struct net_device *netdev, u32 data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int i;
+	struct net_device *v_netdev;
+
+	if (data) {
+		netdev->features |= NETIF_F_TSO;
+		netdev->features |= NETIF_F_TSO6;
+	} else {
+		netdev->features &= ~NETIF_F_TSO;
+		netdev->features &= ~NETIF_F_TSO6;
+		/* disable TSO on all VLANs if they're present */
+		if (!adapter->vlgrp)
+			goto tso_out;
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			v_netdev = vlan_group_get_device(adapter->vlgrp, i);
+			if (!v_netdev)
+				continue;
+
+			v_netdev->features &= ~NETIF_F_TSO;
+			v_netdev->features &= ~NETIF_F_TSO6;
+			vlan_group_set_device(adapter->vlgrp, i, v_netdev);
+		}
+	}
+
+tso_out:
+	dev_info(&adapter->pdev->dev, "TSO is %s\n",
+	         data ? "Enabled" : "Disabled");
+	adapter->flags |= FLAG_TSO_FORCE;
+	return 0;
+}
+
+static u32 igbvf_get_msglevel(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	return adapter->msg_enable;
+}
+
+static void igbvf_set_msglevel(struct net_device *netdev, u32 data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	adapter->msg_enable = data;
+}
+
+static int igbvf_get_regs_len(struct net_device *netdev)
+{
+#define IGBVF_REGS_LEN 8
+	return IGBVF_REGS_LEN * sizeof(u32);
+}
+
+static void igbvf_get_regs(struct net_device *netdev,
+                           struct ethtool_regs *regs, void *p)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 *regs_buff = p;
+	u8 revision_id;
+
+	memset(p, 0, IGBVF_REGS_LEN * sizeof(u32));
+
+	pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id);
+
+	regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device;
+
+	regs_buff[0] = er32(CTRL);
+	regs_buff[1] = er32(STATUS);
+
+	regs_buff[2] = er32(RDLEN(0));
+	regs_buff[3] = er32(RDH(0));
+	regs_buff[4] = er32(RDT(0));
+
+	regs_buff[5] = er32(TDLEN(0));
+	regs_buff[6] = er32(TDH(0));
+	regs_buff[7] = er32(TDT(0));
+}
+
+static int igbvf_get_eeprom_len(struct net_device *netdev)
+{
+	return 0;
+}
+
+static int igbvf_get_eeprom(struct net_device *netdev,
+                            struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	return -EOPNOTSUPP;
+}
+
+static int igbvf_set_eeprom(struct net_device *netdev,
+                            struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	return -EOPNOTSUPP;
+}
+
+static void igbvf_get_drvinfo(struct net_device *netdev,
+                              struct ethtool_drvinfo *drvinfo)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	char firmware_version[32] = "N/A";
+
+	strncpy(drvinfo->driver,  igbvf_driver_name, 32);
+	strncpy(drvinfo->version, igbvf_driver_version, 32);
+	strncpy(drvinfo->fw_version, firmware_version, 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->regdump_len = igbvf_get_regs_len(netdev);
+	drvinfo->eedump_len = igbvf_get_eeprom_len(netdev);
+}
+
+static void igbvf_get_ringparam(struct net_device *netdev,
+                                struct ethtool_ringparam *ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+
+	ring->rx_max_pending = IGBVF_MAX_RXD;
+	ring->tx_max_pending = IGBVF_MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rx_ring->count;
+	ring->tx_pending = tx_ring->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static int igbvf_set_ringparam(struct net_device *netdev,
+                               struct ethtool_ringparam *ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *temp_ring;
+	int err;
+	u32 new_rx_count, new_tx_count;
+
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+		return -EINVAL;
+
+	new_rx_count = max(ring->rx_pending, (u32)IGBVF_MIN_RXD);
+	new_rx_count = min(new_rx_count, (u32)IGBVF_MAX_RXD);
+	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
+
+	new_tx_count = max(ring->tx_pending, (u32)IGBVF_MIN_TXD);
+	new_tx_count = min(new_tx_count, (u32)IGBVF_MAX_TXD);
+	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
+
+	if ((new_tx_count == adapter->tx_ring->count) &&
+	    (new_rx_count == adapter->rx_ring->count)) {
+		/* nothing to do */
+		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);
+
+	/*
+	 * We can't just free everything and then setup again,
+	 * because the ISRs in MSI-X mode get passed pointers
+	 * to the tx and rx ring structs.
+	 */
+	if (new_tx_count != adapter->tx_ring->count) {
+		memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring));
+
+		temp_ring->count = new_tx_count;
+		err = igbvf_setup_tx_resources(adapter, temp_ring);
+		if (err)
+			goto err_setup;
+
+		igbvf_free_tx_resources(adapter->tx_ring);
+
+		memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring));
+	}
+
+	if (new_rx_count != adapter->rx_ring->count) {
+		memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring));
+
+		temp_ring->count = new_rx_count;
+		err = igbvf_setup_rx_resources(adapter, temp_ring);
+		if (err)
+			goto err_setup;
+
+		igbvf_free_rx_resources(adapter->rx_ring);
+
+		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);
+	vfree(temp_ring);
+	return err;
+}
+
+static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	*data = 0;
+
+	hw->mac.ops.check_for_link(hw);
+
+	if (!(er32(STATUS) & E1000_STATUS_LU))
+		*data = 1;
+
+	return *data;
+}
+
+static int igbvf_get_self_test_count(struct net_device *netdev)
+{
+	return IGBVF_TEST_LEN;
+}
+
+static int igbvf_get_stats_count(struct net_device *netdev)
+{
+	return IGBVF_GLOBAL_STATS_LEN;
+}
+
+static void igbvf_diag_test(struct net_device *netdev,
+                            struct ethtool_test *eth_test, u64 *data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	set_bit(__IGBVF_TESTING, &adapter->state);
+
+	/*
+	 * Link test performed before hardware reset so autoneg doesn't
+	 * interfere with test result
+	 */
+	if (igbvf_link_test(adapter, &data[0]))
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+
+	clear_bit(__IGBVF_TESTING, &adapter->state);
+	msleep_interruptible(4 * 1000);
+}
+
+static void igbvf_get_wol(struct net_device *netdev,
+                          struct ethtool_wolinfo *wol)
+{
+	wol->supported = 0;
+	wol->wolopts = 0;
+
+	return;
+}
+
+static int igbvf_set_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
+{
+	return -EOPNOTSUPP;
+}
+
+static int igbvf_phys_id(struct net_device *netdev, u32 data)
+{
+	return 0;
+}
+
+static int igbvf_get_coalesce(struct net_device *netdev,
+                              struct ethtool_coalesce *ec)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->itr_setting <= 3)
+		ec->rx_coalesce_usecs = adapter->itr_setting;
+	else
+		ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
+
+	return 0;
+}
+
+static int igbvf_set_coalesce(struct net_device *netdev,
+                              struct ethtool_coalesce *ec)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) ||
+	    ((ec->rx_coalesce_usecs > 3) &&
+	     (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) ||
+	    (ec->rx_coalesce_usecs == 2))
+		return -EINVAL;
+
+	/* convert to rate of irq's per second */
+	if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
+		adapter->itr = IGBVF_START_ITR;
+		adapter->itr_setting = ec->rx_coalesce_usecs;
+	} else {
+		adapter->itr = ec->rx_coalesce_usecs << 2;
+		adapter->itr_setting = adapter->itr;
+	}
+
+	writel(adapter->itr,
+	       hw->hw_addr + adapter->rx_ring[0].itr_register);
+
+	return 0;
+}
+
+static int igbvf_nway_reset(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	if (netif_running(netdev))
+		igbvf_reinit_locked(adapter);
+	return 0;
+}
+
+
+static void igbvf_get_ethtool_stats(struct net_device *netdev,
+                                    struct ethtool_stats *stats,
+                                    u64 *data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	igbvf_update_stats(adapter);
+	for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+		char *p = (char *)adapter +
+		          igbvf_gstrings_stats[i].stat_offset;
+		char *b = (char *)adapter +
+		          igbvf_gstrings_stats[i].base_stat_offset;
+		data[i] = ((igbvf_gstrings_stats[i].sizeof_stat ==
+		            sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) :
+		            (*(u32 *)p - *(u32 *)b));
+	}
+
+}
+
+static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
+                              u8 *data)
+{
+	u8 *p = data;
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_TEST:
+		memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test));
+		break;
+	case ETH_SS_STATS:
+		for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, igbvf_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+static const struct ethtool_ops igbvf_ethtool_ops = {
+	.get_settings		= igbvf_get_settings,
+	.set_settings		= igbvf_set_settings,
+	.get_drvinfo		= igbvf_get_drvinfo,
+	.get_regs_len		= igbvf_get_regs_len,
+	.get_regs		= igbvf_get_regs,
+	.get_wol		= igbvf_get_wol,
+	.set_wol		= igbvf_set_wol,
+	.get_msglevel		= igbvf_get_msglevel,
+	.set_msglevel		= igbvf_set_msglevel,
+	.nway_reset		= igbvf_nway_reset,
+	.get_link		= igbvf_get_link,
+	.get_eeprom_len		= igbvf_get_eeprom_len,
+	.get_eeprom		= igbvf_get_eeprom,
+	.set_eeprom		= igbvf_set_eeprom,
+	.get_ringparam		= igbvf_get_ringparam,
+	.set_ringparam		= igbvf_set_ringparam,
+	.get_pauseparam		= igbvf_get_pauseparam,
+	.set_pauseparam		= igbvf_set_pauseparam,
+	.get_tx_csum		= igbvf_get_tx_csum,
+	.set_tx_csum		= igbvf_set_tx_csum,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
+	.get_tso		= ethtool_op_get_tso,
+	.set_tso		= igbvf_set_tso,
+	.self_test		= igbvf_diag_test,
+	.get_strings		= igbvf_get_strings,
+	.phys_id		= igbvf_phys_id,
+	.get_ethtool_stats	= igbvf_get_ethtool_stats,
+	.self_test_count	= igbvf_get_self_test_count,
+	.get_stats_count	= igbvf_get_stats_count,
+	.get_coalesce		= igbvf_get_coalesce,
+	.set_coalesce		= igbvf_set_coalesce,
+};
+
+void igbvf_set_ethtool_ops(struct net_device *netdev)
+{
+	/* have to "undeclare" const on this struct to remove warnings */
+	SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igbvf_ethtool_ops);
+}
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
new file mode 100644
index 000000000000..4bff35e46871
--- /dev/null
+++ b/drivers/net/igbvf/igbvf.h
@@ -0,0 +1,332 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* Linux PRO/1000 Ethernet Driver main header file */
+
+#ifndef _IGBVF_H_
+#define _IGBVF_H_
+
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+
+
+#include "vf.h"
+
+/* Forward declarations */
+struct igbvf_info;
+struct igbvf_adapter;
+
+/* Interrupt defines */
+#define IGBVF_START_ITR                 648 /* ~6000 ints/sec */
+
+/* Interrupt modes, as used by the IntMode paramter */
+#define IGBVF_INT_MODE_LEGACY           0
+#define IGBVF_INT_MODE_MSI              1
+#define IGBVF_INT_MODE_MSIX             2
+
+/* Tx/Rx descriptor defines */
+#define IGBVF_DEFAULT_TXD               256
+#define IGBVF_MAX_TXD                   4096
+#define IGBVF_MIN_TXD                   80
+
+#define IGBVF_DEFAULT_RXD               256
+#define IGBVF_MAX_RXD                   4096
+#define IGBVF_MIN_RXD                   80
+
+#define IGBVF_MIN_ITR_USECS             10 /* 100000 irq/sec */
+#define IGBVF_MAX_ITR_USECS             10000 /* 100    irq/sec */
+
+/* RX descriptor control thresholds.
+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
+ *           descriptors available in its onboard memory.
+ *           Setting this to 0 disables RX descriptor prefetch.
+ * HTHRESH - MAC will only prefetch if there are at least this many descriptors
+ *           available in host memory.
+ *           If PTHRESH is 0, this should also be 0.
+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
+ *           descriptors until either it has this many to write back, or the
+ *           ITR timer expires.
+ */
+#define IGBVF_RX_PTHRESH                16
+#define IGBVF_RX_HTHRESH                8
+#define IGBVF_RX_WTHRESH                1
+
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE      1522
+
+#define IGBVF_FC_PAUSE_TIME             0x0680 /* 858 usec */
+
+/* How many Tx Descriptors do we need to call netif_wake_queue ? */
+#define IGBVF_TX_QUEUE_WAKE             32
+/* How many Rx Buffers do we bundle into one write to the hardware ? */
+#define IGBVF_RX_BUFFER_WRITE           16 /* Must be power of 2 */
+
+#define AUTO_ALL_MODES                  0
+#define IGBVF_EEPROM_APME               0x0400
+
+#define IGBVF_MNG_VLAN_NONE             (-1)
+
+/* Number of packet split data buffers (not including the header buffer) */
+#define PS_PAGE_BUFFERS                 (MAX_PS_BUFFERS - 1)
+
+enum igbvf_boards {
+	board_vf,
+};
+
+struct igbvf_queue_stats {
+	u64 packets;
+	u64 bytes;
+};
+
+/*
+ * wrappers around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct igbvf_buffer {
+	dma_addr_t dma;
+	struct sk_buff *skb;
+	union {
+		/* Tx */
+		struct {
+			unsigned long time_stamp;
+			u16 length;
+			u16 next_to_watch;
+		};
+		/* Rx */
+		struct {
+			struct page *page;
+			u64 page_dma;
+			unsigned int page_offset;
+		};
+	};
+	struct page *page;
+};
+
+union igbvf_desc {
+	union e1000_adv_rx_desc rx_desc;
+	union e1000_adv_tx_desc tx_desc;
+	struct e1000_adv_tx_context_desc tx_context_desc;
+};
+
+struct igbvf_ring {
+	struct igbvf_adapter *adapter;  /* backlink */
+	union igbvf_desc *desc;         /* pointer to ring memory  */
+	dma_addr_t dma;                 /* phys address of ring    */
+	unsigned int size;              /* length of ring in bytes */
+	unsigned int count;             /* number of desc. in ring */
+
+	u16 next_to_use;
+	u16 next_to_clean;
+
+	u16 head;
+	u16 tail;
+
+	/* array of buffer information structs */
+	struct igbvf_buffer *buffer_info;
+	struct napi_struct napi;
+
+	char name[IFNAMSIZ + 5];
+	u32 eims_value;
+	u32 itr_val;
+	u16 itr_register;
+	int set_itr;
+
+	struct sk_buff *rx_skb_top;
+
+	struct igbvf_queue_stats stats;
+};
+
+/* board specific private data structure */
+struct igbvf_adapter {
+	struct timer_list watchdog_timer;
+	struct timer_list blink_timer;
+
+	struct work_struct reset_task;
+	struct work_struct watchdog_task;
+
+	const struct igbvf_info *ei;
+
+	struct vlan_group *vlgrp;
+	u32 bd_number;
+	u32 rx_buffer_len;
+	u32 polling_interval;
+	u16 mng_vlan_id;
+	u16 link_speed;
+	u16 link_duplex;
+
+	spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
+
+	/* track device up/down/testing state */
+	unsigned long state;
+
+	/* Interrupt Throttle Rate */
+	u32 itr;
+	u32 itr_setting;
+	u16 tx_itr;
+	u16 rx_itr;
+
+	/*
+	 * Tx
+	 */
+	struct igbvf_ring *tx_ring /* One per active queue */
+	____cacheline_aligned_in_smp;
+
+	unsigned long tx_queue_len;
+	unsigned int restart_queue;
+	u32 txd_cmd;
+
+	bool detect_tx_hung;
+	u8 tx_timeout_factor;
+
+	u32 tx_int_delay;
+	u32 tx_abs_int_delay;
+
+	unsigned int total_tx_bytes;
+	unsigned int total_tx_packets;
+	unsigned int total_rx_bytes;
+	unsigned int total_rx_packets;
+
+	/* Tx stats */
+	u32 tx_timeout_count;
+	u32 tx_fifo_head;
+	u32 tx_head_addr;
+	u32 tx_fifo_size;
+	u32 tx_dma_failed;
+
+	/*
+	 * Rx
+	 */
+	struct igbvf_ring *rx_ring;
+
+	u32 rx_int_delay;
+	u32 rx_abs_int_delay;
+
+	/* Rx stats */
+	u64 hw_csum_err;
+	u64 hw_csum_good;
+	u64 rx_hdr_split;
+	u32 alloc_rx_buff_failed;
+	u32 rx_dma_failed;
+
+	unsigned int rx_ps_hdr_size;
+	u32 max_frame_size;
+	u32 min_frame_size;
+
+	/* OS defined structs */
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct net_device_stats net_stats;
+	spinlock_t stats_lock;      /* prevent concurrent stats updates */
+
+	/* structs defined in e1000_hw.h */
+	struct e1000_hw hw;
+
+	/* The VF counters don't clear on read so we have to get a base
+	 * count on driver start up and always subtract that base on
+	 * on the first update, thus the flag..
+	 */
+	struct e1000_vf_stats stats;
+	u64 zero_base;
+
+	struct igbvf_ring test_tx_ring;
+	struct igbvf_ring test_rx_ring;
+	u32 test_icr;
+
+	u32 msg_enable;
+	struct msix_entry *msix_entries;
+	int int_mode;
+	u32 eims_enable_mask;
+	u32 eims_other;
+	u32 int_counter0;
+	u32 int_counter1;
+
+	u32 eeprom_wol;
+	u32 wol;
+	u32 pba;
+
+	bool fc_autoneg;
+
+	unsigned long led_status;
+
+	unsigned int flags;
+};
+
+struct igbvf_info {
+	enum e1000_mac_type     mac;
+	unsigned int            flags;
+	u32                     pba;
+	void                    (*init_ops)(struct e1000_hw *);
+	s32                     (*get_variants)(struct igbvf_adapter *);
+};
+
+/* hardware capability, feature, and workaround flags */
+#define FLAG_HAS_HW_VLAN_FILTER           (1 << 0)
+#define FLAG_HAS_JUMBO_FRAMES             (1 << 1)
+#define FLAG_MSI_ENABLED                  (1 << 2)
+#define FLAG_RX_CSUM_ENABLED              (1 << 3)
+#define FLAG_TSO_FORCE                    (1 << 4)
+
+#define IGBVF_RX_DESC_ADV(R, i)     \
+	(&((((R).desc))[i].rx_desc))
+#define IGBVF_TX_DESC_ADV(R, i)     \
+	(&((((R).desc))[i].tx_desc))
+#define IGBVF_TX_CTXTDESC_ADV(R, i) \
+	(&((((R).desc))[i].tx_context_desc))
+
+enum igbvf_state_t {
+	__IGBVF_TESTING,
+	__IGBVF_RESETTING,
+	__IGBVF_DOWN
+};
+
+enum latency_range {
+	lowest_latency = 0,
+	low_latency = 1,
+	bulk_latency = 2,
+	latency_invalid = 255
+};
+
+extern char igbvf_driver_name[];
+extern const char igbvf_driver_version[];
+
+extern void igbvf_check_options(struct igbvf_adapter *);
+extern void igbvf_set_ethtool_ops(struct net_device *);
+
+extern int igbvf_up(struct igbvf_adapter *);
+extern void igbvf_down(struct igbvf_adapter *);
+extern void igbvf_reinit_locked(struct igbvf_adapter *);
+extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern void igbvf_free_rx_resources(struct igbvf_ring *);
+extern void igbvf_free_tx_resources(struct igbvf_ring *);
+extern void igbvf_update_stats(struct igbvf_adapter *);
+
+extern unsigned int copybreak;
+
+#endif /* _IGBVF_H_ */
diff --git a/drivers/net/igbvf/mbx.c b/drivers/net/igbvf/mbx.c
new file mode 100644
index 000000000000..819a8ec901dc
--- /dev/null
+++ b/drivers/net/igbvf/mbx.c
@@ -0,0 +1,350 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "mbx.h"
+
+/**
+ *  e1000_poll_for_msg - Wait for message notification
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if it successfully received a message notification
+ **/
+static s32 e1000_poll_for_msg(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_msg)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_msg(hw)) {
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ *  e1000_poll_for_ack - Wait for message acknowledgement
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if it successfully received a message acknowledgement
+ **/
+static s32 e1000_poll_for_ack(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_ack)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_ack(hw)) {
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ *  e1000_read_posted_mbx - Wait for message notification and receive message
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully received a message notification and
+ *  copied it into the receive buffer.
+ **/
+static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!mbx->ops.read)
+		goto out;
+
+	ret_val = e1000_poll_for_msg(hw);
+
+	/* if ack received read message, otherwise we timed out */
+	if (!ret_val)
+		ret_val = mbx->ops.read(hw, msg, size);
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer and
+ *  received an ack to that message within delay * timeout period
+ **/
+static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	/* exit if we either can't write or there isn't a defined timeout */
+	if (!mbx->ops.write || !mbx->timeout)
+		goto out;
+
+	/* send msg*/
+	ret_val = mbx->ops.write(hw, msg, size);
+
+	/* if msg sent wait until we receive an ack */
+	if (!ret_val)
+		ret_val = e1000_poll_for_ack(hw);
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_read_v2p_mailbox - read v2p mailbox
+ *  @hw: pointer to the HW structure
+ *
+ *  This function is used to read the v2p mailbox without losing the read to
+ *  clear status bits.
+ **/
+static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
+{
+	u32 v2p_mailbox = er32(V2PMAILBOX(0));
+
+	v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
+	hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
+
+	return v2p_mailbox;
+}
+
+/**
+ *  e1000_check_for_bit_vf - Determine if a status bit was set
+ *  @hw: pointer to the HW structure
+ *  @mask: bitmask for bits to be tested and cleared
+ *
+ *  This function is used to check for the read to clear bits within
+ *  the V2P mailbox.
+ **/
+static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
+{
+	u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (v2p_mailbox & mask)
+		ret_val = E1000_SUCCESS;
+
+	hw->dev_spec.vf.v2p_mailbox &= ~mask;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_msg_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.reqs++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_ack_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.acks++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_rst_vf - checks to see if the PF has reset
+ *  @hw: pointer to the HW structure
+ *
+ *  returns true if the PF has set the reset done bit or else false
+ **/
+static s32 e1000_check_for_rst_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
+	                                 E1000_V2PMAILBOX_RSTI))) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.rsts++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
+ *  @hw: pointer to the HW structure
+ *
+ *  return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	/* Take ownership of the buffer */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+
+	/* reserve mailbox for vf use */
+	if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
+		ret_val = E1000_SUCCESS;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_write_mbx_vf - Write a message to the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	s32 err;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	err = e1000_obtain_mbx_lock_vf(hw);
+	if (err)
+		goto out_no_write;
+
+	/* flush any ack or msg as we are going to overwrite mailbox */
+	e1000_check_for_ack_vf(hw);
+	e1000_check_for_msg_vf(hw);
+
+	/* copy the caller specified message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		array_ew32(VMBMEM(0), i, msg[i]);
+
+	/* update stats */
+	hw->mbx.stats.msgs_tx++;
+
+	/* Drop VFU and interrupt the PF to tell it a message has been sent */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
+
+out_no_write:
+	return err;
+}
+
+/**
+ *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfuly read message from buffer
+ **/
+static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	s32 err;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	err = e1000_obtain_mbx_lock_vf(hw);
+	if (err)
+		goto out_no_read;
+
+	/* copy the message from the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		msg[i] = array_er32(VMBMEM(0), i);
+
+	/* Acknowledge receipt and release mailbox, then we're done */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
+
+	/* update stats */
+	hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+	return err;
+}
+
+/**
+ *  e1000_init_mbx_params_vf - set initial values for vf mailbox
+ *  @hw: pointer to the HW structure
+ *
+ *  Initializes the hw->mbx struct to correct values for vf mailbox
+ */
+s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+
+	/* start mailbox as timed out and let the reset_hw call set the timeout
+	 * value to being communications */
+	mbx->timeout = 0;
+	mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
+
+	mbx->size = E1000_VFMAILBOX_SIZE;
+
+	mbx->ops.read = e1000_read_mbx_vf;
+	mbx->ops.write = e1000_write_mbx_vf;
+	mbx->ops.read_posted = e1000_read_posted_mbx;
+	mbx->ops.write_posted = e1000_write_posted_mbx;
+	mbx->ops.check_for_msg = e1000_check_for_msg_vf;
+	mbx->ops.check_for_ack = e1000_check_for_ack_vf;
+	mbx->ops.check_for_rst = e1000_check_for_rst_vf;
+
+	mbx->stats.msgs_tx = 0;
+	mbx->stats.msgs_rx = 0;
+	mbx->stats.reqs = 0;
+	mbx->stats.acks = 0;
+	mbx->stats.rsts = 0;
+
+	return E1000_SUCCESS;
+}
+
diff --git a/drivers/net/igbvf/mbx.h b/drivers/net/igbvf/mbx.h
new file mode 100644
index 000000000000..4938609dbfb5
--- /dev/null
+++ b/drivers/net/igbvf/mbx.h
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 1999 - 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "vf.h"
+
+#define E1000_V2PMAILBOX_REQ   0x00000001 /* Request for PF Ready bit */
+#define E1000_V2PMAILBOX_ACK   0x00000002 /* Ack PF message received */
+#define E1000_V2PMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
+#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
+#define E1000_V2PMAILBOX_RSTI  0x00000040 /* PF has reset indication */
+#define E1000_V2PMAILBOX_RSTD  0x00000080 /* PF has indicated reset done */
+#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
+
+#define E1000_VFMAILBOX_SIZE   16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF.  The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
+                                               * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
+                                               * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
+                                                 clear to send requests */
+
+/* We have a total wait time of 1s for vf mailbox posted messages */
+#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mailbox timeout */
+#define E1000_VF_MBX_INIT_DELAY   500  /* usec delay between retries */
+
+#define E1000_VT_MSGINFO_SHIFT    16
+/* bits 23:16 are used for exra info for certain messages */
+#define E1000_VT_MSGINFO_MASK     (0xFF << E1000_VT_MSGINFO_SHIFT)
+
+#define E1000_VF_RESET            0x01 /* VF requests reset */
+#define E1000_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */
+#define E1000_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
+#define E1000_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
+#define E1000_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+
+#define E1000_PF_CONTROL_MSG      0x0100 /* PF control message */
+
+void e1000_init_mbx_ops_generic(struct e1000_hw *hw);
+s32 e1000_init_mbx_params_vf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
new file mode 100644
index 000000000000..b774666ad3cf
--- /dev/null
+++ b/drivers/net/igbvf/netdev.c
@@ -0,0 +1,2922 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/pm_qos_params.h>
+
+#include "igbvf.h"
+
+#define DRV_VERSION "1.0.0-k0"
+char igbvf_driver_name[] = "igbvf";
+const char igbvf_driver_version[] = DRV_VERSION;
+static const char igbvf_driver_string[] =
+				"Intel(R) Virtual Function Network Driver";
+static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+
+static int igbvf_poll(struct napi_struct *napi, int budget);
+static void igbvf_reset(struct igbvf_adapter *);
+static void igbvf_set_interrupt_capability(struct igbvf_adapter *);
+static void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
+
+static struct igbvf_info igbvf_vf_info = {
+	.mac                    = e1000_vfadapt,
+	.flags                  = FLAG_HAS_JUMBO_FRAMES
+	                          | FLAG_RX_CSUM_ENABLED,
+	.pba                    = 10,
+	.init_ops               = e1000_init_function_pointers_vf,
+};
+
+static const struct igbvf_info *igbvf_info_tbl[] = {
+	[board_vf]              = &igbvf_vf_info,
+};
+
+/**
+ * igbvf_desc_unused - calculate if we have unused descriptors
+ **/
+static int igbvf_desc_unused(struct igbvf_ring *ring)
+{
+	if (ring->next_to_clean > ring->next_to_use)
+		return ring->next_to_clean - ring->next_to_use - 1;
+
+	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
+}
+
+/**
+ * igbvf_receive_skb - helper function to handle Rx indications
+ * @adapter: board private structure
+ * @status: descriptor status field as written by hardware
+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @skb: pointer to sk_buff to be indicated to stack
+ **/
+static void igbvf_receive_skb(struct igbvf_adapter *adapter,
+                              struct net_device *netdev,
+                              struct sk_buff *skb,
+                              u32 status, u16 vlan)
+{
+	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
+		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+		                         le16_to_cpu(vlan) &
+		                         E1000_RXD_SPC_VLAN_MASK);
+	else
+		netif_receive_skb(skb);
+
+	netdev->last_rx = jiffies;
+}
+
+static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
+                                         u32 status_err, struct sk_buff *skb)
+{
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* Ignore Checksum bit is set or checksum is disabled through ethtool */
+	if ((status_err & E1000_RXD_STAT_IXSM))
+		return;
+	/* TCP/UDP checksum error bit is set */
+	if (status_err &
+	    (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+		/* let the stack verify checksum errors */
+		adapter->hw_csum_err++;
+		return;
+	}
+	/* It must be a TCP or UDP packet with a valid checksum */
+	if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	adapter->hw_csum_good++;
+}
+
+/**
+ * igbvf_alloc_rx_buffers - Replace used receive buffers; packet split
+ * @rx_ring: address of ring structure to repopulate
+ * @cleaned_count: number of buffers to repopulate
+ **/
+static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
+                                   int cleaned_count)
+{
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	union e1000_adv_rx_desc *rx_desc;
+	struct igbvf_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	int bufsz;
+
+	i = rx_ring->next_to_use;
+	buffer_info = &rx_ring->buffer_info[i];
+
+	if (adapter->rx_ps_hdr_size)
+		bufsz = adapter->rx_ps_hdr_size;
+	else
+		bufsz = adapter->rx_buffer_len;
+	bufsz += NET_IP_ALIGN;
+
+	while (cleaned_count--) {
+		rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+
+		if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
+			if (!buffer_info->page) {
+				buffer_info->page = alloc_page(GFP_ATOMIC);
+				if (!buffer_info->page) {
+					adapter->alloc_rx_buff_failed++;
+					goto no_buffers;
+				}
+				buffer_info->page_offset = 0;
+			} else {
+				buffer_info->page_offset ^= PAGE_SIZE / 2;
+			}
+			buffer_info->page_dma =
+				pci_map_page(pdev, buffer_info->page,
+				             buffer_info->page_offset,
+				             PAGE_SIZE / 2,
+				             PCI_DMA_FROMDEVICE);
+		}
+
+		if (!buffer_info->skb) {
+			skb = netdev_alloc_skb(netdev, bufsz);
+			if (!skb) {
+				adapter->alloc_rx_buff_failed++;
+				goto no_buffers;
+			}
+
+			/* Make buffer alignment 2 beyond a 16 byte boundary
+			 * this will result in a 16 byte aligned IP header after
+			 * the 14 byte MAC header is removed
+			 */
+			skb_reserve(skb, NET_IP_ALIGN);
+
+			buffer_info->skb = skb;
+			buffer_info->dma = pci_map_single(pdev, skb->data,
+			                                  bufsz,
+			                                  PCI_DMA_FROMDEVICE);
+		}
+		/* Refresh the desc even if buffer_addrs didn't change because
+		 * each write-back erases this info. */
+		if (adapter->rx_ps_hdr_size) {
+			rx_desc->read.pkt_addr =
+			     cpu_to_le64(buffer_info->page_dma);
+			rx_desc->read.hdr_addr = cpu_to_le64(buffer_info->dma);
+		} else {
+			rx_desc->read.pkt_addr =
+			     cpu_to_le64(buffer_info->dma);
+			rx_desc->read.hdr_addr = 0;
+		}
+
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+		buffer_info = &rx_ring->buffer_info[i];
+	}
+
+no_buffers:
+	if (rx_ring->next_to_use != i) {
+		rx_ring->next_to_use = i;
+		if (i == 0)
+			i = (rx_ring->count - 1);
+		else
+			i--;
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+	}
+}
+
+/**
+ * igbvf_clean_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ **/
+static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
+                               int *work_done, int work_to_do)
+{
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	union e1000_adv_rx_desc *rx_desc, *next_rxd;
+	struct igbvf_buffer *buffer_info, *next_buffer;
+	struct sk_buff *skb;
+	bool cleaned = false;
+	int cleaned_count = 0;
+	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int i;
+	u32 length, hlen, staterr;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+	while (staterr & E1000_RXD_STAT_DD) {
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		buffer_info = &rx_ring->buffer_info[i];
+
+		/* HW will not DMA in data larger than the given buffer, even
+		 * if it parses the (NFS, of course) header to be larger.  In
+		 * that case, it fills the header buffer and spills the rest
+		 * into the page.
+		 */
+		hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info) &
+		  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+		if (hlen > adapter->rx_ps_hdr_size)
+			hlen = adapter->rx_ps_hdr_size;
+
+		length = le16_to_cpu(rx_desc->wb.upper.length);
+		cleaned = true;
+		cleaned_count++;
+
+		skb = buffer_info->skb;
+		prefetch(skb->data - NET_IP_ALIGN);
+		buffer_info->skb = NULL;
+		if (!adapter->rx_ps_hdr_size) {
+			pci_unmap_single(pdev, buffer_info->dma,
+			                 adapter->rx_buffer_len,
+			                 PCI_DMA_FROMDEVICE);
+			buffer_info->dma = 0;
+			skb_put(skb, length);
+			goto send_up;
+		}
+
+		if (!skb_shinfo(skb)->nr_frags) {
+			pci_unmap_single(pdev, buffer_info->dma,
+			                 adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+			                 PCI_DMA_FROMDEVICE);
+			skb_put(skb, hlen);
+		}
+
+		if (length) {
+			pci_unmap_page(pdev, buffer_info->page_dma,
+			               PAGE_SIZE / 2,
+			               PCI_DMA_FROMDEVICE);
+			buffer_info->page_dma = 0;
+
+			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+			                   buffer_info->page,
+			                   buffer_info->page_offset,
+			                   length);
+
+			if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+			    (page_count(buffer_info->page) != 1))
+				buffer_info->page = NULL;
+			else
+				get_page(buffer_info->page);
+
+			skb->len += length;
+			skb->data_len += length;
+			skb->truesize += length;
+		}
+send_up:
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+		next_rxd = IGBVF_RX_DESC_ADV(*rx_ring, i);
+		prefetch(next_rxd);
+		next_buffer = &rx_ring->buffer_info[i];
+
+		if (!(staterr & E1000_RXD_STAT_EOP)) {
+			buffer_info->skb = next_buffer->skb;
+			buffer_info->dma = next_buffer->dma;
+			next_buffer->skb = skb;
+			next_buffer->dma = 0;
+			goto next_desc;
+		}
+
+		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+			dev_kfree_skb_irq(skb);
+			goto next_desc;
+		}
+
+		total_bytes += skb->len;
+		total_packets++;
+
+		igbvf_rx_checksum_adv(adapter, staterr, skb);
+
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		igbvf_receive_skb(adapter, netdev, skb, staterr,
+		                  rx_desc->wb.upper.vlan);
+
+		netdev->last_rx = jiffies;
+
+next_desc:
+		rx_desc->wb.upper.status_error = 0;
+
+		/* return some buffers to hardware, one at a time is too slow */
+		if (cleaned_count >= IGBVF_RX_BUFFER_WRITE) {
+			igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+
+		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	}
+
+	rx_ring->next_to_clean = i;
+	cleaned_count = igbvf_desc_unused(rx_ring);
+
+	if (cleaned_count)
+		igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+
+	adapter->total_rx_packets += total_packets;
+	adapter->total_rx_bytes += total_bytes;
+	adapter->net_stats.rx_bytes += total_bytes;
+	adapter->net_stats.rx_packets += total_packets;
+	return cleaned;
+}
+
+static void igbvf_put_txbuf(struct igbvf_adapter *adapter,
+                            struct igbvf_buffer *buffer_info)
+{
+	buffer_info->dma = 0;
+	if (buffer_info->skb) {
+		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+		              DMA_TO_DEVICE);
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+	buffer_info->time_stamp = 0;
+}
+
+static void igbvf_print_tx_hang(struct igbvf_adapter *adapter)
+{
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	unsigned int i = tx_ring->next_to_clean;
+	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
+	union e1000_adv_tx_desc *eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+	/* detected Tx unit hang */
+	dev_err(&adapter->pdev->dev,
+	        "Detected Tx Unit Hang:\n"
+	        "  TDH                  <%x>\n"
+	        "  TDT                  <%x>\n"
+	        "  next_to_use          <%x>\n"
+	        "  next_to_clean        <%x>\n"
+	        "buffer_info[next_to_clean]:\n"
+	        "  time_stamp           <%lx>\n"
+	        "  next_to_watch        <%x>\n"
+	        "  jiffies              <%lx>\n"
+	        "  next_to_watch.status <%x>\n",
+	        readl(adapter->hw.hw_addr + tx_ring->head),
+	        readl(adapter->hw.hw_addr + tx_ring->tail),
+	        tx_ring->next_to_use,
+	        tx_ring->next_to_clean,
+	        tx_ring->buffer_info[eop].time_stamp,
+	        eop,
+	        jiffies,
+	        eop_desc->wb.status);
+}
+
+/**
+ * igbvf_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+int igbvf_setup_tx_resources(struct igbvf_adapter *adapter,
+                             struct igbvf_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size;
+
+	size = sizeof(struct igbvf_buffer) * tx_ring->count;
+	tx_ring->buffer_info = vmalloc(size);
+	if (!tx_ring->buffer_info)
+		goto err;
+	memset(tx_ring->buffer_info, 0, size);
+
+	/* round up to nearest 4K */
+	tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
+	tx_ring->size = ALIGN(tx_ring->size, 4096);
+
+	tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+					     &tx_ring->dma);
+
+	if (!tx_ring->desc)
+		goto err;
+
+	tx_ring->adapter = adapter;
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+
+	return 0;
+err:
+	vfree(tx_ring->buffer_info);
+	dev_err(&adapter->pdev->dev,
+	        "Unable to allocate memory for the transmit descriptor ring\n");
+	return -ENOMEM;
+}
+
+/**
+ * igbvf_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int igbvf_setup_rx_resources(struct igbvf_adapter *adapter,
+			     struct igbvf_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size, desc_len;
+
+	size = sizeof(struct igbvf_buffer) * rx_ring->count;
+	rx_ring->buffer_info = vmalloc(size);
+	if (!rx_ring->buffer_info)
+		goto err;
+	memset(rx_ring->buffer_info, 0, size);
+
+	desc_len = sizeof(union e1000_adv_rx_desc);
+
+	/* Round up to nearest 4K */
+	rx_ring->size = rx_ring->count * desc_len;
+	rx_ring->size = ALIGN(rx_ring->size, 4096);
+
+	rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+	                                     &rx_ring->dma);
+
+	if (!rx_ring->desc)
+		goto err;
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	rx_ring->adapter = adapter;
+
+	return 0;
+
+err:
+	vfree(rx_ring->buffer_info);
+	rx_ring->buffer_info = NULL;
+	dev_err(&adapter->pdev->dev,
+	        "Unable to allocate memory for the receive descriptor ring\n");
+	return -ENOMEM;
+}
+
+/**
+ * igbvf_clean_tx_ring - Free Tx Buffers
+ * @tx_ring: ring to be cleaned
+ **/
+static void igbvf_clean_tx_ring(struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = tx_ring->adapter;
+	struct igbvf_buffer *buffer_info;
+	unsigned long size;
+	unsigned int i;
+
+	if (!tx_ring->buffer_info)
+		return;
+
+	/* Free all the Tx ring sk_buffs */
+	for (i = 0; i < tx_ring->count; i++) {
+		buffer_info = &tx_ring->buffer_info[i];
+		igbvf_put_txbuf(adapter, buffer_info);
+	}
+
+	size = sizeof(struct igbvf_buffer) * tx_ring->count;
+	memset(tx_ring->buffer_info, 0, size);
+
+	/* Zero out the descriptor ring */
+	memset(tx_ring->desc, 0, tx_ring->size);
+
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+
+	writel(0, adapter->hw.hw_addr + tx_ring->head);
+	writel(0, adapter->hw.hw_addr + tx_ring->tail);
+}
+
+/**
+ * igbvf_free_tx_resources - Free Tx Resources per Queue
+ * @tx_ring: ring to free resources from
+ *
+ * Free all transmit software resources
+ **/
+void igbvf_free_tx_resources(struct igbvf_ring *tx_ring)
+{
+	struct pci_dev *pdev = tx_ring->adapter->pdev;
+
+	igbvf_clean_tx_ring(tx_ring);
+
+	vfree(tx_ring->buffer_info);
+	tx_ring->buffer_info = NULL;
+
+	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+	tx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_clean_rx_ring - Free Rx Buffers per Queue
+ * @adapter: board private structure
+ **/
+static void igbvf_clean_rx_ring(struct igbvf_ring *rx_ring)
+{
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct igbvf_buffer *buffer_info;
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned long size;
+	unsigned int i;
+
+	if (!rx_ring->buffer_info)
+		return;
+
+	/* Free all the Rx ring sk_buffs */
+	for (i = 0; i < rx_ring->count; i++) {
+		buffer_info = &rx_ring->buffer_info[i];
+		if (buffer_info->dma) {
+			if (adapter->rx_ps_hdr_size){
+				pci_unmap_single(pdev, buffer_info->dma,
+				                 adapter->rx_ps_hdr_size,
+				                 PCI_DMA_FROMDEVICE);
+			} else {
+				pci_unmap_single(pdev, buffer_info->dma,
+				                 adapter->rx_buffer_len,
+				                 PCI_DMA_FROMDEVICE);
+			}
+			buffer_info->dma = 0;
+		}
+
+		if (buffer_info->skb) {
+			dev_kfree_skb(buffer_info->skb);
+			buffer_info->skb = NULL;
+		}
+
+		if (buffer_info->page) {
+			if (buffer_info->page_dma)
+				pci_unmap_page(pdev, buffer_info->page_dma,
+				               PAGE_SIZE / 2,
+				               PCI_DMA_FROMDEVICE);
+			put_page(buffer_info->page);
+			buffer_info->page = NULL;
+			buffer_info->page_dma = 0;
+			buffer_info->page_offset = 0;
+		}
+	}
+
+	size = sizeof(struct igbvf_buffer) * rx_ring->count;
+	memset(rx_ring->buffer_info, 0, size);
+
+	/* Zero out the descriptor ring */
+	memset(rx_ring->desc, 0, rx_ring->size);
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	writel(0, adapter->hw.hw_addr + rx_ring->head);
+	writel(0, adapter->hw.hw_addr + rx_ring->tail);
+}
+
+/**
+ * igbvf_free_rx_resources - Free Rx Resources
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+
+void igbvf_free_rx_resources(struct igbvf_ring *rx_ring)
+{
+	struct pci_dev *pdev = rx_ring->adapter->pdev;
+
+	igbvf_clean_rx_ring(rx_ring);
+
+	vfree(rx_ring->buffer_info);
+	rx_ring->buffer_info = NULL;
+
+	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
+	                  rx_ring->dma);
+	rx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
+ *      Stores a new ITR value based on packets and byte
+ *      counts during the last interrupt.  The advantage of per interrupt
+ *      computation is faster updates and more accurate ITR for the current
+ *      traffic pattern.  Constants in this function were computed
+ *      based on theoretical maximum wire speed and thresholds were set based
+ *      on testing data as well as attempting to minimize response time
+ *      while increasing bulk throughput.  This functionality is controlled
+ *      by the InterruptThrottleRate module parameter.
+ **/
+static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
+                                     u16 itr_setting, int packets,
+                                     int bytes)
+{
+	unsigned int retval = itr_setting;
+
+	if (packets == 0)
+		goto update_itr_done;
+
+	switch (itr_setting) {
+	case lowest_latency:
+		/* handle TSO and jumbo frames */
+		if (bytes/packets > 8000)
+			retval = bulk_latency;
+		else if ((packets < 5) && (bytes > 512))
+			retval = low_latency;
+		break;
+	case low_latency:  /* 50 usec aka 20000 ints/s */
+		if (bytes > 10000) {
+			/* this if handles the TSO accounting */
+			if (bytes/packets > 8000)
+				retval = bulk_latency;
+			else if ((packets < 10) || ((bytes/packets) > 1200))
+				retval = bulk_latency;
+			else if ((packets > 35))
+				retval = lowest_latency;
+		} else if (bytes/packets > 2000) {
+			retval = bulk_latency;
+		} else if (packets <= 2 && bytes < 512) {
+			retval = lowest_latency;
+		}
+		break;
+	case bulk_latency: /* 250 usec aka 4000 ints/s */
+		if (bytes > 25000) {
+			if (packets > 35)
+				retval = low_latency;
+		} else if (bytes < 6000) {
+			retval = low_latency;
+		}
+		break;
+	}
+
+update_itr_done:
+	return retval;
+}
+
+static void igbvf_set_itr(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u16 current_itr;
+	u32 new_itr = adapter->itr;
+
+	adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr,
+	                                   adapter->total_tx_packets,
+	                                   adapter->total_tx_bytes);
+	/* conservative mode (itr 3) eliminates the lowest_latency setting */
+	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
+		adapter->tx_itr = low_latency;
+
+	adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr,
+	                                   adapter->total_rx_packets,
+	                                   adapter->total_rx_bytes);
+	/* conservative mode (itr 3) eliminates the lowest_latency setting */
+	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
+		adapter->rx_itr = low_latency;
+
+	current_itr = max(adapter->rx_itr, adapter->tx_itr);
+
+	switch (current_itr) {
+	/* counts and packets in update_itr are dependent on these numbers */
+	case lowest_latency:
+		new_itr = 70000;
+		break;
+	case low_latency:
+		new_itr = 20000; /* aka hwitr = ~200 */
+		break;
+	case bulk_latency:
+		new_itr = 4000;
+		break;
+	default:
+		break;
+	}
+
+	if (new_itr != adapter->itr) {
+		/*
+		 * this attempts to bias the interrupt rate towards Bulk
+		 * by adding intermediate steps when interrupt rate is
+		 * increasing
+		 */
+		new_itr = new_itr > adapter->itr ?
+		             min(adapter->itr + (new_itr >> 2), new_itr) :
+		             new_itr;
+		adapter->itr = new_itr;
+		adapter->rx_ring->itr_val = 1952;
+
+		if (adapter->msix_entries)
+			adapter->rx_ring->set_itr = 1;
+		else
+			ew32(ITR, 1952);
+	}
+}
+
+/**
+ * igbvf_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ * returns true if ring is completely cleaned
+ **/
+static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = tx_ring->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct igbvf_buffer *buffer_info;
+	struct sk_buff *skb;
+	union e1000_adv_tx_desc *tx_desc, *eop_desc;
+	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int i, eop, count = 0;
+	bool cleaned = false;
+
+	i = tx_ring->next_to_clean;
+	eop = tx_ring->buffer_info[i].next_to_watch;
+	eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+	       (count < tx_ring->count)) {
+		for (cleaned = false; !cleaned; count++) {
+			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+			buffer_info = &tx_ring->buffer_info[i];
+			cleaned = (i == eop);
+			skb = buffer_info->skb;
+
+			if (skb) {
+				unsigned int segs, bytecount;
+
+				/* gso_segs is currently only valid for tcp */
+				segs = skb_shinfo(skb)->gso_segs ?: 1;
+				/* multiply data chunks by size of headers */
+				bytecount = ((segs - 1) * skb_headlen(skb)) +
+				            skb->len;
+				total_packets += segs;
+				total_bytes += bytecount;
+			}
+
+			igbvf_put_txbuf(adapter, buffer_info);
+			tx_desc->wb.status = 0;
+
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
+		eop = tx_ring->buffer_info[i].next_to_watch;
+		eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+	}
+
+	tx_ring->next_to_clean = i;
+
+	if (unlikely(count &&
+	             netif_carrier_ok(netdev) &&
+	             igbvf_desc_unused(tx_ring) >= IGBVF_TX_QUEUE_WAKE)) {
+		/* Make sure that anybody stopping the queue after this
+		 * sees the new next_to_clean.
+		 */
+		smp_mb();
+		if (netif_queue_stopped(netdev) &&
+		    !(test_bit(__IGBVF_DOWN, &adapter->state))) {
+			netif_wake_queue(netdev);
+			++adapter->restart_queue;
+		}
+	}
+
+	if (adapter->detect_tx_hung) {
+		/* Detect a transmit hang in hardware, this serializes the
+		 * check with the clearing of time_stamp and movement of i */
+		adapter->detect_tx_hung = false;
+		if (tx_ring->buffer_info[i].time_stamp &&
+		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
+		               (adapter->tx_timeout_factor * HZ))
+		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+
+			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+			/* detected Tx unit hang */
+			igbvf_print_tx_hang(adapter);
+
+			netif_stop_queue(netdev);
+		}
+	}
+	adapter->net_stats.tx_bytes += total_bytes;
+	adapter->net_stats.tx_packets += total_packets;
+	return (count < tx_ring->count);
+}
+
+static irqreturn_t igbvf_msix_other(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	adapter->int_counter1++;
+
+	netif_carrier_off(netdev);
+	hw->mac.get_link_status = 1;
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+	ew32(EIMS, adapter->eims_other);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_tx(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+
+
+	adapter->total_tx_bytes = 0;
+	adapter->total_tx_packets = 0;
+
+	/* auto mask will automatically reenable the interrupt when we write
+	 * EICS */
+	if (!igbvf_clean_tx_irq(tx_ring))
+		/* Ring was not completely cleaned, so fire another interrupt */
+		ew32(EICS, tx_ring->eims_value);
+	else
+		ew32(EIMS, tx_ring->eims_value);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_rx(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	adapter->int_counter0++;
+
+	/* Write the ITR value calculated at the end of the
+	 * previous interrupt.
+	 */
+	if (adapter->rx_ring->set_itr) {
+		writel(adapter->rx_ring->itr_val,
+		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
+		adapter->rx_ring->set_itr = 0;
+	}
+
+	if (napi_schedule_prep(&adapter->rx_ring->napi)) {
+		adapter->total_rx_bytes = 0;
+		adapter->total_rx_packets = 0;
+		__napi_schedule(&adapter->rx_ring->napi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+#define IGBVF_NO_QUEUE -1
+
+static void igbvf_assign_vector(struct igbvf_adapter *adapter, int rx_queue,
+                                int tx_queue, int msix_vector)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 ivar, index;
+
+	/* 82576 uses a table-based method for assigning vectors.
+	   Each queue has a single entry in the table to which we write
+	   a vector number along with a "valid" bit.  Sadly, the layout
+	   of the table is somewhat counterintuitive. */
+	if (rx_queue > IGBVF_NO_QUEUE) {
+		index = (rx_queue >> 1);
+		ivar = array_er32(IVAR0, index);
+		if (rx_queue & 0x1) {
+			/* vector goes into third byte of register */
+			ivar = ivar & 0xFF00FFFF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+		} else {
+			/* vector goes into low byte of register */
+			ivar = ivar & 0xFFFFFF00;
+			ivar |= msix_vector | E1000_IVAR_VALID;
+		}
+		adapter->rx_ring[rx_queue].eims_value = 1 << msix_vector;
+		array_ew32(IVAR0, index, ivar);
+	}
+	if (tx_queue > IGBVF_NO_QUEUE) {
+		index = (tx_queue >> 1);
+		ivar = array_er32(IVAR0, index);
+		if (tx_queue & 0x1) {
+			/* vector goes into high byte of register */
+			ivar = ivar & 0x00FFFFFF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+		} else {
+			/* vector goes into second byte of register */
+			ivar = ivar & 0xFFFF00FF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+		}
+		adapter->tx_ring[tx_queue].eims_value = 1 << msix_vector;
+		array_ew32(IVAR0, index, ivar);
+	}
+}
+
+/**
+ * igbvf_configure_msix - Configure MSI-X hardware
+ *
+ * igbvf_configure_msix sets up the hardware to properly
+ * generate MSI-X interrupts.
+ **/
+static void igbvf_configure_msix(struct igbvf_adapter *adapter)
+{
+	u32 tmp;
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	int vector = 0;
+
+	adapter->eims_enable_mask = 0;
+
+	igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++);
+	adapter->eims_enable_mask |= tx_ring->eims_value;
+	if (tx_ring->itr_val)
+		writel(tx_ring->itr_val,
+		       hw->hw_addr + tx_ring->itr_register);
+	else
+		writel(1952, hw->hw_addr + tx_ring->itr_register);
+
+	igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++);
+	adapter->eims_enable_mask |= rx_ring->eims_value;
+	if (rx_ring->itr_val)
+		writel(rx_ring->itr_val,
+		       hw->hw_addr + rx_ring->itr_register);
+	else
+		writel(1952, hw->hw_addr + rx_ring->itr_register);
+
+	/* set vector for other causes, i.e. link changes */
+
+	tmp = (vector++ | E1000_IVAR_VALID);
+
+	ew32(IVAR_MISC, tmp);
+
+	adapter->eims_enable_mask = (1 << (vector)) - 1;
+	adapter->eims_other = 1 << (vector - 1);
+	e1e_flush();
+}
+
+static void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter)
+{
+	if (adapter->msix_entries) {
+		pci_disable_msix(adapter->pdev);
+		kfree(adapter->msix_entries);
+		adapter->msix_entries = NULL;
+	}
+}
+
+/**
+ * igbvf_set_interrupt_capability - set MSI or MSI-X if supported
+ *
+ * Attempt to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter)
+{
+	int err = -ENOMEM;
+	int i;
+
+	/* we allocate 3 vectors, 1 for tx, 1 for rx, one for pf messages */
+	adapter->msix_entries = kcalloc(3, sizeof(struct msix_entry),
+	                                GFP_KERNEL);
+	if (adapter->msix_entries) {
+		for (i = 0; i < 3; i++)
+			adapter->msix_entries[i].entry = i;
+
+		err = pci_enable_msix(adapter->pdev,
+		                      adapter->msix_entries, 3);
+	}
+
+	if (err) {
+		/* MSI-X failed */
+		dev_err(&adapter->pdev->dev,
+		        "Failed to initialize MSI-X interrupts.\n");
+		igbvf_reset_interrupt_capability(adapter);
+	}
+}
+
+/**
+ * igbvf_request_msix - Initialize MSI-X interrupts
+ *
+ * igbvf_request_msix allocates MSI-X vectors and requests interrupts from the
+ * kernel.
+ **/
+static int igbvf_request_msix(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int err = 0, vector = 0;
+
+	if (strlen(netdev->name) < (IFNAMSIZ - 5)) {
+		sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
+		sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
+	} else {
+		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
+		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
+	}
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
+	                  netdev);
+	if (err)
+		goto out;
+
+	adapter->tx_ring->itr_register = E1000_EITR(vector);
+	adapter->tx_ring->itr_val = 1952;
+	vector++;
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
+	                  netdev);
+	if (err)
+		goto out;
+
+	adapter->rx_ring->itr_register = E1000_EITR(vector);
+	adapter->rx_ring->itr_val = 1952;
+	vector++;
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_msix_other, 0, netdev->name, netdev);
+	if (err)
+		goto out;
+
+	igbvf_configure_msix(adapter);
+	return 0;
+out:
+	return err;
+}
+
+/**
+ * igbvf_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ **/
+static int __devinit igbvf_alloc_queues(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	adapter->tx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+	if (!adapter->tx_ring)
+		return -ENOMEM;
+
+	adapter->rx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+	if (!adapter->rx_ring) {
+		kfree(adapter->tx_ring);
+		return -ENOMEM;
+	}
+
+	netif_napi_add(netdev, &adapter->rx_ring->napi, igbvf_poll, 64);
+
+	return 0;
+}
+
+/**
+ * igbvf_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static int igbvf_request_irq(struct igbvf_adapter *adapter)
+{
+	int err = -1;
+
+	/* igbvf supports msi-x only */
+	if (adapter->msix_entries)
+		err = igbvf_request_msix(adapter);
+
+	if (!err)
+		return err;
+
+	dev_err(&adapter->pdev->dev,
+	        "Unable to allocate interrupt, Error: %d\n", err);
+
+	return err;
+}
+
+static void igbvf_free_irq(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int vector;
+
+	if (adapter->msix_entries) {
+		for (vector = 0; vector < 3; vector++)
+			free_irq(adapter->msix_entries[vector].vector, netdev);
+	}
+}
+
+/**
+ * igbvf_irq_disable - Mask off interrupt generation on the NIC
+ **/
+static void igbvf_irq_disable(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	ew32(EIMC, ~0);
+
+	if (adapter->msix_entries)
+		ew32(EIAC, 0);
+}
+
+/**
+ * igbvf_irq_enable - Enable default interrupt generation settings
+ **/
+static void igbvf_irq_enable(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	ew32(EIAC, adapter->eims_enable_mask);
+	ew32(EIAM, adapter->eims_enable_mask);
+	ew32(EIMS, adapter->eims_enable_mask);
+}
+
+/**
+ * igbvf_poll - NAPI Rx polling callback
+ * @napi: struct associated with this polling callback
+ * @budget: amount of packets driver is allowed to process this poll
+ **/
+static int igbvf_poll(struct napi_struct *napi, int budget)
+{
+	struct igbvf_ring *rx_ring = container_of(napi, struct igbvf_ring, napi);
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+	int work_done = 0;
+
+	igbvf_clean_rx_irq(adapter, &work_done, budget);
+
+	/* If not enough Rx work done, exit the polling mode */
+	if (work_done < budget) {
+		napi_complete(napi);
+
+		if (adapter->itr_setting & 3)
+			igbvf_set_itr(adapter);
+
+		if (!test_bit(__IGBVF_DOWN, &adapter->state))
+			ew32(EIMS, adapter->rx_ring->eims_value);
+	}
+
+	return work_done;
+}
+
+/**
+ * igbvf_set_rlpml - set receive large packet maximum length
+ * @adapter: board private structure
+ *
+ * Configure the maximum size of packets that will be received
+ */
+static void igbvf_set_rlpml(struct igbvf_adapter *adapter)
+{
+	int max_frame_size = adapter->max_frame_size;
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (adapter->vlgrp)
+		max_frame_size += VLAN_TAG_SIZE;
+
+	e1000_rlpml_set_vf(hw, max_frame_size);
+}
+
+static void igbvf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (hw->mac.ops.set_vfta(hw, vid, true))
+		dev_err(&adapter->pdev->dev, "Failed to add vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	igbvf_irq_disable(adapter);
+	vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		igbvf_irq_enable(adapter);
+
+	if (hw->mac.ops.set_vfta(hw, vid, false))
+		dev_err(&adapter->pdev->dev,
+		        "Failed to remove vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_register(struct net_device *netdev,
+                                   struct vlan_group *grp)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	adapter->vlgrp = grp;
+}
+
+static void igbvf_restore_vlan(struct igbvf_adapter *adapter)
+{
+	u16 vid;
+
+	if (!adapter->vlgrp)
+		return;
+
+	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		if (!vlan_group_get_device(adapter->vlgrp, vid))
+			continue;
+		igbvf_vlan_rx_add_vid(adapter->netdev, vid);
+	}
+
+	igbvf_set_rlpml(adapter);
+}
+
+/**
+ * igbvf_configure_tx - Configure Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_tx(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	u64 tdba;
+	u32 txdctl, dca_txctrl;
+
+	/* disable transmits */
+	txdctl = er32(TXDCTL(0));
+	ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+	msleep(10);
+
+	/* Setup the HW Tx Head and Tail descriptor pointers */
+	ew32(TDLEN(0), tx_ring->count * sizeof(union e1000_adv_tx_desc));
+	tdba = tx_ring->dma;
+	ew32(TDBAL(0), (tdba & DMA_32BIT_MASK));
+	ew32(TDBAH(0), (tdba >> 32));
+	ew32(TDH(0), 0);
+	ew32(TDT(0), 0);
+	tx_ring->head = E1000_TDH(0);
+	tx_ring->tail = E1000_TDT(0);
+
+	/* Turn off Relaxed Ordering on head write-backs.  The writebacks
+	 * MUST be delivered in order or it will completely screw up
+	 * our bookeeping.
+	 */
+	dca_txctrl = er32(DCA_TXCTRL(0));
+	dca_txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
+	ew32(DCA_TXCTRL(0), dca_txctrl);
+
+	/* enable transmits */
+	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+	ew32(TXDCTL(0), txdctl);
+
+	/* Setup Transmit Descriptor Settings for eop descriptor */
+	adapter->txd_cmd = E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_IFCS;
+
+	/* enable Report Status bit */
+	adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
+
+	adapter->tx_queue_len = adapter->netdev->tx_queue_len;
+}
+
+/**
+ * igbvf_setup_srrctl - configure the receive control registers
+ * @adapter: Board private structure
+ **/
+static void igbvf_setup_srrctl(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 srrctl = 0;
+
+	srrctl &= ~(E1000_SRRCTL_DESCTYPE_MASK |
+	            E1000_SRRCTL_BSIZEHDR_MASK |
+	            E1000_SRRCTL_BSIZEPKT_MASK);
+
+	/* Enable queue drop to avoid head of line blocking */
+	srrctl |= E1000_SRRCTL_DROP_EN;
+
+	/* Setup buffer sizes */
+	srrctl |= ALIGN(adapter->rx_buffer_len, 1024) >>
+	          E1000_SRRCTL_BSIZEPKT_SHIFT;
+
+	if (adapter->rx_buffer_len < 2048) {
+		adapter->rx_ps_hdr_size = 0;
+		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+	} else {
+		adapter->rx_ps_hdr_size = 128;
+		srrctl |= adapter->rx_ps_hdr_size <<
+		          E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+		srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+	}
+
+	ew32(SRRCTL(0), srrctl);
+}
+
+/**
+ * igbvf_configure_rx - Configure Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_rx(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	u64 rdba;
+	u32 rdlen, rxdctl;
+
+	/* disable receives */
+	rxdctl = er32(RXDCTL(0));
+	ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+	msleep(10);
+
+	rdlen = rx_ring->count * sizeof(union e1000_adv_rx_desc);
+
+	/*
+	 * Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring
+	 */
+	rdba = rx_ring->dma;
+	ew32(RDBAL(0), (rdba & DMA_32BIT_MASK));
+	ew32(RDBAH(0), (rdba >> 32));
+	ew32(RDLEN(0), rx_ring->count * sizeof(union e1000_adv_rx_desc));
+	rx_ring->head = E1000_RDH(0);
+	rx_ring->tail = E1000_RDT(0);
+	ew32(RDH(0), 0);
+	ew32(RDT(0), 0);
+
+	rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+	rxdctl &= 0xFFF00000;
+	rxdctl |= IGBVF_RX_PTHRESH;
+	rxdctl |= IGBVF_RX_HTHRESH << 8;
+	rxdctl |= IGBVF_RX_WTHRESH << 16;
+
+	igbvf_set_rlpml(adapter);
+
+	/* enable receives */
+	ew32(RXDCTL(0), rxdctl);
+}
+
+/**
+ * igbvf_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igbvf_set_multi(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct dev_mc_list *mc_ptr;
+	u8  *mta_list = NULL;
+	int i;
+
+	if (netdev->mc_count) {
+		mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+		if (!mta_list) {
+			dev_err(&adapter->pdev->dev,
+			        "failed to allocate multicast filter list\n");
+			return;
+		}
+	}
+
+	/* prepare a packed array of only addresses. */
+	mc_ptr = netdev->mc_list;
+
+	for (i = 0; i < netdev->mc_count; i++) {
+		if (!mc_ptr)
+			break;
+		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
+		       ETH_ALEN);
+		mc_ptr = mc_ptr->next;
+	}
+
+	hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0);
+	kfree(mta_list);
+}
+
+/**
+ * igbvf_configure - configure the hardware for Rx and Tx
+ * @adapter: private board structure
+ **/
+static void igbvf_configure(struct igbvf_adapter *adapter)
+{
+	igbvf_set_multi(adapter->netdev);
+
+	igbvf_restore_vlan(adapter);
+
+	igbvf_configure_tx(adapter);
+	igbvf_setup_srrctl(adapter);
+	igbvf_configure_rx(adapter);
+	igbvf_alloc_rx_buffers(adapter->rx_ring,
+	                       igbvf_desc_unused(adapter->rx_ring));
+}
+
+/* igbvf_reset - bring the hardware into a known good state
+ *
+ * This function boots the hardware and enables some settings that
+ * require a configuration cycle of the hardware - those cannot be
+ * set/changed during runtime. After reset the device needs to be
+ * properly configured for Rx, Tx etc.
+ */
+static void igbvf_reset(struct igbvf_adapter *adapter)
+{
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+
+	/* Allow time for pending master requests to run */
+	if (mac->ops.reset_hw(hw))
+		dev_err(&adapter->pdev->dev, "PF still resetting\n");
+
+	mac->ops.init_hw(hw);
+
+	if (is_valid_ether_addr(adapter->hw.mac.addr)) {
+		memcpy(netdev->dev_addr, adapter->hw.mac.addr,
+		       netdev->addr_len);
+		memcpy(netdev->perm_addr, adapter->hw.mac.addr,
+		       netdev->addr_len);
+	}
+}
+
+int igbvf_up(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	/* hardware has been reset, we need to reload some things */
+	igbvf_configure(adapter);
+
+	clear_bit(__IGBVF_DOWN, &adapter->state);
+
+	napi_enable(&adapter->rx_ring->napi);
+	if (adapter->msix_entries)
+		igbvf_configure_msix(adapter);
+
+	/* Clear any pending interrupts. */
+	er32(EICR);
+	igbvf_irq_enable(adapter);
+
+	/* start the watchdog */
+	hw->mac.get_link_status = 1;
+	mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+
+	return 0;
+}
+
+void igbvf_down(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 rxdctl, txdctl;
+
+	/*
+	 * signal that we're down so the interrupt handler does not
+	 * reschedule our watchdog timer
+	 */
+	set_bit(__IGBVF_DOWN, &adapter->state);
+
+	/* disable receives in the hardware */
+	rxdctl = er32(RXDCTL(0));
+	ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+
+	netif_stop_queue(netdev);
+
+	/* disable transmits in the hardware */
+	txdctl = er32(TXDCTL(0));
+	ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+
+	/* flush both disables and wait for them to finish */
+	e1e_flush();
+	msleep(10);
+
+	napi_disable(&adapter->rx_ring->napi);
+
+	igbvf_irq_disable(adapter);
+
+	del_timer_sync(&adapter->watchdog_timer);
+
+	netdev->tx_queue_len = adapter->tx_queue_len;
+	netif_carrier_off(netdev);
+
+	/* record the stats before reset*/
+	igbvf_update_stats(adapter);
+
+	adapter->link_speed = 0;
+	adapter->link_duplex = 0;
+
+	igbvf_reset(adapter);
+	igbvf_clean_tx_ring(adapter->tx_ring);
+	igbvf_clean_rx_ring(adapter->rx_ring);
+}
+
+void igbvf_reinit_locked(struct igbvf_adapter *adapter)
+{
+	might_sleep();
+	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+		msleep(1);
+	igbvf_down(adapter);
+	igbvf_up(adapter);
+	clear_bit(__IGBVF_RESETTING, &adapter->state);
+}
+
+/**
+ * igbvf_sw_init - Initialize general software structures (struct igbvf_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * igbvf_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	s32 rc;
+
+	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
+	adapter->rx_ps_hdr_size = 0;
+	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+	adapter->tx_int_delay = 8;
+	adapter->tx_abs_int_delay = 32;
+	adapter->rx_int_delay = 0;
+	adapter->rx_abs_int_delay = 8;
+	adapter->itr_setting = 3;
+	adapter->itr = 20000;
+
+	/* Set various function pointers */
+	adapter->ei->init_ops(&adapter->hw);
+
+	rc = adapter->hw.mac.ops.init_params(&adapter->hw);
+	if (rc)
+		return rc;
+
+	rc = adapter->hw.mbx.ops.init_params(&adapter->hw);
+	if (rc)
+		return rc;
+
+	igbvf_set_interrupt_capability(adapter);
+
+	if (igbvf_alloc_queues(adapter))
+		return -ENOMEM;
+
+	spin_lock_init(&adapter->tx_queue_lock);
+
+	/* Explicitly disable IRQ since the NIC can be in any state. */
+	igbvf_irq_disable(adapter);
+
+	spin_lock_init(&adapter->stats_lock);
+
+	set_bit(__IGBVF_DOWN, &adapter->state);
+	return 0;
+}
+
+static void igbvf_initialize_last_counter_stats(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	adapter->stats.last_gprc = er32(VFGPRC);
+	adapter->stats.last_gorc = er32(VFGORC);
+	adapter->stats.last_gptc = er32(VFGPTC);
+	adapter->stats.last_gotc = er32(VFGOTC);
+	adapter->stats.last_mprc = er32(VFMPRC);
+	adapter->stats.last_gotlbc = er32(VFGOTLBC);
+	adapter->stats.last_gptlbc = er32(VFGPTLBC);
+	adapter->stats.last_gorlbc = er32(VFGORLBC);
+	adapter->stats.last_gprlbc = er32(VFGPRLBC);
+
+	adapter->stats.base_gprc = er32(VFGPRC);
+	adapter->stats.base_gorc = er32(VFGORC);
+	adapter->stats.base_gptc = er32(VFGPTC);
+	adapter->stats.base_gotc = er32(VFGOTC);
+	adapter->stats.base_mprc = er32(VFMPRC);
+	adapter->stats.base_gotlbc = er32(VFGOTLBC);
+	adapter->stats.base_gptlbc = er32(VFGPTLBC);
+	adapter->stats.base_gorlbc = er32(VFGORLBC);
+	adapter->stats.base_gprlbc = er32(VFGPRLBC);
+}
+
+/**
+ * igbvf_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+static int igbvf_open(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	int err;
+
+	/* disallow open during test */
+	if (test_bit(__IGBVF_TESTING, &adapter->state))
+		return -EBUSY;
+
+	/* allocate transmit descriptors */
+	err = igbvf_setup_tx_resources(adapter, adapter->tx_ring);
+	if (err)
+		goto err_setup_tx;
+
+	/* allocate receive descriptors */
+	err = igbvf_setup_rx_resources(adapter, adapter->rx_ring);
+	if (err)
+		goto err_setup_rx;
+
+	/*
+	 * before we allocate an interrupt, we must be ready to handle it.
+	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
+	 * as soon as we call pci_request_irq, so we have to setup our
+	 * clean_rx handler before we do so.
+	 */
+	igbvf_configure(adapter);
+
+	err = igbvf_request_irq(adapter);
+	if (err)
+		goto err_req_irq;
+
+	/* From here on the code is the same as igbvf_up() */
+	clear_bit(__IGBVF_DOWN, &adapter->state);
+
+	napi_enable(&adapter->rx_ring->napi);
+
+	/* clear any pending interrupts */
+	er32(EICR);
+
+	igbvf_irq_enable(adapter);
+
+	/* start the watchdog */
+	hw->mac.get_link_status = 1;
+	mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+	return 0;
+
+err_req_irq:
+	igbvf_free_rx_resources(adapter->rx_ring);
+err_setup_rx:
+	igbvf_free_tx_resources(adapter->tx_ring);
+err_setup_tx:
+	igbvf_reset(adapter);
+
+	return err;
+}
+
+/**
+ * igbvf_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the drivers control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+static int igbvf_close(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+	igbvf_down(adapter);
+
+	igbvf_free_irq(adapter);
+
+	igbvf_free_tx_resources(adapter->tx_ring);
+	igbvf_free_rx_resources(adapter->rx_ring);
+
+	return 0;
+}
+/**
+ * igbvf_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_set_mac(struct net_device *netdev, void *p)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+	if (memcmp(addr->sa_data, hw->mac.addr, 6))
+		return -EADDRNOTAVAIL;
+
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+	return 0;
+}
+
+#define UPDATE_VF_COUNTER(reg, name)                                    \
+	{                                                               \
+		u32 current_counter = er32(reg);                        \
+		if (current_counter < adapter->stats.last_##name)       \
+			adapter->stats.name += 0x100000000LL;           \
+		adapter->stats.last_##name = current_counter;           \
+		adapter->stats.name &= 0xFFFFFFFF00000000LL;            \
+		adapter->stats.name |= current_counter;                 \
+	}
+
+/**
+ * igbvf_update_stats - Update the board statistics counters
+ * @adapter: board private structure
+**/
+void igbvf_update_stats(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct pci_dev *pdev = adapter->pdev;
+
+	/*
+	 * Prevent stats update while adapter is being reset, link is down
+	 * or if the pci connection is down.
+	 */
+	if (adapter->link_speed == 0)
+		return;
+
+	if (test_bit(__IGBVF_RESETTING, &adapter->state))
+		return;
+
+	if (pci_channel_offline(pdev))
+		return;
+
+	UPDATE_VF_COUNTER(VFGPRC, gprc);
+	UPDATE_VF_COUNTER(VFGORC, gorc);
+	UPDATE_VF_COUNTER(VFGPTC, gptc);
+	UPDATE_VF_COUNTER(VFGOTC, gotc);
+	UPDATE_VF_COUNTER(VFMPRC, mprc);
+	UPDATE_VF_COUNTER(VFGOTLBC, gotlbc);
+	UPDATE_VF_COUNTER(VFGPTLBC, gptlbc);
+	UPDATE_VF_COUNTER(VFGORLBC, gorlbc);
+	UPDATE_VF_COUNTER(VFGPRLBC, gprlbc);
+
+	/* Fill out the OS statistics structure */
+	adapter->net_stats.multicast = adapter->stats.mprc;
+}
+
+static void igbvf_print_link_info(struct igbvf_adapter *adapter)
+{
+	dev_info(&adapter->pdev->dev, "Link is Up %d Mbps %s\n",
+	         adapter->link_speed,
+	         ((adapter->link_duplex == FULL_DUPLEX) ?
+	          "Full Duplex" : "Half Duplex"));
+}
+
+static bool igbvf_has_link(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	s32 ret_val = E1000_SUCCESS;
+	bool link_active;
+
+	ret_val = hw->mac.ops.check_for_link(hw);
+	link_active = !hw->mac.get_link_status;
+
+	/* if check for link returns error we will need to reset */
+	if (ret_val)
+		schedule_work(&adapter->reset_task);
+
+	return link_active;
+}
+
+/**
+ * igbvf_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void igbvf_watchdog(unsigned long data)
+{
+	struct igbvf_adapter *adapter = (struct igbvf_adapter *) data;
+
+	/* Do the rest outside of interrupt context */
+	schedule_work(&adapter->watchdog_task);
+}
+
+static void igbvf_watchdog_task(struct work_struct *work)
+{
+	struct igbvf_adapter *adapter = container_of(work,
+	                                             struct igbvf_adapter,
+	                                             watchdog_task);
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 link;
+	int tx_pending = 0;
+
+	link = igbvf_has_link(adapter);
+
+	if (link) {
+		if (!netif_carrier_ok(netdev)) {
+			bool txb2b = 1;
+
+			mac->ops.get_link_up_info(&adapter->hw,
+			                          &adapter->link_speed,
+			                          &adapter->link_duplex);
+			igbvf_print_link_info(adapter);
+
+			/*
+			 * tweak tx_queue_len according to speed/duplex
+			 * and adjust the timeout factor
+			 */
+			netdev->tx_queue_len = adapter->tx_queue_len;
+			adapter->tx_timeout_factor = 1;
+			switch (adapter->link_speed) {
+			case SPEED_10:
+				txb2b = 0;
+				netdev->tx_queue_len = 10;
+				adapter->tx_timeout_factor = 16;
+				break;
+			case SPEED_100:
+				txb2b = 0;
+				netdev->tx_queue_len = 100;
+				/* maybe add some timeout factor ? */
+				break;
+			}
+
+			netif_carrier_on(netdev);
+			netif_wake_queue(netdev);
+		}
+	} else {
+		if (netif_carrier_ok(netdev)) {
+			adapter->link_speed = 0;
+			adapter->link_duplex = 0;
+			dev_info(&adapter->pdev->dev, "Link is Down\n");
+			netif_carrier_off(netdev);
+			netif_stop_queue(netdev);
+		}
+	}
+
+	if (netif_carrier_ok(netdev)) {
+		igbvf_update_stats(adapter);
+	} else {
+		tx_pending = (igbvf_desc_unused(tx_ring) + 1 <
+		              tx_ring->count);
+		if (tx_pending) {
+			/*
+			 * We've lost link, so the controller stops DMA,
+			 * but we've got queued Tx work that's never going
+			 * to get done, so reset controller to flush Tx.
+			 * (Do the reset outside of interrupt context).
+			 */
+			adapter->tx_timeout_count++;
+			schedule_work(&adapter->reset_task);
+		}
+	}
+
+	/* Cause software interrupt to ensure Rx ring is cleaned */
+	ew32(EICS, adapter->rx_ring->eims_value);
+
+	/* Force detection of hung controller every watchdog period */
+	adapter->detect_tx_hung = 1;
+
+	/* Reset the timer */
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		mod_timer(&adapter->watchdog_timer,
+			  round_jiffies(jiffies + (2 * HZ)));
+}
+
+#define IGBVF_TX_FLAGS_CSUM             0x00000001
+#define IGBVF_TX_FLAGS_VLAN             0x00000002
+#define IGBVF_TX_FLAGS_TSO              0x00000004
+#define IGBVF_TX_FLAGS_IPV4             0x00000008
+#define IGBVF_TX_FLAGS_VLAN_MASK        0xffff0000
+#define IGBVF_TX_FLAGS_VLAN_SHIFT       16
+
+static int igbvf_tso(struct igbvf_adapter *adapter,
+                     struct igbvf_ring *tx_ring,
+                     struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
+{
+	struct e1000_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	int err;
+	struct igbvf_buffer *buffer_info;
+	u32 info = 0, tu_cmd = 0;
+	u32 mss_l4len_idx, l4len;
+	*hdr_len = 0;
+
+	if (skb_header_cloned(skb)) {
+		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+		if (err) {
+			dev_err(&adapter->pdev->dev,
+			        "igbvf_tso returning an error\n");
+			return err;
+		}
+	}
+
+	l4len = tcp_hdrlen(skb);
+	*hdr_len += l4len;
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+		struct iphdr *iph = ip_hdr(skb);
+		iph->tot_len = 0;
+		iph->check = 0;
+		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
+		                                         iph->daddr, 0,
+		                                         IPPROTO_TCP,
+		                                         0);
+	} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+		ipv6_hdr(skb)->payload_len = 0;
+		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+		                                       &ipv6_hdr(skb)->daddr,
+		                                       0, IPPROTO_TCP, 0);
+	}
+
+	i = tx_ring->next_to_use;
+
+	buffer_info = &tx_ring->buffer_info[i];
+	context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+	/* VLAN MACLEN IPLEN */
+	if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+		info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+	info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+	*hdr_len += skb_network_offset(skb);
+	info |= (skb_transport_header(skb) - skb_network_header(skb));
+	*hdr_len += (skb_transport_header(skb) - skb_network_header(skb));
+	context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+	/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
+	tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+	if (skb->protocol == htons(ETH_P_IP))
+		tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+	tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+
+	context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+
+	/* MSS L4LEN IDX */
+	mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
+	mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
+
+	context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+	context_desc->seqnum_seed = 0;
+
+	buffer_info->time_stamp = jiffies;
+	buffer_info->next_to_watch = i;
+	buffer_info->dma = 0;
+	i++;
+	if (i == tx_ring->count)
+		i = 0;
+
+	tx_ring->next_to_use = i;
+
+	return true;
+}
+
+static inline bool igbvf_tx_csum(struct igbvf_adapter *adapter,
+                                 struct igbvf_ring *tx_ring,
+                                 struct sk_buff *skb, u32 tx_flags)
+{
+	struct e1000_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	struct igbvf_buffer *buffer_info;
+	u32 info = 0, tu_cmd = 0;
+
+	if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
+	    (tx_flags & IGBVF_TX_FLAGS_VLAN)) {
+		i = tx_ring->next_to_use;
+		buffer_info = &tx_ring->buffer_info[i];
+		context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+
+		if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+			info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+
+		info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+		if (skb->ip_summed == CHECKSUM_PARTIAL)
+			info |= (skb_transport_header(skb) -
+			         skb_network_header(skb));
+
+
+		context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+		tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			switch (skb->protocol) {
+			case __constant_htons(ETH_P_IP):
+				tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+				break;
+			case __constant_htons(ETH_P_IPV6):
+				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+				break;
+			default:
+				break;
+			}
+		}
+
+		context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+		context_desc->seqnum_seed = 0;
+		context_desc->mss_l4len_idx = 0;
+
+		buffer_info->time_stamp = jiffies;
+		buffer_info->next_to_watch = i;
+		buffer_info->dma = 0;
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+		tx_ring->next_to_use = i;
+
+		return true;
+	}
+
+	return false;
+}
+
+static int igbvf_maybe_stop_tx(struct net_device *netdev, int size)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* there is enough descriptors then we don't need to worry  */
+	if (igbvf_desc_unused(adapter->tx_ring) >= size)
+		return 0;
+
+	netif_stop_queue(netdev);
+
+	smp_mb();
+
+	/* We need to check again just in case room has been made available */
+	if (igbvf_desc_unused(adapter->tx_ring) < size)
+		return -EBUSY;
+
+	netif_wake_queue(netdev);
+
+	++adapter->restart_queue;
+	return 0;
+}
+
+#define IGBVF_MAX_TXD_PWR       16
+#define IGBVF_MAX_DATA_PER_TXD  (1 << IGBVF_MAX_TXD_PWR)
+
+static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
+                                   struct igbvf_ring *tx_ring,
+                                   struct sk_buff *skb,
+                                   unsigned int first)
+{
+	struct igbvf_buffer *buffer_info;
+	unsigned int len = skb_headlen(skb);
+	unsigned int count = 0, i;
+	unsigned int f;
+	dma_addr_t *map;
+
+	i = tx_ring->next_to_use;
+
+	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+		return 0;
+	}
+
+	map = skb_shinfo(skb)->dma_maps;
+
+	buffer_info = &tx_ring->buffer_info[i];
+	BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
+	buffer_info->length = len;
+	/* set time_stamp *before* dma to help avoid a possible race */
+	buffer_info->time_stamp = jiffies;
+	buffer_info->next_to_watch = i;
+	buffer_info->dma = map[count];
+	count++;
+
+	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+		struct skb_frag_struct *frag;
+
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+
+		frag = &skb_shinfo(skb)->frags[f];
+		len = frag->size;
+
+		buffer_info = &tx_ring->buffer_info[i];
+		BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
+		buffer_info->length = len;
+		buffer_info->time_stamp = jiffies;
+		buffer_info->next_to_watch = i;
+		buffer_info->dma = map[count];
+		count++;
+	}
+
+	tx_ring->buffer_info[i].skb = skb;
+	tx_ring->buffer_info[first].next_to_watch = i;
+
+	return count;
+}
+
+static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
+                                      struct igbvf_ring *tx_ring,
+                                      int tx_flags, int count, u32 paylen,
+                                      u8 hdr_len)
+{
+	union e1000_adv_tx_desc *tx_desc = NULL;
+	struct igbvf_buffer *buffer_info;
+	u32 olinfo_status = 0, cmd_type_len;
+	unsigned int i;
+
+	cmd_type_len = (E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS |
+	                E1000_ADVTXD_DCMD_DEXT);
+
+	if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+		cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+
+	if (tx_flags & IGBVF_TX_FLAGS_TSO) {
+		cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
+
+		/* insert tcp checksum */
+		olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+
+		/* insert ip checksum */
+		if (tx_flags & IGBVF_TX_FLAGS_IPV4)
+			olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
+
+	} else if (tx_flags & IGBVF_TX_FLAGS_CSUM) {
+		olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+	}
+
+	olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
+
+	i = tx_ring->next_to_use;
+	while (count--) {
+		buffer_info = &tx_ring->buffer_info[i];
+		tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+		tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
+		tx_desc->read.cmd_type_len =
+		         cpu_to_le32(cmd_type_len | buffer_info->length);
+		tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+	}
+
+	tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+	/* Force memory writes to complete before letting h/w
+	 * know there are new descriptors to fetch.  (Only
+	 * applicable for weak-ordered memory model archs,
+	 * such as IA-64). */
+	wmb();
+
+	tx_ring->next_to_use = i;
+	writel(i, adapter->hw.hw_addr + tx_ring->tail);
+	/* we need this if more than one processor can write to our tail
+	 * at a time, it syncronizes IO on IA64/Altix systems */
+	mmiowb();
+}
+
+static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
+                                   struct net_device *netdev,
+                                   struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	unsigned int first, tx_flags = 0;
+	u8 hdr_len = 0;
+	int count = 0;
+	int tso = 0;
+
+	if (test_bit(__IGBVF_DOWN, &adapter->state)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (skb->len <= 0) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	/*
+	 * need: count + 4 desc gap to keep tail from touching
+         *       + 2 desc gap to keep tail from touching head,
+         *       + 1 desc for skb->data,
+         *       + 1 desc for context descriptor,
+	 * head, otherwise try next time
+	 */
+	if (igbvf_maybe_stop_tx(netdev, skb_shinfo(skb)->nr_frags + 4)) {
+		/* this is a hard error */
+		return NETDEV_TX_BUSY;
+	}
+
+	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+		tx_flags |= IGBVF_TX_FLAGS_VLAN;
+		tx_flags |= (vlan_tx_tag_get(skb) << IGBVF_TX_FLAGS_VLAN_SHIFT);
+	}
+
+	if (skb->protocol == htons(ETH_P_IP))
+		tx_flags |= IGBVF_TX_FLAGS_IPV4;
+
+	first = tx_ring->next_to_use;
+
+	tso = skb_is_gso(skb) ?
+		igbvf_tso(adapter, tx_ring, skb, tx_flags, &hdr_len) : 0;
+	if (unlikely(tso < 0)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (tso)
+		tx_flags |= IGBVF_TX_FLAGS_TSO;
+	else if (igbvf_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+	         (skb->ip_summed == CHECKSUM_PARTIAL))
+		tx_flags |= IGBVF_TX_FLAGS_CSUM;
+
+	/*
+	 * count reflects descriptors mapped, if 0 then mapping error
+	 * has occured and we need to rewind the descriptor queue
+	 */
+	count = igbvf_tx_map_adv(adapter, tx_ring, skb, first);
+
+	if (count) {
+		igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count,
+		                   skb->len, hdr_len);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *tx_ring;
+	int retval;
+
+	if (test_bit(__IGBVF_DOWN, &adapter->state)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	tx_ring = &adapter->tx_ring[0];
+
+	retval = igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
+
+	return retval;
+}
+
+/**
+ * igbvf_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+static void igbvf_tx_timeout(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* Do the reset outside of interrupt context */
+	adapter->tx_timeout_count++;
+	schedule_work(&adapter->reset_task);
+}
+
+static void igbvf_reset_task(struct work_struct *work)
+{
+	struct igbvf_adapter *adapter;
+	adapter = container_of(work, struct igbvf_adapter, reset_task);
+
+	igbvf_reinit_locked(adapter);
+}
+
+/**
+ * igbvf_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ **/
+static struct net_device_stats *igbvf_get_stats(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* only return the current stats */
+	return &adapter->net_stats;
+}
+
+/**
+ * igbvf_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+
+	if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+		dev_err(&adapter->pdev->dev, "Invalid MTU setting\n");
+		return -EINVAL;
+	}
+
+	/* Jumbo frame size limits */
+	if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+			dev_err(&adapter->pdev->dev,
+			        "Jumbo Frames not supported.\n");
+			return -EINVAL;
+		}
+	}
+
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
+	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+		dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
+		return -EINVAL;
+	}
+
+	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+		msleep(1);
+	/* igbvf_down has a dependency on max_frame_size */
+	adapter->max_frame_size = max_frame;
+	if (netif_running(netdev))
+		igbvf_down(adapter);
+
+	/*
+	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
+	 * means we reserve 2 more, this pushes us to allocate from the next
+	 * larger slab size.
+	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 * However with the new *_jumbo_rx* routines, jumbo receives will use
+	 * fragmented skbs
+	 */
+
+	if (max_frame <= 1024)
+		adapter->rx_buffer_len = 1024;
+	else if (max_frame <= 2048)
+		adapter->rx_buffer_len = 2048;
+	else
+#if (PAGE_SIZE / 2) > 16384
+		adapter->rx_buffer_len = 16384;
+#else
+		adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
+
+
+	/* adjust allocation if LPE protects us, and we aren't using SBP */
+	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
+	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
+		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN +
+		                         ETH_FCS_LEN;
+
+	dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
+	         netdev->mtu, new_mtu);
+	netdev->mtu = new_mtu;
+
+	if (netif_running(netdev))
+		igbvf_up(adapter);
+	else
+		igbvf_reset(adapter);
+
+	clear_bit(__IGBVF_RESETTING, &adapter->state);
+
+	return 0;
+}
+
+static int igbvf_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	switch (cmd) {
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int igbvf_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+	int retval = 0;
+#endif
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+		igbvf_down(adapter);
+		igbvf_free_irq(adapter);
+	}
+
+#ifdef CONFIG_PM
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+#endif
+
+	pci_disable_device(pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int igbvf_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	u32 err;
+
+	pci_restore_state(pdev);
+	err = pci_enable_device_mem(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
+		return err;
+	}
+
+	pci_set_master(pdev);
+
+	if (netif_running(netdev)) {
+		err = igbvf_request_irq(adapter);
+		if (err)
+			return err;
+	}
+
+	igbvf_reset(adapter);
+
+	if (netif_running(netdev))
+		igbvf_up(adapter);
+
+	netif_device_attach(netdev);
+
+	return 0;
+}
+#endif
+
+static void igbvf_shutdown(struct pci_dev *pdev)
+{
+	igbvf_suspend(pdev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void igbvf_netpoll(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	disable_irq(adapter->pdev->irq);
+
+	igbvf_clean_tx_irq(adapter->tx_ring);
+
+	enable_irq(adapter->pdev->irq);
+}
+#endif
+
+/**
+ * igbvf_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t igbvf_io_error_detected(struct pci_dev *pdev,
+                                                pci_channel_state_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		igbvf_down(adapter);
+	pci_disable_device(pdev);
+
+	/* Request a slot slot reset. */
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * igbvf_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the igbvf_resume routine.
+ */
+static pci_ers_result_t igbvf_io_slot_reset(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (pci_enable_device_mem(pdev)) {
+		dev_err(&pdev->dev,
+			"Cannot re-enable PCI device after reset.\n");
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+	pci_set_master(pdev);
+
+	igbvf_reset(adapter);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * igbvf_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the igbvf_resume routine.
+ */
+static void igbvf_io_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (netif_running(netdev)) {
+		if (igbvf_up(adapter)) {
+			dev_err(&pdev->dev,
+				"can't bring device back up after reset\n");
+			return;
+		}
+	}
+
+	netif_device_attach(netdev);
+}
+
+static void igbvf_print_device_info(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n");
+	dev_info(&pdev->dev, "Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+	         /* MAC address */
+	         netdev->dev_addr[0], netdev->dev_addr[1],
+	         netdev->dev_addr[2], netdev->dev_addr[3],
+	         netdev->dev_addr[4], netdev->dev_addr[5]);
+	dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
+}
+
+static const struct net_device_ops igbvf_netdev_ops = {
+	.ndo_open                       = igbvf_open,
+	.ndo_stop                       = igbvf_close,
+	.ndo_start_xmit                 = igbvf_xmit_frame,
+	.ndo_get_stats                  = igbvf_get_stats,
+	.ndo_set_multicast_list         = igbvf_set_multi,
+	.ndo_set_mac_address            = igbvf_set_mac,
+	.ndo_change_mtu                 = igbvf_change_mtu,
+	.ndo_do_ioctl                   = igbvf_ioctl,
+	.ndo_tx_timeout                 = igbvf_tx_timeout,
+	.ndo_vlan_rx_register           = igbvf_vlan_rx_register,
+	.ndo_vlan_rx_add_vid            = igbvf_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid           = igbvf_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller            = igbvf_netpoll,
+#endif
+};
+
+/**
+ * igbvf_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in igbvf_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * igbvf_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+static int __devinit igbvf_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+	struct net_device *netdev;
+	struct igbvf_adapter *adapter;
+	struct e1000_hw *hw;
+	const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data];
+
+	static int cards_found;
+	int err, pci_using_dac;
+
+	err = pci_enable_device_mem(pdev);
+	if (err)
+		return err;
+
+	pci_using_dac = 0;
+	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	if (!err) {
+		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		if (!err)
+			pci_using_dac = 1;
+	} else {
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			if (err) {
+				dev_err(&pdev->dev, "No usable DMA "
+				        "configuration, aborting\n");
+				goto err_dma;
+			}
+		}
+	}
+
+	err = pci_request_regions(pdev, igbvf_driver_name);
+	if (err)
+		goto err_pci_reg;
+
+	pci_set_master(pdev);
+
+	err = -ENOMEM;
+	netdev = alloc_etherdev(sizeof(struct igbvf_adapter));
+	if (!netdev)
+		goto err_alloc_etherdev;
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	pci_set_drvdata(pdev, netdev);
+	adapter = netdev_priv(netdev);
+	hw = &adapter->hw;
+	adapter->netdev = netdev;
+	adapter->pdev = pdev;
+	adapter->ei = ei;
+	adapter->pba = ei->pba;
+	adapter->flags = ei->flags;
+	adapter->hw.back = adapter;
+	adapter->hw.mac.type = ei->mac;
+	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+
+	/* PCI config space info */
+
+	hw->vendor_id = pdev->vendor;
+	hw->device_id = pdev->device;
+	hw->subsystem_vendor_id = pdev->subsystem_vendor;
+	hw->subsystem_device_id = pdev->subsystem_device;
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+
+	err = -EIO;
+	adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0),
+	                              pci_resource_len(pdev, 0));
+
+	if (!adapter->hw.hw_addr)
+		goto err_ioremap;
+
+	if (ei->get_variants) {
+		err = ei->get_variants(adapter);
+		if (err)
+			goto err_ioremap;
+	}
+
+	/* setup adapter struct */
+	err = igbvf_sw_init(adapter);
+	if (err)
+		goto err_sw_init;
+
+	/* construct the net_device struct */
+	netdev->netdev_ops = &igbvf_netdev_ops;
+
+	igbvf_set_ethtool_ops(netdev);
+	netdev->watchdog_timeo = 5 * HZ;
+	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+	adapter->bd_number = cards_found++;
+
+	netdev->features = NETIF_F_SG |
+	                   NETIF_F_IP_CSUM |
+	                   NETIF_F_HW_VLAN_TX |
+	                   NETIF_F_HW_VLAN_RX |
+	                   NETIF_F_HW_VLAN_FILTER;
+
+	netdev->features |= NETIF_F_IPV6_CSUM;
+	netdev->features |= NETIF_F_TSO;
+	netdev->features |= NETIF_F_TSO6;
+
+	if (pci_using_dac)
+		netdev->features |= NETIF_F_HIGHDMA;
+
+	netdev->vlan_features |= NETIF_F_TSO;
+	netdev->vlan_features |= NETIF_F_TSO6;
+	netdev->vlan_features |= NETIF_F_IP_CSUM;
+	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
+	netdev->vlan_features |= NETIF_F_SG;
+
+	/*reset the controller to put the device in a known good state */
+	err = hw->mac.ops.reset_hw(hw);
+	if (err) {
+		dev_info(&pdev->dev,
+		         "PF still in reset state, assigning new address\n");
+		random_ether_addr(hw->mac.addr);
+	} else {
+		err = hw->mac.ops.read_mac_addr(hw);
+		if (err) {
+			dev_err(&pdev->dev, "Error reading MAC address\n");
+			goto err_hw_init;
+		}
+	}
+
+	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
+	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+
+	if (!is_valid_ether_addr(netdev->perm_addr)) {
+		dev_err(&pdev->dev, "Invalid MAC Address: "
+		        "%02x:%02x:%02x:%02x:%02x:%02x\n",
+		        netdev->dev_addr[0], netdev->dev_addr[1],
+		        netdev->dev_addr[2], netdev->dev_addr[3],
+		        netdev->dev_addr[4], netdev->dev_addr[5]);
+		err = -EIO;
+		goto err_hw_init;
+	}
+
+	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
+	            (unsigned long) adapter);
+
+	INIT_WORK(&adapter->reset_task, igbvf_reset_task);
+	INIT_WORK(&adapter->watchdog_task, igbvf_watchdog_task);
+
+	/* ring size defaults */
+	adapter->rx_ring->count = 1024;
+	adapter->tx_ring->count = 1024;
+
+	/* reset the hardware with the new settings */
+	igbvf_reset(adapter);
+
+	/* tell the stack to leave us alone until igbvf_open() is called */
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	strcpy(netdev->name, "eth%d");
+	err = register_netdev(netdev);
+	if (err)
+		goto err_hw_init;
+
+	igbvf_print_device_info(adapter);
+
+	igbvf_initialize_last_counter_stats(adapter);
+
+	return 0;
+
+err_hw_init:
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+err_sw_init:
+	igbvf_reset_interrupt_capability(adapter);
+	iounmap(adapter->hw.hw_addr);
+err_ioremap:
+	free_netdev(netdev);
+err_alloc_etherdev:
+	pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+	pci_disable_device(pdev);
+	return err;
+}
+
+/**
+ * igbvf_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * igbvf_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.  The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ **/
+static void __devexit igbvf_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	/*
+	 * flush_scheduled work may reschedule our watchdog task, so
+	 * explicitly disable watchdog tasks from being rescheduled
+	 */
+	set_bit(__IGBVF_DOWN, &adapter->state);
+	del_timer_sync(&adapter->watchdog_timer);
+
+	flush_scheduled_work();
+
+	unregister_netdev(netdev);
+
+	igbvf_reset_interrupt_capability(adapter);
+
+	/*
+	 * it is important to delete the napi struct prior to freeing the
+	 * rx ring so that you do not end up with null pointer refs
+	 */
+	netif_napi_del(&adapter->rx_ring->napi);
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+
+	iounmap(hw->hw_addr);
+	if (hw->flash_address)
+		iounmap(hw->flash_address);
+	pci_release_regions(pdev);
+
+	free_netdev(netdev);
+
+	pci_disable_device(pdev);
+}
+
+/* PCI Error Recovery (ERS) */
+static struct pci_error_handlers igbvf_err_handler = {
+	.error_detected = igbvf_io_error_detected,
+	.slot_reset = igbvf_io_slot_reset,
+	.resume = igbvf_io_resume,
+};
+
+static struct pci_device_id igbvf_pci_tbl[] = {
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
+	{ } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl);
+
+/* PCI Device API Driver */
+static struct pci_driver igbvf_driver = {
+	.name     = igbvf_driver_name,
+	.id_table = igbvf_pci_tbl,
+	.probe    = igbvf_probe,
+	.remove   = __devexit_p(igbvf_remove),
+#ifdef CONFIG_PM
+	/* Power Management Hooks */
+	.suspend  = igbvf_suspend,
+	.resume   = igbvf_resume,
+#endif
+	.shutdown = igbvf_shutdown,
+	.err_handler = &igbvf_err_handler
+};
+
+/**
+ * igbvf_init_module - Driver Registration Routine
+ *
+ * igbvf_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+static int __init igbvf_init_module(void)
+{
+	int ret;
+	printk(KERN_INFO "%s - version %s\n",
+	       igbvf_driver_string, igbvf_driver_version);
+	printk(KERN_INFO "%s\n", igbvf_copyright);
+
+	ret = pci_register_driver(&igbvf_driver);
+	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
+	                       PM_QOS_DEFAULT_VALUE);
+
+	return ret;
+}
+module_init(igbvf_init_module);
+
+/**
+ * igbvf_exit_module - Driver Exit Cleanup Routine
+ *
+ * igbvf_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+static void __exit igbvf_exit_module(void)
+{
+	pci_unregister_driver(&igbvf_driver);
+	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
+}
+module_exit(igbvf_exit_module);
+
+
+MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
+MODULE_DESCRIPTION("Intel(R) 82576 Virtual Function Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+/* netdev.c */
diff --git a/drivers/net/igbvf/regs.h b/drivers/net/igbvf/regs.h
new file mode 100644
index 000000000000..b9e24ed70d0a
--- /dev/null
+++ b/drivers/net/igbvf/regs.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_REGS_H_
+#define _E1000_REGS_H_
+
+#define E1000_CTRL      0x00000 /* Device Control - RW */
+#define E1000_STATUS    0x00008 /* Device Status - RO */
+#define E1000_ITR       0x000C4 /* Interrupt Throttling Rate - RW */
+#define E1000_EICR      0x01580 /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n)  (0x01680 + (0x4 * (_n)))
+#define E1000_EICS      0x01520 /* Ext. Interrupt Cause Set - W0 */
+#define E1000_EIMS      0x01524 /* Ext. Interrupt Mask Set/Read - RW */
+#define E1000_EIMC      0x01528 /* Ext. Interrupt Mask Clear - WO */
+#define E1000_EIAC      0x0152C /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAM      0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_IVAR0     0x01700 /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
+/*
+ * Convenience macros
+ *
+ * Note: "_n" is the queue number of the register to be written to.
+ *
+ * Example usage:
+ * E1000_RDBAL_REG(current_rx_queue)
+ */
+#define E1000_RDBAL(_n)      ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
+                                         (0x0C000 + ((_n) * 0x40)))
+#define E1000_RDBAH(_n)      ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
+                                         (0x0C004 + ((_n) * 0x40)))
+#define E1000_RDLEN(_n)      ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
+                                         (0x0C008 + ((_n) * 0x40)))
+#define E1000_SRRCTL(_n)     ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
+                                         (0x0C00C + ((_n) * 0x40)))
+#define E1000_RDH(_n)        ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
+                                         (0x0C010 + ((_n) * 0x40)))
+#define E1000_RDT(_n)        ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
+                                         (0x0C018 + ((_n) * 0x40)))
+#define E1000_RXDCTL(_n)     ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
+                                         (0x0C028 + ((_n) * 0x40)))
+#define E1000_TDBAL(_n)      ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
+                                         (0x0E000 + ((_n) * 0x40)))
+#define E1000_TDBAH(_n)      ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
+                                         (0x0E004 + ((_n) * 0x40)))
+#define E1000_TDLEN(_n)      ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
+                                         (0x0E008 + ((_n) * 0x40)))
+#define E1000_TDH(_n)        ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
+                                         (0x0E010 + ((_n) * 0x40)))
+#define E1000_TDT(_n)        ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
+                                         (0x0E018 + ((_n) * 0x40)))
+#define E1000_TXDCTL(_n)     ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
+                                         (0x0E028 + ((_n) * 0x40)))
+#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
+#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#define E1000_RAL(_i)  (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
+                                       (0x054E0 + ((_i - 16) * 8)))
+#define E1000_RAH(_i)  (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
+                                       (0x054E4 + ((_i - 16) * 8)))
+
+/* Statistics registers */
+#define E1000_VFGPRC    0x00F10
+#define E1000_VFGORC    0x00F18
+#define E1000_VFMPRC    0x00F3C
+#define E1000_VFGPTC    0x00F14
+#define E1000_VFGOTC    0x00F34
+#define E1000_VFGOTLBC  0x00F50
+#define E1000_VFGPTLBC  0x00F44
+#define E1000_VFGORLBC  0x00F48
+#define E1000_VFGPRLBC  0x00F40
+
+/* These act per VF so an array friendly macro is used */
+#define E1000_V2PMAILBOX(_n)   (0x00C40 + (4 * (_n)))
+#define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n)))
+
+/* Define macros for handling registers */
+#define er32(reg) readl(hw->hw_addr + E1000_##reg)
+#define ew32(reg, val) writel((val), hw->hw_addr +  E1000_##reg)
+#define array_er32(reg, offset) \
+	readl(hw->hw_addr + E1000_##reg + (offset << 2))
+#define array_ew32(reg, offset, val) \
+	writel((val), hw->hw_addr +  E1000_##reg + (offset << 2))
+#define e1e_flush() er32(STATUS)
+
+#endif
diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c
new file mode 100644
index 000000000000..2a4faf9ade69
--- /dev/null
+++ b/drivers/net/igbvf/vf.c
@@ -0,0 +1,398 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+
+#include "vf.h"
+
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+                                     u16 *duplex);
+static s32 e1000_init_hw_vf(struct e1000_hw *hw);
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
+
+static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *,
+                                         u32, u32, u32);
+static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
+static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool);
+
+/**
+ *  e1000_init_mac_params_vf - Inits MAC params
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+
+	/* VF's have no MTA Registers - PF feature only */
+	mac->mta_reg_count = 128;
+	/* VF's have no access to RAR entries  */
+	mac->rar_entry_count = 1;
+
+	/* Function pointers */
+	/* reset */
+	mac->ops.reset_hw = e1000_reset_hw_vf;
+	/* hw initialization */
+	mac->ops.init_hw = e1000_init_hw_vf;
+	/* check for link */
+	mac->ops.check_for_link = e1000_check_for_link_vf;
+	/* link info */
+	mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
+	/* multicast address update */
+	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
+	/* set mac address */
+	mac->ops.rar_set = e1000_rar_set_vf;
+	/* read mac address */
+	mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
+	/* set vlan filter table array */
+	mac->ops.set_vfta = e1000_set_vfta_vf;
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_init_function_pointers_vf - Inits function pointers
+ *  @hw: pointer to the HW structure
+ **/
+void e1000_init_function_pointers_vf(struct e1000_hw *hw)
+{
+	hw->mac.ops.init_params = e1000_init_mac_params_vf;
+	hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
+}
+
+/**
+ *  e1000_get_link_up_info_vf - Gets link info.
+ *  @hw: pointer to the HW structure
+ *  @speed: pointer to 16 bit value to store link speed.
+ *  @duplex: pointer to 16 bit value to store duplex.
+ *
+ *  Since we cannot read the PHY and get accurate link info, we must rely upon
+ *  the status register's data which is often stale and inaccurate.
+ **/
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+                                     u16 *duplex)
+{
+	s32 status;
+
+	status = er32(STATUS);
+	if (status & E1000_STATUS_SPEED_1000)
+		*speed = SPEED_1000;
+	else if (status & E1000_STATUS_SPEED_100)
+		*speed = SPEED_100;
+	else
+		*speed = SPEED_10;
+
+	if (status & E1000_STATUS_FD)
+		*duplex = FULL_DUPLEX;
+	else
+		*duplex = HALF_DUPLEX;
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_reset_hw_vf - Resets the HW
+ *  @hw: pointer to the HW structure
+ *
+ *  VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
+ *  This is all the reset we can perform on a VF.
+ **/
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 timeout = E1000_VF_INIT_TIMEOUT;
+	u32 ret_val = -E1000_ERR_MAC_INIT;
+	u32 msgbuf[3];
+	u8 *addr = (u8 *)(&msgbuf[1]);
+	u32 ctrl;
+
+	/* assert vf queue/interrupt reset */
+	ctrl = er32(CTRL);
+	ew32(CTRL, ctrl | E1000_CTRL_RST);
+
+	/* we cannot initialize while the RSTI / RSTD bits are asserted */
+	while (!mbx->ops.check_for_rst(hw) && timeout) {
+		timeout--;
+		udelay(5);
+	}
+
+	if (timeout) {
+		/* mailbox timeout can now become active */
+		mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
+
+		/* notify pf of vf reset completion */
+		msgbuf[0] = E1000_VF_RESET;
+		mbx->ops.write_posted(hw, msgbuf, 1);
+
+		msleep(10);
+
+		/* set our "perm_addr" based on info provided by PF */
+		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+		if (!ret_val) {
+			if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK))
+				memcpy(hw->mac.perm_addr, addr, 6);
+			else
+				ret_val = -E1000_ERR_MAC_INIT;
+		}
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_init_hw_vf - Inits the HW
+ *  @hw: pointer to the HW structure
+ *
+ *  Not much to do here except clear the PF Reset indication if there is one.
+ **/
+static s32 e1000_init_hw_vf(struct e1000_hw *hw)
+{
+	/* attempt to set and restore our mac address */
+	e1000_rar_set_vf(hw, hw->mac.addr, 0);
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_hash_mc_addr_vf - Generate a multicast hash value
+ *  @hw: pointer to the HW structure
+ *  @mc_addr: pointer to a multicast address
+ *
+ *  Generates a multicast address hash value which is used to determine
+ *  the multicast filter table array address and new table value.  See
+ *  e1000_mta_set_generic()
+ **/
+static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
+{
+	u32 hash_value, hash_mask;
+	u8 bit_shift = 0;
+
+	/* Register count multiplied by bits per register */
+	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
+
+	/*
+	 * The bit_shift is the number of left-shifts
+	 * where 0xFF would still fall within the hash mask.
+	 */
+	while (hash_mask >> bit_shift != 0xFF)
+		bit_shift++;
+
+	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
+	                          (((u16) mc_addr[5]) << bit_shift)));
+
+	return hash_value;
+}
+
+/**
+ *  e1000_update_mc_addr_list_vf - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *  @rar_used_count: the first RAR register free to program
+ *  @rar_count: total number of supported Receive Address Registers
+ *
+ *  Updates the Receive Address Registers and Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ *  The parameter rar_count will usually be hw->mac.rar_entry_count
+ *  unless there are workarounds that change this.
+ **/
+void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
+                                  u8 *mc_addr_list, u32 mc_addr_count,
+                                  u32 rar_used_count, u32 rar_count)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[E1000_VFMAILBOX_SIZE];
+	u16 *hash_list = (u16 *)&msgbuf[1];
+	u32 hash_value;
+	u32 cnt, i;
+
+	/* Each entry in the list uses 1 16 bit word.  We have 30
+	 * 16 bit words available in our HW msg buffer (minus 1 for the
+	 * msg type).  That's 30 hash values if we pack 'em right.  If
+	 * there are more than 30 MC addresses to add then punt the
+	 * extras for now and then add code to handle more than 30 later.
+	 * It would be unusual for a server to request that many multi-cast
+	 * addresses except for in large enterprise network environments.
+	 */
+
+	cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
+	msgbuf[0] = E1000_VF_SET_MULTICAST;
+	msgbuf[0] |= cnt << E1000_VT_MSGINFO_SHIFT;
+
+	for (i = 0; i < cnt; i++) {
+		hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
+		hash_list[i] = hash_value & 0x0FFFF;
+		mc_addr_list += ETH_ADDR_LEN;
+	}
+
+	mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE);
+}
+
+/**
+ *  e1000_set_vfta_vf - Set/Unset vlan filter table address
+ *  @hw: pointer to the HW structure
+ *  @vid: determines the vfta register and bit to set/unset
+ *  @set: if true then set bit, else clear bit
+ **/
+static s32 e1000_set_vfta_vf(struct e1000_hw *hw, u16 vid, bool set)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[2];
+	s32 err;
+
+	msgbuf[0] = E1000_VF_SET_VLAN;
+	msgbuf[1] = vid;
+	/* Setting the 8 bit field MSG INFO to true indicates "add" */
+	if (set)
+		msgbuf[0] |= 1 << E1000_VT_MSGINFO_SHIFT;
+
+	mbx->ops.write_posted(hw, msgbuf, 2);
+
+	err = mbx->ops.read_posted(hw, msgbuf, 2);
+
+	/* if nacked the vlan was rejected */
+	if (!err && (msgbuf[0] == (E1000_VF_SET_VLAN | E1000_VT_MSGTYPE_NACK)))
+		err = -E1000_ERR_MAC_INIT;
+
+	return err;
+}
+
+/** e1000_rlpml_set_vf - Set the maximum receive packet length
+ *  @hw: pointer to the HW structure
+ *  @max_size: value to assign to max frame size
+ **/
+void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[2];
+
+	msgbuf[0] = E1000_VF_SET_LPE;
+	msgbuf[1] = max_size;
+
+	mbx->ops.write_posted(hw, msgbuf, 2);
+}
+
+/**
+ *  e1000_rar_set_vf - set device MAC address
+ *  @hw: pointer to the HW structure
+ *  @addr: pointer to the receive address
+ *  @index receive address array register
+ **/
+static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[3];
+	u8 *msg_addr = (u8 *)(&msgbuf[1]);
+	s32 ret_val;
+
+	memset(msgbuf, 0, 12);
+	msgbuf[0] = E1000_VF_SET_MAC_ADDR;
+	memcpy(msg_addr, addr, 6);
+	ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+	if (!ret_val)
+		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+	/* if nacked the address was rejected, use "perm_addr" */
+	if (!ret_val &&
+	    (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
+		e1000_read_mac_addr_vf(hw);
+}
+
+/**
+ *  e1000_read_mac_addr_vf - Read device MAC address
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < ETH_ADDR_LEN; i++)
+		hw->mac.addr[i] = hw->mac.perm_addr[i];
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_check_for_link_vf - Check for link for a virtual interface
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks to see if the underlying PF is still talking to the VF and
+ *  if it is then it reports the link state to the hardware, otherwise
+ *  it reports link down and returns an error.
+ **/
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val = E1000_SUCCESS;
+	u32 in_msg = 0;
+
+	/*
+	 * We only want to run this if there has been a rst asserted.
+	 * in this case that could mean a link change, device reset,
+	 * or a virtual function reset
+	 */
+
+	/* If we were hit with a reset drop the link */
+	if (!mbx->ops.check_for_rst(hw))
+		mac->get_link_status = true;
+
+	if (!mac->get_link_status)
+		goto out;
+
+	/* if link status is down no point in checking to see if pf is up */
+	if (!(er32(STATUS) & E1000_STATUS_LU))
+		goto out;
+
+	/* if the read failed it could just be a mailbox collision, best wait
+	 * until we are called again and don't report an error */
+	if (mbx->ops.read(hw, &in_msg, 1))
+		goto out;
+
+	/* if incoming message isn't clear to send we are waiting on response */
+	if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
+		/* message is not CTS and is NACK we must have lost CTS status */
+		if (in_msg & E1000_VT_MSGTYPE_NACK)
+			ret_val = -E1000_ERR_MAC_INIT;
+		goto out;
+	}
+
+	/* the pf is talking, if we timed out in the past we reinit */
+	if (!mbx->timeout) {
+		ret_val = -E1000_ERR_MAC_INIT;
+		goto out;
+	}
+
+	/* if we passed all the tests above then the link is up and we no
+	 * longer need to check for link */
+	mac->get_link_status = false;
+
+out:
+	return ret_val;
+}
+
diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h
new file mode 100644
index 000000000000..1e8ce3741a67
--- /dev/null
+++ b/drivers/net/igbvf/vf.h
@@ -0,0 +1,264 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 2009 Intel Corporation.
+
+  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".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_VF_H_
+#define _E1000_VF_H_
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "regs.h"
+#include "defines.h"
+
+struct e1000_hw;
+
+#define E1000_DEV_ID_82576_VF                 0x10CA
+#define E1000_REVISION_0 0
+#define E1000_REVISION_1 1
+#define E1000_REVISION_2 2
+#define E1000_REVISION_3 3
+#define E1000_REVISION_4 4
+
+#define E1000_FUNC_0     0
+#define E1000_FUNC_1     1
+
+/*
+ * Receive Address Register Count
+ * Number of high/low register pairs in the RAR.  The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor.
+ * These entries are also used for MAC-based filtering.
+ */
+#define E1000_RAR_ENTRIES_VF      1
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+	struct {
+		u64 pkt_addr;             /* Packet buffer address */
+		u64 hdr_addr;             /* Header buffer address */
+	} read;
+	struct {
+		struct {
+			union {
+				u32 data;
+				struct {
+					u16 pkt_info; /* RSS/Packet type */
+					u16 hdr_info; /* Split Header,
+					               * hdr buffer length */
+				} hs_rss;
+			} lo_dword;
+			union {
+				u32 rss;          /* RSS Hash */
+				struct {
+					u16 ip_id;    /* IP id */
+					u16 csum;     /* Packet Checksum */
+				} csum_ip;
+			} hi_dword;
+		} lower;
+		struct {
+			u32 status_error;     /* ext status/error */
+			u16 length;           /* Packet length */
+			u16 vlan;             /* VLAN tag */
+		} upper;
+	} wb;  /* writeback */
+};
+
+#define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
+#define E1000_RXDADV_HDRBUFLEN_SHIFT     5
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+	struct {
+		u64 buffer_addr;    /* Address of descriptor's data buf */
+		u32 cmd_type_len;
+		u32 olinfo_status;
+	} read;
+	struct {
+		u64 rsvd;       /* Reserved */
+		u32 nxtseq_seed;
+		u32 status;
+	} wb;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_EOP     0x01000000 /* End of Packet */
+#define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_RS      0x08000000 /* Report Status */
+#define E1000_ADVTXD_DCMD_DEXT    0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE     0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE     0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+
+/* Context descriptors */
+struct e1000_adv_tx_context_desc {
+	u32 vlan_macip_lens;
+	u32 seqnum_seed;
+	u32 type_tucmd_mlhl;
+	u32 mss_l4len_idx;
+};
+
+#define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
+#define E1000_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */
+#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
+#define E1000_ADVTXD_MSS_SHIFT      16  /* Adv ctxt MSS shift */
+
+enum e1000_mac_type {
+	e1000_undefined = 0,
+	e1000_vfadapt,
+	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
+};
+
+struct e1000_vf_stats {
+	u64 base_gprc;
+	u64 base_gptc;
+	u64 base_gorc;
+	u64 base_gotc;
+	u64 base_mprc;
+	u64 base_gotlbc;
+	u64 base_gptlbc;
+	u64 base_gorlbc;
+	u64 base_gprlbc;
+
+	u32 last_gprc;
+	u32 last_gptc;
+	u32 last_gorc;
+	u32 last_gotc;
+	u32 last_mprc;
+	u32 last_gotlbc;
+	u32 last_gptlbc;
+	u32 last_gorlbc;
+	u32 last_gprlbc;
+
+	u64 gprc;
+	u64 gptc;
+	u64 gorc;
+	u64 gotc;
+	u64 mprc;
+	u64 gotlbc;
+	u64 gptlbc;
+	u64 gorlbc;
+	u64 gprlbc;
+};
+
+#include "mbx.h"
+
+struct e1000_mac_operations {
+	/* Function pointers for the MAC. */
+	s32  (*init_params)(struct e1000_hw *);
+	s32  (*check_for_link)(struct e1000_hw *);
+	void (*clear_vfta)(struct e1000_hw *);
+	s32  (*get_bus_info)(struct e1000_hw *);
+	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
+	s32  (*reset_hw)(struct e1000_hw *);
+	s32  (*init_hw)(struct e1000_hw *);
+	s32  (*setup_link)(struct e1000_hw *);
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
+	void (*mta_set)(struct e1000_hw *, u32);
+	void (*rar_set)(struct e1000_hw *, u8*, u32);
+	s32  (*read_mac_addr)(struct e1000_hw *);
+	s32  (*set_vfta)(struct e1000_hw *, u16, bool);
+};
+
+struct e1000_mac_info {
+	struct e1000_mac_operations ops;
+	u8 addr[6];
+	u8 perm_addr[6];
+
+	enum e1000_mac_type type;
+
+	u16 mta_reg_count;
+	u16 rar_entry_count;
+
+	bool get_link_status;
+};
+
+struct e1000_mbx_operations {
+	s32 (*init_params)(struct e1000_hw *hw);
+	s32 (*read)(struct e1000_hw *, u32 *, u16);
+	s32 (*write)(struct e1000_hw *, u32 *, u16);
+	s32 (*read_posted)(struct e1000_hw *, u32 *, u16);
+	s32 (*write_posted)(struct e1000_hw *, u32 *, u16);
+	s32 (*check_for_msg)(struct e1000_hw *);
+	s32 (*check_for_ack)(struct e1000_hw *);
+	s32 (*check_for_rst)(struct e1000_hw *);
+};
+
+struct e1000_mbx_stats {
+	u32 msgs_tx;
+	u32 msgs_rx;
+
+	u32 acks;
+	u32 reqs;
+	u32 rsts;
+};
+
+struct e1000_mbx_info {
+	struct e1000_mbx_operations ops;
+	struct e1000_mbx_stats stats;
+	u32 timeout;
+	u32 usec_delay;
+	u16 size;
+};
+
+struct e1000_dev_spec_vf {
+	u32 vf_number;
+	u32 v2p_mailbox;
+};
+
+struct e1000_hw {
+	void *back;
+
+	u8 __iomem *hw_addr;
+	u8 __iomem *flash_address;
+	unsigned long io_base;
+
+	struct e1000_mac_info  mac;
+	struct e1000_mbx_info mbx;
+
+	union {
+		struct e1000_dev_spec_vf vf;
+	} dev_spec;
+
+	u16 device_id;
+	u16 subsystem_vendor_id;
+	u16 subsystem_device_id;
+	u16 vendor_id;
+
+	u8  revision_id;
+};
+
+/* These functions must be implemented by drivers */
+void e1000_rlpml_set_vf(struct e1000_hw *, u16);
+void e1000_init_function_pointers_vf(struct e1000_hw *hw);
+
+
+#endif /* _E1000_VF_H_ */
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index cbc63ff13add..c5593f4665a4 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1214,6 +1214,19 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
 }
 #endif
 
+static const struct net_device_ops ioc3_netdev_ops = {
+	.ndo_open		= ioc3_open,
+	.ndo_stop		= ioc3_close,
+	.ndo_start_xmit		= ioc3_start_xmit,
+	.ndo_tx_timeout		= ioc3_timeout,
+	.ndo_get_stats		= ioc3_get_stats,
+	.ndo_set_multicast_list	= ioc3_set_multicast_list,
+	.ndo_do_ioctl		= ioc3_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= ioc3_set_mac_address,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int __devinit ioc3_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -1310,15 +1323,8 @@ static int __devinit ioc3_probe(struct pci_dev *pdev,
 	ioc3_get_eaddr(ip);
 
 	/* The IOC3-specific entries in the device structure. */
-	dev->open		= ioc3_open;
-	dev->hard_start_xmit	= ioc3_start_xmit;
-	dev->tx_timeout		= ioc3_timeout;
 	dev->watchdog_timeo	= 5 * HZ;
-	dev->stop		= ioc3_close;
-	dev->get_stats		= ioc3_get_stats;
-	dev->do_ioctl		= ioc3_ioctl;
-	dev->set_multicast_list	= ioc3_set_multicast_list;
-	dev->set_mac_address	= ioc3_set_mac_address;
+	dev->netdev_ops		= &ioc3_netdev_ops;
 	dev->ethtool_ops	= &ioc3_ethtool_ops;
 	dev->features		= NETIF_F_IP_CSUM;
 
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
index 3126678bdd3c..73585fd8f29f 100644
--- a/drivers/net/isa-skeleton.c
+++ b/drivers/net/isa-skeleton.c
@@ -181,6 +181,18 @@ out:
 }
 #endif
 
+static const struct net_device_ops netcard_netdev_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_start_xmit		= net_send_packet,
+	.ndo_get_stats		= net_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_tx_timeout		= net_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /*
  * This is the real probe routine. Linux has a history of friendly device
  * probes on the ISA bus. A good device probes avoids doing writes, and
@@ -303,13 +315,7 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr)
 	np = netdev_priv(dev);
 	spin_lock_init(&np->lock);
 
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit	= net_send_packet;
-	dev->get_stats		= net_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-
-        dev->tx_timeout		= &net_tx_timeout;
+        dev->netdev_ops		= &netcard_netdev_ops;
         dev->watchdog_timeo	= MY_TX_TIMEOUT;
 
 	err = register_netdev(dev);
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index de4db0dc7879..4791238c3f6e 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -885,61 +885,6 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_blink_led_start_82598 - Blink LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to blink
- **/
-static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
-{
-	ixgbe_link_speed speed = 0;
-	bool link_up = 0;
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	/*
-	 * Link must be up to auto-blink the LEDs on the 82598EB MAC;
-	 * force it if link is down.
-	 */
-	hw->mac.ops.check_link(hw, &speed, &link_up, false);
-
-	if (!link_up) {
-		autoc_reg |= IXGBE_AUTOC_FLU;
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		msleep(10);
-	}
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg |= IXGBE_LED_BLINK(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
- *  ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to stop blinking
- **/
-static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
-{
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	autoc_reg &= ~IXGBE_AUTOC_FLU;
-	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
-	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg &= ~IXGBE_LED_BLINK(index);
-	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
  *  @hw: pointer to hardware structure
  *  @reg: analog register to read
@@ -1128,8 +1073,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
 	.get_link_capabilities	= &ixgbe_get_link_capabilities_82598,
 	.led_on			= &ixgbe_led_on_generic,
 	.led_off		= &ixgbe_led_off_generic,
-	.blink_led_start	= &ixgbe_blink_led_start_82598,
-	.blink_led_stop		= &ixgbe_blink_led_stop_82598,
+	.blink_led_start	= &ixgbe_blink_led_start_generic,
+	.blink_led_stop		= &ixgbe_blink_led_stop_generic,
 	.set_rar		= &ixgbe_set_rar_generic,
 	.clear_rar		= &ixgbe_clear_rar_generic,
 	.set_vmdq		= &ixgbe_set_vmdq_82598,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index beae7e012609..29771fbaa42d 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -68,8 +68,6 @@ s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
 s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
                          u32 vind, bool vlan_on);
 s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
-s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
 s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
@@ -991,40 +989,6 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_blink_led_start_82599 - Blink LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to blink
- **/
-s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index)
-{
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg |= IXGBE_LED_BLINK(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
- *  ixgbe_blink_led_stop_82599 - Stop blinking LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to stop blinking
- **/
-s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index)
-{
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg &= ~IXGBE_LED_BLINK(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
  *  ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
  *  @hw: pointer to hardware structure
  **/
@@ -1243,8 +1207,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
 	.get_link_capabilities  = &ixgbe_get_link_capabilities_82599,
 	.led_on                 = &ixgbe_led_on_generic,
 	.led_off                = &ixgbe_led_off_generic,
-	.blink_led_start        = &ixgbe_blink_led_start_82599,
-	.blink_led_stop         = &ixgbe_blink_led_stop_82599,
+	.blink_led_start        = &ixgbe_blink_led_start_generic,
+	.blink_led_stop         = &ixgbe_blink_led_stop_generic,
 	.set_rar                = &ixgbe_set_rar_generic,
 	.clear_rar              = &ixgbe_clear_rar_generic,
 	.set_vmdq               = &ixgbe_set_vmdq_82599,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 63ab6671d08e..5567519676d5 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -2071,3 +2071,58 @@ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
 
 	return 0;
 }
+
+/**
+ *  ixgbe_blink_led_start_generic - Blink LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to blink
+ **/
+s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
+{
+	ixgbe_link_speed speed = 0;
+	bool link_up = 0;
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	/*
+	 * Link must be up to auto-blink the LEDs;
+	 * Force it if link is down.
+	 */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+	if (!link_up) {
+		autoc_reg |= IXGBE_AUTOC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+		msleep(10);
+	}
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg |= IXGBE_LED_BLINK(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to stop blinking
+ **/
+s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
+{
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	autoc_reg &= ~IXGBE_AUTOC_FLU;
+	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg &= ~IXGBE_LED_BLINK(index);
+	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 24f73e719c3f..dd260890ad0a 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -76,6 +76,9 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
 s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
 
+s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
+
 #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
 
 #ifndef writeq
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 470b676c1dae..f4417fc3b0fd 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -290,7 +290,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
 s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
                                struct ixgbe_dcb_config *dcb_config)
 {
-	u32 i, reg;
+	u32 i, reg, rx_pba_size;
 
 	/* If PFC is disabled globally then fall back to LFC. */
 	if (!dcb_config->pfc_mode_enable) {
@@ -301,17 +301,23 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
 
 	/* Configure PFC Tx thresholds per TC */
 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
-		/* Config and remember Tx */
+		if (dcb_config->rx_pba_cfg == pba_equal)
+			rx_pba_size = IXGBE_RXPBSIZE_64KB;
+		else
+			rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
+			                      : IXGBE_RXPBSIZE_48KB;
+
+		reg = ((rx_pba_size >> 5) & 0xFFE0);
 		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
-		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) {
-			reg = hw->fc.high_water | IXGBE_FCRTH_FCEN;
-			IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
-			reg = hw->fc.low_water | IXGBE_FCRTL_XONE;
-			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
-		} else {
-			IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
-			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
-		}
+		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+			reg |= IXGBE_FCRTL_XONE;
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+
+		reg = ((rx_pba_size >> 2) & 0xFFE0);
+		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+			reg |= IXGBE_FCRTH_FCEN;
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
 	}
 
 	/* Configure pause time (2 TCs per register) */
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index aafc120f164e..f0a20facc650 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -943,6 +943,24 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
 }
 
 
+static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
+                               struct ethtool_wolinfo *wol)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int retval = 1;
+
+	switch(hw->device_id) {
+	case IXGBE_DEV_ID_82599_KX4:
+		retval = 0;
+		break;
+	default:
+		wol->supported = 0;
+		retval = 0;
+	}
+
+	return retval;
+}
+
 static void ixgbe_get_wol(struct net_device *netdev,
                           struct ethtool_wolinfo *wol)
 {
@@ -952,7 +970,8 @@ static void ixgbe_get_wol(struct net_device *netdev,
 	                 WAKE_BCAST | WAKE_MAGIC;
 	wol->wolopts = 0;
 
-	if (!device_can_wakeup(&adapter->pdev->dev))
+	if (ixgbe_wol_exclusion(adapter, wol) ||
+	    !device_can_wakeup(&adapter->pdev->dev))
 		return;
 
 	if (adapter->wol & IXGBE_WUFC_EX)
@@ -974,6 +993,9 @@ static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
 		return -EOPNOTSUPP;
 
+	if (ixgbe_wol_exclusion(adapter, wol))
+		return wol->wolopts ? -EOPNOTSUPP : 0;
+
 	adapter->wol = 0;
 
 	if (wol->wolopts & WAKE_UCAST)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 9ef128ae6458..01884256f4c9 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2723,17 +2723,21 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
  **/
 static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
 {
-	/* Start with base case */
-	adapter->num_rx_queues = 1;
-	adapter->num_tx_queues = 1;
-
 #ifdef CONFIG_IXGBE_DCB
 	if (ixgbe_set_dcb_queues(adapter))
-		return;
+		goto done;
 
 #endif
 	if (ixgbe_set_rss_queues(adapter))
-		return;
+		goto done;
+
+	/* fallback to base case */
+	adapter->num_rx_queues = 1;
+	adapter->num_tx_queues = 1;
+
+done:
+	/* Notify the stack of the (possibly) reduced Tx Queue count. */
+	adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
 }
 
 static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
@@ -2837,11 +2841,55 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
 			}
 			ret = true;
 		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-			for (i = 0; i < dcb_i; i++) {
-				adapter->rx_ring[i].reg_idx = i << 4;
-				adapter->tx_ring[i].reg_idx = i << 4;
+			if (dcb_i == 8) {
+				/*
+				 * Tx TC0 starts at: descriptor queue 0
+				 * Tx TC1 starts at: descriptor queue 32
+				 * Tx TC2 starts at: descriptor queue 64
+				 * Tx TC3 starts at: descriptor queue 80
+				 * Tx TC4 starts at: descriptor queue 96
+				 * Tx TC5 starts at: descriptor queue 104
+				 * Tx TC6 starts at: descriptor queue 112
+				 * Tx TC7 starts at: descriptor queue 120
+				 *
+				 * Rx TC0-TC7 are offset by 16 queues each
+				 */
+				for (i = 0; i < 3; i++) {
+					adapter->tx_ring[i].reg_idx = i << 5;
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+				for ( ; i < 5; i++) {
+					adapter->tx_ring[i].reg_idx =
+					                         ((i + 2) << 4);
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+				for ( ; i < dcb_i; i++) {
+					adapter->tx_ring[i].reg_idx =
+					                         ((i + 8) << 3);
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+
+				ret = true;
+			} else if (dcb_i == 4) {
+				/*
+				 * Tx TC0 starts at: descriptor queue 0
+				 * Tx TC1 starts at: descriptor queue 64
+				 * Tx TC2 starts at: descriptor queue 96
+				 * Tx TC3 starts at: descriptor queue 112
+				 *
+				 * Rx TC0-TC3 are offset by 32 queues each
+				 */
+				adapter->tx_ring[0].reg_idx = 0;
+				adapter->tx_ring[1].reg_idx = 64;
+				adapter->tx_ring[2].reg_idx = 96;
+				adapter->tx_ring[3].reg_idx = 112;
+				for (i = 0 ; i < dcb_i; i++)
+					adapter->rx_ring[i].reg_idx = i << 5;
+
+				ret = true;
+			} else {
+				ret = false;
 			}
-			ret = true;
 		} else {
 			ret = false;
 		}
@@ -2992,9 +3040,6 @@ try_msi:
 	}
 
 out:
-	/* Notify the stack of the (possibly) reduced Tx Queue count. */
-	adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
-
 	return err;
 }
 
@@ -3611,9 +3656,9 @@ static int ixgbe_resume(struct pci_dev *pdev)
 
 	return 0;
 }
-
 #endif /* CONFIG_PM */
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+
+static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3672,18 +3717,46 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
 		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
+	*enable_wake = !!wufc;
+
 	ixgbe_release_hw_control(adapter);
 
 	pci_disable_device(pdev);
 
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __ixgbe_shutdown(pdev, &wake);
+	if (retval)
+		return retval;
+
+	if (wake) {
+		pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 static void ixgbe_shutdown(struct pci_dev *pdev)
 {
-	ixgbe_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+
+	__ixgbe_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, wake);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 /**
@@ -3917,7 +3990,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
 	}
 	hw->mac.ops.setup_sfp(hw);
 
-	if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)
+	if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
 		/* This will also work for DA Twinax connections */
 		schedule_work(&adapter->multispeed_fiber_task);
 	adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
@@ -4342,7 +4415,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	int count = 0;
 	unsigned int f;
 
-	r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
+	r_idx = skb->queue_mapping;
 	tx_ring = &adapter->tx_ring[r_idx];
 
 	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index ece35040288c..621a7c0c46ba 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -2591,13 +2591,13 @@ static int
 jme_pci_dma64(struct pci_dev *pdev)
 {
 	if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
-		if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
 			return 1;
 
 	if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
-	    !pci_set_dma_mask(pdev, DMA_40BIT_MASK))
-		if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK))
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(40)))
+		if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)))
 			return 1;
 
 	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index 380a1a54d530..384e072de2e7 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -168,6 +168,17 @@ writereg(struct net_device *dev, int portno, int value)
 	nubus_writew(swab16(value), dev->mem_start + portno);
 }
 
+static const struct net_device_ops mac89x0_netdev_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_start_xmit		= net_send_packet,
+	.ndo_get_stats		= net_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_set_mac_address	= set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /* Probe for the CS8900 card in slot E.  We won't bother looking
    anywhere else until we have a really good reason to do so. */
 struct net_device * __init mac89x0_probe(int unit)
@@ -280,12 +291,7 @@ struct net_device * __init mac89x0_probe(int unit)
 
 	printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
 
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit = net_send_packet;
-	dev->get_stats	= net_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = &set_mac_address;
+	dev->netdev_ops		= &mac89x0_netdev_ops;
 
 	err = register_netdev(dev);
 	if (err)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index f50501013b1c..e82aee41d77e 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -316,10 +316,11 @@ static void macb_tx(struct macb *bp)
 	dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
 		(unsigned long)status);
 
-	if (status & MACB_BIT(UND)) {
+	if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
 		int i;
-		printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
-			bp->dev->name);
+		printk(KERN_ERR "%s: TX %s, resetting buffers\n",
+			bp->dev->name, status & MACB_BIT(UND) ?
+			"underrun" : "retry limit exceeded");
 
 		/* Transfer ongoing, disable transmitter, to avoid confusion */
 		if (status & MACB_BIT(TGO))
@@ -520,27 +521,10 @@ static int macb_poll(struct napi_struct *napi, int budget)
 	macb_writel(bp, RSR, status);
 
 	work_done = 0;
-	if (!status) {
-		/*
-		 * This may happen if an interrupt was pending before
-		 * this function was called last time, and no packets
-		 * have been received since.
-		 */
-		napi_complete(napi);
-		goto out;
-	}
 
 	dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
 		(unsigned long)status, budget);
 
-	if (!(status & MACB_BIT(REC))) {
-		dev_warn(&bp->pdev->dev,
-			 "No RX buffers complete, status = %02lx\n",
-			 (unsigned long)status);
-		napi_complete(napi);
-		goto out;
-	}
-
 	work_done = macb_rx(bp, budget);
 	if (work_done < budget)
 		napi_complete(napi);
@@ -549,7 +533,6 @@ static int macb_poll(struct napi_struct *napi, int budget)
 	 * We've done what we can to clean the buffers. Make sure we
 	 * get notified when new packets arrive.
 	 */
-out:
 	macb_writel(bp, IER, MACB_RX_INT_FLAGS);
 
 	/* TODO: Handle errors */
@@ -590,7 +573,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 			}
 		}
 
-		if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND)))
+		if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
+			    MACB_BIT(ISR_RLE)))
 			macb_tx(bp);
 
 		/*
@@ -1100,6 +1084,18 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
 }
 
+static const struct net_device_ops macb_netdev_ops = {
+	.ndo_open		= macb_open,
+	.ndo_stop		= macb_close,
+	.ndo_start_xmit		= macb_start_xmit,
+	.ndo_set_multicast_list	= macb_set_rx_mode,
+	.ndo_get_stats		= macb_get_stats,
+	.ndo_do_ioctl		= macb_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init macb_probe(struct platform_device *pdev)
 {
 	struct eth_platform_data *pdata;
@@ -1175,12 +1171,7 @@ static int __init macb_probe(struct platform_device *pdev)
 		goto err_out_iounmap;
 	}
 
-	dev->open = macb_open;
-	dev->stop = macb_close;
-	dev->hard_start_xmit = macb_start_xmit;
-	dev->get_stats = macb_get_stats;
-	dev->set_multicast_list = macb_set_rx_mode;
-	dev->do_ioctl = macb_ioctl;
+	dev->netdev_ops = &macb_netdev_ops;
 	netif_napi_add(dev, &bp->napi, macb_poll, 64);
 	dev->ethtool_ops = &macb_ethtool_ops;
 
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 527166e35d56..acd143da161d 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -167,6 +167,18 @@ static int macsonic_close(struct net_device* dev)
 	return err;
 }
 
+static const struct net_device_ops macsonic_netdev_ops = {
+	.ndo_open		= macsonic_open,
+	.ndo_stop		= macsonic_close,
+	.ndo_start_xmit		= sonic_send_packet,
+	.ndo_set_multicast_list	= sonic_multicast_list,
+	.ndo_tx_timeout		= sonic_tx_timeout,
+	.ndo_get_stats		= sonic_get_stats,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init macsonic_init(struct net_device *dev)
 {
 	struct sonic_local* lp = netdev_priv(dev);
@@ -198,12 +210,7 @@ static int __init macsonic_init(struct net_device *dev)
 	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-	dev->open = macsonic_open;
-	dev->stop = macsonic_close;
-	dev->hard_start_xmit = sonic_send_packet;
-	dev->get_stats = sonic_get_stats;
-	dev->set_multicast_list = &sonic_multicast_list;
-	dev->tx_timeout = sonic_tx_timeout;
+	dev->netdev_ops = &macsonic_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	/*
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 70d3ef4a2c5f..214a8cf2b708 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -376,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (lowerdev->ethtool_ops->get_rx_csum == NULL)
+	if (lowerdev->ethtool_ops == NULL ||
+	    lowerdev->ethtool_ops->get_rx_csum == NULL)
 		return 0;
 	return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
 }
@@ -387,7 +388,8 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (!lowerdev->ethtool_ops->get_settings)
+	if (!lowerdev->ethtool_ops ||
+	    !lowerdev->ethtool_ops->get_settings)
 		return -EOPNOTSUPP;
 
 	return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
@@ -398,7 +400,8 @@ static u32 macvlan_ethtool_get_flags(struct net_device *dev)
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (!lowerdev->ethtool_ops->get_flags)
+	if (!lowerdev->ethtool_ops ||
+	    !lowerdev->ethtool_ops->get_flags)
 		return 0;
 	return lowerdev->ethtool_ops->get_flags(lowerdev);
 }
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index eda72dd2120f..510633fd57f6 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -181,7 +181,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
 	mdev->workqueue = create_singlethread_workqueue("mlx4_en");
 	if (!mdev->workqueue) {
 		err = -ENOMEM;
-		goto err_close_nic;
+		goto err_mr;
 	}
 
 	/* At this stage all non-port specific tasks are complete:
@@ -214,9 +214,8 @@ err_free_netdev:
 	flush_workqueue(mdev->workqueue);
 
 	/* Stop event queue before we drop down to release shared SW state */
-
-err_close_nic:
 	destroy_workqueue(mdev->workqueue);
+
 err_mr:
 	mlx4_mr_free(dev, &mdev->mr);
 err_uar:
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 303c23de6cac..438678ab2a10 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -348,11 +348,9 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
 	if (netif_msg_timer(priv))
 		mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
 
-	if (netif_carrier_ok(dev)) {
-		priv->port_stats.tx_timeout++;
-		mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
-		queue_work(mdev->workqueue, &priv->watchdog_task);
-	}
+	priv->port_stats.tx_timeout++;
+	mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+	queue_work(mdev->workqueue, &priv->watchdog_task);
 }
 
 
@@ -761,9 +759,14 @@ static void mlx4_en_restart(struct work_struct *work)
 	struct net_device *dev = priv->dev;
 
 	mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
-	mlx4_en_stop_port(dev);
-	if (mlx4_en_start_port(dev))
-	    mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+
+	mutex_lock(&mdev->state_lock);
+	if (priv->port_up) {
+		mlx4_en_stop_port(dev);
+		if (mlx4_en_start_port(dev))
+			mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+	}
+	mutex_unlock(&mdev->state_lock);
 }
 
 
@@ -1054,7 +1057,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 	 * Set driver features
 	 */
 	dev->features |= NETIF_F_SG;
-	dev->features |= NETIF_F_HW_CSUM;
+	dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	dev->features |= NETIF_F_HIGHDMA;
 	dev->features |= NETIF_F_HW_VLAN_TX |
 			 NETIF_F_HW_VLAN_RX |
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index c5a4c0389752..a29abe845d2e 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -151,6 +151,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 	struct mlx4_cmd_mailbox *mailbox;
 	u64 in_mod = reset << 8 | port;
 	int err;
+	int i;
 
 	mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
 	if (IS_ERR(mailbox))
@@ -165,38 +166,18 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 
 	spin_lock_bh(&priv->stats_lock);
 
-	stats->rx_packets = be32_to_cpu(mlx4_en_stats->RTOTFRMS) -
-			    be32_to_cpu(mlx4_en_stats->RDROP);
-	stats->tx_packets = be64_to_cpu(mlx4_en_stats->TTOT_prio_0) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_1) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_2) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_3) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_4) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_5) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_6) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_7) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_novlan) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_loopbk);
-	stats->rx_bytes = be64_to_cpu(mlx4_en_stats->ROCT_prio_0) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_1) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_2) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_3) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_4) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_5) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_6) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_7) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_novlan);
-
-	stats->tx_bytes = be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_0) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_1) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_2) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_3) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_4) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_5) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_6) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_7) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_novlan) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_loopbk);
+	stats->rx_packets = 0;
+	stats->rx_bytes = 0;
+	for (i = 0; i < priv->rx_ring_num; i++) {
+		stats->rx_packets += priv->rx_ring[i].packets;
+		stats->rx_bytes += priv->rx_ring[i].bytes;
+	}
+	stats->tx_packets = 0;
+	stats->tx_bytes = 0;
+	for (i = 0; i <= priv->tx_ring_num; i++) {
+		stats->tx_packets += priv->tx_ring[i].packets;
+		stats->tx_bytes += priv->tx_ring[i].bytes;
+	}
 
 	stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) +
 			   be32_to_cpu(mlx4_en_stats->RdropLength) +
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c
index a0545209e507..65ca706c04bb 100644
--- a/drivers/net/mlx4/en_resources.c
+++ b/drivers/net/mlx4/en_resources.c
@@ -94,3 +94,9 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf)
 
 	vunmap(buf->direct.buf);
 }
+
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
+{
+    return;
+}
+
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 7e40741fb7d8..0cbb78ca7b29 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -436,8 +436,9 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 		/* Initialize page allocators */
 		err = mlx4_en_init_allocator(priv, ring);
 		if (err) {
-			 mlx4_err(mdev, "Failed initializing ring allocator\n");
-			 goto err_allocator;
+			mlx4_err(mdev, "Failed initializing ring allocator\n");
+			ring_ind--;
+			goto err_allocator;
 		}
 
 		/* Fill Rx buffers */
@@ -467,6 +468,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 				     ring->wqres.db.dma, &ring->srq);
 		if (err){
 			mlx4_err(mdev, "Failed to allocate srq\n");
+			ring_ind--;
 			goto err_srq;
 		}
 		ring->srq.event = mlx4_en_srq_event;
@@ -926,12 +928,6 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
 	}
 }
 
-static void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
-{
-    return;
-}
-
-
 static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
 				 int qpn, int srqn, int cqn,
 				 enum mlx4_qp_state *state,
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 4afd5993e31c..ac6fc499b280 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -112,6 +112,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
 		mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
 		goto err_reserve;
 	}
+	ring->qp.event = mlx4_en_sqp_event;
 
 	return 0;
 
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 102bac90a302..30bea9689694 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -976,7 +976,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
 				nreq = err;
 				goto retry;
 			}
-
+			kfree(entries);
 			goto no_msi;
 		}
 
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index e9af32d41ca4..ef840abbcd39 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -538,6 +538,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
 void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 			     int is_tx, int rss, int qpn, int cqn, int srqn,
 			     struct mlx4_qp_context *context);
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
 int mlx4_en_map_buffer(struct mlx4_buf *buf);
 void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
 
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
index 7cce3342ef8c..606aa58afdea 100644
--- a/drivers/net/mlx4/port.c
+++ b/drivers/net/mlx4/port.c
@@ -299,13 +299,14 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
 	struct mlx4_cmd_mailbox *mailbox;
 	int err;
 
+	if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
+		return 0;
+
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
 
 	memset(mailbox->buf, 0, 256);
-	if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
-		return 0;
 
 	((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
 	err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a56d9d2df73f..b3185bf2c158 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2274,8 +2274,6 @@ static void port_start(struct mv643xx_eth_private *mp)
 		pscr |= FORCE_LINK_PASS;
 	wrlp(mp, PORT_SERIAL_CONTROL, pscr);
 
-	wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
-
 	/*
 	 * Configure TX path and queues.
 	 */
@@ -2957,6 +2955,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 
 	netif_carrier_off(dev);
 
+	wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
+
 	set_rx_coal(mp, 250);
 	set_tx_coal(mp, 0);
 
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 9eed126a82f0..f2c4a665e93f 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2447,6 +2447,7 @@ static int myri10ge_open(struct net_device *dev)
 		lro_mgr->lro_arr = ss->rx_done.lro_desc;
 		lro_mgr->get_frag_header = myri10ge_get_frag_header;
 		lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+		lro_mgr->frag_align_pad = 2;
 		if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
 			lro_mgr->max_aggr = MAX_SKB_FRAGS;
 
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 73cac6c78cb6..2b1745328cf7 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -4834,6 +4834,7 @@ static int niu_compute_rbr_cfig_b(struct rx_ring_info *rp, u64 *ret)
 {
 	u64 val = 0;
 
+	*ret = 0;
 	switch (rp->rbr_block_size) {
 	case 4 * 1024:
 		val |= (RBR_BLKSIZE_4K << RBR_CFIG_B_BLKSIZE_SHIFT);
@@ -9542,7 +9543,7 @@ static struct niu_parent * __devinit niu_new_parent(struct niu *np,
 
 	plat_dev = platform_device_register_simple("niu", niu_parent_index,
 						   NULL, 0);
-	if (!plat_dev)
+	if (IS_ERR(plat_dev))
 		return NULL;
 
 	for (i = 0; attr_name(niu_parent_attributes[i]); i++) {
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2fbf9f9ddd37..652a36888361 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1758,7 +1758,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
-	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.cis"),
+	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index cf24cc34debe..e7070515d2e3 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -19,6 +19,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
+#include <linux/err.h>
 
 #define MII_REGS_NUM 29
 
@@ -207,8 +208,8 @@ static int __init fixed_mdio_bus_init(void)
 	int ret;
 
 	pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
-	if (!pdev) {
-		ret = -ENOMEM;
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
 		goto err_pdev;
 	}
 
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index eb6411c4694f..7a3ec9d39a9a 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -69,6 +69,11 @@
 #define MII_M1111_COPPER		0
 #define MII_M1111_FIBER			1
 
+#define MII_88E1121_PHY_LED_CTRL	16
+#define MII_88E1121_PHY_LED_PAGE	3
+#define MII_88E1121_PHY_LED_DEF		0x0030
+#define MII_88E1121_PHY_PAGE		22
+
 #define MII_M1011_PHY_STATUS		0x11
 #define MII_M1011_PHY_STATUS_1000	0x8000
 #define MII_M1011_PHY_STATUS_100	0x4000
@@ -154,6 +159,30 @@ static int marvell_config_aneg(struct phy_device *phydev)
 	return err;
 }
 
+static int m88e1121_config_aneg(struct phy_device *phydev)
+{
+	int err, temp;
+
+	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, MII_M1011_PHY_SCR,
+			MII_M1011_PHY_SCR_AUTO_CROSS);
+	if (err < 0)
+		return err;
+
+	temp = phy_read(phydev, MII_88E1121_PHY_PAGE);
+
+	phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
+	phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
+	phy_write(phydev, MII_88E1121_PHY_PAGE, temp);
+
+	err = genphy_config_aneg(phydev);
+
+	return err;
+}
+
 static int m88e1111_config_init(struct phy_device *phydev)
 {
 	int err;
@@ -429,6 +458,18 @@ static int marvell_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+static int m88e1121_did_interrupt(struct phy_device *phydev)
+{
+	int imask;
+
+	imask = phy_read(phydev, MII_M1011_IEVENT);
+
+	if (imask & MII_M1011_IMASK_INIT)
+		return 1;
+
+	return 0;
+}
+
 static struct phy_driver marvell_drivers[] = {
 	{
 		.phy_id = 0x01410c60,
@@ -482,6 +523,19 @@ static struct phy_driver marvell_drivers[] = {
 		.driver = {.owner = THIS_MODULE,},
 	},
 	{
+		.phy_id = 0x01410cb0,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1121R",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_aneg = &m88e1121_config_aneg,
+		.read_status = &marvell_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.did_interrupt = &m88e1121_did_interrupt,
+		.driver = { .owner = THIS_MODULE },
+	},
+	{
 		.phy_id = 0x01410cd0,
 		.phy_id_mask = 0xfffffff0,
 		.name = "Marvell 88E1145",
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3ff1f425f1bb..61755cbd978e 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -434,7 +434,7 @@ void phy_start_machine(struct phy_device *phydev,
 	phydev->adjust_state = handler;
 
 	INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
-	schedule_delayed_work(&phydev->state_queue, jiffies + HZ);
+	schedule_delayed_work(&phydev->state_queue, HZ);
 }
 
 /**
@@ -655,6 +655,10 @@ static void phy_change(struct work_struct *work)
 	struct phy_device *phydev =
 		container_of(work, struct phy_device, phy_queue);
 
+	if (phydev->drv->did_interrupt &&
+	    !phydev->drv->did_interrupt(phydev))
+		goto ignore;
+
 	err = phy_disable_interrupts(phydev);
 
 	if (err)
@@ -681,6 +685,11 @@ static void phy_change(struct work_struct *work)
 
 	return;
 
+ignore:
+	atomic_dec(&phydev->irq_disable);
+	enable_irq(phydev->irq);
+	return;
+
 irq_enable_err:
 	disable_irq(phydev->irq);
 	atomic_inc(&phydev->irq_disable);
@@ -937,6 +946,5 @@ static void phy_state_machine(struct work_struct *work)
 	if (err < 0)
 		phy_error(phydev);
 
-	schedule_delayed_work(&phydev->state_queue,
-				jiffies + PHY_STATE_TIME * HZ);
+	schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
 }
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index a5ac2bd58b5b..4f3ada622f9b 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2101,6 +2101,9 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
 	if (ret) {
 		pr_debug("%s: WEP/WPA setup failed %d\n", __func__,
 			 ret);
+		ret = -EPERM;
+		gelic_wl_send_iwap_event(wl, NULL);
+		goto out;
 	}
 
 	/* start association */
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 5e8540b6ffa1..6f97b47d74a6 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -160,6 +160,7 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
 	"Florian Fainelli <florian@openwrt.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
+MODULE_VERSION(DRV_VERSION " " DRV_RELDATE);
 
 /* RX and TX interrupts that we handle */
 #define RX_INTS			(RX_FIFO_FULL | RX_NO_DESC | RX_FINISH)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index dee23b159df2..7269a426051c 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -448,9 +448,6 @@ static void efx_init_channels(struct efx_nic *efx)
 
 		WARN_ON(channel->rx_pkt != NULL);
 		efx_rx_strategy(channel);
-
-		netif_napi_add(channel->napi_dev, &channel->napi_str,
-			       efx_poll, napi_weight);
 	}
 }
 
@@ -1321,6 +1318,8 @@ static int efx_init_napi(struct efx_nic *efx)
 
 	efx_for_each_channel(channel, efx) {
 		channel->napi_dev = efx->net_dev;
+		netif_napi_add(channel->napi_dev, &channel->napi_str,
+			       efx_poll, napi_weight);
 	}
 	return 0;
 }
@@ -1330,6 +1329,8 @@ static void efx_fini_napi(struct efx_nic *efx)
 	struct efx_channel *channel;
 
 	efx_for_each_channel(channel, efx) {
+		if (channel->napi_dev)
+			netif_napi_del(&channel->napi_str);
 		channel->napi_dev = NULL;
 	}
 }
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index d4629ab2c614..466a8abb0053 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1176,9 +1176,9 @@ void falcon_sim_phy_event(struct efx_nic *efx)
 
 	EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE);
 	if (EFX_IS10G(efx))
-		EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1);
+		EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1);
 	else
-		EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1);
+		EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1);
 
 	falcon_generate_event(&efx->channel[0], &phy_event);
 }
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 7b1882765a0c..3ab28bb00c12 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1188,6 +1188,19 @@ out:
 	return ret;
 }
 
+static const struct net_device_ops sh_eth_netdev_ops = {
+	.ndo_open		= sh_eth_open,
+	.ndo_stop		= sh_eth_close,
+	.ndo_start_xmit		= sh_eth_start_xmit,
+	.ndo_get_stats		= sh_eth_get_stats,
+	.ndo_set_multicast_list	= sh_eth_set_multicast_list,
+	.ndo_tx_timeout		= sh_eth_tx_timeout,
+	.ndo_do_ioctl		= sh_eth_do_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int sh_eth_drv_probe(struct platform_device *pdev)
 {
 	int ret, i, devno = 0;
@@ -1240,13 +1253,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	mdp->edmac_endian = pd->edmac_endian;
 
 	/* set function */
-	ndev->open = sh_eth_open;
-	ndev->hard_start_xmit = sh_eth_start_xmit;
-	ndev->stop = sh_eth_close;
-	ndev->get_stats = sh_eth_get_stats;
-	ndev->set_multicast_list = sh_eth_set_multicast_list;
-	ndev->do_ioctl = sh_eth_do_ioctl;
-	ndev->tx_timeout = sh_eth_tx_timeout;
+	ndev->netdev_ops = &sh_eth_netdev_ops;
 	ndev->watchdog_timeo = TX_TIMEOUT;
 
 	mdp->post_rx = POST_RX >> (devno << 1);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index b8978d4af1b7..c11cdd08ec57 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2674,7 +2674,7 @@ static int skge_down(struct net_device *dev)
 	if (netif_msg_ifdown(skge))
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
-	netif_stop_queue(dev);
+	netif_tx_disable(dev);
 
 	if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
 		del_timer_sync(&skge->link_timer);
@@ -2881,7 +2881,6 @@ static void skge_tx_clean(struct net_device *dev)
 	}
 
 	skge->tx_ring.to_clean = e;
-	netif_wake_queue(dev);
 }
 
 static void skge_tx_timeout(struct net_device *dev)
@@ -2893,6 +2892,7 @@ static void skge_tx_timeout(struct net_device *dev)
 
 	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP);
 	skge_tx_clean(dev);
+	netif_wake_queue(dev);
 }
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 912308eec865..329f890e2903 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -369,7 +369,7 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
  * MN10300/AM33 configuration
  */
 
-#include <asm/unit/smc91111.h>
+#include <unit/smc91111.h>
 
 #else
 
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 6da678129828..eb7db032a780 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -317,7 +317,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
 			goto out;
 		}
 
-	SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+	SMSC_WARNING(HW, "Timed out waiting for MII read to finish");
 	reg = -EIO;
 
 out:
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index e0d84772771c..a39c0b9ba8b6 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -331,6 +331,18 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops sun3_82586_netdev_ops = {
+	.ndo_open		= sun3_82586_open,
+	.ndo_stop		= sun3_82586_close,
+	.ndo_start_xmit		= sun3_82586_send_packet,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_tx_timeout		= sun3_82586_timeout,
+	.ndo_get_stats		= sun3_82586_get_stats,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
 {
 	int i, size, retval;
@@ -381,13 +393,8 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
 
 	printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
 
-	dev->open		= sun3_82586_open;
-	dev->stop		= sun3_82586_close;
-	dev->get_stats		= sun3_82586_get_stats;
-	dev->tx_timeout 	= sun3_82586_timeout;
+	dev->netdev_ops		= &sun3_82586_netdev_ops;
 	dev->watchdog_timeo	= HZ/20;
-	dev->hard_start_xmit 	= sun3_82586_send_packet;
-	dev->set_multicast_list = set_multicast_list;
 
 	dev->if_port 		= 0;
 	return 0;
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index d91e95b237b7..0ce2db6ce2bf 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -862,6 +862,22 @@ static int __devinit tc35815_init_dev_addr(struct net_device *dev)
 	return 0;
 }
 
+static const struct net_device_ops tc35815_netdev_ops = {
+	.ndo_open		= tc35815_open,
+	.ndo_stop		= tc35815_close,
+	.ndo_start_xmit		= tc35815_send_packet,
+	.ndo_get_stats		= tc35815_get_stats,
+	.ndo_set_multicast_list	= tc35815_set_multicast_list,
+	.ndo_tx_timeout		= tc35815_tx_timeout,
+	.ndo_do_ioctl		= tc35815_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= tc35815_poll_controller,
+#endif
+};
+
 static int __devinit tc35815_init_one(struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
@@ -904,21 +920,12 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev,
 	ioaddr = pcim_iomap_table(pdev)[1];
 
 	/* Initialize the device structure. */
-	dev->open = tc35815_open;
-	dev->hard_start_xmit = tc35815_send_packet;
-	dev->stop = tc35815_close;
-	dev->get_stats = tc35815_get_stats;
-	dev->set_multicast_list = tc35815_set_multicast_list;
-	dev->do_ioctl = tc35815_ioctl;
+	dev->netdev_ops = &tc35815_netdev_ops;
 	dev->ethtool_ops = &tc35815_ethtool_ops;
-	dev->tx_timeout = tc35815_tx_timeout;
 	dev->watchdog_timeo = TC35815_TX_TIMEOUT;
 #ifdef TC35815_NAPI
 	netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT);
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tc35815_poll_controller;
-#endif
 
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long)ioaddr;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6a736dda3ee2..201be425643a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2190,7 +2190,14 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
 	if (!(tmp & EEPROM_ADDR_COMPLETE))
 		return -EBUSY;
 
-	*val = tr32(GRC_EEPROM_DATA);
+	tmp = tr32(GRC_EEPROM_DATA);
+
+	/*
+	 * The data will always be opposite the native endian
+	 * format.  Perform a blind byteswap to compensate.
+	 */
+	*val = swab32(tmp);
+
 	return 0;
 }
 
@@ -10663,7 +10670,13 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
 
 		memcpy(&data, buf + i, 4);
 
-		tw32(GRC_EEPROM_DATA, be32_to_cpu(data));
+		/*
+		 * The SEEPROM interface expects the data to always be opposite
+		 * the native endian format.  We accomplish this by reversing
+		 * all the operations that would have been performed on the
+		 * data from a call to tg3_nvram_read_be32().
+		 */
+		tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
 
 		val = tr32(GRC_EEPROM_ADDR);
 		tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index bb43e7fb2a50..0f78f99f9b20 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1561,6 +1561,18 @@ static const struct ethtool_ops tsi108_ethtool_ops = {
 	.set_settings	= tsi108_set_settings,
 };
 
+static const struct net_device_ops tsi108_netdev_ops = {
+	.ndo_open		= tsi108_open,
+	.ndo_stop		= tsi108_close,
+	.ndo_start_xmit		= tsi108_send_packet,
+	.ndo_set_multicast_list	= tsi108_set_rx_mode,
+	.ndo_get_stats		= tsi108_get_stats,
+	.ndo_do_ioctl		= tsi108_do_ioctl,
+	.ndo_set_mac_address	= tsi108_set_mac,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int
 tsi108_init_one(struct platform_device *pdev)
 {
@@ -1616,14 +1628,8 @@ tsi108_init_one(struct platform_device *pdev)
 	data->phy_type = einfo->phy_type;
 	data->irq_num = einfo->irq_num;
 	data->id = pdev->id;
-	dev->open = tsi108_open;
-	dev->stop = tsi108_close;
-	dev->hard_start_xmit = tsi108_send_packet;
-	dev->set_mac_address = tsi108_set_mac;
-	dev->set_multicast_list = tsi108_set_rx_mode;
-	dev->get_stats = tsi108_get_stats;
 	netif_napi_add(dev, &data->napi, tsi108_poll, 64);
-	dev->do_ioctl = tsi108_do_ioctl;
+	dev->netdev_ops = &tsi108_netdev_ops;
 	dev->ethtool_ops = &tsi108_ethtool_ops;
 
 	/* Apparently, the Linux networking code won't use scatter-gather
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a1b0697340ba..735bf41c654a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -93,7 +93,6 @@ struct tun_file {
 	atomic_t count;
 	struct tun_struct *tun;
 	struct net *net;
-	wait_queue_head_t	read_wait;
 };
 
 struct tun_sock;
@@ -156,6 +155,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
 	tfile->tun = tun;
 	tun->tfile = tfile;
 	dev_hold(tun->dev);
+	sock_hold(tun->sk);
 	atomic_inc(&tfile->count);
 
 out:
@@ -165,11 +165,8 @@ out:
 
 static void __tun_detach(struct tun_struct *tun)
 {
-	struct tun_file *tfile = tun->tfile;
-
 	/* Detach from net device */
 	netif_tx_lock_bh(tun->dev);
-	tfile->tun = NULL;
 	tun->tfile = NULL;
 	netif_tx_unlock_bh(tun->dev);
 
@@ -333,12 +330,19 @@ static void tun_net_uninit(struct net_device *dev)
 	/* Inform the methods they need to stop using the dev.
 	 */
 	if (tfile) {
-		wake_up_all(&tfile->read_wait);
+		wake_up_all(&tun->socket.wait);
 		if (atomic_dec_and_test(&tfile->count))
 			__tun_detach(tun);
 	}
 }
 
+static void tun_free_netdev(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	sock_put(tun->sk);
+}
+
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
 {
@@ -393,7 +397,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
 		kill_fasync(&tun->fasync, SIGIO, POLL_IN);
-	wake_up_interruptible(&tun->tfile->read_wait);
+	wake_up_interruptible(&tun->socket.wait);
 	return 0;
 
 drop:
@@ -490,7 +494,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
 
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
 
-	poll_wait(file, &tfile->read_wait, wait);
+	poll_wait(file, &tun->socket.wait, wait);
 
 	if (!skb_queue_empty(&tun->readq))
 		mask |= POLLIN | POLLRDNORM;
@@ -518,7 +522,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 	int err;
 
 	/* Under a page?  Don't bother with paged skb. */
-	if (prepad + len < PAGE_SIZE)
+	if (prepad + len < PAGE_SIZE || !linear)
 		linear = len;
 
 	skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
@@ -565,7 +569,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 
 	if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
 		align = NET_IP_ALIGN;
-		if (unlikely(len < ETH_HLEN))
+		if (unlikely(len < ETH_HLEN ||
+			     (gso.hdr_len && gso.hdr_len < ETH_HLEN)))
 			return -EINVAL;
 	}
 
@@ -762,7 +767,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 		goto out;
 	}
 
-	add_wait_queue(&tfile->read_wait, &wait);
+	add_wait_queue(&tun->socket.wait, &wait);
 	while (len) {
 		current->state = TASK_INTERRUPTIBLE;
 
@@ -793,7 +798,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 	}
 
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&tfile->read_wait, &wait);
+	remove_wait_queue(&tun->socket.wait, &wait);
 
 out:
 	tun_put(tun);
@@ -810,7 +815,7 @@ static void tun_setup(struct net_device *dev)
 	tun->group = -1;
 
 	dev->ethtool_ops = &tun_ethtool_ops;
-	dev->destructor = free_netdev;
+	dev->destructor = tun_free_netdev;
 }
 
 /* Trivial set of netlink ops to allow deleting tun or tap
@@ -847,7 +852,7 @@ static void tun_sock_write_space(struct sock *sk)
 
 static void tun_sock_destruct(struct sock *sk)
 {
-	dev_put(container_of(sk, struct tun_sock, sk)->tun->dev);
+	free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev);
 }
 
 static struct proto tun_proto = {
@@ -861,7 +866,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 	struct sock *sk;
 	struct tun_struct *tun;
 	struct net_device *dev;
-	struct tun_file *tfile = file->private_data;
 	int err;
 
 	dev = __dev_get_by_name(net, ifr->ifr_name);
@@ -919,13 +923,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		if (!sk)
 			goto err_free_dev;
 
-		/* This ref count is for tun->sk. */
-		dev_hold(dev);
+		init_waitqueue_head(&tun->socket.wait);
 		sock_init_data(&tun->socket, sk);
 		sk->sk_write_space = tun_sock_write_space;
-		sk->sk_destruct = tun_sock_destruct;
 		sk->sk_sndbuf = INT_MAX;
-		sk->sk_sleep = &tfile->read_wait;
 
 		tun->sk = sk;
 		container_of(sk, struct tun_sock, sk)->tun = tun;
@@ -941,11 +942,13 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		err = -EINVAL;
 		err = register_netdevice(tun->dev);
 		if (err < 0)
-			goto err_free_dev;
+			goto err_free_sk;
+
+		sk->sk_destruct = tun_sock_destruct;
 
 		err = tun_attach(tun, file);
 		if (err < 0)
-			goto err_free_dev;
+			goto failed;
 	}
 
 	DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -1265,7 +1268,6 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 	atomic_set(&tfile->count, 0);
 	tfile->tun = NULL;
 	tfile->net = get_net(current->nsproxy->net_ns);
-	init_waitqueue_head(&tfile->read_wait);
 	file->private_data = tfile;
 	return 0;
 }
@@ -1283,14 +1285,16 @@ static int tun_chr_close(struct inode *inode, struct file *file)
 		__tun_detach(tun);
 
 		/* If desireable, unregister the netdevice. */
-		if (!(tun->flags & TUN_PERSIST)) {
-			sock_put(tun->sk);
+		if (!(tun->flags & TUN_PERSIST))
 			unregister_netdevice(tun->dev);
-		}
 
 		rtnl_unlock();
 	}
 
+	tun = tfile->tun;
+	if (tun)
+		sock_put(tun->sk);
+
 	put_net(tfile->net);
 	kfree(tfile);
 
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index d3f39e86eb95..44f8392da117 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1394,7 +1394,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
-		upsmr |= UCC_GETH_UPSMR_RPM;
+		if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
+			upsmr |= UCC_GETH_UPSMR_RPM;
 		switch (ugeth->max_speed) {
 		case SPEED_10:
 			upsmr |= UCC_GETH_UPSMR_R10M;
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index a8228d87c8cf..2138535f2339 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -899,6 +899,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
 			/* cleanup should already have been scheduled */
 			break;
 		case -ENODEV:		/* disconnect() upcoming */
+		case -EPERM:
 			netif_device_detach(pegasus->net);
 			break;
 		default:
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index fb53ef872df3..754a4b182c1d 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -377,7 +377,7 @@ static void velocity_print_info(struct velocity_info *vptr);
 static int velocity_open(struct net_device *dev);
 static int velocity_change_mtu(struct net_device *dev, int mtu);
 static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
-static int velocity_intr(int irq, void *dev_instance);
+static irqreturn_t velocity_intr(int irq, void *dev_instance);
 static void velocity_set_multi(struct net_device *dev);
 static struct net_device_stats *velocity_get_stats(struct net_device *dev);
 static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -2215,7 +2215,7 @@ out:
  *	efficiently as possible.
  */
 
-static int velocity_intr(int irq, void *dev_instance)
+static irqreturn_t velocity_intr(int irq, void *dev_instance)
 {
 	struct net_device *dev = dev_instance;
 	struct velocity_info *vptr = netdev_priv(dev);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f21a6171c691..c36d3a3d655f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6713,11 +6713,11 @@ static int airo_set_auth(struct net_device *dev,
 				local->config.authType = AUTH_ENCRYPT;
 			} else
 				return -EINVAL;
-			break;
 
 			/* Commit the changes to flags if needed */
 			if (local->config.authType != currentAuthType)
 				set_bit (FLAG_COMMIT, &local->flags);
+			break;
 		}
 
 	case IW_AUTH_WPA_ENABLED:
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
index 13091bd9d815..53e250a4278f 100644
--- a/drivers/net/wireless/ar9170/hw.h
+++ b/drivers/net/wireless/ar9170/hw.h
@@ -310,7 +310,7 @@ struct ar9170_tx_control {
 
 struct ar9170_rx_head {
 	u8 plcp[12];
-};
+} __packed;
 
 struct ar9170_rx_tail {
 	union {
@@ -318,16 +318,16 @@ struct ar9170_rx_tail {
 			u8 rssi_ant0, rssi_ant1, rssi_ant2,
 			   rssi_ant0x, rssi_ant1x, rssi_ant2x,
 			   rssi_combined;
-		};
+		} __packed;
 		u8 rssi[7];
-	};
+	} __packed;
 
 	u8 evm_stream0[6], evm_stream1[6];
 	u8 phy_err;
 	u8 SAidx, DAidx;
 	u8 error;
 	u8 status;
-};
+} __packed;
 
 #define AR9170_ENC_ALG_NONE			0x0
 #define AR9170_ENC_ALG_WEP64			0x1
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
index ad296840893e..fddda477095c 100644
--- a/drivers/net/wireless/ar9170/usb.c
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -59,6 +59,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
 	{ USB_DEVICE(0x0cf3, 0x9170) },
 	/* Atheros TG121N */
 	{ USB_DEVICE(0x0cf3, 0x1001) },
+	/* Cace Airpcap NX */
+	{ USB_DEVICE(0xcace, 0x0300) },
 	/* D-Link DWA 160A */
 	{ USB_DEVICE(0x07d1, 0x3c10) },
 	/* Netgear WNDA3100 */
@@ -67,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
 	{ USB_DEVICE(0x0846, 0x9001) },
 	/* Zydas ZD1221 */
 	{ USB_DEVICE(0x0ace, 0x1221) },
+	/* ZyXEL NWD271N */
+	{ USB_DEVICE(0x0586, 0x3417) },
 	/* Z-Com UB81 BG */
 	{ USB_DEVICE(0x0cde, 0x0023) },
 	/* Z-Com UB82 ABG */
@@ -619,6 +623,39 @@ static int ar9170_usb_open(struct ar9170 *ar)
 	return 0;
 }
 
+static int ar9170_usb_init_device(struct ar9170_usb *aru)
+{
+	int err;
+
+	err = ar9170_usb_alloc_rx_irq_urb(aru);
+	if (err)
+		goto err_out;
+
+	err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_usb_upload_firmware(aru);
+	if (err) {
+		err = ar9170_echo_test(&aru->common, 0x60d43110);
+		if (err) {
+			/* force user invention, by disabling the device */
+			err = usb_driver_set_configuration(aru->udev, -1);
+			dev_err(&aru->udev->dev, "device is in a bad state. "
+						 "please reconnect it!\n");
+			goto err_unrx;
+		}
+	}
+
+	return 0;
+
+err_unrx:
+	ar9170_usb_cancel_urbs(aru);
+
+err_out:
+	return err;
+}
+
 static int ar9170_usb_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
@@ -654,32 +691,16 @@ static int ar9170_usb_probe(struct usb_interface *intf,
 
 	err = ar9170_usb_reset(aru);
 	if (err)
-		goto err_unlock;
+		goto err_freehw;
 
 	err = ar9170_usb_request_firmware(aru);
 	if (err)
-		goto err_unlock;
+		goto err_freehw;
 
-	err = ar9170_usb_alloc_rx_irq_urb(aru);
+	err = ar9170_usb_init_device(aru);
 	if (err)
 		goto err_freefw;
 
-	err = ar9170_usb_alloc_rx_bulk_urbs(aru);
-	if (err)
-		goto err_unrx;
-
-	err = ar9170_usb_upload_firmware(aru);
-	if (err) {
-		err = ar9170_echo_test(&aru->common, 0x60d43110);
-		if (err) {
-			/* force user invention, by disabling the device */
-			err = usb_driver_set_configuration(aru->udev, -1);
-			dev_err(&aru->udev->dev, "device is in a bad state. "
-						 "please reconnect it!\n");
-			goto err_unrx;
-		}
-	}
-
 	err = ar9170_usb_open(ar);
 	if (err)
 		goto err_unrx;
@@ -699,7 +720,7 @@ err_freefw:
 	release_firmware(aru->init_values);
 	release_firmware(aru->firmware);
 
-err_unlock:
+err_freehw:
 	usb_set_intfdata(intf, NULL);
 	usb_put_dev(udev);
 	ieee80211_free_hw(ar->hw);
@@ -726,12 +747,65 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
 	ieee80211_free_hw(aru->common.hw);
 }
 
+#ifdef CONFIG_PM
+static int ar9170_suspend(struct usb_interface *intf,
+			  pm_message_t  message)
+{
+	struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+	if (!aru)
+		return -ENODEV;
+
+	aru->common.state = AR9170_IDLE;
+	ar9170_usb_cancel_urbs(aru);
+
+	return 0;
+}
+
+static int ar9170_resume(struct usb_interface *intf)
+{
+	struct ar9170_usb *aru = usb_get_intfdata(intf);
+	int err;
+
+	if (!aru)
+		return -ENODEV;
+
+	usb_unpoison_anchored_urbs(&aru->rx_submitted);
+	usb_unpoison_anchored_urbs(&aru->tx_submitted);
+
+	/*
+	 * FIXME: firmware upload will fail on resume.
+	 * but this is better than a hang!
+	 */
+
+	err = ar9170_usb_init_device(aru);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_usb_open(&aru->common);
+	if (err)
+		goto err_unrx;
+
+	return 0;
+
+err_unrx:
+	aru->common.state = AR9170_IDLE;
+	ar9170_usb_cancel_urbs(aru);
+
+	return err;
+}
+#endif /* CONFIG_PM */
+
 static struct usb_driver ar9170_driver = {
 	.name = "ar9170usb",
 	.probe = ar9170_usb_probe,
 	.disconnect = ar9170_usb_disconnect,
 	.id_table = ar9170_usb_ids,
 	.soft_unbind = 1,
+#ifdef CONFIG_PM
+	.suspend = ar9170_suspend,
+	.resume = ar9170_resume,
+#endif /* CONFIG_PM */
 };
 
 static int __init ar9170_init(void)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 0c02f1c2bd94..744f4f4dd3d1 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -250,6 +250,8 @@ static struct usb_device_id dev_table[] = {
 	{ USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
 	/* Siemens Gigaset USB WLAN Adapter 11 */
 	{ USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+	/* OQO Model 01+ Internal Wi-Fi */
+	{ USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) },
 	/*
 	 * at76c505amx-rfmd
 	 */
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
index 6dbc58580abb..168411d322a2 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -93,14 +93,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (pci_enable_device(pdev))
 		return -EIO;
 
-	ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 
 	if (ret) {
 		printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
 		goto bad;
 	}
 
-	ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 
 	if (ret) {
 		printk(KERN_ERR "ath9k: 32-bit DMA consistent "
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 71cb18d6757d..dd1f30156740 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -493,6 +493,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 	int hdrlen, padsize, retval;
 	bool decrypt_error = false;
 	u8 keyix;
+	__le16 fc;
 
 	spin_lock_bh(&sc->rx.rxbuflock);
 
@@ -606,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		/* see if any padding is done by the hw and remove it */
 		hdr = (struct ieee80211_hdr *)skb->data;
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+		fc = hdr->frame_control;
 
 		/* The MAC header is padded to have 32-bit boundary if the
 		 * packet payload is non-zero. The general calculation for
@@ -690,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			sc->rx.rxotherant = 0;
 		}
 
-		if (ieee80211_is_beacon(hdr->frame_control) &&
+		if (ieee80211_is_beacon(fc) &&
 				(sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
 			sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
 			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 857d84148b1d..27eef8fb7107 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1502,7 +1502,6 @@ static const struct net_device_ops atmel_netdev_ops = {
 	.ndo_set_mac_address 	= atmel_set_mac_address,
 	.ndo_start_xmit 	= start_tx,
 	.ndo_do_ioctl 		= atmel_ioctl,
-	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index e228c1de6e11..eae680b53052 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -555,11 +555,32 @@ address_error:
 	return 1;
 }
 
+static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+	unsigned char *f = skb->data + ring->frameoffset;
+
+	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF);
+}
+
+static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+	struct b43_rxhdr_fw4 *rxhdr;
+	unsigned char *frame;
+
+	/* This poisons the RX buffer to detect DMA failures. */
+
+	rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
+	rxhdr->frame_len = 0;
+
+	B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2);
+	frame = skb->data + ring->frameoffset;
+	memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */);
+}
+
 static int setup_rx_descbuffer(struct b43_dmaring *ring,
 			       struct b43_dmadesc_generic *desc,
 			       struct b43_dmadesc_meta *meta, gfp_t gfp_flags)
 {
-	struct b43_rxhdr_fw4 *rxhdr;
 	dma_addr_t dmaaddr;
 	struct sk_buff *skb;
 
@@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
 	skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
 	if (unlikely(!skb))
 		return -ENOMEM;
+	b43_poison_rx_buffer(ring, skb);
 	dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
 	if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
 		/* ugh. try to realloc in zone_dma */
@@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
 		skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
 		if (unlikely(!skb))
 			return -ENOMEM;
+		b43_poison_rx_buffer(ring, skb);
 		dmaaddr = map_descbuffer(ring, skb->data,
 					 ring->rx_buffersize, 0);
 		if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
@@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
 	ring->ops->fill_descriptor(ring, desc, dmaaddr,
 				   ring->rx_buffersize, 0, 0, 0);
 
-	rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
-	rxhdr->frame_len = 0;
-
 	return 0;
 }
 
@@ -1483,12 +1503,17 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
 			len = le16_to_cpu(rxhdr->frame_len);
 		} while (len == 0 && i++ < 5);
 		if (unlikely(len == 0)) {
-			/* recycle the descriptor buffer. */
-			sync_descbuffer_for_device(ring, meta->dmaaddr,
-						   ring->rx_buffersize);
-			goto drop;
+			dmaaddr = meta->dmaaddr;
+			goto drop_recycle_buffer;
 		}
 	}
+	if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) {
+		/* Something went wrong with the DMA.
+		 * The device did not touch the buffer and did not overwrite the poison. */
+		b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n");
+		dmaaddr = meta->dmaaddr;
+		goto drop_recycle_buffer;
+	}
 	if (unlikely(len > ring->rx_buffersize)) {
 		/* The data did not fit into one descriptor buffer
 		 * and is split over multiple buffers.
@@ -1501,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
 		while (1) {
 			desc = ops->idx2desc(ring, *slot, &meta);
 			/* recycle the descriptor buffer. */
+			b43_poison_rx_buffer(ring, meta->skb);
 			sync_descbuffer_for_device(ring, meta->dmaaddr,
 						   ring->rx_buffersize);
 			*slot = next_slot(ring, *slot);
@@ -1519,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
 	err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
 	if (unlikely(err)) {
 		b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
-		sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
-		goto drop;
+		goto drop_recycle_buffer;
 	}
 
 	unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
@@ -1530,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
 	b43_rx(ring->dev, skb, rxhdr);
 drop:
 	return;
+
+drop_recycle_buffer:
+	/* Poison and recycle the RX buffer. */
+	b43_poison_rx_buffer(ring, skb);
+	sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
 }
 
 void b43_dma_rx(struct b43_dmaring *ring)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 4896e0831114..79b685e300c7 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3974,6 +3974,11 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev,
 	phy->next_txpwr_check_time = jiffies;
 	/* PHY TX errors counter. */
 	atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+
+#if B43_DEBUG
+	phy->phy_locked = 0;
+	phy->radio_locked = 0;
+#endif
 }
 
 static void setup_struct_wldev_for_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 026b61c03fb9..e176b6e0d9cf 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -131,12 +131,16 @@ void b43_radio_lock(struct b43_wldev *dev)
 {
 	u32 macctl;
 
+#if B43_DEBUG
+	B43_WARN_ON(dev->phy.radio_locked);
+	dev->phy.radio_locked = 1;
+#endif
+
 	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
 	macctl |= B43_MACCTL_RADIOLOCK;
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
-	/* Commit the write and wait for the device
-	 * to exit any radio register access. */
+	/* Commit the write and wait for the firmware
+	 * to finish any radio register access. */
 	b43_read32(dev, B43_MMIO_MACCTL);
 	udelay(10);
 }
@@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *dev)
 {
 	u32 macctl;
 
+#if B43_DEBUG
+	B43_WARN_ON(!dev->phy.radio_locked);
+	dev->phy.radio_locked = 0;
+#endif
+
 	/* Commit any write */
 	b43_read16(dev, B43_MMIO_PHY_VER);
 	/* unlock */
 	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
 	macctl &= ~B43_MACCTL_RADIOLOCK;
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
 }
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index c9f5430d1d7d..b2d99101947b 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -245,8 +245,10 @@ struct b43_phy {
 	atomic_t txerr_cnt;
 
 #ifdef CONFIG_B43_DEBUG
-	/* PHY registers locked by b43_phy_lock()? */
+	/* PHY registers locked (w.r.t. firmware) */
 	bool phy_locked;
+	/* Radio registers locked (w.r.t. firmware) */
+	bool radio_locked;
 #endif /* B43_DEBUG */
 };
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 2399328e8de7..527525cc0919 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1192,7 +1192,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
 			return -ENOMEM;
 		}
 	} else
-		iwl_rx_queue_reset(priv, rxq);
+		iwl3945_rx_queue_reset(priv, rxq);
 
 	iwl3945_rx_replenish(priv);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index ab7aaf6872c7..55188844657b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -215,6 +215,7 @@ extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
 extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
 			     struct iwl_tx_queue *txq, int count, u32 id);
 extern void iwl3945_rx_replenish(void *data);
+extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
 			    const void *data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3889158b359c..1ef4192207a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -976,11 +976,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
 
 		rxq->queue[i] = NULL;
 
-		dma_sync_single_range_for_cpu(
-				&priv->pci_dev->dev, rxb->real_dma_addr,
-				rxb->aligned_dma_addr - rxb->real_dma_addr,
-				priv->hw_params.rx_buf_size,
-				PCI_DMA_FROMDEVICE);
+		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+				 priv->hw_params.rx_buf_size + 256,
+				 PCI_DMA_FROMDEVICE);
 		pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
 		/* Reclaim a command buffer only if this packet is a response
@@ -1031,9 +1029,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
 			rxb->skb = NULL;
 		}
 
-		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-				 priv->hw_params.rx_buf_size + 256,
-				 PCI_DMA_FROMDEVICE);
 		spin_lock_irqsave(&rxq->lock, flags);
 		list_add_tail(&rxb->list, &priv->rxq.rx_used);
 		spin_unlock_irqrestore(&rxq->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 2f1242447b3b..6e983149b83b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -223,7 +223,7 @@
 #define CSR_EEPROM_REG_MSK_DATA		(0xFFFF0000)
 
 /* EEPROM GP */
-#define CSR_EEPROM_GP_VALID_MSK		(0x00000006)
+#define CSR_EEPROM_GP_VALID_MSK		(0x00000007)
 #define CSR_EEPROM_GP_BAD_SIGNATURE	(0x00000000)
 #define CSR_EEPROM_GP_IF_OWNER_MSK	(0x00000180)
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ec9a13846edd..cf7f0db58fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -360,12 +360,16 @@ struct iwl_host_cmd {
 
 /**
  * struct iwl_rx_queue - Rx queue
+ * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
+ * @dma_addr: bus address of buffer of receive buffer descriptors (rbd)
  * @read: Shared index to newest available Rx buffer
  * @write: Shared index to oldest written Rx packet
  * @free_count: Number of pre-allocated buffers in rx_free
  * @rx_free: list of free SKBs for use
  * @rx_used: List of Rx buffers with no SKB
  * @need_update: flag to indicate we need to update read/write index
+ * @rb_stts: driver's pointer to receive buffer status
+ * @rb_stts_dma: bus address of receive buffer status
  *
  * NOTE:  rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
  */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1f117a49c569..71d5b8a1a73e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -799,6 +799,22 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	/* Copy MAC header from skb into command buffer */
 	memcpy(tx_cmd->hdr, hdr, hdr_len);
 
+
+	/* Total # bytes to be transmitted */
+	len = (u16)skb->len;
+	tx_cmd->len = cpu_to_le16(len);
+
+	if (info->control.hw_key)
+		iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+
+	/* TODO need this for burst mode later on */
+	iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+
+	/* set is_hcca to 0; it probably will never be implemented */
+	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
+
+	iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
+
 	/*
 	 * Use the first empty entry in this queue's command buffer array
 	 * to contain the Tx command and MAC header concatenated together
@@ -819,21 +835,30 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	else
 		len_org = 0;
 
+	/* Tell NIC about any 2-byte padding after MAC header */
+	if (len_org)
+		tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
 	txcmd_phys = pci_map_single(priv->pci_dev,
-				    out_cmd, sizeof(struct iwl_cmd),
+				    &out_cmd->hdr, len,
 				    PCI_DMA_BIDIRECTIONAL);
 	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
-	pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+	pci_unmap_len_set(&out_cmd->meta, len, len);
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
-	txcmd_phys += offsetof(struct iwl_cmd, hdr);
 	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
 						   txcmd_phys, len, 1, 0);
 
-	if (info->control.hw_key)
-		iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+	if (!ieee80211_has_morefrags(hdr->frame_control)) {
+		txq->need_update = 1;
+		if (qc)
+			priv->stations[sta_id].tid[tid].seq_number = seq_number;
+	} else {
+		wait_write_ptr = 1;
+		txq->need_update = 0;
+	}
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
@@ -846,41 +871,29 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 							   0, 0);
 	}
 
-	/* Tell NIC about any 2-byte padding after MAC header */
-	if (len_org)
-		tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
-
-	/* Total # bytes to be transmitted */
-	len = (u16)skb->len;
-	tx_cmd->len = cpu_to_le16(len);
-	/* TODO need this for burst mode later on */
-	iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
-
-	/* set is_hcca to 0; it probably will never be implemented */
-	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
-
-	iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
-
 	scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-		offsetof(struct iwl_tx_cmd, scratch);
+				offsetof(struct iwl_tx_cmd, scratch);
+
+	len = sizeof(struct iwl_tx_cmd) +
+		sizeof(struct iwl_cmd_header) + hdr_len;
+	/* take back ownership of DMA buffer to enable update */
+	pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
+				    len, PCI_DMA_BIDIRECTIONAL);
 	tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
 	tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
 
-	if (!ieee80211_has_morefrags(hdr->frame_control)) {
-		txq->need_update = 1;
-		if (qc)
-			priv->stations[sta_id].tid[tid].seq_number = seq_number;
-	} else {
-		wait_write_ptr = 1;
-		txq->need_update = 0;
-	}
-
+	IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
+		     le16_to_cpu(out_cmd->hdr.sequence));
+	IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
-
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
 
 	/* Set up entry for this TFD in Tx byte-count array */
-	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
+	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
+						     le16_to_cpu(tx_cmd->len));
+
+	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
+				       len, PCI_DMA_BIDIRECTIONAL);
 
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -968,18 +981,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 			INDEX_TO_SEQ(q->write_ptr));
 	if (out_cmd->meta.flags & CMD_SIZE_HUGE)
 		out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
-	len = (idx == TFD_CMD_SLOTS) ?
-			IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
-
-	phys_addr = pci_map_single(priv->pci_dev, out_cmd,
-				   len, PCI_DMA_BIDIRECTIONAL);
-	pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
-	pci_unmap_len_set(&out_cmd->meta, len, len);
-	phys_addr += offsetof(struct iwl_cmd, hdr);
+	len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta);
+	len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
 
-	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
-						   phys_addr, fix_size, 1,
-						   U32_PAD(cmd->len));
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	switch (out_cmd->hdr.cmd) {
@@ -1007,6 +1011,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 		/* Set up entry in queue's byte count circular buffer */
 		priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
 
+	phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+				   fix_size, PCI_DMA_BIDIRECTIONAL);
+	pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
+	pci_unmap_len_set(&out_cmd->meta, len, fix_size);
+
+	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+						   phys_addr, fix_size, 1,
+						   U32_PAD(cmd->len));
+
 	/* Increment and update queue's write index */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 	ret = iwl_txq_update_write_ptr(priv, txq);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ce729281ff62..617c4235d971 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -972,7 +972,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	dma_addr_t phys_addr;
 	dma_addr_t txcmd_phys;
 	int txq_id = skb_get_queue_mapping(skb);
-	u16 len, idx, len_org, hdr_len;
+	u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
 	u8 id;
 	u8 unicast;
 	u8 sta_id;
@@ -1074,6 +1074,40 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	/* Copy MAC header from skb into command buffer */
 	memcpy(tx->hdr, hdr, hdr_len);
 
+
+	if (info->control.hw_key)
+		iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
+
+	/* TODO need this for burst mode later on */
+	iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
+
+	/* set is_hcca to 0; it probably will never be implemented */
+	iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
+
+	/* Total # bytes to be transmitted */
+	len = (u16)skb->len;
+	tx->len = cpu_to_le16(len);
+
+
+	tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+	tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+
+	if (!ieee80211_has_morefrags(hdr->frame_control)) {
+		txq->need_update = 1;
+		if (qc)
+			priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+	} else {
+		wait_write_ptr = 1;
+		txq->need_update = 0;
+	}
+
+	IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
+		     le16_to_cpu(out_cmd->hdr.sequence));
+	IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags));
+	iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
+	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
+			   ieee80211_hdrlen(fc));
+
 	/*
 	 * Use the first empty entry in this queue's command buffer array
 	 * to contain the Tx command and MAC header concatenated together
@@ -1096,22 +1130,18 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
-	txcmd_phys = pci_map_single(priv->pci_dev,
-				    out_cmd, sizeof(struct iwl_cmd),
-				    PCI_DMA_TODEVICE);
+	txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+				    len, PCI_DMA_TODEVICE);
+	/* we do not map meta data ... so we can safely access address to
+	 * provide to unmap command*/
 	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
-	pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
-	/* Add buffer containing Tx command and MAC(!) header to TFD's
-	 * first entry */
-	txcmd_phys += offsetof(struct iwl_cmd, hdr);
+	pci_unmap_len_set(&out_cmd->meta, len, len);
 
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
 	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
 						   txcmd_phys, len, 1, 0);
 
-	if (info->control.hw_key)
-		iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
@@ -1124,32 +1154,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 							   0, U32_PAD(len));
 	}
 
-	/* Total # bytes to be transmitted */
-	len = (u16)skb->len;
-	tx->len = cpu_to_le16(len);
-
-	/* TODO need this for burst mode later on */
-	iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
-
-	/* set is_hcca to 0; it probably will never be implemented */
-	iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
-
-	tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
-	tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
-
-	if (!ieee80211_has_morefrags(hdr->frame_control)) {
-		txq->need_update = 1;
-		if (qc)
-			priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
-	} else {
-		wait_write_ptr = 1;
-		txq->need_update = 0;
-	}
-
-	iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
-
-	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
-			   ieee80211_hdrlen(fc));
 
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1661,6 +1665,37 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
 	spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
+void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+	unsigned long flags;
+	int i;
+	spin_lock_irqsave(&rxq->lock, flags);
+	INIT_LIST_HEAD(&rxq->rx_free);
+	INIT_LIST_HEAD(&rxq->rx_used);
+	/* Fill the rx_used queue with _all_ of the Rx buffers */
+	for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
+		/* In the reset function, these buffers may have been allocated
+		 * to an SKB, so we need to unmap and free potential storage */
+		if (rxq->pool[i].skb != NULL) {
+			pci_unmap_single(priv->pci_dev,
+					 rxq->pool[i].real_dma_addr,
+					 priv->hw_params.rx_buf_size,
+					 PCI_DMA_FROMDEVICE);
+			priv->alloc_rxb_skb--;
+			dev_kfree_skb(rxq->pool[i].skb);
+			rxq->pool[i].skb = NULL;
+		}
+		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+	}
+
+	/* Set us so that we have processed and used all buffers, but have
+	 * not restocked the Rx queue with fresh buffers */
+	rxq->read = rxq->write = 0;
+	rxq->free_count = 0;
+	spin_unlock_irqrestore(&rxq->lock, flags);
+}
+EXPORT_SYMBOL(iwl3945_rx_queue_reset);
+
 /*
  * this should be called while priv->lock is locked
  */
@@ -1685,6 +1720,34 @@ void iwl3945_rx_replenish(void *data)
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
+ * If an SKB has been detached, the POOL needs to have its SKB set to NULL
+ * This free routine walks the list of POOL entries and if SKB is set to
+ * non NULL it is unmapped and freed
+ */
+static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+	int i;
+	for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
+		if (rxq->pool[i].skb != NULL) {
+			pci_unmap_single(priv->pci_dev,
+					 rxq->pool[i].real_dma_addr,
+					 priv->hw_params.rx_buf_size,
+					 PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(rxq->pool[i].skb);
+		}
+	}
+
+	pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+			    rxq->dma_addr);
+	pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
+			    rxq->rb_stts, rxq->rb_stts_dma);
+	rxq->bd = NULL;
+	rxq->rb_stts  = NULL;
+}
+EXPORT_SYMBOL(iwl3945_rx_queue_free);
+
+
 /* Convert linear signal-to-noise ratio into dB */
 static u8 ratio2dB[100] = {
 /*	 0   1   2   3   4   5   6   7   8   9 */
@@ -1802,9 +1865,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 
 		rxq->queue[i] = NULL;
 
-		pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
-					    priv->hw_params.rx_buf_size,
-					    PCI_DMA_FROMDEVICE);
+		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+				priv->hw_params.rx_buf_size,
+				PCI_DMA_FROMDEVICE);
 		pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
 		/* Reclaim a command buffer only if this packet is a response
@@ -1852,9 +1915,6 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 			rxb->skb = NULL;
 		}
 
-		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-				priv->hw_params.rx_buf_size,
-				PCI_DMA_FROMDEVICE);
 		spin_lock_irqsave(&rxq->lock, flags);
 		list_add_tail(&rxb->list, &priv->rxq.rx_used);
 		spin_unlock_irqrestore(&rxq->lock, flags);
@@ -4075,7 +4135,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	if (!static_key) {
 		sta_id = iwl3945_hw_find_station(priv, addr);
 		if (sta_id == IWL_INVALID_STATION) {
-			IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n",
+			IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
 					    addr);
 			return -EINVAL;
 		}
@@ -4913,6 +4973,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
 
 	hw->wiphy->custom_regulatory = true;
 
+	hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+
 	/* Default value; 4 EDCA QOS priorities */
 	hw->queues = 4;
 
@@ -5194,12 +5256,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
 	iwl_rfkill_unregister(priv);
-	cancel_delayed_work(&priv->rfkill_poll);
+	cancel_delayed_work_sync(&priv->rfkill_poll);
 
 	iwl3945_dealloc_ucode_pci(priv);
 
 	if (priv->rxq.bd)
-		iwl_rx_queue_free(priv, &priv->rxq);
+		iwl3945_rx_queue_free(priv, &priv->rxq);
 	iwl3945_hw_txq_ctx_free(priv);
 
 	iwl3945_unset_hw_params(priv);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 63d7e19ce9bd..8e669775cb5d 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -170,6 +170,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 		lbs_deb_rx("rx err: frame received with bad length\n");
 		dev->stats.rx_length_errors++;
 		ret = 0;
+		dev_kfree_skb(skb);
 		goto done;
 	}
 
@@ -181,6 +182,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 		lbs_pr_alert("rxpd not ok\n");
 		dev->stats.rx_errors++;
 		ret = 0;
+		dev_kfree_skb(skb);
 		goto done;
 	}
 
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 57a0268d1bae..a9a970469c2a 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -893,8 +893,7 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
 		rx_desc->next_rx_desc_phys_addr =
 			cpu_to_le32(rxq->rx_desc_dma
 						+ nexti * sizeof(*rx_desc));
-		rx_desc->rx_ctrl =
-			cpu_to_le32(MWL8K_RX_CTRL_OWNED_BY_HOST);
+		rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST;
 	}
 
 	return 0;
@@ -3720,12 +3719,12 @@ err_free_reg:
 	return rc;
 }
 
-static void __devexit mwl8k_remove(struct pci_dev *pdev)
+static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
 {
 	printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
 }
 
-static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
+static void __devexit mwl8k_remove(struct pci_dev *pdev)
 {
 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 	struct mwl8k_priv *priv;
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 081428d9409e..632fac86a308 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -372,15 +372,13 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
 	}
 
 	/* Wait upto 100ms for tx queue to empty */
-	k = 100;
-	do {
-		k--;
+	for (k = 100; k > 0; k--) {
 		udelay(1000);
 		ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
 					  &xmitting);
-		if (ret)
+		if (ret || !xmitting)
 			break;
-	} while ((k > 0) && xmitting);
+	}
 
 	if (k == 0)
 		ret = -ETIMEDOUT;
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 2dda5fe418b6..ecf8b6ed5a47 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -14,9 +14,9 @@
  * published by the Free Software Foundation.
  */
 
-#ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
 #include <linux/leds.h>
-#endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
 
 enum p54_control_frame_types {
 	P54_CONTROL_TYPE_SETUP = 0,
@@ -116,7 +116,7 @@ enum fw_state {
 	FW_STATE_RESETTING,
 };
 
-#ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
 
 #define P54_LED_MAX_NAME_LEN 31
 
@@ -129,7 +129,7 @@ struct p54_led_dev {
 	unsigned int registered;
 };
 
-#endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
 
 struct p54_common {
 	struct ieee80211_hw *hw;
@@ -177,10 +177,10 @@ struct p54_common {
 	u8 privacy_caps;
 	u8 rx_keycache_size;
 	/* LED management */
-	#ifdef CONFIG_MAC80211_LEDS
+#ifdef CONFIG_P54_LEDS
 	struct p54_led_dev assoc_led;
 	struct p54_led_dev tx_led;
-	#endif /* CONFIG_MAC80211_LEDS */
+#endif /* CONFIG_P54_LEDS */
 	u16 softled_state;		/* bit field of glowing LEDs */
 };
 
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 0c1b0577d4ee..c8f0232ee5e0 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -2543,8 +2543,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 	priv->basic_rate_mask = 0x15f;
 	skb_queue_head_init(&priv->tx_queue);
 	dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-		     IEEE80211_HW_SUPPORTS_PS |
-		     IEEE80211_HW_PS_NULLFUNC_STACK |
 		     IEEE80211_HW_SIGNAL_DBM |
 		     IEEE80211_HW_NOISE_DBM;
 
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index e3569a0a952d..b1610ea4bb3d 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -492,8 +492,8 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
 		goto err_disable_dev;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
-	    pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		dev_err(&pdev->dev, "No suitable DMA available\n");
 		goto err_free_reg;
 	}
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 2b222aaa6f0a..d1fe577de3d4 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -457,9 +457,10 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
 	struct ieee80211_tx_info *info;
 	struct p54_tx_info *minfo;
 	struct p54s_tx_info *dinfo;
+	unsigned long flags;
 	int ret = 0;
 
-	spin_lock_bh(&priv->tx_lock);
+	spin_lock_irqsave(&priv->tx_lock, flags);
 
 	while (!list_empty(&priv->tx_pending)) {
 		entry = list_entry(priv->tx_pending.next,
@@ -467,7 +468,7 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
 
 		list_del_init(&entry->tx_list);
 
-		spin_unlock_bh(&priv->tx_lock);
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
 
 		dinfo = container_of((void *) entry, struct p54s_tx_info,
 				     tx_list);
@@ -479,16 +480,14 @@ static int p54spi_wq_tx(struct p54s_priv *priv)
 
 		ret = p54spi_tx_frame(priv, skb);
 
-		spin_lock_bh(&priv->tx_lock);
-
 		if (ret < 0) {
 			p54_free_skb(priv->hw, skb);
-			goto out;
+			return ret;
 		}
-	}
 
-out:
-	spin_unlock_bh(&priv->tx_lock);
+		spin_lock_irqsave(&priv->tx_lock, flags);
+	}
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
 	return ret;
 }
 
@@ -498,12 +497,13 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data;
 	struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data;
+	unsigned long flags;
 
 	BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data)));
 
-	spin_lock_bh(&priv->tx_lock);
+	spin_lock_irqsave(&priv->tx_lock, flags);
 	list_add_tail(&di->tx_list, &priv->tx_pending);
-	spin_unlock_bh(&priv->tx_lock);
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
 
 	queue_work(priv->hw->workqueue, &priv->work);
 }
@@ -604,6 +604,7 @@ out:
 static void p54spi_op_stop(struct ieee80211_hw *dev)
 {
 	struct p54s_priv *priv = dev->priv;
+	unsigned long flags;
 
 	if (mutex_lock_interruptible(&priv->mutex)) {
 		/* FIXME: how to handle this error? */
@@ -615,9 +616,9 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 	cancel_work_sync(&priv->work);
 
 	p54spi_power_off(priv);
-	spin_lock_bh(&priv->tx_lock);
+	spin_lock_irqsave(&priv->tx_lock, flags);
 	INIT_LIST_HEAD(&priv->tx_pending);
-	spin_unlock_bh(&priv->tx_lock);
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
 
 	priv->fw_state = FW_STATE_OFF;
 	mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index da6640afc835..6cc6cbc9234f 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -71,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
 	{USB_DEVICE(0x1260, 0xee22)},	/* SMC 2862W-G version 2 */
 	{USB_DEVICE(0x13b1, 0x000a)},	/* Linksys WUSB54G ver 2 */
 	{USB_DEVICE(0x13B1, 0x000C)},	/* Linksys WUSB54AG */
+	{USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */
 	{USB_DEVICE(0x1435, 0x0427)},	/* Inventel UR054G */
 	{USB_DEVICE(0x2001, 0x3704)},	/* DLink DWL-G122 rev A2 */
 	{USB_DEVICE(0x413c, 0x8102)},	/* Spinnaker DUT */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 05f94e21b423..5752aaae906b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -646,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 * Register HW.
 	 */
 	status = ieee80211_register_hw(rt2x00dev->hw);
-	if (status) {
-		rt2x00lib_remove_hw(rt2x00dev);
+	if (status)
 		return status;
-	}
 
 	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 43fa0f849003..9730b4f8fd26 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -369,8 +369,6 @@ int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
 	if (retval)
 		return retval;
 
-	rt2x00pci_free_reg(rt2x00dev);
-
 	pci_save_state(pci_dev);
 	pci_disable_device(pci_dev);
 	return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
@@ -381,7 +379,6 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
 {
 	struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	int retval;
 
 	if (pci_set_power_state(pci_dev, PCI_D0) ||
 	    pci_enable_device(pci_dev) ||
@@ -390,20 +387,7 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
 		return -EIO;
 	}
 
-	retval = rt2x00pci_alloc_reg(rt2x00dev);
-	if (retval)
-		return retval;
-
-	retval = rt2x00lib_resume(rt2x00dev);
-	if (retval)
-		goto exit_free_reg;
-
-	return 0;
-
-exit_free_reg:
-	rt2x00pci_free_reg(rt2x00dev);
-
-	return retval;
+	return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_resume);
 #endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 7d50ca82375e..501544882c2c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -702,8 +702,6 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
 	if (retval)
 		return retval;
 
-	rt2x00usb_free_reg(rt2x00dev);
-
 	/*
 	 * Decrease usbdev refcount.
 	 */
@@ -717,24 +715,10 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
 {
 	struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	int retval;
 
 	usb_get_dev(interface_to_usbdev(usb_intf));
 
-	retval = rt2x00usb_alloc_reg(rt2x00dev);
-	if (retval)
-		return retval;
-
-	retval = rt2x00lib_resume(rt2x00dev);
-	if (retval)
-		goto exit_free_reg;
-
-	return 0;
-
-exit_free_reg:
-	rt2x00usb_free_reg(rt2x00dev);
-
-	return retval;
+	return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_resume);
 #endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 420fff42c0dd..853b2b279b64 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2369,6 +2369,8 @@ static struct usb_device_id rt73usb_device_table[] = {
 	/* Buffalo */
 	{ USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* CNet */
 	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index a12a7211c982..5a4ad156f63e 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -108,6 +108,18 @@ static int xtsonic_close(struct net_device *dev)
 	return err;
 }
 
+static const struct net_device_ops xtsonic_netdev_ops = {
+	.ndo_open		= xtsonic_open,
+	.ndo_stop		= xtsonic_close,
+	.ndo_start_xmit		= sonic_send_packet,
+	.ndo_get_stats		= sonic_get_stats,
+	.ndo_set_multicast_list	= sonic_multicast_list,
+	.ndo_tx_timeout		= sonic_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init sonic_probe1(struct net_device *dev)
 {
 	static unsigned version_printed = 0;
@@ -205,12 +217,7 @@ static int __init sonic_probe1(struct net_device *dev)
 	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 					 * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-	dev->open = xtsonic_open;
-	dev->stop = xtsonic_close;
-	dev->hard_start_xmit	= sonic_send_packet;
-	dev->get_stats		= sonic_get_stats;
-	dev->set_multicast_list	= &sonic_multicast_list;
-	dev->tx_timeout		= sonic_tx_timeout;
+	dev->netdev_ops		= &xtsonic_netdev_ops;
 	dev->watchdog_timeo	= TX_TIMEOUT;
 
 	/*
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 4fa3bb2ddfe4..33e5ade774ca 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -434,7 +434,8 @@ static void __init superio_parport_init(void)
 			0 /*base_hi*/,
 			PAR_IRQ, 
 			PARPORT_DMA_NONE /* dma */,
-			NULL /*struct pci_dev* */) )
+			NULL /*struct pci_dev* */),
+			0 /* shared irq flags */ )
 
 		printk(KERN_WARNING PFX "Probing parallel port failed.\n");
 #endif	/* CONFIG_PARPORT_PC */
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 64dd7df90e62..0f3706512686 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -87,8 +87,8 @@ EXPORT_SYMBOL(pci_read_vpd);
  * pci_write_vpd - Write entry to Vital Product Data
  * @dev:	pci device struct
  * @pos:	offset in vpd space
- * @count:	number of bytes to read
- * @val:	value to write
+ * @count:	number of bytes to write
+ * @buf:	buffer containing write data
  *
  */
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf)
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 25a00ce4f24d..fa3a11365ec3 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -173,12 +173,21 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
 	struct dmar_drhd_unit *dmaru;
 	int ret = 0;
 
+	drhd = (struct acpi_dmar_hardware_unit *)header;
+	if (!drhd->address) {
+		/* Promote an attitude of violence to a BIOS engineer today */
+		WARN(1, "Your BIOS is broken; DMAR reported at address zero!\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));
+		return -ENODEV;
+	}
 	dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
 	if (!dmaru)
 		return -ENOMEM;
 
 	dmaru->hdr = header;
-	drhd = (struct acpi_dmar_hardware_unit *)header;
 	dmaru->reg_base_addr = drhd->address;
 	dmaru->segment = drhd->segment;
 	dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index bf7d6ce9bbb3..6808d8333ecc 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -158,6 +158,7 @@ int ht_create_irq(struct pci_dev *dev, int idx)
 
 /**
  * ht_destroy_irq - destroy an irq created with ht_create_irq
+ * @irq: irq to be destroyed
  *
  * This reverses ht_create_irq removing the specified irq from
  * existence.  The irq should be free before this happens.
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index fb3a3f3fca7a..001b328adf80 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -733,8 +733,8 @@ static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
 	start &= (((u64)1) << addr_width) - 1;
 	end &= (((u64)1) << addr_width) - 1;
 	/* in case it's partial page */
-	start = PAGE_ALIGN(start);
-	end &= PAGE_MASK;
+	start &= PAGE_MASK;
+	end = PAGE_ALIGN(end);
 	npages = (end - start) / VTD_PAGE_SIZE;
 
 	/* we don't need lock here, nobody else touches the iova range */
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index a7eb1b46a5a8..85ebd02a64a7 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -492,6 +492,7 @@ write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr,
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
  * @kobj: kobject corresponding to file to read from
+ * @bin_attr: struct bin_attribute for this file
  * @buf: buffer to store results
  * @off: offset into legacy I/O port space
  * @count: number of bytes to read
@@ -517,6 +518,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
 /**
  * pci_write_legacy_io - write byte(s) to legacy I/O port space
  * @kobj: kobject corresponding to file to read from
+ * @bin_attr: struct bin_attribute for this file
  * @buf: buffer containing value to be written
  * @off: offset into legacy I/O port space
  * @count: number of bytes to write
@@ -733,9 +735,9 @@ pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr,
 
 /**
  * pci_remove_resource_files - cleanup resource files
- * @dev: dev to cleanup
+ * @pdev: dev to cleanup
  *
- * If we created resource files for @dev, remove them from sysfs and
+ * If we created resource files for @pdev, remove them from sysfs and
  * free their resources.
  */
 static void
@@ -793,9 +795,9 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 
 /**
  * pci_create_resource_files - create resource files in sysfs for @dev
- * @dev: dev in question
+ * @pdev: dev in question
  *
- * Walk the resources in @dev creating files for each resource available.
+ * Walk the resources in @pdev creating files for each resource available.
  */
 static int pci_create_resource_files(struct pci_dev *pdev)
 {
@@ -829,6 +831,7 @@ void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
 /**
  * pci_write_rom - used to enable access to the PCI ROM display
  * @kobj: kernel object handle
+ * @bin_attr: struct bin_attribute for this file
  * @buf: user input
  * @off: file offset
  * @count: number of byte in input
@@ -852,6 +855,7 @@ pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
 /**
  * pci_read_rom - read a PCI ROM
  * @kobj: kernel object handle
+ * @bin_attr: struct bin_attribute for this file
  * @buf: where to put the data we read from the ROM
  * @off: file offset
  * @count: number of bytes to read
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 16fd0d4c3166..34bf0fdf5047 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -681,11 +681,34 @@ EXPORT_SYMBOL(pci_choose_state);
 
 #define PCI_EXP_SAVE_REGS	7
 
+#define pcie_cap_has_devctl(type, flags)	1
+#define pcie_cap_has_lnkctl(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 (type == PCI_EXP_TYPE_ROOT_PORT ||	\
+		  type == PCI_EXP_TYPE_ENDPOINT ||	\
+		  type == PCI_EXP_TYPE_LEG_END))
+#define pcie_cap_has_sltctl(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 ((type == PCI_EXP_TYPE_ROOT_PORT) ||	\
+		  (type == PCI_EXP_TYPE_DOWNSTREAM &&	\
+		   (flags & PCI_EXP_FLAGS_SLOT))))
+#define pcie_cap_has_rtctl(type, flags)			\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 (type == PCI_EXP_TYPE_ROOT_PORT ||	\
+		  type == PCI_EXP_TYPE_RC_EC))
+#define pcie_cap_has_devctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+#define pcie_cap_has_lnkctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+#define pcie_cap_has_sltctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+
 static int pci_save_pcie_state(struct pci_dev *dev)
 {
 	int pos, i = 0;
 	struct pci_cap_saved_state *save_state;
 	u16 *cap;
+	u16 flags;
 
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	if (pos <= 0)
@@ -698,13 +721,22 @@ static int pci_save_pcie_state(struct pci_dev *dev)
 	}
 	cap = (u16 *)&save_state->data[0];
 
-	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
+
+	if (pcie_cap_has_devctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
+	if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
+	if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
+	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
+	if (pcie_cap_has_devctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
+	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
+	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
 
 	return 0;
 }
@@ -714,6 +746,7 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
 	int i = 0, pos;
 	struct pci_cap_saved_state *save_state;
 	u16 *cap;
+	u16 flags;
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
@@ -721,13 +754,22 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
 		return;
 	cap = (u16 *)&save_state->data[0];
 
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
+
+	if (pcie_cap_has_devctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
+	if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
+	if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
+	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
+	if (pcie_cap_has_devctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
+	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
+	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
 }
 
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8eb50dffb78a..e3c3e081b834 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1118,10 +1118,6 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
 	return max;
 }
 
-void __attribute__((weak)) set_pci_bus_resources_arch_default(struct pci_bus *b)
-{
-}
-
 struct pci_bus * pci_create_bus(struct device *parent,
 		int bus, struct pci_ops *ops, void *sysdata)
 {
@@ -1180,8 +1176,6 @@ struct pci_bus * pci_create_bus(struct device *parent,
 	b->resource[0] = &ioport_resource;
 	b->resource[1] = &iomem_resource;
 
-	set_pci_bus_resources_arch_default(b);
-
 	return b;
 
 dev_create_file_err:
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0254741bece0..3067673d54f6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2033,6 +2033,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_di
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
 static void __devinit quirk_disable_msi(struct pci_dev *dev)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8d9da9d30a61..a00f85471b6e 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -536,11 +536,13 @@ static void pci_bus_dump_res(struct pci_bus *bus)
 
         for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
                 struct resource *res = bus->resource[i];
-                if (!res)
+                if (!res || !res->end)
                         continue;
 
 		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i,
-			   (res->flags & IORESOURCE_IO) ? "io: " : "mem:", res);
+			   (res->flags & IORESOURCE_IO) ? "io: " :
+			    ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"),
+			   res);
         }
 }
 
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 21189447e545..fe95ce20bcbd 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -264,8 +264,8 @@ EXPORT_SYMBOL_GPL(pci_create_slot);
 
 /**
  * pci_renumber_slot - update %struct pci_slot -> number
- * @slot - %struct pci_slot to update
- * @slot_nr - new number for slot
+ * @slot: &struct pci_slot to update
+ * @slot_nr: new number for slot
  *
  * The primary purpose of this interface is to allow callers who earlier
  * created a placeholder slot in pci_create_slot() by passing a -1 as
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 1cd02f5a23a0..bc43f78f6f0b 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -255,6 +255,9 @@ static int __init sharpsl_pcmcia_init(void)
 {
 	int ret;
 
+	if (!platform_scoop_config)
+		return -ENODEV;
+
 	sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs;
 	sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 45940f31fe9e..218b9a16ac3f 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -174,8 +174,7 @@ struct fujitsu_hotkey_t {
 
 static struct fujitsu_hotkey_t *fujitsu_hotkey;
 
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
-				       void *data);
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event);
 
 #ifdef CONFIG_LEDS_CLASS
 static enum led_brightness logolamp_get(struct led_classdev *cdev);
@@ -203,7 +202,7 @@ struct led_classdev kblamps_led = {
 static u32 dbg_level = 0x03;
 #endif
 
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event);
 
 /* Fujitsu ACPI interface function */
 
@@ -658,7 +657,6 @@ static struct dmi_system_id fujitsu_dmi_table[] = {
 
 static int acpi_fujitsu_add(struct acpi_device *device)
 {
-	acpi_status status;
 	acpi_handle handle;
 	int result = 0;
 	int state = 0;
@@ -673,20 +671,10 @@ static int acpi_fujitsu_add(struct acpi_device *device)
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 	device->driver_data = fujitsu;
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_fujitsu_notify, fujitsu);
-
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop;
-	}
-
 	fujitsu->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_stop;
 	}
 
 	snprintf(fujitsu->phys, sizeof(fujitsu->phys),
@@ -743,9 +731,6 @@ static int acpi_fujitsu_add(struct acpi_device *device)
 end:
 err_free_input_dev:
 	input_free_device(input);
-err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_fujitsu_notify);
 err_stop:
 
 	return result;
@@ -753,7 +738,6 @@ err_stop:
 
 static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct fujitsu_t *fujitsu = NULL;
 
 	if (!device || !acpi_driver_data(device))
@@ -761,10 +745,6 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 
 	fujitsu = acpi_driver_data(device);
 
-	status = acpi_remove_notify_handler(fujitsu->acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_fujitsu_notify);
-
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
@@ -775,7 +755,7 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 
 /* Brightness notify */
 
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event)
 {
 	struct input_dev *input;
 	int keycode;
@@ -829,15 +809,12 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
 		input_report_key(input, keycode, 0);
 		input_sync(input);
 	}
-
-	return;
 }
 
 /* ACPI device for hotkey handling */
 
 static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 {
-	acpi_status status;
 	acpi_handle handle;
 	int result = 0;
 	int state = 0;
@@ -854,17 +831,6 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 	device->driver_data = fujitsu_hotkey;
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_fujitsu_hotkey_notify,
-					     fujitsu_hotkey);
-
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop;
-	}
-
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
 	fujitsu_hotkey->fifo =
@@ -879,7 +845,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 	fujitsu_hotkey->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_free_fifo;
 	}
 
 	snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
@@ -975,9 +941,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 end:
 err_free_input_dev:
 	input_free_device(input);
-err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_fujitsu_hotkey_notify);
+err_free_fifo:
 	kfifo_free(fujitsu_hotkey->fifo);
 err_stop:
 
@@ -986,7 +950,6 @@ err_stop:
 
 static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
 
 	if (!device || !acpi_driver_data(device))
@@ -994,10 +957,6 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
 
 	fujitsu_hotkey = acpi_driver_data(device);
 
-	status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_fujitsu_hotkey_notify);
-
 	fujitsu_hotkey->acpi_handle = NULL;
 
 	kfifo_free(fujitsu_hotkey->fifo);
@@ -1005,8 +964,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
 	return 0;
 }
 
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
-				       void *data)
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
 {
 	struct input_dev *input;
 	int keycode, keycode_r;
@@ -1089,8 +1047,6 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
 		input_sync(input);
 		break;
 	}
-
-	return;
 }
 
 /* Initialization */
@@ -1107,6 +1063,7 @@ static struct acpi_driver acpi_fujitsu_driver = {
 	.ops = {
 		.add = acpi_fujitsu_add,
 		.remove = acpi_fujitsu_remove,
+		.notify = acpi_fujitsu_notify,
 		},
 };
 
@@ -1122,6 +1079,7 @@ static struct acpi_driver acpi_fujitsu_hotkey_driver = {
 	.ops = {
 		.add = acpi_fujitsu_hotkey_add,
 		.remove = acpi_fujitsu_hotkey_remove,
+		.notify = acpi_fujitsu_hotkey_notify,
 		},
 };
 
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index a5ce4bc202e3..fe7cf0188acc 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -176,6 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
 static int acpi_pcc_hotkey_add(struct acpi_device *device);
 static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
 static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id pcc_device_ids[] = {
 	{ "MAT0012", 0},
@@ -194,6 +195,7 @@ static struct acpi_driver acpi_pcc_driver = {
 				.add =		acpi_pcc_hotkey_add,
 				.remove =	acpi_pcc_hotkey_remove,
 				.resume =       acpi_pcc_hotkey_resume,
+				.notify =	acpi_pcc_hotkey_notify,
 			},
 };
 
@@ -271,7 +273,7 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
 	union acpi_object *hkey = NULL;
 	int i;
 
-	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, NULL,
 				      &buffer);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -527,9 +529,9 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
 	return;
 }
 
-static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
 {
-	struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+	struct pcc_acpi *pcc = acpi_driver_data(device);
 
 	switch (event) {
 	case HKEY_NOTIFY:
@@ -599,7 +601,6 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
-	acpi_status status;
 	struct pcc_acpi *pcc;
 	int num_sifr, result;
 
@@ -640,22 +641,11 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
 		goto out_sinf;
 	}
 
-	/* initialize hotkey input device */
-	status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-					     acpi_pcc_hotkey_notify, pcc);
-
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Error installing notify handler\n"));
-		result = -ENODEV;
-		goto out_input;
-	}
-
 	/* initialize backlight */
 	pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
 						   &pcc_backlight_ops);
 	if (IS_ERR(pcc->backlight))
-		goto out_notify;
+		goto out_input;
 
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -680,9 +670,6 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
 
 out_backlight:
 	backlight_device_unregister(pcc->backlight);
-out_notify:
-	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_pcc_hotkey_notify);
 out_input:
 	input_unregister_device(pcc->input_dev);
 	/* no need to input_free_device() since core input API refcount and
@@ -723,9 +710,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
 
 	backlight_device_unregister(pcc->backlight);
 
-	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_pcc_hotkey_notify);
-
 	input_unregister_device(pcc->input_dev);
 	/* no need to input_free_device() since core input API refcount and
 	 * free()s the device */
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index a90ec5cb2f20..552958545f94 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -317,7 +317,8 @@ static void sony_laptop_report_input_event(u8 event)
 	struct input_dev *key_dev = sony_laptop_input.key_dev;
 	struct sony_laptop_keypress kp = { NULL };
 
-	if (event == SONYPI_EVENT_FNKEY_RELEASED) {
+	if (event == SONYPI_EVENT_FNKEY_RELEASED ||
+			event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
 		/* Nothing, not all VAIOs generate this event */
 		return;
 	}
@@ -905,7 +906,6 @@ static struct sony_nc_event sony_127_events[] = {
 	{ 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0x86, SONYPI_EVENT_PKEY_P5 },
 	{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
-	{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
 	{ 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0, 0 },
@@ -914,7 +914,7 @@ static struct sony_nc_event sony_127_events[] = {
 /*
  * ACPI callbacks
  */
-static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+static void sony_nc_notify(struct acpi_device *device, u32 event)
 {
 	u32 ev = event;
 
@@ -933,7 +933,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
 			struct sony_nc_event *key_event;
 
 			if (sony_call_snc_handle(key_handle, 0x200, &result)) {
-				dprintk("sony_acpi_notify, unable to decode"
+				dprintk("sony_nc_notify, unable to decode"
 					" event 0x%.2x 0x%.2x\n", key_handle,
 					ev);
 				/* restore the original event */
@@ -968,7 +968,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
 	} else
 		sony_laptop_report_input_event(ev);
 
-	dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
+	dprintk("sony_nc_notify, event: 0x%.2x\n", ev);
 	acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
 }
 
@@ -1004,6 +1004,7 @@ static int sony_nc_function_setup(struct acpi_device *device)
 	sony_call_snc_handle(0x0100, 0, &result);
 	sony_call_snc_handle(0x0101, 0, &result);
 	sony_call_snc_handle(0x0102, 0x100, &result);
+	sony_call_snc_handle(0x0127, 0, &result);
 
 	return 0;
 }
@@ -1040,7 +1041,7 @@ static int sony_nc_resume(struct acpi_device *device)
 
 	/* set the last requested brightness level */
 	if (sony_backlight_device &&
-			!sony_backlight_update_status(sony_backlight_device))
+			sony_backlight_update_status(sony_backlight_device) < 0)
 		printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
 
 	return 0;
@@ -1102,8 +1103,11 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
 	err = rfkill_register(sony_wifi_rfkill);
 	if (err)
 		rfkill_free(sony_wifi_rfkill);
-	else
+	else {
 		sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+		sony_nc_rfkill_set(sony_wifi_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
 	return err;
 }
 
@@ -1124,8 +1128,11 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
 	err = rfkill_register(sony_bluetooth_rfkill);
 	if (err)
 		rfkill_free(sony_bluetooth_rfkill);
-	else
+	else {
 		sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+		sony_nc_rfkill_set(sony_bluetooth_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
 	return err;
 }
 
@@ -1145,8 +1152,11 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
 	err = rfkill_register(sony_wwan_rfkill);
 	if (err)
 		rfkill_free(sony_wwan_rfkill);
-	else
+	else {
 		sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+		sony_nc_rfkill_set(sony_wwan_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
 	return err;
 }
 
@@ -1166,8 +1176,11 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
 	err = rfkill_register(sony_wimax_rfkill);
 	if (err)
 		rfkill_free(sony_wimax_rfkill);
-	else
+	else {
 		sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+		sony_nc_rfkill_set(sony_wimax_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
 	return err;
 }
 
@@ -1276,15 +1289,6 @@ static int sony_nc_add(struct acpi_device *device)
 		goto outwalk;
 	}
 
-	status = acpi_install_notify_handler(sony_nc_acpi_handle,
-					     ACPI_DEVICE_NOTIFY,
-					     sony_acpi_notify, NULL);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
-		result = -ENODEV;
-		goto outinput;
-	}
-
 	if (acpi_video_backlight_support()) {
 		printk(KERN_INFO DRV_PFX "brightness ignored, must be "
 		       "controlled by ACPI video driver\n");
@@ -1362,13 +1366,6 @@ static int sony_nc_add(struct acpi_device *device)
 	if (sony_backlight_device)
 		backlight_device_unregister(sony_backlight_device);
 
-	status = acpi_remove_notify_handler(sony_nc_acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    sony_acpi_notify);
-	if (ACPI_FAILURE(status))
-		printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
-      outinput:
 	sony_laptop_remove_input();
 
       outwalk:
@@ -1378,7 +1375,6 @@ static int sony_nc_add(struct acpi_device *device)
 
 static int sony_nc_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct sony_nc_value *item;
 
 	if (sony_backlight_device)
@@ -1386,12 +1382,6 @@ static int sony_nc_remove(struct acpi_device *device, int type)
 
 	sony_nc_acpi_device = NULL;
 
-	status = acpi_remove_notify_handler(sony_nc_acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    sony_acpi_notify);
-	if (ACPI_FAILURE(status))
-		printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
 	for (item = sony_nc_values; item->name; ++item) {
 		device_remove_file(&sony_pf_device->dev, &item->devattr);
 	}
@@ -1425,6 +1415,7 @@ static struct acpi_driver sony_nc_driver = {
 		.add = sony_nc_add,
 		.remove = sony_nc_remove,
 		.resume = sony_nc_resume,
+		.notify = sony_nc_notify,
 		},
 };
 
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a40b075743d9..912be65b6261 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -21,7 +21,7 @@
  *  02110-1301, USA.
  */
 
-#define TPACPI_VERSION "0.22"
+#define TPACPI_VERSION "0.23"
 #define TPACPI_SYSFS_VERSION 0x020300
 
 /*
@@ -303,11 +303,17 @@ static u32 dbg_level;
 
 static struct workqueue_struct *tpacpi_wq;
 
+enum led_status_t {
+	TPACPI_LED_OFF = 0,
+	TPACPI_LED_ON,
+	TPACPI_LED_BLINK,
+};
+
 /* Special LED class that can defer work */
 struct tpacpi_led_classdev {
 	struct led_classdev led_classdev;
 	struct work_struct work;
-	enum led_brightness new_brightness;
+	enum led_status_t new_state;
 	unsigned int led;
 };
 
@@ -2946,12 +2952,18 @@ static int hotkey_read(char *p)
 	return len;
 }
 
-static void hotkey_enabledisable_warn(void)
+static void hotkey_enabledisable_warn(bool enable)
 {
 	tpacpi_log_usertask("procfs hotkey enable/disable");
-	WARN(1, TPACPI_WARN
-	     "hotkey enable/disable functionality has been "
-	     "removed from the driver. Hotkeys are always enabled.\n");
+	if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
+			TPACPI_WARN
+			"hotkey enable/disable functionality has been "
+			"removed from the driver.  Hotkeys are always "
+			"enabled\n"))
+		printk(TPACPI_ERR
+			"Please remove the hotkey=enable module "
+			"parameter, it is deprecated.  Hotkeys are always "
+			"enabled\n");
 }
 
 static int hotkey_write(char *buf)
@@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf)
 	res = 0;
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			hotkey_enabledisable_warn();
+			hotkey_enabledisable_warn(1);
 		} else if (strlencmp(cmd, "disable") == 0) {
-			hotkey_enabledisable_warn();
+			hotkey_enabledisable_warn(0);
 			res = -EPERM;
 		} else if (strlencmp(cmd, "reset") == 0) {
 			mask = hotkey_orig_mask;
@@ -4207,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work)
 			container_of(work, struct tpacpi_led_classdev, work);
 
 	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
-		light_set_status((data->new_brightness != LED_OFF));
+		light_set_status((data->new_state != TPACPI_LED_OFF));
 }
 
 static void light_sysfs_set(struct led_classdev *led_cdev,
@@ -4217,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
 		container_of(led_cdev,
 			     struct tpacpi_led_classdev,
 			     led_classdev);
-	data->new_brightness = brightness;
+	data->new_state = (brightness != LED_OFF) ?
+				TPACPI_LED_ON : TPACPI_LED_OFF;
 	queue_work(tpacpi_wq, &data->work);
 }
 
@@ -4724,12 +4737,6 @@ enum {	/* For TPACPI_LED_OLD */
 	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
 };
 
-enum led_status_t {
-	TPACPI_LED_OFF = 0,
-	TPACPI_LED_ON,
-	TPACPI_LED_BLINK,
-};
-
 static enum led_access_mode led_supported;
 
 TPACPI_HANDLE(led, ec, "SLED",	/* 570 */
@@ -4841,23 +4848,13 @@ static int led_set_status(const unsigned int led,
 	return rc;
 }
 
-static void led_sysfs_set_status(unsigned int led,
-				 enum led_brightness brightness)
-{
-	led_set_status(led,
-			(brightness == LED_OFF) ?
-			TPACPI_LED_OFF :
-			(tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
-				TPACPI_LED_BLINK : TPACPI_LED_ON);
-}
-
 static void led_set_status_worker(struct work_struct *work)
 {
 	struct tpacpi_led_classdev *data =
 		container_of(work, struct tpacpi_led_classdev, work);
 
 	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
-		led_sysfs_set_status(data->led, data->new_brightness);
+		led_set_status(data->led, data->new_state);
 }
 
 static void led_sysfs_set(struct led_classdev *led_cdev,
@@ -4866,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
 	struct tpacpi_led_classdev *data = container_of(led_cdev,
 			     struct tpacpi_led_classdev, led_classdev);
 
-	data->new_brightness = brightness;
+	if (brightness == LED_OFF)
+		data->new_state = TPACPI_LED_OFF;
+	else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
+		data->new_state = TPACPI_LED_ON;
+	else
+		data->new_state = TPACPI_LED_BLINK;
+
 	queue_work(tpacpi_wq, &data->work);
 }
 
@@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
 	} else if ((*delay_on != 500) || (*delay_off != 500))
 		return -EINVAL;
 
-	data->new_brightness = TPACPI_LED_BLINK;
+	data->new_state = TPACPI_LED_BLINK;
 	queue_work(tpacpi_wq, &data->work);
 
 	return 0;
@@ -7858,6 +7861,15 @@ static int __init thinkpad_acpi_module_init(void)
 MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
 
 /*
+ * This will autoload the driver in almost every ThinkPad
+ * in widespread use.
+ *
+ * Only _VERY_ old models, like the 240, 240x and 570 lack
+ * the HKEY event interface.
+ */
+MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);
+
+/*
  * DMI matching for module autoloading
  *
  * See http://thinkwiki.org/wiki/List_of_DMI_IDs
@@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
 #define IBM_BIOS_MODULE_ALIAS(__type) \
 	MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
 
-/* Non-ancient thinkpads */
-MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
-MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
-
 /* Ancient thinkpad BIOSes have to be identified by
  * BIOS type or model number, and there are far less
  * BIOS types than model numbers... */
-IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]");
-IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
-IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
+IBM_BIOS_MODULE_ALIAS("I[MU]");		/* 570, 570e */
 
-MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
+MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
+MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
 MODULE_DESCRIPTION(TPACPI_DESC);
 MODULE_VERSION(TPACPI_VERSION);
 MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 2f269e117b8f..043b208d971d 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -81,6 +81,7 @@ static struct wmi_block wmi_blocks;
 
 static int acpi_wmi_remove(struct acpi_device *device, int type);
 static int acpi_wmi_add(struct acpi_device *device);
+static void acpi_wmi_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id wmi_device_ids[] = {
 	{"PNP0C14", 0},
@@ -96,6 +97,7 @@ static struct acpi_driver acpi_wmi_driver = {
 	.ops = {
 		.add = acpi_wmi_add,
 		.remove = acpi_wmi_remove,
+		.notify = acpi_wmi_notify,
 		},
 };
 
@@ -643,12 +645,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
 	}
 }
 
-static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_wmi_notify(struct acpi_device *device, u32 event)
 {
 	struct guid_block *block;
 	struct wmi_block *wblock;
 	struct list_head *p;
-	struct acpi_device *device = data;
 
 	list_for_each(p, &wmi_blocks.list) {
 		wblock = list_entry(p, struct wmi_block, list);
@@ -669,9 +670,6 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
 
 static int acpi_wmi_remove(struct acpi_device *device, int type)
 {
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-		acpi_wmi_notify);
-
 	acpi_remove_address_space_handler(device->handle,
 				ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
 
@@ -683,13 +681,6 @@ static int __init acpi_wmi_add(struct acpi_device *device)
 	acpi_status status;
 	int result = 0;
 
-	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-		acpi_wmi_notify, device);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Error installing notify handler\n");
-		return -ENODEV;
-	}
-
 	status = acpi_install_address_space_handler(device->handle,
 						    ACPI_ADR_SPACE_EC,
 						    &acpi_wmi_ec_space_handler,
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index 41aec2acbb91..e8b278f71781 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -36,6 +36,8 @@ struct pcf50633_mbc {
 
 	struct power_supply usb;
 	struct power_supply adapter;
+
+	struct delayed_work charging_restart_work;
 };
 
 int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
@@ -43,6 +45,8 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
 	struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
 	int ret = 0;
 	u8 bits;
+	int charging_start = 1;
+	u8 mbcs2, chgmod;
 
 	if (ma >= 1000)
 		bits = PCF50633_MBCC7_USB_1000mA;
@@ -50,8 +54,10 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
 		bits = PCF50633_MBCC7_USB_500mA;
 	else if (ma >= 100)
 		bits = PCF50633_MBCC7_USB_100mA;
-	else
+	else {
 		bits = PCF50633_MBCC7_USB_SUSPEND;
+		charging_start = 0;
+	}
 
 	ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
 					PCF50633_MBCC7_USB_MASK, bits);
@@ -60,6 +66,22 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
 	else
 		dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
 
+	/* Manual charging start */
+	mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
+	chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+	/* If chgmod == BATFULL, setting chgena has no effect.
+	 * We need to set resume instead.
+	 */
+	if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
+	else
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
+
+	mbc->usb_active = charging_start;
+
 	power_supply_changed(&mbc->usb);
 
 	return ret;
@@ -84,21 +106,6 @@ int pcf50633_mbc_get_status(struct pcf50633 *pcf)
 }
 EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
 
-void pcf50633_mbc_set_status(struct pcf50633 *pcf, int what, int status)
-{
-	struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
-
-	if (what & PCF50633_MBC_USB_ONLINE)
-		mbc->usb_online = !!status;
-	if (what & PCF50633_MBC_USB_ACTIVE)
-		mbc->usb_active = !!status;
-	if (what & PCF50633_MBC_ADAPTER_ONLINE)
-		mbc->adapter_online = !!status;
-	if (what & PCF50633_MBC_ADAPTER_ACTIVE)
-		mbc->adapter_active = !!status;
-}
-EXPORT_SYMBOL_GPL(pcf50633_mbc_set_status);
-
 static ssize_t
 show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -160,10 +167,44 @@ static struct attribute_group mbc_attr_group = {
 	.attrs	= pcf50633_mbc_sysfs_entries,
 };
 
+/* MBC state machine switches into charging mode when the battery voltage
+ * falls below 96% of a battery float voltage. But the voltage drop in Li-ion
+ * batteries is marginal(1~2 %) till about 80% of its capacity - which means,
+ * after a BATFULL, charging won't be restarted until 80%.
+ *
+ * This work_struct function restarts charging at regular intervals to make
+ * sure we don't discharge too much
+ */
+
+static void pcf50633_mbc_charging_restart(struct work_struct *work)
+{
+	struct pcf50633_mbc *mbc;
+	u8 mbcs2, chgmod;
+
+	mbc = container_of(work, struct pcf50633_mbc,
+				charging_restart_work.work);
+
+	mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
+	chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+	if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
+		return;
+
+	/* Restart charging */
+	pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
+	mbc->usb_active = 1;
+	power_supply_changed(&mbc->usb);
+
+	dev_info(mbc->pcf->dev, "Charging restarted\n");
+}
+
 static void
 pcf50633_mbc_irq_handler(int irq, void *data)
 {
 	struct pcf50633_mbc *mbc = data;
+	int chg_restart_interval =
+			mbc->pcf->pdata->charging_restart_interval;
 
 	/* USB */
 	if (irq == PCF50633_IRQ_USBINS) {
@@ -172,6 +213,7 @@ pcf50633_mbc_irq_handler(int irq, void *data)
 		mbc->usb_online = 0;
 		mbc->usb_active = 0;
 		pcf50633_mbc_usb_curlim_set(mbc->pcf, 0);
+		cancel_delayed_work_sync(&mbc->charging_restart_work);
 	}
 
 	/* Adapter */
@@ -186,7 +228,14 @@ pcf50633_mbc_irq_handler(int irq, void *data)
 	if (irq == PCF50633_IRQ_BATFULL) {
 		mbc->usb_active = 0;
 		mbc->adapter_active = 0;
-	}
+
+		if (chg_restart_interval > 0)
+			schedule_delayed_work(&mbc->charging_restart_work,
+							chg_restart_interval);
+	} else if (irq == PCF50633_IRQ_USBLIMON)
+		mbc->usb_active = 0;
+	else if (irq == PCF50633_IRQ_USBLIMOFF)
+		mbc->usb_active = 1;
 
 	power_supply_changed(&mbc->usb);
 	power_supply_changed(&mbc->adapter);
@@ -303,6 +352,9 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	INIT_DELAYED_WORK(&mbc->charging_restart_work,
+				pcf50633_mbc_charging_restart);
+
 	ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
 	if (ret)
 		dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
@@ -328,6 +380,8 @@ static int __devexit pcf50633_mbc_remove(struct platform_device *pdev)
 	power_supply_unregister(&mbc->usb);
 	power_supply_unregister(&mbc->adapter);
 
+	cancel_delayed_work_sync(&mbc->charging_restart_work);
+
 	kfree(mbc);
 
 	return 0;
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index b56a704409d2..a232de6a5703 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -12,11 +12,14 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/power_supply.h>
 #include <linux/pda_power.h>
+#include <linux/regulator/consumer.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
+#include <linux/usb/otg.h>
 
 static inline unsigned int get_irq_flags(struct resource *res)
 {
@@ -35,6 +38,11 @@ static struct timer_list supply_timer;
 static struct timer_list polling_timer;
 static int polling;
 
+#ifdef CONFIG_USB_OTG_UTILS
+static struct otg_transceiver *transceiver;
+#endif
+static struct regulator *ac_draw;
+
 enum {
 	PDA_PSY_OFFLINE = 0,
 	PDA_PSY_ONLINE = 1,
@@ -104,18 +112,35 @@ static void update_status(void)
 
 static void update_charger(void)
 {
-	if (!pdata->set_charge)
-		return;
-
-	if (new_ac_status > 0) {
-		dev_dbg(dev, "charger on (AC)\n");
-		pdata->set_charge(PDA_POWER_CHARGE_AC);
-	} else if (new_usb_status > 0) {
-		dev_dbg(dev, "charger on (USB)\n");
-		pdata->set_charge(PDA_POWER_CHARGE_USB);
-	} else {
-		dev_dbg(dev, "charger off\n");
-		pdata->set_charge(0);
+	static int regulator_enabled;
+	int max_uA = pdata->ac_max_uA;
+
+	if (pdata->set_charge) {
+		if (new_ac_status > 0) {
+			dev_dbg(dev, "charger on (AC)\n");
+			pdata->set_charge(PDA_POWER_CHARGE_AC);
+		} else if (new_usb_status > 0) {
+			dev_dbg(dev, "charger on (USB)\n");
+			pdata->set_charge(PDA_POWER_CHARGE_USB);
+		} else {
+			dev_dbg(dev, "charger off\n");
+			pdata->set_charge(0);
+		}
+	} else if (ac_draw) {
+		if (new_ac_status > 0) {
+			regulator_set_current_limit(ac_draw, max_uA, max_uA);
+			if (!regulator_enabled) {
+				dev_dbg(dev, "charger on (AC)\n");
+				regulator_enable(ac_draw);
+				regulator_enabled = 1;
+			}
+		} else {
+			if (regulator_enabled) {
+				dev_dbg(dev, "charger off\n");
+				regulator_disable(ac_draw);
+				regulator_enabled = 0;
+			}
+		}
 	}
 }
 
@@ -194,6 +219,13 @@ static void polling_timer_func(unsigned long unused)
 		  jiffies + msecs_to_jiffies(pdata->polling_interval));
 }
 
+#ifdef CONFIG_USB_OTG_UTILS
+static int otg_is_usb_online(void)
+{
+	return (transceiver->state == OTG_STATE_B_PERIPHERAL);
+}
+#endif
+
 static int pda_power_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -227,6 +259,9 @@ static int pda_power_probe(struct platform_device *pdev)
 	if (!pdata->polling_interval)
 		pdata->polling_interval = 2000;
 
+	if (!pdata->ac_max_uA)
+		pdata->ac_max_uA = 500000;
+
 	setup_timer(&charger_timer, charger_timer_func, 0);
 	setup_timer(&supply_timer, supply_timer_func, 0);
 
@@ -240,6 +275,13 @@ static int pda_power_probe(struct platform_device *pdev)
 		pda_psy_usb.num_supplicants = pdata->num_supplicants;
 	}
 
+	ac_draw = regulator_get(dev, "ac_draw");
+	if (IS_ERR(ac_draw)) {
+		dev_dbg(dev, "couldn't get ac_draw regulator\n");
+		ac_draw = NULL;
+		ret = PTR_ERR(ac_draw);
+	}
+
 	if (pdata->is_ac_online) {
 		ret = power_supply_register(&pdev->dev, &pda_psy_ac);
 		if (ret) {
@@ -261,6 +303,13 @@ static int pda_power_probe(struct platform_device *pdev)
 		}
 	}
 
+#ifdef CONFIG_USB_OTG_UTILS
+	transceiver = otg_get_transceiver();
+	if (transceiver && !pdata->is_usb_online) {
+		pdata->is_usb_online = otg_is_usb_online;
+	}
+#endif
+
 	if (pdata->is_usb_online) {
 		ret = power_supply_register(&pdev->dev, &pda_psy_usb);
 		if (ret) {
@@ -300,10 +349,18 @@ usb_irq_failed:
 usb_supply_failed:
 	if (pdata->is_ac_online && ac_irq)
 		free_irq(ac_irq->start, &pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+	if (transceiver)
+		otg_put_transceiver(transceiver);
+#endif
 ac_irq_failed:
 	if (pdata->is_ac_online)
 		power_supply_unregister(&pda_psy_ac);
 ac_supply_failed:
+	if (ac_draw) {
+		regulator_put(ac_draw);
+		ac_draw = NULL;
+	}
 	if (pdata->exit)
 		pdata->exit(dev);
 init_failed:
@@ -327,6 +384,14 @@ static int pda_power_remove(struct platform_device *pdev)
 		power_supply_unregister(&pda_psy_usb);
 	if (pdata->is_ac_online)
 		power_supply_unregister(&pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+	if (transceiver)
+		otg_put_transceiver(transceiver);
+#endif
+	if (ac_draw) {
+		regulator_put(ac_draw);
+		ac_draw = NULL;
+	}
 	if (pdata->exit)
 		pdata->exit(dev);
 
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index 7ecb820ceebc..d08cd9b66c6d 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -61,8 +61,7 @@ static int bq24022_disable(struct regulator_dev *rdev)
 
 static int bq24022_is_enabled(struct regulator_dev *rdev)
 {
-	struct platform_device *pdev = rdev_get_drvdata(rdev);
-	struct bq24022_mach_info *pdata = pdev->dev.platform_data;
+	struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
 
 	return !gpio_get_value(pdata->gpio_nce);
 }
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 01f7702a805d..98c3a74e9949 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -540,8 +540,8 @@ static void drms_uA_update(struct regulator_dev *rdev)
 
 	err = regulator_check_drms(rdev);
 	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
-	    !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode);
-	return;
+	    !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode)
+		return;
 
 	/* get output voltage */
 	output_uV = rdev->desc->ops->get_voltage(rdev);
@@ -703,10 +703,13 @@ static int set_machine_constraints(struct regulator_dev *rdev,
 		int	cmin = constraints->min_uV;
 		int	cmax = constraints->max_uV;
 
-		/* it's safe to autoconfigure fixed-voltage supplies */
+		/* it's safe to autoconfigure fixed-voltage supplies
+		   and the constraints are used by list_voltage. */
 		if (count == 1 && !cmin) {
-			cmin = INT_MIN;
+			cmin = 1;
 			cmax = INT_MAX;
+			constraints->min_uV = cmin;
+			constraints->max_uV = cmax;
 		}
 
 		/* voltage constraints are optional */
@@ -2001,8 +2004,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
 		return ERR_PTR(-EINVAL);
 
-	if (!regulator_desc->type == REGULATOR_VOLTAGE &&
-	    !regulator_desc->type == REGULATOR_CURRENT)
+	if (regulator_desc->type != REGULATOR_VOLTAGE &&
+	    regulator_desc->type != REGULATOR_CURRENT)
 		return ERR_PTR(-EINVAL);
 
 	if (!init_data)
@@ -2080,6 +2083,10 @@ out:
 
 scrub:
 	device_unregister(&rdev->dev);
+	/* device core frees rdev */
+	rdev = ERR_PTR(ret);
+	goto out;
+
 clean:
 	kfree(rdev);
 	rdev = ERR_PTR(ret);
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 3d08348584e1..71403fa3ffa1 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -230,13 +230,13 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
 	 * sysfs_streq() doesn't need the \n's, but we add them so the strings
 	 * will be shared with show_mode(), above.
 	 */
-	if (sysfs_streq(buf, "fast\n") == 0)
+	if (sysfs_streq(buf, "fast\n"))
 		mode = REGULATOR_MODE_FAST;
-	else if (sysfs_streq(buf, "normal\n") == 0)
+	else if (sysfs_streq(buf, "normal\n"))
 		mode = REGULATOR_MODE_NORMAL;
-	else if (sysfs_streq(buf, "idle\n") == 0)
+	else if (sysfs_streq(buf, "idle\n"))
 		mode = REGULATOR_MODE_IDLE;
-	else if (sysfs_streq(buf, "standby\n") == 0)
+	else if (sysfs_streq(buf, "standby\n"))
 		mode = REGULATOR_MODE_STANDBY;
 	else {
 		dev_err(dev, "Configuring invalid mode\n");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ffe34a12f446..4e9851fc1746 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -573,7 +573,7 @@ config RTC_DRV_SA1100
 
 config RTC_DRV_SH
 	tristate "SuperH On-Chip RTC"
-	depends on RTC_CLASS && SUPERH
+	depends on RTC_CLASS && SUPERH && HAVE_CLK
 	help
 	  Say Y here to enable support for the on-chip RTC found in
 	  most SuperH processors.
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index b6d35f50e404..23e10b6263d6 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -797,17 +797,15 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 		goto cleanup2;
 	}
 
-	pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n",
-			dev_name(&cmos_rtc.rtc->dev),
-			is_valid_irq(rtc_irq)
-				?  (cmos_rtc.mon_alrm
-					? "year"
-					: (cmos_rtc.day_alrm
-						? "month" : "day"))
-				: "no",
-			cmos_rtc.century ? ", y3k" : "",
-			nvram.size,
-			is_hpet_enabled() ? ", hpet irqs" : "");
+	pr_info("%s: %s%s, %zd bytes nvram%s\n",
+		dev_name(&cmos_rtc.rtc->dev),
+		!is_valid_irq(rtc_irq) ? "no alarms" :
+			cmos_rtc.mon_alrm ? "alarms up to one year" :
+			cmos_rtc.day_alrm ? "alarms up to one month" :
+			"alarms up to one day",
+		cmos_rtc.century ? ", y3k" : "",
+		nvram.size,
+		is_hpet_enabled() ? ", hpet irqs" : "");
 
 	return 0;
 
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 9b1ff12bf947..d7310adb7152 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -1,7 +1,7 @@
 /*
  * SuperH On-Chip RTC Support
  *
- * Copyright (C) 2006, 2007, 2008  Paul Mundt
+ * Copyright (C) 2006 - 2009  Paul Mundt
  * Copyright (C) 2006  Jamie Lenehan
  * Copyright (C) 2008  Angelo Castello
  *
@@ -25,10 +25,11 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/log2.h>
+#include <linux/clk.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME	"sh-rtc"
-#define DRV_VERSION	"0.2.1"
+#define DRV_VERSION	"0.2.2"
 
 #define RTC_REG(r)	((r) * rtc_reg_size)
 
@@ -87,16 +88,17 @@
 #define RCR2_START	0x01	/* Start bit               */
 
 struct sh_rtc {
-	void __iomem *regbase;
-	unsigned long regsize;
-	struct resource *res;
-	int alarm_irq;
-	int periodic_irq;
-	int carry_irq;
-	struct rtc_device *rtc_dev;
-	spinlock_t lock;
-	unsigned long capabilities;	/* See asm-sh/rtc.h for cap bits */
-	unsigned short periodic_freq;
+	void __iomem		*regbase;
+	unsigned long		regsize;
+	struct resource		*res;
+	int			alarm_irq;
+	int			periodic_irq;
+	int			carry_irq;
+	struct clk		*clk;
+	struct rtc_device	*rtc_dev;
+	spinlock_t		lock;
+	unsigned long		capabilities;	/* See asm/rtc.h for cap bits */
+	unsigned short		periodic_freq;
 };
 
 static int __sh_rtc_interrupt(struct sh_rtc *rtc)
@@ -294,10 +296,10 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
 
 	tmp = readb(rtc->regbase + RCR1);
 
-	if (!enable)
-		tmp &= ~RCR1_AIE;
-	else
+	if (enable)
 		tmp |= RCR1_AIE;
+	else
+		tmp &= ~RCR1_AIE;
 
 	writeb(tmp, rtc->regbase + RCR1);
 
@@ -618,6 +620,7 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq)
 {
 	if (!is_power_of_2(freq))
 		return -EINVAL;
+
 	return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
 }
 
@@ -637,7 +640,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 	struct sh_rtc *rtc;
 	struct resource *res;
 	struct rtc_time r;
-	int ret;
+	char clk_name[6];
+	int clk_id, ret;
 
 	rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
 	if (unlikely(!rtc))
@@ -652,6 +656,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "No IRQ resource\n");
 		goto err_badres;
 	}
+
 	rtc->periodic_irq = ret;
 	rtc->carry_irq = platform_get_irq(pdev, 1);
 	rtc->alarm_irq = platform_get_irq(pdev, 2);
@@ -663,7 +668,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 		goto err_badres;
 	}
 
-	rtc->regsize = res->end - res->start + 1;
+	rtc->regsize = resource_size(res);
 
 	rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name);
 	if (unlikely(!rtc->res)) {
@@ -677,6 +682,26 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 		goto err_badmap;
 	}
 
+	clk_id = pdev->id;
+	/* With a single device, the clock id is still "rtc0" */
+	if (clk_id < 0)
+		clk_id = 0;
+
+	snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
+
+	rtc->clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(rtc->clk)) {
+		/*
+		 * No error handling for rtc->clk intentionally, not all
+		 * platforms will have a unique clock for the RTC, and
+		 * the clk API can handle the struct clk pointer being
+		 * NULL.
+		 */
+		rtc->clk = NULL;
+	}
+
+	clk_enable(rtc->clk);
+
 	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
 					   &sh_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
@@ -759,6 +784,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 	return 0;
 
 err_unmap:
+	clk_disable(rtc->clk);
+	clk_put(rtc->clk);
 	iounmap(rtc->regbase);
 err_badmap:
 	release_resource(rtc->res);
@@ -780,6 +807,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
 	sh_rtc_setcie(&pdev->dev, 0);
 
 	free_irq(rtc->periodic_irq, rtc);
+
 	if (rtc->carry_irq > 0) {
 		free_irq(rtc->carry_irq, rtc);
 		free_irq(rtc->alarm_irq, rtc);
@@ -789,6 +817,9 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
 
 	iounmap(rtc->regbase);
 
+	clk_disable(rtc->clk);
+	clk_put(rtc->clk);
+
 	platform_set_drvdata(pdev, NULL);
 
 	kfree(rtc);
@@ -802,11 +833,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
 	struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
 	set_irq_wake(rtc->periodic_irq, enabled);
+
 	if (rtc->carry_irq > 0) {
 		set_irq_wake(rtc->carry_irq, enabled);
 		set_irq_wake(rtc->alarm_irq, enabled);
 	}
-
 }
 
 static int sh_rtc_suspend(struct device *dev)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0570794ccf1c..d1815272c435 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/hdreg.h>
+#include <linux/async.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
@@ -480,8 +481,10 @@ static void dasd_change_state(struct dasd_device *device)
         if (rc && rc != -EAGAIN)
                 device->target = device->state;
 
-	if (device->state == device->target)
+	if (device->state == device->target) {
 		wake_up(&dasd_init_waitq);
+		dasd_put_device(device);
+	}
 
 	/* let user-space know that the device status changed */
 	kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
@@ -513,12 +516,15 @@ void dasd_kick_device(struct dasd_device *device)
  */
 void dasd_set_target_state(struct dasd_device *device, int target)
 {
+	dasd_get_device(device);
 	/* If we are in probeonly mode stop at DASD_STATE_READY. */
 	if (dasd_probeonly && target > DASD_STATE_READY)
 		target = DASD_STATE_READY;
 	if (device->target != target) {
-                if (device->state == target)
+		if (device->state == target) {
 			wake_up(&dasd_init_waitq);
+			dasd_put_device(device);
+		}
 		device->target = target;
 	}
 	if (device->state != device->target)
@@ -2148,6 +2154,22 @@ dasd_exit(void)
  * SECTION: common functions for ccw_driver use
  */
 
+static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
+{
+	struct ccw_device *cdev = data;
+	int ret;
+
+	ret = ccw_device_set_online(cdev);
+	if (ret)
+		pr_warning("%s: Setting the DASD online failed with rc=%d\n",
+			   dev_name(&cdev->dev), ret);
+	else {
+		struct dasd_device *device = dasd_device_from_cdev(cdev);
+		wait_event(dasd_init_waitq, _wait_for_device(device));
+		dasd_put_device(device);
+	}
+}
+
 /*
  * Initial attempt at a probe function. this can be simplified once
  * the other detection code is gone.
@@ -2180,10 +2202,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
 	 */
 	if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
 	    (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
-		ret = ccw_device_set_online(cdev);
-	if (ret)
-		pr_warning("%s: Setting the DASD online failed with rc=%d\n",
-		       dev_name(&cdev->dev), ret);
+		async_schedule(dasd_generic_auto_online, cdev);
 	return 0;
 }
 
@@ -2290,13 +2309,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
 	} else
 		pr_debug("dasd_generic device %s found\n",
 				dev_name(&cdev->dev));
-
-	/* FIXME: we have to wait for the root device but we don't want
-	 * to wait for each single device but for all at once. */
-	wait_event(dasd_init_waitq, _wait_for_device(device));
-
 	dasd_put_device(device);
-
 	return rc;
 }
 
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 21254793c604..cb52da033f06 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2019,15 +2019,23 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
 				ccw++;
 				recid += count;
 				new_track = 0;
+				/* first idaw for a ccw may start anywhere */
+				if (!idaw_dst)
+					idaw_dst = dst;
 			}
-			/* If we start a new idaw, everything is fine and the
-			 * start of the new idaw is the start of this segment.
+			/* If we start a new idaw, we must make sure that it
+			 * starts on an IDA_BLOCK_SIZE boundary.
 			 * If we continue an idaw, we must make sure that the
 			 * current segment begins where the so far accumulated
 			 * idaw ends
 			 */
-			if (!idaw_dst)
-				idaw_dst = dst;
+			if (!idaw_dst) {
+				if (__pa(dst) & (IDA_BLOCK_SIZE-1)) {
+					dasd_sfree_request(cqr, startdev);
+					return ERR_PTR(-ERANGE);
+				} else
+					idaw_dst = dst;
+			}
 			if ((idaw_dst + idaw_len) != dst) {
 				dasd_sfree_request(cqr, startdev);
 				return ERR_PTR(-ERANGE);
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index c07809c8016a..5469e099597e 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -285,7 +285,7 @@ extern int tape_mtop(struct tape_device *, int, int);
 extern void tape_state_set(struct tape_device *, enum tape_state);
 
 extern int tape_generic_online(struct tape_device *, struct tape_discipline *);
-extern int tape_generic_offline(struct tape_device *device);
+extern int tape_generic_offline(struct ccw_device *);
 
 /* Externals from tape_devmap.c */
 extern int tape_generic_probe(struct ccw_device *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 807ded5eb049..5f8e8ef43dd3 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1294,12 +1294,6 @@ tape_34xx_online(struct ccw_device *cdev)
 	);
 }
 
-static int
-tape_34xx_offline(struct ccw_device *cdev)
-{
-	return tape_generic_offline(cdev->dev.driver_data);
-}
-
 static struct ccw_driver tape_34xx_driver = {
 	.name = "tape_34xx",
 	.owner = THIS_MODULE,
@@ -1307,7 +1301,7 @@ static struct ccw_driver tape_34xx_driver = {
 	.probe = tape_generic_probe,
 	.remove = tape_generic_remove,
 	.set_online = tape_34xx_online,
-	.set_offline = tape_34xx_offline,
+	.set_offline = tape_generic_offline,
 };
 
 static int
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index fc1d91294143..823b05bd0dd7 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -1707,19 +1707,13 @@ tape_3590_online(struct ccw_device *cdev)
 				   &tape_discipline_3590);
 }
 
-static int
-tape_3590_offline(struct ccw_device *cdev)
-{
-	return tape_generic_offline(cdev->dev.driver_data);
-}
-
 static struct ccw_driver tape_3590_driver = {
 	.name = "tape_3590",
 	.owner = THIS_MODULE,
 	.ids = tape_3590_ids,
 	.probe = tape_generic_probe,
 	.remove = tape_generic_remove,
-	.set_offline = tape_3590_offline,
+	.set_offline = tape_generic_offline,
 	.set_online = tape_3590_online,
 };
 
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 08c09d3503cf..8a109f3b69c6 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -387,8 +387,11 @@ tape_cleanup_device(struct tape_device *device)
  * Manual offline is only allowed while the drive is not in use.
  */
 int
-tape_generic_offline(struct tape_device *device)
+tape_generic_offline(struct ccw_device *cdev)
 {
+	struct tape_device *device;
+
+	device = cdev->dev.driver_data;
 	if (!device) {
 		return -ENODEV;
 	}
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 9e8a2914259b..accd957454e7 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -881,42 +881,6 @@ no_handler:
 	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 }
 
-static void qdio_call_shutdown(struct work_struct *work)
-{
-	struct ccw_device_private *priv;
-	struct ccw_device *cdev;
-
-	priv = container_of(work, struct ccw_device_private, kick_work);
-	cdev = priv->cdev;
-	qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
-	put_device(&cdev->dev);
-}
-
-static void qdio_int_error(struct ccw_device *cdev)
-{
-	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
-
-	switch (irq_ptr->state) {
-	case QDIO_IRQ_STATE_INACTIVE:
-	case QDIO_IRQ_STATE_CLEANUP:
-		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
-		break;
-	case QDIO_IRQ_STATE_ESTABLISHED:
-	case QDIO_IRQ_STATE_ACTIVE:
-		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
-		if (get_device(&cdev->dev)) {
-			/* Can't call shutdown from interrupt context. */
-			PREPARE_WORK(&cdev->private->kick_work,
-				     qdio_call_shutdown);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
-		}
-		break;
-	default:
-		WARN_ON(1);
-	}
-	wake_up(&cdev->private->wait_q);
-}
-
 static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat,
 				       int dstat)
 {
@@ -973,10 +937,8 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
 		switch (PTR_ERR(irb)) {
 		case -EIO:
 			DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no);
-			return;
-		case -ETIMEDOUT:
-			DBF_ERROR("%4x IO timeout", irq_ptr->schid.sch_no);
-			qdio_int_error(cdev);
+			qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
+			wake_up(&cdev->private->wait_q);
 			return;
 		default:
 			WARN_ON(1);
@@ -1001,7 +963,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
 	case QDIO_IRQ_STATE_ACTIVE:
 		if (cstat & SCHN_STAT_PCI) {
 			qdio_int_handler_pci(irq_ptr);
-			/* no state change so no need to wake up wait_q */
 			return;
 		}
 		if ((cstat & ~SCHN_STAT_PCI) || dstat) {
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index e6d1fc8c54f1..a85ad05e8548 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -383,18 +383,22 @@ static int jsf_ioctl_program(void __user *arg)
 	return 0;
 }
 
-static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
-    unsigned long arg)
+static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 {
+	lock_kernel();
 	int error = -ENOTTY;
 	void __user *argp = (void __user *)arg;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN)) {
+		unlock_kernel();
 		return -EPERM;
+	}
 	switch (cmd) {
 	case JSFLASH_IDENT:
-		if (copy_to_user(argp, &jsf0.id, JSFIDSZ))
+		if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) {
+			unlock_kernel();
 			return -EFAULT;
+		}
 		break;
 	case JSFLASH_ERASE:
 		error = jsf_ioctl_erase(arg);
@@ -404,6 +408,7 @@ static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
 		break;
 	}
 
+	unlock_kernel();
 	return error;
 }
 
@@ -439,7 +444,7 @@ static const struct file_operations jsf_fops = {
 	.llseek =	jsf_lseek,
 	.read =		jsf_read,
 	.write =	jsf_write,
-	.ioctl =	jsf_ioctl,
+	.unlocked_ioctl =	jsf_ioctl,
 	.mmap =		jsf_mmap,
 	.open =		jsf_open,
 	.release =	jsf_release,
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 27993c37775d..2c56fd56ec63 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -197,9 +197,8 @@ static struct uctrl_driver {
 static void uctrl_get_event_status(struct uctrl_driver *);
 static void uctrl_get_external_status(struct uctrl_driver *);
 
-static int
-uctrl_ioctl(struct inode *inode, struct file *file,
-	      unsigned int cmd, unsigned long arg)
+static long
+uctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	switch (cmd) {
 		default:
@@ -226,7 +225,7 @@ static irqreturn_t uctrl_interrupt(int irq, void *dev_id)
 static const struct file_operations uctrl_fops = {
 	.owner =	THIS_MODULE,
 	.llseek =	no_llseek,
-	.ioctl =	uctrl_ioctl,
+	.unlocked_ioctl =	uctrl_ioctl,
 	.open =		uctrl_open,
 };
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fdb14ec4fd47..8b7983aba8f7 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -2234,10 +2234,10 @@ static int twa_resume(struct pci_dev *pdev)
 	pci_set_master(pdev);
 	pci_try_set_mwi(pdev);
 
-	if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
-	    || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
-		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
-		    || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 			TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume");
 			retval = -ENODEV;
 			goto out_disable_device;
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index 61af3d91ac8a..e3519fa5a3ba 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -129,7 +129,7 @@ static int __init a4000t_scsi_init(void)
 	a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
 			-1, NULL, 0);
 	if (IS_ERR(a4000t_scsi_device)) {
-		platform_driver_register(&a4000t_scsi_driver);
+		platform_driver_unregister(&a4000t_scsi_driver);
 		return PTR_ERR(a4000t_scsi_device);
 	}
 
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 280261c451d6..2a889853a106 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1378,7 +1378,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
 	if (dev->nondasd_support && !dev->in_reset)
 		printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
 
-	if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
+	if (dma_get_required_mask(&dev->pdev->dev) > DMA_BIT_MASK(32))
 		dev->needs_dac = 1;
 	dev->dac_support = 0;
 	if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index b1bd3fc7bae8..36fd2e75da1c 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1394,7 +1394,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
 		 */
 		cmd->sense_buffer[8] = 0;     /* Information */
 		cmd->sense_buffer[9] = 0xa;   /* Add. length */
-		do_div(bghm, cmd->device->sector_size);
+		bghm /= cmd->device->sector_size;
 
 		failing_sector = scsi_get_lba(cmd);
 		failing_sector += bghm;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 52427a8324f5..a91f5143ceac 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -855,9 +855,9 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
 	if (sizeof(dma_addr_t) > 4) {
 		const uint64_t required_mask =
 		    dma_get_required_mask(&pdev->dev);
-		if ((required_mask > DMA_32BIT_MASK) && !pci_set_dma_mask(pdev,
-		    DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(pdev,
-		    DMA_64BIT_MASK)) {
+		if ((required_mask > DMA_BIT_MASK(32)) && !pci_set_dma_mask(pdev,
+		    DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(pdev,
+		    DMA_BIT_MASK(64))) {
 			ioc->base_add_sg_single = &_base_add_sg_single_64;
 			ioc->sge_size = sizeof(Mpi2SGESimple64_t);
 			desc = "64";
@@ -865,8 +865,8 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
 		}
 	}
 
-	if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
-	    && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+	    && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		ioc->base_add_sg_single = &_base_add_sg_single_32;
 		ioc->sge_size = sizeof(Mpi2SGESimple32_t);
 		desc = "32";
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 687dcf2d0154..5defe5ea5eda 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1663,7 +1663,7 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
 
 	/* Load RISC code. */
 	risc_address = ha->fwstart;
-	fw_data = (const __le16 *)&fw->data[4];
+	fw_data = (const __le16 *)&fw->data[6];
 	risc_code_size = (fw->size - 6) / 2;
 
 	for (i = 0; i < risc_code_size; i++) {
@@ -1722,7 +1722,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
 
 	/* Load RISC code. */
 	risc_address = ha->fwstart;
-	fw_data = (const __le16 *)&fw->data[4];
+	fw_data = (const __le16 *)&fw->data[6];
 	risc_code_size = (fw->size - 6) / 2;
 
 	dprintk(1, "%s: DMA RISC code (%i) words\n",
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index e1850904ff73..fbc83bebdd8e 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -38,9 +38,6 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
 	{ };
 #endif
 
-/* scsi_scan.c */
-int scsi_complete_async_scans(void);
-
 /* scsi_devinfo.c */
 extern int scsi_get_device_flags(struct scsi_device *sdev,
 				 const unsigned char *vendor,
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a14d245a66b8..6f51ca485f35 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -180,8 +180,6 @@ int scsi_complete_async_scans(void)
 	spin_unlock(&async_scan_lock);
 
 	kfree(data);
-	/* Synchronize async operations globally */
-	async_synchronize_full();
 	return 0;
 }
 
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c
index 8a636103083d..74708fcaf82f 100644
--- a/drivers/scsi/scsi_wait_scan.c
+++ b/drivers/scsi/scsi_wait_scan.c
@@ -11,10 +11,21 @@
  */
 
 #include <linux/module.h>
-#include "scsi_priv.h"
+#include <linux/device.h>
+#include <scsi/scsi_scan.h>
 
 static int __init wait_scan_init(void)
 {
+	/*
+	 * First we need to wait for device probing to finish;
+	 * the drivers we just loaded might just still be probing
+	 * and might not yet have reached the scsi async scanning
+	 */
+	wait_for_device_probe();
+	/*
+	 * and then we wait for the actual asynchronous scsi scan
+	 * to finish.
+	 */
 	scsi_complete_async_scans();
 	return 0;
 }
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 7ddff3f55087..938bc1b6c3fa 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -771,8 +771,6 @@ static int pci_netmos_init(struct pci_dev *dev)
 }
 
 /*
- * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com>
- *
  * These chips are available with optionally one parallel port and up to
  * two serial ports. Unfortunately they all have the same product id.
  *
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0328fd4006e5..343e3a35b6a3 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -854,7 +854,7 @@ config SERIAL_IMX_CONSOLE
 
 config SERIAL_UARTLITE
 	tristate "Xilinx uartlite serial port support"
-	depends on PPC32
+	depends on PPC32 || MICROBLAZE
 	select SERIAL_CORE
 	help
 	  Say Y here if you want to use the Xilinx uartlite serial controller.
@@ -1340,7 +1340,7 @@ config SERIAL_NETX_CONSOLE
 
 config SERIAL_OF_PLATFORM
 	tristate "Serial port on Open Firmware platform bus"
-	depends on PPC_OF
+	depends on PPC_OF || MICROBLAZE
 	depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
 	help
 	  If you have a PowerPC based system that has serial ports
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 18ba812a4f84..d86123e03391 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -166,7 +166,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
 	struct tty_struct *tty = uart->port.info->port.tty;
 
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+	if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
 		uart->scts = 0;
 		uart_handle_cts_change(&uart->port, uart->scts);
 	}
@@ -368,7 +368,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
 	struct bfin_serial_port *uart = dev_id;
 
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+	if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
 		uart->scts = 0;
 		uart_handle_cts_change(&uart->port, uart->scts);
 	}
@@ -504,7 +504,7 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
 	struct circ_buf *xmit = &uart->port.info->xmit;
 
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+	if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
 		uart->scts = 0;
 		uart_handle_cts_change(&uart->port, uart->scts);
 	}
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
new file mode 100644
index 000000000000..9fd33e5622bd
--- /dev/null
+++ b/drivers/serial/max3100.c
@@ -0,0 +1,927 @@
+/*
+ *
+ *  Copyright (C) 2008 Christian Pellegrin <chripell@evolware.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *
+ * Notes: the MAX3100 doesn't provide an interrupt on CTS so we have
+ * to use polling for flow control. TX empty IRQ is unusable, since
+ * writing conf clears FIFO buffer and we cannot have this interrupt
+ * always asking us for attention.
+ *
+ * Example platform data:
+
+ static struct plat_max3100 max3100_plat_data = {
+ .loopback = 0,
+ .crystal = 0,
+ .poll_time = 100,
+ };
+
+ static struct spi_board_info spi_board_info[] = {
+ {
+ .modalias	= "max3100",
+ .platform_data	= &max3100_plat_data,
+ .irq		= IRQ_EINT12,
+ .max_speed_hz	= 5*1000*1000,
+ .chip_select	= 0,
+ },
+ };
+
+ * The initial minor number is 209 in the low-density serial port:
+ * mknod /dev/ttyMAX0 c 204 209
+ */
+
+#define MAX3100_MAJOR 204
+#define MAX3100_MINOR 209
+/* 4 MAX3100s should be enough for everyone */
+#define MAX_MAX3100 4
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/spi/spi.h>
+#include <linux/freezer.h>
+
+#include <linux/serial_max3100.h>
+
+#define MAX3100_C    (1<<14)
+#define MAX3100_D    (0<<14)
+#define MAX3100_W    (1<<15)
+#define MAX3100_RX   (0<<15)
+
+#define MAX3100_WC   (MAX3100_W  | MAX3100_C)
+#define MAX3100_RC   (MAX3100_RX | MAX3100_C)
+#define MAX3100_WD   (MAX3100_W  | MAX3100_D)
+#define MAX3100_RD   (MAX3100_RX | MAX3100_D)
+#define MAX3100_CMD  (3 << 14)
+
+#define MAX3100_T    (1<<14)
+#define MAX3100_R    (1<<15)
+
+#define MAX3100_FEN  (1<<13)
+#define MAX3100_SHDN (1<<12)
+#define MAX3100_TM   (1<<11)
+#define MAX3100_RM   (1<<10)
+#define MAX3100_PM   (1<<9)
+#define MAX3100_RAM  (1<<8)
+#define MAX3100_IR   (1<<7)
+#define MAX3100_ST   (1<<6)
+#define MAX3100_PE   (1<<5)
+#define MAX3100_L    (1<<4)
+#define MAX3100_BAUD (0xf)
+
+#define MAX3100_TE   (1<<10)
+#define MAX3100_RAFE (1<<10)
+#define MAX3100_RTS  (1<<9)
+#define MAX3100_CTS  (1<<9)
+#define MAX3100_PT   (1<<8)
+#define MAX3100_DATA (0xff)
+
+#define MAX3100_RT   (MAX3100_R | MAX3100_T)
+#define MAX3100_RTC  (MAX3100_RT | MAX3100_CTS | MAX3100_RAFE)
+
+/* the following simulate a status reg for ignore_status_mask */
+#define MAX3100_STATUS_PE 1
+#define MAX3100_STATUS_FE 2
+#define MAX3100_STATUS_OE 4
+
+struct max3100_port {
+	struct uart_port port;
+	struct spi_device *spi;
+
+	int cts;	        /* last CTS received for flow ctrl */
+	int tx_empty;		/* last TX empty bit */
+
+	spinlock_t conf_lock;	/* shared data */
+	int conf_commit;	/* need to make changes */
+	int conf;		/* configuration for the MAX31000
+				 * (bits 0-7, bits 8-11 are irqs) */
+	int rts_commit;	        /* need to change rts */
+	int rts;		/* rts status */
+	int baud;		/* current baud rate */
+
+	int parity;		/* keeps track if we should send parity */
+#define MAX3100_PARITY_ON 1
+#define MAX3100_PARITY_ODD 2
+#define MAX3100_7BIT 4
+	int rx_enabled;	        /* if we should rx chars */
+
+	int irq;		/* irq assigned to the max3100 */
+
+	int minor;		/* minor number */
+	int crystal;		/* 1 if 3.6864Mhz crystal 0 for 1.8432 */
+	int loopback;		/* 1 if we are in loopback mode */
+
+	/* for handling irqs: need workqueue since we do spi_sync */
+	struct workqueue_struct *workqueue;
+	struct work_struct work;
+	/* set to 1 to make the workhandler exit as soon as possible */
+	int  force_end_work;
+	/* need to know we are suspending to avoid deadlock on workqueue */
+	int suspending;
+
+	/* hook for suspending MAX3100 via dedicated pin */
+	void (*max3100_hw_suspend) (int suspend);
+
+	/* poll time (in ms) for ctrl lines */
+	int poll_time;
+	/* and its timer */
+	struct timer_list	timer;
+};
+
+static struct max3100_port *max3100s[MAX_MAX3100]; /* the chips */
+static DEFINE_MUTEX(max3100s_lock);		   /* race on probe */
+
+static int max3100_do_parity(struct max3100_port *s, u16 c)
+{
+	int parity;
+
+	if (s->parity & MAX3100_PARITY_ODD)
+		parity = 1;
+	else
+		parity = 0;
+
+	if (s->parity & MAX3100_7BIT)
+		c &= 0x7f;
+	else
+		c &= 0xff;
+
+	parity = parity ^ (hweight8(c) & 1);
+	return parity;
+}
+
+static int max3100_check_parity(struct max3100_port *s, u16 c)
+{
+	return max3100_do_parity(s, c) == ((c >> 8) & 1);
+}
+
+static void max3100_calc_parity(struct max3100_port *s, u16 *c)
+{
+	if (s->parity & MAX3100_7BIT)
+		*c &= 0x7f;
+	else
+		*c &= 0xff;
+
+	if (s->parity & MAX3100_PARITY_ON)
+		*c |= max3100_do_parity(s, *c) << 8;
+}
+
+static void max3100_work(struct work_struct *w);
+
+static void max3100_dowork(struct max3100_port *s)
+{
+	if (!s->force_end_work && !work_pending(&s->work) &&
+	    !freezing(current) && !s->suspending)
+		queue_work(s->workqueue, &s->work);
+}
+
+static void max3100_timeout(unsigned long data)
+{
+	struct max3100_port *s = (struct max3100_port *)data;
+
+	if (s->port.info) {
+		max3100_dowork(s);
+		mod_timer(&s->timer, jiffies + s->poll_time);
+	}
+}
+
+static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx)
+{
+	struct spi_message message;
+	u16 etx, erx;
+	int status;
+	struct spi_transfer tran = {
+		.tx_buf = &etx,
+		.rx_buf = &erx,
+		.len = 2,
+	};
+
+	etx = cpu_to_be16(tx);
+	spi_message_init(&message);
+	spi_message_add_tail(&tran, &message);
+	status = spi_sync(s->spi, &message);
+	if (status) {
+		dev_warn(&s->spi->dev, "error while calling spi_sync\n");
+		return -EIO;
+	}
+	*rx = be16_to_cpu(erx);
+	s->tx_empty = (*rx & MAX3100_T) > 0;
+	dev_dbg(&s->spi->dev, "%04x - %04x\n", tx, *rx);
+	return 0;
+}
+
+static int max3100_handlerx(struct max3100_port *s, u16 rx)
+{
+	unsigned int ch, flg, status = 0;
+	int ret = 0, cts;
+
+	if (rx & MAX3100_R && s->rx_enabled) {
+		dev_dbg(&s->spi->dev, "%s\n", __func__);
+		ch = rx & (s->parity & MAX3100_7BIT ? 0x7f : 0xff);
+		if (rx & MAX3100_RAFE) {
+			s->port.icount.frame++;
+			flg = TTY_FRAME;
+			status |= MAX3100_STATUS_FE;
+		} else {
+			if (s->parity & MAX3100_PARITY_ON) {
+				if (max3100_check_parity(s, rx)) {
+					s->port.icount.rx++;
+					flg = TTY_NORMAL;
+				} else {
+					s->port.icount.parity++;
+					flg = TTY_PARITY;
+					status |= MAX3100_STATUS_PE;
+				}
+			} else {
+				s->port.icount.rx++;
+				flg = TTY_NORMAL;
+			}
+		}
+		uart_insert_char(&s->port, status, MAX3100_STATUS_OE, ch, flg);
+		ret = 1;
+	}
+
+	cts = (rx & MAX3100_CTS) > 0;
+	if (s->cts != cts) {
+		s->cts = cts;
+		uart_handle_cts_change(&s->port, cts ? TIOCM_CTS : 0);
+	}
+
+	return ret;
+}
+
+static void max3100_work(struct work_struct *w)
+{
+	struct max3100_port *s = container_of(w, struct max3100_port, work);
+	int rxchars;
+	u16 tx, rx;
+	int conf, cconf, rts, crts;
+	struct circ_buf *xmit = &s->port.info->xmit;
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	rxchars = 0;
+	do {
+		spin_lock(&s->conf_lock);
+		conf = s->conf;
+		cconf = s->conf_commit;
+		s->conf_commit = 0;
+		rts = s->rts;
+		crts = s->rts_commit;
+		s->rts_commit = 0;
+		spin_unlock(&s->conf_lock);
+		if (cconf)
+			max3100_sr(s, MAX3100_WC | conf, &rx);
+		if (crts) {
+			max3100_sr(s, MAX3100_WD | MAX3100_TE |
+				   (s->rts ? MAX3100_RTS : 0), &rx);
+			rxchars += max3100_handlerx(s, rx);
+		}
+
+		max3100_sr(s, MAX3100_RD, &rx);
+		rxchars += max3100_handlerx(s, rx);
+
+		if (rx & MAX3100_T) {
+			tx = 0xffff;
+			if (s->port.x_char) {
+				tx = s->port.x_char;
+				s->port.icount.tx++;
+				s->port.x_char = 0;
+			} else if (!uart_circ_empty(xmit) &&
+				   !uart_tx_stopped(&s->port)) {
+				tx = xmit->buf[xmit->tail];
+				xmit->tail = (xmit->tail + 1) &
+					(UART_XMIT_SIZE - 1);
+				s->port.icount.tx++;
+			}
+			if (tx != 0xffff) {
+				max3100_calc_parity(s, &tx);
+				tx |= MAX3100_WD | (s->rts ? MAX3100_RTS : 0);
+				max3100_sr(s, tx, &rx);
+				rxchars += max3100_handlerx(s, rx);
+			}
+		}
+
+		if (rxchars > 16 && s->port.info->port.tty != NULL) {
+			tty_flip_buffer_push(s->port.info->port.tty);
+			rxchars = 0;
+		}
+		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+			uart_write_wakeup(&s->port);
+
+	} while (!s->force_end_work &&
+		 !freezing(current) &&
+		 ((rx & MAX3100_R) ||
+		  (!uart_circ_empty(xmit) &&
+		   !uart_tx_stopped(&s->port))));
+
+	if (rxchars > 0 && s->port.info->port.tty != NULL)
+		tty_flip_buffer_push(s->port.info->port.tty);
+}
+
+static irqreturn_t max3100_irq(int irqno, void *dev_id)
+{
+	struct max3100_port *s = dev_id;
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	max3100_dowork(s);
+	return IRQ_HANDLED;
+}
+
+static void max3100_enable_ms(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	if (s->poll_time > 0)
+		mod_timer(&s->timer, jiffies);
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static void max3100_start_tx(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	max3100_dowork(s);
+}
+
+static void max3100_stop_rx(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	s->rx_enabled = 0;
+	spin_lock(&s->conf_lock);
+	s->conf &= ~MAX3100_RM;
+	s->conf_commit = 1;
+	spin_unlock(&s->conf_lock);
+	max3100_dowork(s);
+}
+
+static unsigned int max3100_tx_empty(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	/* may not be truly up-to-date */
+	max3100_dowork(s);
+	return s->tx_empty;
+}
+
+static unsigned int max3100_get_mctrl(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	/* may not be truly up-to-date */
+	max3100_dowork(s);
+	/* always assert DCD and DSR since these lines are not wired */
+	return (s->cts ? TIOCM_CTS : 0) | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void max3100_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+	int rts;
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	rts = (mctrl & TIOCM_RTS) > 0;
+
+	spin_lock(&s->conf_lock);
+	if (s->rts != rts) {
+		s->rts = rts;
+		s->rts_commit = 1;
+		max3100_dowork(s);
+	}
+	spin_unlock(&s->conf_lock);
+}
+
+static void
+max3100_set_termios(struct uart_port *port, struct ktermios *termios,
+		    struct ktermios *old)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+	int baud = 0;
+	unsigned cflag;
+	u32 param_new, param_mask, parity = 0;
+	struct tty_struct *tty = s->port.info->port.tty;
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+	if (!tty)
+		return;
+
+	cflag = termios->c_cflag;
+	param_new = 0;
+	param_mask = 0;
+
+	baud = tty_get_baud_rate(tty);
+	param_new = s->conf & MAX3100_BAUD;
+	switch (baud) {
+	case 300:
+		if (s->crystal)
+			baud = s->baud;
+		else
+			param_new = 15;
+		break;
+	case 600:
+		param_new = 14 + s->crystal;
+		break;
+	case 1200:
+		param_new = 13 + s->crystal;
+		break;
+	case 2400:
+		param_new = 12 + s->crystal;
+		break;
+	case 4800:
+		param_new = 11 + s->crystal;
+		break;
+	case 9600:
+		param_new = 10 + s->crystal;
+		break;
+	case 19200:
+		param_new = 9 + s->crystal;
+		break;
+	case 38400:
+		param_new = 8 + s->crystal;
+		break;
+	case 57600:
+		param_new = 1 + s->crystal;
+		break;
+	case 115200:
+		param_new = 0 + s->crystal;
+		break;
+	case 230400:
+		if (s->crystal)
+			param_new = 0;
+		else
+			baud = s->baud;
+		break;
+	default:
+		baud = s->baud;
+	}
+	tty_encode_baud_rate(tty, baud, baud);
+	s->baud = baud;
+	param_mask |= MAX3100_BAUD;
+
+	if ((cflag & CSIZE) == CS8) {
+		param_new &= ~MAX3100_L;
+		parity &= ~MAX3100_7BIT;
+	} else {
+		param_new |= MAX3100_L;
+		parity |= MAX3100_7BIT;
+		cflag = (cflag & ~CSIZE) | CS7;
+	}
+	param_mask |= MAX3100_L;
+
+	if (cflag & CSTOPB)
+		param_new |= MAX3100_ST;
+	else
+		param_new &= ~MAX3100_ST;
+	param_mask |= MAX3100_ST;
+
+	if (cflag & PARENB) {
+		param_new |= MAX3100_PE;
+		parity |= MAX3100_PARITY_ON;
+	} else {
+		param_new &= ~MAX3100_PE;
+		parity &= ~MAX3100_PARITY_ON;
+	}
+	param_mask |= MAX3100_PE;
+
+	if (cflag & PARODD)
+		parity |= MAX3100_PARITY_ODD;
+	else
+		parity &= ~MAX3100_PARITY_ODD;
+
+	/* mask termios capabilities we don't support */
+	cflag &= ~CMSPAR;
+	termios->c_cflag = cflag;
+
+	s->port.ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		s->port.ignore_status_mask |=
+			MAX3100_STATUS_PE | MAX3100_STATUS_FE |
+			MAX3100_STATUS_OE;
+
+	/* we are sending char from a workqueue so enable */
+	s->port.info->port.tty->low_latency = 1;
+
+	if (s->poll_time > 0)
+		del_timer_sync(&s->timer);
+
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	spin_lock(&s->conf_lock);
+	s->conf = (s->conf & ~param_mask) | (param_new & param_mask);
+	s->conf_commit = 1;
+	s->parity = parity;
+	spin_unlock(&s->conf_lock);
+	max3100_dowork(s);
+
+	if (UART_ENABLE_MS(&s->port, termios->c_cflag))
+		max3100_enable_ms(&s->port);
+}
+
+static void max3100_shutdown(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	if (s->suspending)
+		return;
+
+	s->force_end_work = 1;
+
+	if (s->poll_time > 0)
+		del_timer_sync(&s->timer);
+
+	if (s->workqueue) {
+		flush_workqueue(s->workqueue);
+		destroy_workqueue(s->workqueue);
+		s->workqueue = NULL;
+	}
+	if (s->irq)
+		free_irq(s->irq, s);
+
+	/* set shutdown mode to save power */
+	if (s->max3100_hw_suspend)
+		s->max3100_hw_suspend(1);
+	else  {
+		u16 tx, rx;
+
+		tx = MAX3100_WC | MAX3100_SHDN;
+		max3100_sr(s, tx, &rx);
+	}
+}
+
+static int max3100_startup(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+	char b[12];
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	s->conf = MAX3100_RM;
+	s->baud = s->crystal ? 230400 : 115200;
+	s->rx_enabled = 1;
+
+	if (s->suspending)
+		return 0;
+
+	s->force_end_work = 0;
+	s->parity = 0;
+	s->rts = 0;
+
+	sprintf(b, "max3100-%d", s->minor);
+	s->workqueue = create_freezeable_workqueue(b);
+	if (!s->workqueue) {
+		dev_warn(&s->spi->dev, "cannot create workqueue\n");
+		return -EBUSY;
+	}
+	INIT_WORK(&s->work, max3100_work);
+
+	if (request_irq(s->irq, max3100_irq,
+			IRQF_TRIGGER_FALLING, "max3100", s) < 0) {
+		dev_warn(&s->spi->dev, "cannot allocate irq %d\n", s->irq);
+		s->irq = 0;
+		destroy_workqueue(s->workqueue);
+		s->workqueue = NULL;
+		return -EBUSY;
+	}
+
+	if (s->loopback) {
+		u16 tx, rx;
+		tx = 0x4001;
+		max3100_sr(s, tx, &rx);
+	}
+
+	if (s->max3100_hw_suspend)
+		s->max3100_hw_suspend(0);
+	s->conf_commit = 1;
+	max3100_dowork(s);
+	/* wait for clock to settle */
+	msleep(50);
+
+	max3100_enable_ms(&s->port);
+
+	return 0;
+}
+
+static const char *max3100_type(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	return s->port.type == PORT_MAX3100 ? "MAX3100" : NULL;
+}
+
+static void max3100_release_port(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static void max3100_config_port(struct uart_port *port, int flags)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	if (flags & UART_CONFIG_TYPE)
+		s->port.type = PORT_MAX3100;
+}
+
+static int max3100_verify_port(struct uart_port *port,
+			       struct serial_struct *ser)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+	int ret = -EINVAL;
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3100)
+		ret = 0;
+	return ret;
+}
+
+static void max3100_stop_tx(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static int max3100_request_port(struct uart_port *port)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+	return 0;
+}
+
+static void max3100_break_ctl(struct uart_port *port, int break_state)
+{
+	struct max3100_port *s = container_of(port,
+					      struct max3100_port,
+					      port);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static struct uart_ops max3100_ops = {
+	.tx_empty	= max3100_tx_empty,
+	.set_mctrl	= max3100_set_mctrl,
+	.get_mctrl	= max3100_get_mctrl,
+	.stop_tx        = max3100_stop_tx,
+	.start_tx	= max3100_start_tx,
+	.stop_rx	= max3100_stop_rx,
+	.enable_ms      = max3100_enable_ms,
+	.break_ctl      = max3100_break_ctl,
+	.startup	= max3100_startup,
+	.shutdown	= max3100_shutdown,
+	.set_termios	= max3100_set_termios,
+	.type		= max3100_type,
+	.release_port   = max3100_release_port,
+	.request_port   = max3100_request_port,
+	.config_port	= max3100_config_port,
+	.verify_port	= max3100_verify_port,
+};
+
+static struct uart_driver max3100_uart_driver = {
+	.owner          = THIS_MODULE,
+	.driver_name    = "ttyMAX",
+	.dev_name       = "ttyMAX",
+	.major          = MAX3100_MAJOR,
+	.minor          = MAX3100_MINOR,
+	.nr             = MAX_MAX3100,
+};
+static int uart_driver_registered;
+
+static int __devinit max3100_probe(struct spi_device *spi)
+{
+	int i, retval;
+	struct plat_max3100 *pdata;
+	u16 tx, rx;
+
+	mutex_lock(&max3100s_lock);
+
+	if (!uart_driver_registered) {
+		uart_driver_registered = 1;
+		retval = uart_register_driver(&max3100_uart_driver);
+		if (retval) {
+			printk(KERN_ERR "Couldn't register max3100 uart driver\n");
+			mutex_unlock(&max3100s_lock);
+			return retval;
+		}
+	}
+
+	for (i = 0; i < MAX_MAX3100; i++)
+		if (!max3100s[i])
+			break;
+	if (i == MAX_MAX3100) {
+		dev_warn(&spi->dev, "too many MAX3100 chips\n");
+		mutex_unlock(&max3100s_lock);
+		return -ENOMEM;
+	}
+
+	max3100s[i] = kzalloc(sizeof(struct max3100_port), GFP_KERNEL);
+	if (!max3100s[i]) {
+		dev_warn(&spi->dev,
+			 "kmalloc for max3100 structure %d failed!\n", i);
+		mutex_unlock(&max3100s_lock);
+		return -ENOMEM;
+	}
+	max3100s[i]->spi = spi;
+	max3100s[i]->irq = spi->irq;
+	spin_lock_init(&max3100s[i]->conf_lock);
+	dev_set_drvdata(&spi->dev, max3100s[i]);
+	pdata = spi->dev.platform_data;
+	max3100s[i]->crystal = pdata->crystal;
+	max3100s[i]->loopback = pdata->loopback;
+	max3100s[i]->poll_time = pdata->poll_time * HZ / 1000;
+	if (pdata->poll_time > 0 && max3100s[i]->poll_time == 0)
+		max3100s[i]->poll_time = 1;
+	max3100s[i]->max3100_hw_suspend = pdata->max3100_hw_suspend;
+	max3100s[i]->minor = i;
+	init_timer(&max3100s[i]->timer);
+	max3100s[i]->timer.function = max3100_timeout;
+	max3100s[i]->timer.data = (unsigned long) max3100s[i];
+
+	dev_dbg(&spi->dev, "%s: adding port %d\n", __func__, i);
+	max3100s[i]->port.irq = max3100s[i]->irq;
+	max3100s[i]->port.uartclk = max3100s[i]->crystal ? 3686400 : 1843200;
+	max3100s[i]->port.fifosize = 16;
+	max3100s[i]->port.ops = &max3100_ops;
+	max3100s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+	max3100s[i]->port.line = i;
+	max3100s[i]->port.type = PORT_MAX3100;
+	max3100s[i]->port.dev = &spi->dev;
+	retval = uart_add_one_port(&max3100_uart_driver, &max3100s[i]->port);
+	if (retval < 0)
+		dev_warn(&spi->dev,
+			 "uart_add_one_port failed for line %d with error %d\n",
+			 i, retval);
+
+	/* set shutdown mode to save power. Will be woken-up on open */
+	if (max3100s[i]->max3100_hw_suspend)
+		max3100s[i]->max3100_hw_suspend(1);
+	else {
+		tx = MAX3100_WC | MAX3100_SHDN;
+		max3100_sr(max3100s[i], tx, &rx);
+	}
+	mutex_unlock(&max3100s_lock);
+	return 0;
+}
+
+static int __devexit max3100_remove(struct spi_device *spi)
+{
+	struct max3100_port *s = dev_get_drvdata(&spi->dev);
+	int i;
+
+	mutex_lock(&max3100s_lock);
+
+	/* find out the index for the chip we are removing */
+	for (i = 0; i < MAX_MAX3100; i++)
+		if (max3100s[i] == s)
+			break;
+
+	dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i);
+	uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port);
+	kfree(max3100s[i]);
+	max3100s[i] = NULL;
+
+	/* check if this is the last chip we have */
+	for (i = 0; i < MAX_MAX3100; i++)
+		if (max3100s[i]) {
+			mutex_unlock(&max3100s_lock);
+			return 0;
+		}
+	pr_debug("removing max3100 driver\n");
+	uart_unregister_driver(&max3100_uart_driver);
+
+	mutex_unlock(&max3100s_lock);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int max3100_suspend(struct spi_device *spi, pm_message_t state)
+{
+	struct max3100_port *s = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	disable_irq(s->irq);
+
+	s->suspending = 1;
+	uart_suspend_port(&max3100_uart_driver, &s->port);
+
+	if (s->max3100_hw_suspend)
+		s->max3100_hw_suspend(1);
+	else {
+		/* no HW suspend, so do SW one */
+		u16 tx, rx;
+
+		tx = MAX3100_WC | MAX3100_SHDN;
+		max3100_sr(s, tx, &rx);
+	}
+	return 0;
+}
+
+static int max3100_resume(struct spi_device *spi)
+{
+	struct max3100_port *s = dev_get_drvdata(&spi->dev);
+
+	dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+	if (s->max3100_hw_suspend)
+		s->max3100_hw_suspend(0);
+	uart_resume_port(&max3100_uart_driver, &s->port);
+	s->suspending = 0;
+
+	enable_irq(s->irq);
+
+	s->conf_commit = 1;
+	if (s->workqueue)
+		max3100_dowork(s);
+
+	return 0;
+}
+
+#else
+#define max3100_suspend NULL
+#define max3100_resume  NULL
+#endif
+
+static struct spi_driver max3100_driver = {
+	.driver = {
+		.name		= "max3100",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= max3100_probe,
+	.remove		= __devexit_p(max3100_remove),
+	.suspend	= max3100_suspend,
+	.resume		= max3100_resume,
+};
+
+static int __init max3100_init(void)
+{
+	return spi_register_driver(&max3100_driver);
+}
+module_init(max3100_init);
+
+static void __exit max3100_exit(void)
+{
+	spi_unregister_driver(&max3100_driver);
+}
+module_exit(max3100_exit);
+
+MODULE_DESCRIPTION("MAX3100 driver");
+MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 41ac94872b8d..e06686ae858b 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -127,7 +127,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (tx_enabled(port)) {
-		disable_irq(ourport->tx_irq);
+		disable_irq_nosync(ourport->tx_irq);
 		tx_enabled(port) = 0;
 		if (port->flags & UPF_CONS_FLOW)
 			s3c24xx_serial_rx_enable(port);
@@ -154,7 +154,7 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
 
 	if (rx_enabled(port)) {
 		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
-		disable_irq(ourport->rx_irq);
+		disable_irq_nosync(ourport->rx_irq);
 		rx_enabled(port) = 0;
 	}
 }
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index a4dc79b1d7ab..47c6837850b1 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1178,7 +1178,7 @@ static struct uart_driver sunsu_reg = {
 	.major			= TTY_MAJOR,
 };
 
-static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
+static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up)
 {
 	int quot, baud;
 #ifdef CONFIG_SERIO
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 7fb9b5c4669a..12d13d99b6f0 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -44,6 +44,7 @@ struct intc_handle_int {
 struct intc_desc_int {
 	struct list_head list;
 	struct sys_device sysdev;
+	pm_message_t state;
 	unsigned long *reg;
 #ifdef CONFIG_SMP
 	unsigned long *smp;
@@ -786,18 +787,44 @@ static int intc_suspend(struct sys_device *dev, pm_message_t state)
 	/* get intc controller associated with this sysdev */
 	d = container_of(dev, struct intc_desc_int, sysdev);
 
-	/* enable wakeup irqs belonging to this intc controller */
-	for_each_irq_desc(irq, desc) {
-		if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
-			intc_enable(irq);
+	switch (state.event) {
+	case PM_EVENT_ON:
+		if (d->state.event != PM_EVENT_FREEZE)
+			break;
+		for_each_irq_desc(irq, desc) {
+			if (desc->chip != &d->chip)
+				continue;
+			if (desc->status & IRQ_DISABLED)
+				intc_disable(irq);
+			else
+				intc_enable(irq);
+		}
+		break;
+	case PM_EVENT_FREEZE:
+		/* nothing has to be done */
+		break;
+	case PM_EVENT_SUSPEND:
+		/* enable wakeup irqs belonging to this intc controller */
+		for_each_irq_desc(irq, desc) {
+			if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
+				intc_enable(irq);
+		}
+		break;
 	}
+	d->state = state;
 
 	return 0;
 }
 
+static int intc_resume(struct sys_device *dev)
+{
+	return intc_suspend(dev, PMSG_ON);
+}
+
 static struct sysdev_class intc_sysdev_class = {
 	.name = "intc",
 	.suspend = intc_suspend,
+	.resume = intc_resume,
 };
 
 /* register this intc as sysdev to allow suspend/resume */
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index c1688c71f052..885194a07418 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -195,7 +195,7 @@ static void cs_deassert(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	if (chip->cs_control) {
-		chip->cs_control(PXA2XX_CS_ASSERT);
+		chip->cs_control(PXA2XX_CS_DEASSERT);
 		return;
 	}
 
@@ -213,7 +213,7 @@ static int flush(struct driver_data *drv_data)
 		while (read_SSSR(reg) & SSSR_RNE) {
 			read_SSDR(reg);
 		}
-	} while ((read_SSSR(reg) & SSSR_BSY) && limit--);
+	} while ((read_SSSR(reg) & SSSR_BSY) && --limit);
 	write_SSSR(SSSR_ROR, reg);
 
 	return limit;
@@ -484,7 +484,7 @@ static int wait_ssp_rx_stall(void const __iomem *ioaddr)
 {
 	unsigned long limit = loops_per_jiffy << 1;
 
-	while ((read_SSSR(ioaddr) & SSSR_BSY) && limit--)
+	while ((read_SSSR(ioaddr) & SSSR_BSY) && --limit)
 		cpu_relax();
 
 	return limit;
@@ -494,7 +494,7 @@ static int wait_dma_channel_stop(int channel)
 {
 	unsigned long limit = loops_per_jiffy << 1;
 
-	while (!(DCSR(channel) & DCSR_STOPSTATE) && limit--)
+	while (!(DCSR(channel) & DCSR_STOPSTATE) && --limit)
 		cpu_relax();
 
 	return limit;
@@ -1700,6 +1700,13 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
 	struct ssp_device *ssp = drv_data->ssp;
 	int status = 0;
 
+	if (drv_data->rx_channel != -1)
+		DRCMR(drv_data->ssp->drcmr_rx) =
+			DRCMR_MAPVLD | drv_data->rx_channel;
+	if (drv_data->tx_channel != -1)
+		DRCMR(drv_data->ssp->drcmr_tx) =
+			DRCMR_MAPVLD | drv_data->tx_channel;
+
 	/* Enable the SSP clock */
 	clk_enable(ssp->clk);
 
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 643908b74bc0..8eba98c8ed1e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -658,7 +658,7 @@ int spi_write_then_read(struct spi_device *spi,
 
 	int			status;
 	struct spi_message	message;
-	struct spi_transfer	x;
+	struct spi_transfer	x[2];
 	u8			*local_buf;
 
 	/* Use preallocated DMA-safe buffer.  We can't avoid copying here,
@@ -669,9 +669,15 @@ int spi_write_then_read(struct spi_device *spi,
 		return -EINVAL;
 
 	spi_message_init(&message);
-	memset(&x, 0, sizeof x);
-	x.len = n_tx + n_rx;
-	spi_message_add_tail(&x, &message);
+	memset(x, 0, sizeof x);
+	if (n_tx) {
+		x[0].len = n_tx;
+		spi_message_add_tail(&x[0], &message);
+	}
+	if (n_rx) {
+		x[1].len = n_rx;
+		spi_message_add_tail(&x[1], &message);
+	}
 
 	/* ... unless someone else is using the pre-allocated buffer */
 	if (!mutex_trylock(&lock)) {
@@ -682,15 +688,15 @@ int spi_write_then_read(struct spi_device *spi,
 		local_buf = buf;
 
 	memcpy(local_buf, txbuf, n_tx);
-	x.tx_buf = local_buf;
-	x.rx_buf = local_buf;
+	x[0].tx_buf = local_buf;
+	x[1].rx_buf = local_buf + n_tx;
 
 	/* do the i/o */
 	status = spi_sync(spi, &message);
 	if (status == 0)
-		memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
+		memcpy(rxbuf, x[1].rx_buf, n_rx);
 
-	if (x.tx_buf == buf)
+	if (x[0].tx_buf == buf)
 		mutex_unlock(&lock);
 	else
 		kfree(local_buf);
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 79e90fed27d3..299d29d1dadb 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -41,6 +41,8 @@ static int binder_last_id;
 static struct proc_dir_entry *binder_proc_dir_entry_root;
 static struct proc_dir_entry *binder_proc_dir_entry_proc;
 static struct hlist_head binder_dead_nodes;
+static HLIST_HEAD(binder_deferred_list);
+static DEFINE_MUTEX(binder_deferred_lock);
 
 static int binder_read_proc_proc(
 	char *page, char **start, off_t off, int count, int *eof, void *data);
@@ -54,11 +56,7 @@ static int binder_read_proc_proc(
 #define SZ_4M                               0x400000
 #endif
 
-#ifndef __i386__
-#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE | VM_EXEC)
-#else
 #define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
-#endif
 
 #define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64)
 
@@ -236,6 +234,12 @@ struct binder_buffer {
 	uint8_t data[0];
 };
 
+enum {
+	BINDER_DEFERRED_PUT_FILES    = 0x01,
+	BINDER_DEFERRED_FLUSH        = 0x02,
+	BINDER_DEFERRED_RELEASE      = 0x04,
+};
+
 struct binder_proc {
 	struct hlist_node proc_node;
 	struct rb_root threads;
@@ -245,8 +249,11 @@ struct binder_proc {
 	int pid;
 	struct vm_area_struct *vma;
 	struct task_struct *tsk;
+	struct files_struct *files;
+	struct hlist_node deferred_work_node;
+	int deferred_work;
 	void *buffer;
-	size_t user_buffer_offset;
+	ptrdiff_t user_buffer_offset;
 
 	struct list_head buffers;
 	struct rb_root free_buffers;
@@ -310,12 +317,14 @@ struct binder_transaction {
 	uid_t	sender_euid;
 };
 
+static void binder_defer_work(struct binder_proc *proc, int defer);
+
 /*
  * copied from get_unused_fd_flags
  */
-int task_get_unused_fd_flags(struct task_struct *tsk, int flags)
+int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
 {
-	struct files_struct *files = get_files_struct(tsk);
+	struct files_struct *files = proc->files;
 	int fd, error;
 	struct fdtable *fdt;
 	unsigned long rlim_cur;
@@ -337,9 +346,9 @@ repeat:
 	 * will limit the total number of files that can be opened.
 	 */
 	rlim_cur = 0;
-	if (lock_task_sighand(tsk, &irqs)) {
-		rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
-		unlock_task_sighand(tsk, &irqs);
+	if (lock_task_sighand(proc->tsk, &irqs)) {
+		rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
+		unlock_task_sighand(proc->tsk, &irqs);
 	}
 	if (fd >= rlim_cur)
 		goto out;
@@ -375,7 +384,6 @@ repeat:
 
 out:
 	spin_unlock(&files->file_lock);
-	put_files_struct(files);
 	return error;
 }
 
@@ -383,9 +391,9 @@ out:
  * copied from fd_install
  */
 static void task_fd_install(
-	struct task_struct *tsk, unsigned int fd, struct file *file)
+	struct binder_proc *proc, unsigned int fd, struct file *file)
 {
-	struct files_struct *files = get_files_struct(tsk);
+	struct files_struct *files = proc->files;
 	struct fdtable *fdt;
 
 	if (files == NULL)
@@ -396,7 +404,6 @@ static void task_fd_install(
 	BUG_ON(fdt->fd[fd] != NULL);
 	rcu_assign_pointer(fdt->fd[fd], file);
 	spin_unlock(&files->file_lock);
-	put_files_struct(files);
 }
 
 /*
@@ -413,10 +420,10 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
 /*
  * copied from sys_close
  */
-static long task_close_fd(struct task_struct *tsk, unsigned int fd)
+static long task_close_fd(struct binder_proc *proc, unsigned int fd)
 {
 	struct file *filp;
-	struct files_struct *files = get_files_struct(tsk);
+	struct files_struct *files = proc->files;
 	struct fdtable *fdt;
 	int retval;
 
@@ -443,12 +450,10 @@ static long task_close_fd(struct task_struct *tsk, unsigned int fd)
 		     retval == -ERESTART_RESTARTBLOCK))
 		retval = -EINTR;
 
-	put_files_struct(files);
 	return retval;
 
 out_unlock:
 	spin_unlock(&files->file_lock);
-	put_files_struct(files);
 	return -EBADF;
 }
 
@@ -618,7 +623,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
 			       proc->pid, page_addr);
 			goto err_map_kernel_failed;
 		}
-		user_page_addr = (size_t)page_addr + proc->user_buffer_offset;
+		user_page_addr =
+			(uintptr_t)page_addr + proc->user_buffer_offset;
 		ret = vm_insert_page(vma, user_page_addr, page[0]);
 		if (ret) {
 			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
@@ -639,7 +645,7 @@ free_range:
 	     page_addr -= PAGE_SIZE) {
 		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
 		if (vma)
-			zap_page_range(vma, (size_t)page_addr +
+			zap_page_range(vma, (uintptr_t)page_addr +
 				proc->user_buffer_offset, PAGE_SIZE, NULL);
 err_vm_insert_page_failed:
 		unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE);
@@ -720,18 +726,19 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 		       "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
 
 	has_page_addr =
-		(void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK);
+		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
 	if (n == NULL) {
 		if (size + sizeof(struct binder_buffer) + 4 >= buffer_size)
 			buffer_size = size; /* no room for other buffers */
 		else
 			buffer_size = size + sizeof(struct binder_buffer);
 	}
-	end_page_addr = (void *)PAGE_ALIGN((size_t)buffer->data + buffer_size);
+	end_page_addr =
+		(void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size);
 	if (end_page_addr > has_page_addr)
 		end_page_addr = has_page_addr;
 	if (binder_update_page_range(proc, 1,
-	    (void *)PAGE_ALIGN((size_t)buffer->data), end_page_addr, NULL))
+	    (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL))
 		return NULL;
 
 	rb_erase(best_fit, &proc->free_buffers);
@@ -762,12 +769,12 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 
 static void *buffer_start_page(struct binder_buffer *buffer)
 {
-	return (void *)((size_t)buffer & PAGE_MASK);
+	return (void *)((uintptr_t)buffer & PAGE_MASK);
 }
 
 static void *buffer_end_page(struct binder_buffer *buffer)
 {
-	return (void *)(((size_t)(buffer + 1) - 1) & PAGE_MASK);
+	return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK);
 }
 
 static void binder_delete_free_buffer(
@@ -845,8 +852,8 @@ static void binder_free_buf(
 	}
 
 	binder_update_page_range(proc, 0,
-		(void *)PAGE_ALIGN((size_t)buffer->data),
-		(void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK),
+		(void *)PAGE_ALIGN((uintptr_t)buffer->data),
+		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK),
 		NULL);
 	rb_erase(&buffer->rb_node, &proc->allocated_buffers);
 	buffer->free = 1;
@@ -1345,6 +1352,17 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread,
 		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
 			struct binder_transaction *tmp;
 			tmp = thread->transaction_stack;
+			if (tmp->to_thread != thread) {
+				binder_user_error("binder: %d:%d got new "
+					"transaction with bad transaction stack"
+					", transaction %d has target %d:%d\n",
+					proc->pid, thread->pid, tmp->debug_id,
+					tmp->to_proc ? tmp->to_proc->pid : 0,
+					tmp->to_thread ?
+					tmp->to_thread->pid : 0);
+				return_error = BR_FAILED_REPLY;
+				goto err_bad_call_stack;
+			}
 			while (tmp) {
 				if (tmp->from && tmp->from->proc == target_proc)
 					target_thread = tmp->from;
@@ -1434,10 +1452,19 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread,
 		return_error = BR_FAILED_REPLY;
 		goto err_copy_data_failed;
 	}
+	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
+		binder_user_error("binder: %d:%d got transaction with "
+			"invalid offsets size, %zd\n",
+			proc->pid, thread->pid, tr->offsets_size);
+		return_error = BR_FAILED_REPLY;
+		goto err_bad_offset;
+	}
 	off_end = (void *)offp + tr->offsets_size;
 	for (; offp < off_end; offp++) {
 		struct flat_binder_object *fp;
-		if (*offp > t->buffer->data_size - sizeof(*fp)) {
+		if (*offp > t->buffer->data_size - sizeof(*fp) ||
+		    t->buffer->data_size < sizeof(*fp) ||
+		    !IS_ALIGNED(*offp, sizeof(void *))) {
 			binder_user_error("binder: %d:%d got transaction with "
 				"invalid offset, %zd\n",
 				proc->pid, thread->pid, *offp);
@@ -1544,13 +1571,13 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread,
 				return_error = BR_FAILED_REPLY;
 				goto err_fget_failed;
 			}
-			target_fd = task_get_unused_fd_flags(target_proc->tsk, O_CLOEXEC);
+			target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
 			if (target_fd < 0) {
 				fput(file);
 				return_error = BR_FAILED_REPLY;
 				goto err_get_unused_fd_failed;
 			}
-			task_fd_install(target_proc->tsk, target_fd, file);
+			task_fd_install(target_proc, target_fd, file);
 			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
 				printk(KERN_INFO "        fd %ld -> %d\n", fp->handle, target_fd);
 			/* TODO: fput? */
@@ -1655,7 +1682,9 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer
 		off_end = (void *)offp + buffer->offsets_size;
 	for (; offp < off_end; offp++) {
 		struct flat_binder_object *fp;
-		if (*offp > buffer->data_size - sizeof(*fp)) {
+		if (*offp > buffer->data_size - sizeof(*fp) ||
+		    buffer->data_size < sizeof(*fp) ||
+		    !IS_ALIGNED(*offp, sizeof(void *))) {
 			printk(KERN_ERR "binder: transaction release %d bad"
 					"offset %zd, size %zd\n", debug_id, *offp, buffer->data_size);
 			continue;
@@ -1691,7 +1720,7 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer
 			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
 				printk(KERN_INFO "        fd %ld\n", fp->handle);
 			if (failed_at)
-				task_close_fd(proc->tsk, fp->handle);
+				task_close_fd(proc, fp->handle);
 			break;
 
 		default:
@@ -2340,7 +2369,7 @@ retry:
 
 		tr.data_size = t->buffer->data_size;
 		tr.offsets_size = t->buffer->offsets_size;
-		tr.data.ptr.buffer = (void *)((void *)t->buffer->data + proc->user_buffer_offset);
+		tr.data.ptr.buffer = (void *)t->buffer->data + proc->user_buffer_offset;
 		tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *));
 
 		if (put_user(cmd, (uint32_t __user *)ptr))
@@ -2656,6 +2685,7 @@ static void binder_vma_open(struct vm_area_struct *vma)
 			(unsigned long)pgprot_val(vma->vm_page_prot));
 	dump_stack();
 }
+
 static void binder_vma_close(struct vm_area_struct *vma)
 {
 	struct binder_proc *proc = vma->vm_private_data;
@@ -2666,6 +2696,7 @@ static void binder_vma_close(struct vm_area_struct *vma)
 			(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
 			(unsigned long)pgprot_val(vma->vm_page_prot));
 	proc->vma = NULL;
+	binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
 }
 
 static struct vm_operations_struct binder_vm_ops = {
@@ -2698,6 +2729,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
 	}
 	vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
 
+	if (proc->buffer) {
+		ret = -EBUSY;
+		failure_string = "already mapped";
+		goto err_already_mapped;
+	}
+
 	area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);
 	if (area == NULL) {
 		ret = -ENOMEM;
@@ -2705,7 +2742,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
 		goto err_get_vm_area_failed;
 	}
 	proc->buffer = area->addr;
-	proc->user_buffer_offset = vma->vm_start - (size_t)proc->buffer;
+	proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
 
 #ifdef CONFIG_CPU_CACHE_VIPT
 	if (cache_is_vipt_aliasing()) {
@@ -2738,6 +2775,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
 	binder_insert_free_buffer(proc, buffer);
 	proc->free_async_space = proc->buffer_size / 2;
 	barrier();
+	proc->files = get_files_struct(current);
 	proc->vma = vma;
 
 	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
@@ -2745,10 +2783,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
 
 err_alloc_small_buf_failed:
 	kfree(proc->pages);
+	proc->pages = NULL;
 err_alloc_pages_failed:
 	vfree(proc->buffer);
+	proc->buffer = NULL;
 err_get_vm_area_failed:
-	mutex_unlock(&binder_lock);
+err_already_mapped:
 err_bad_arg:
 	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
 	return ret;
@@ -2780,6 +2820,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
 	if (binder_proc_dir_entry_proc) {
 		char strbuf[11];
 		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
+		remove_proc_entry(strbuf, binder_proc_dir_entry_proc);
 		create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc);
 	}
 
@@ -2788,11 +2829,17 @@ static int binder_open(struct inode *nodp, struct file *filp)
 
 static int binder_flush(struct file *filp, fl_owner_t id)
 {
-	struct rb_node *n;
 	struct binder_proc *proc = filp->private_data;
-	int wake_count = 0;
 
-	mutex_lock(&binder_lock);
+	binder_defer_work(proc, BINDER_DEFERRED_FLUSH);
+
+	return 0;
+}
+
+static void binder_deferred_flush(struct binder_proc *proc)
+{
+	struct rb_node *n;
+	int wake_count = 0;
 	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
 		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
 		thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
@@ -2802,28 +2849,35 @@ static int binder_flush(struct file *filp, fl_owner_t id)
 		}
 	}
 	wake_up_interruptible_all(&proc->wait);
-	mutex_unlock(&binder_lock);
 
 	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
 		printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count);
-
-	return 0;
 }
 
 static int binder_release(struct inode *nodp, struct file *filp)
 {
-	struct hlist_node *pos;
-	struct binder_transaction *t;
-	struct rb_node *n;
 	struct binder_proc *proc = filp->private_data;
-	int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count;
-
 	if (binder_proc_dir_entry_proc) {
 		char strbuf[11];
 		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
 		remove_proc_entry(strbuf, binder_proc_dir_entry_proc);
 	}
-	mutex_lock(&binder_lock);
+
+	binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
+
+	return 0;
+}
+
+static void binder_deferred_release(struct binder_proc *proc)
+{
+	struct hlist_node *pos;
+	struct binder_transaction *t;
+	struct rb_node *n;
+	int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count;
+
+	BUG_ON(proc->vma);
+	BUG_ON(proc->files);
+
 	hlist_del(&proc->proc_node);
 	if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) {
 		if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
@@ -2897,7 +2951,6 @@ static int binder_release(struct inode *nodp, struct file *filp)
 	}
 
 	binder_stats.obj_deleted[BINDER_STAT_PROC]++;
-	mutex_unlock(&binder_lock);
 
 	page_count = 0;
 	if (proc->pages) {
@@ -2921,7 +2974,57 @@ static int binder_release(struct inode *nodp, struct file *filp)
 		       proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count);
 
 	kfree(proc);
-	return 0;
+}
+
+static void binder_deferred_func(struct work_struct *work)
+{
+	struct binder_proc *proc;
+	struct files_struct *files;
+
+	int defer;
+	do {
+		mutex_lock(&binder_lock);
+		mutex_lock(&binder_deferred_lock);
+		if (!hlist_empty(&binder_deferred_list)) {
+			proc = hlist_entry(binder_deferred_list.first,
+					struct binder_proc, deferred_work_node);
+			hlist_del_init(&proc->deferred_work_node);
+			defer = proc->deferred_work;
+			proc->deferred_work = 0;
+		} else {
+			proc = NULL;
+			defer = 0;
+		}
+		mutex_unlock(&binder_deferred_lock);
+
+		files = NULL;
+		if (defer & BINDER_DEFERRED_PUT_FILES)
+			if ((files = proc->files))
+				proc->files = NULL;
+
+		if (defer & BINDER_DEFERRED_FLUSH)
+			binder_deferred_flush(proc);
+
+		if (defer & BINDER_DEFERRED_RELEASE)
+			binder_deferred_release(proc); /* frees proc */
+
+		mutex_unlock(&binder_lock);
+		if (files)
+			put_files_struct(files);
+	} while (proc);
+}
+static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
+
+static void binder_defer_work(struct binder_proc *proc, int defer)
+{
+	mutex_lock(&binder_deferred_lock);
+	proc->deferred_work |= defer;
+	if (hlist_unhashed(&proc->deferred_work_node)) {
+		hlist_add_head(&proc->deferred_work_node,
+				&binder_deferred_list);
+		schedule_work(&binder_deferred_work);
+	}
+	mutex_unlock(&binder_deferred_lock);
 }
 
 static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t)
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index 6f6e36a3bd9f..c8af9a868d62 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -5259,6 +5259,18 @@ static int at76_alloc_urbs(struct at76_priv *priv,
 	return 0;
 }
 
+static const struct net_device_ops at76_netdev_ops = {
+	.ndo_open		= at76_open,
+	.ndo_stop		= at76_stop,
+	.ndo_get_stats		= at76_get_stats,
+	.ndo_start_xmit		= at76_tx,
+	.ndo_tx_timeout		= at76_tx_timeout,
+	.ndo_set_multicast_list	= at76_set_multicast,
+	.ndo_set_mac_address	= at76_set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /* Register network device and initialize the hardware */
 static int at76_init_new_device(struct at76_priv *priv,
 				struct usb_interface *interface)
@@ -5303,21 +5315,15 @@ static int at76_init_new_device(struct at76_priv *priv,
 	priv->scan_mode = SCAN_TYPE_ACTIVE;
 
 	netdev->flags &= ~IFF_MULTICAST;	/* not yet or never */
-	netdev->open = at76_open;
-	netdev->stop = at76_stop;
-	netdev->get_stats = at76_get_stats;
+	netdev->netdev_ops = &at76_netdev_ops;
 	netdev->ethtool_ops = &at76_ethtool_ops;
 
 	/* Add pointers to enable iwspy support. */
 	priv->wireless_data.spy_data = &priv->spy_data;
 	netdev->wireless_data = &priv->wireless_data;
 
-	netdev->hard_start_xmit = at76_tx;
-	netdev->tx_timeout = at76_tx_timeout;
 	netdev->watchdog_timeo = 2 * HZ;
 	netdev->wireless_handlers = &at76_handler_def;
-	netdev->set_multicast_list = at76_set_multicast;
-	netdev->set_mac_address = at76_set_mac_address;
 	dev_alloc_name(netdev, "wlan%d");
 
 	ret = register_netdev(priv->netdev);
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
index 0348072b3ab5..75ebe338c6f2 100644
--- a/drivers/staging/b3dfg/b3dfg.c
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -1000,7 +1000,7 @@ static int __devinit b3dfg_probe(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-	r = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (r) {
 		dev_err(&pdev->dev, "no usable DMA configuration\n");
 		goto err_free_res;
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
index 21206c4d22ff..077724a556cc 100644
--- a/drivers/staging/epl/VirtualEthernetLinux.c
+++ b/drivers/staging/epl/VirtualEthernetLinux.c
@@ -284,6 +284,17 @@ static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p)
 	return Ret;
 }
 
+static const struct net_device_ops epl_netdev_ops = {
+	.ndo_open		= VEthOpen,
+	.ndo_stop		= VEthClose,
+	.ndo_get_stats		= VEthGetStats,
+	.ndo_start_xmit		= VEthXmit,
+	.ndo_tx_timeout		= VEthTimeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
 {
 	tEplKernel Ret = kEplSuccessful;
@@ -299,11 +310,7 @@ tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
 		goto Exit;
 	}
 
-	pVEthNetDevice_g->open = VEthOpen;
-	pVEthNetDevice_g->stop = VEthClose;
-	pVEthNetDevice_g->get_stats = VEthGetStats;
-	pVEthNetDevice_g->hard_start_xmit = VEthXmit;
-	pVEthNetDevice_g->tx_timeout = VEthTimeout;
+	pVEthNetDevice_g->netdev_ops = &epl_netdev_ops;
 	pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT;
 	pVEthNetDevice_g->destructor = free_netdev;
 
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index de65972ff362..951c73d5db20 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -112,6 +112,19 @@ void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
 void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
 void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 
+static const struct net_device_ops et131x_netdev_ops = {
+	.ndo_open		= et131x_open,
+	.ndo_stop		= et131x_close,
+	.ndo_start_xmit		= et131x_tx,
+	.ndo_set_multicast_list	= et131x_multicast,
+	.ndo_tx_timeout		= et131x_tx_timeout,
+	.ndo_change_mtu		= et131x_change_mtu,
+	.ndo_set_mac_address	= et131x_set_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_get_stats		= et131x_stats,
+	.ndo_do_ioctl		= et131x_ioctl,
+};
+
 /**
  * et131x_device_alloc
  *
@@ -142,16 +155,8 @@ struct net_device *et131x_device_alloc(void)
 	 */
 	//netdev->init               = &et131x_init;
 	//netdev->set_config = &et131x_config;
-	netdev->get_stats = &et131x_stats;
-	netdev->open = &et131x_open;
-	netdev->stop = &et131x_close;
-	netdev->do_ioctl = &et131x_ioctl;
-	netdev->set_multicast_list = &et131x_multicast;
-	netdev->hard_start_xmit = &et131x_tx;
-	netdev->tx_timeout = &et131x_tx_timeout;
 	netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
-	netdev->change_mtu = &et131x_change_mtu;
-	netdev->set_mac_address = &et131x_set_mac_addr;
+	netdev->netdev_ops = &et131x_netdev_ops;
 
 	//netdev->ethtool_ops        = &et131x_ethtool_ops;
 
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 58bfc8d81b3b..77b1e769ac92 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -191,8 +191,10 @@ int go7007_reset_encoder(struct go7007 *go)
 /*
  * Attempt to instantiate an I2C client by ID, probably loading a module.
  */
-static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
+static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
+			   int id, int addr)
 {
+	struct i2c_board_info info;
 	char *modname;
 
 	switch (id) {
@@ -226,7 +228,11 @@ static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
 	}
 	if (modname != NULL)
 		request_module(modname);
-	if (wis_i2c_probe_device(adapter, id, addr) == 1)
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = addr;
+	strlcpy(info.type, type, I2C_NAME_SIZE);
+	if (!i2c_new_device(adapter, &info))
 		return 0;
 	if (modname != NULL)
 		printk(KERN_INFO
@@ -266,23 +272,9 @@ int go7007_register_encoder(struct go7007 *go)
 	if (go->i2c_adapter_online) {
 		for (i = 0; i < go->board_info->num_i2c_devs; ++i)
 			init_i2c_module(&go->i2c_adapter,
+					go->board_info->i2c_devs[i].type,
 					go->board_info->i2c_devs[i].id,
 					go->board_info->i2c_devs[i].addr);
-#ifdef TUNER_SET_TYPE_ADDR
-		if (go->tuner_type >= 0) {
-			struct tuner_setup tun_setup = {
-				.mode_mask	= T_ANALOG_TV,
-				.addr		= ADDR_UNSET,
-				.type		= go->tuner_type
-			};
-			i2c_clients_command(&go->i2c_adapter,
-				TUNER_SET_TYPE_ADDR, &tun_setup);
-		}
-#else
-		if (go->tuner_type >= 0)
-			i2c_clients_command(&go->i2c_adapter,
-				TUNER_SET_TYPE, &go->tuner_type);
-#endif
 		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
 			i2c_clients_command(&go->i2c_adapter,
 				DECODER_SET_CHANNEL, &go->channel_number);
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
index cd55b76eabc7..c82867fdd28d 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -31,87 +31,6 @@
 #include "go7007-priv.h"
 #include "wis-i2c.h"
 
-/************** Registration interface for I2C client drivers **************/
-
-/* Since there's no way to auto-probe the I2C devices connected to the I2C
- * bus on the go7007, we have this silly little registration system that
- * client drivers can use to register their I2C driver ID and their
- * detect_client function (the one that's normally passed to i2c_probe).
- *
- * When a new go7007 device is connected, we can look up in a board info
- * table by the USB or PCI vendor/product/revision ID to determine
- * which I2C client module to load.  The client driver module will register
- * itself here, and then we can call the registered detect_client function
- * to force-load a new client at the address listed in the board info table.
- *
- * Really the I2C subsystem should have a way to force-load I2C client
- * drivers when we have a priori knowledge of what's on the bus, especially
- * since the existing I2C auto-probe mechanism is so hokey, but we'll use
- * our own mechanism for the time being. */
-
-struct wis_i2c_client_driver {
-	unsigned int id;
-	found_proc found_proc;
-	struct list_head list;
-};
-
-static LIST_HEAD(i2c_client_drivers);
-static DECLARE_MUTEX(i2c_client_driver_list_lock);
-
-/* Client drivers register here by their I2C driver ID */
-int wis_i2c_add_driver(unsigned int id, found_proc found_proc)
-{
-	struct wis_i2c_client_driver *driver;
-
-	driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL);
-	if (driver == NULL)
-		return -ENOMEM;
-	driver->id = id;
-	driver->found_proc = found_proc;
-
-	down(&i2c_client_driver_list_lock);
-	list_add_tail(&driver->list, &i2c_client_drivers);
-	up(&i2c_client_driver_list_lock);
-
-	return 0;
-}
-EXPORT_SYMBOL(wis_i2c_add_driver);
-
-void wis_i2c_del_driver(found_proc found_proc)
-{
-	struct wis_i2c_client_driver *driver, *next;
-
-	down(&i2c_client_driver_list_lock);
-	list_for_each_entry_safe(driver, next, &i2c_client_drivers, list)
-		if (driver->found_proc == found_proc) {
-			list_del(&driver->list);
-			kfree(driver);
-		}
-	up(&i2c_client_driver_list_lock);
-}
-EXPORT_SYMBOL(wis_i2c_del_driver);
-
-/* The main go7007 driver calls this to instantiate a client by driver
- * ID and bus address, which are both stored in the board info table */
-int wis_i2c_probe_device(struct i2c_adapter *adapter,
-				unsigned int id, int addr)
-{
-	struct wis_i2c_client_driver *driver;
-	int found = 0;
-
-	if (addr < 0 || addr > 0x7f)
-		return -1;
-	down(&i2c_client_driver_list_lock);
-	list_for_each_entry(driver, &i2c_client_drivers, list)
-		if (driver->id == id) {
-			if (driver->found_proc(adapter, addr, 0) == 0)
-				found = 1;
-			break;
-		}
-	up(&i2c_client_driver_list_lock);
-	return found;
-}
-
 /********************* Driver for on-board I2C adapter *********************/
 
 /* #define GO7007_I2C_DEBUG */
@@ -287,9 +206,7 @@ static struct i2c_algorithm go7007_algo = {
 
 static struct i2c_adapter go7007_adap_templ = {
 	.owner			= THIS_MODULE,
-	.class			= I2C_CLASS_TV_ANALOG,
 	.name			= "WIS GO7007SB",
-	.id			= I2C_ALGO_GO7007,
 	.algo			= &go7007_algo,
 };
 
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index 372f1f1c09b2..178d18119faa 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -87,6 +87,7 @@ struct go7007_board_info {
 	int audio_main_div;
 	int num_i2c_devs;
 	struct {
+		const char *type;
 		int id;
 		int addr;
 	} i2c_devs[4];
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index 83eec920c7d3..aa4a9e0b9954 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -91,6 +91,7 @@ static struct go7007_usb_board board_matrix_ii = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_saa7115",
 				.id	= I2C_DRIVERID_WIS_SAA7115,
 				.addr	= 0x20,
 			},
@@ -127,6 +128,7 @@ static struct go7007_usb_board board_matrix_reload = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_saa7113",
 				.id	= I2C_DRIVERID_WIS_SAA7113,
 				.addr	= 0x25,
 			},
@@ -164,6 +166,7 @@ static struct go7007_usb_board board_star_trek = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_saa7115",
 				.id	= I2C_DRIVERID_WIS_SAA7115,
 				.addr	= 0x20,
 			},
@@ -209,14 +212,17 @@ static struct go7007_usb_board board_px_tv402u = {
 		.num_i2c_devs	 = 3,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_saa7115",
 				.id	= I2C_DRIVERID_WIS_SAA7115,
 				.addr	= 0x20,
 			},
 			{
+				.type	= "wis_uda1342",
 				.id	= I2C_DRIVERID_WIS_UDA1342,
 				.addr	= 0x1a,
 			},
 			{
+				.type	= "wis_sony_tuner",
 				.id	= I2C_DRIVERID_WIS_SONY_TUNER,
 				.addr	= 0x60,
 			},
@@ -264,6 +270,7 @@ static struct go7007_usb_board board_xmen = {
 		.num_i2c_devs	  = 1,
 		.i2c_devs	  = {
 			{
+				.type	= "wis_ov7640",
 				.id	= I2C_DRIVERID_WIS_OV7640,
 				.addr	= 0x21,
 			},
@@ -296,6 +303,7 @@ static struct go7007_usb_board board_matrix_revolution = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_tw9903",
 				.id	= I2C_DRIVERID_WIS_TW9903,
 				.addr	= 0x44,
 			},
@@ -385,6 +393,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "wis_twTW2804",
 				.id	= I2C_DRIVERID_WIS_TW2804,
 				.addr	= 0x00, /* yes, really */
 			},
@@ -415,8 +424,9 @@ static struct go7007_usb_board board_sensoray_2250 = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
+				.type	= "s2250_board",
 				.id	= I2C_DRIVERID_S2250,
-				.addr	= 0x34,
+				.addr	= 0x43,
 			},
 		},
 		.num_inputs	 = 2,
@@ -943,9 +953,7 @@ static struct i2c_algorithm go7007_usb_algo = {
 
 static struct i2c_adapter go7007_usb_adap_templ = {
 	.owner			= THIS_MODULE,
-	.class			= I2C_CLASS_TV_ANALOG,
 	.name			= "WIS GO7007SB EZ-USB",
-	.id			= I2C_ALGO_GO7007_USB,
 	.algo			= &go7007_usb_algo,
 };
 
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index d333ea2cd774..1706fbf06847 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -28,7 +28,6 @@ extern int s2250loader_init(void);
 extern void s2250loader_cleanup(void);
 
 #define TLV320_ADDRESS      0x34
-#define S2250_VIDDEC        0x86
 #define VPX322_ADDR_ANALOGCONTROL1	0x02
 #define VPX322_ADDR_BRIGHTNESS0		0x0127
 #define VPX322_ADDR_BRIGHTNESS1		0x0131
@@ -123,6 +122,7 @@ struct s2250 {
 	int hue;
 	int reg12b_val;
 	int audio_input;
+	struct i2c_client *audio;
 };
 
 /* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
@@ -452,16 +452,15 @@ static int s2250_command(struct i2c_client *client,
 	{
 		struct v4l2_audio *audio = arg;
 
-		client->addr = TLV320_ADDRESS;
 		switch (audio->index) {
 		case 0:
-			write_reg(client, 0x08, 0x02); /* Line In */
+			write_reg(dec->audio, 0x08, 0x02); /* Line In */
 			break;
 		case 1:
-			write_reg(client, 0x08, 0x04); /* Mic */
+			write_reg(dec->audio, 0x08, 0x04); /* Mic */
 			break;
 		case 2:
-			write_reg(client, 0x08, 0x05); /* Mic Boost */
+			write_reg(dec->audio, 0x08, 0x05); /* Mic Boost */
 			break;
 		default:
 			return -EINVAL;
@@ -477,31 +476,23 @@ static int s2250_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver s2250_driver;
-
-static struct i2c_client s2250_client_templ = {
-	.name		= "Sensoray 2250",
-	.driver		= &s2250_driver,
-};
-
-static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int s2250_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_client *audio;
+	struct i2c_adapter *adapter = client->adapter;
 	struct s2250 *dec;
 	u8 *data;
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct go7007_usb *usb = go->hpi_context;
 
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
+	audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
+	if (audio == NULL)
 		return -ENOMEM;
-	memcpy(client, &s2250_client_templ,
-	       sizeof(s2250_client_templ));
-	client->adapter = adapter;
 
 	dec = kmalloc(sizeof(struct s2250), GFP_KERNEL);
 	if (dec == NULL) {
-		kfree(client);
+		i2c_unregister_device(audio);
 		return -ENOMEM;
 	}
 
@@ -510,7 +501,7 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
 	dec->contrast = 50;
 	dec->saturation = 50;
 	dec->hue = 0;
-	client->addr = TLV320_ADDRESS;
+	dec->audio = audio;
 	i2c_set_clientdata(client, dec);
 
 	printk(KERN_DEBUG
@@ -518,28 +509,25 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
 	       adapter->name);
 
 	/* initialize the audio */
-	client->addr = TLV320_ADDRESS;
-	if (write_regs(client, aud_regs) < 0) {
+	if (write_regs(audio, aud_regs) < 0) {
 		printk(KERN_ERR
 		       "s2250: error initializing audio\n");
-		kfree(client);
+		i2c_unregister_device(audio);
 		kfree(dec);
 		return 0;
 	}
-	client->addr = S2250_VIDDEC;
-	i2c_set_clientdata(client, dec);
 
 	if (write_regs(client, vid_regs) < 0) {
 		printk(KERN_ERR
 		       "s2250: error initializing decoder\n");
-		kfree(client);
+		i2c_unregister_device(audio);
 		kfree(dec);
 		return 0;
 	}
 	if (write_regs_fp(client, vid_regs_fp) < 0) {
 		printk(KERN_ERR
 		       "s2250: error initializing decoder\n");
-		kfree(client);
+		i2c_unregister_device(audio);
 		kfree(dec);
 		return 0;
 	}
@@ -575,32 +563,33 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
 		up(&usb->i2c_lock);
 	}
 
-	i2c_attach_client(client);
 	printk("s2250: initialized successfully\n");
 	return 0;
 }
 
-static int s2250_detach(struct i2c_client *client)
+static int s2250_remove(struct i2c_client *client)
 {
 	struct s2250 *dec = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
-	kfree(client);
+	i2c_set_clientdata(client, NULL);
+	i2c_unregister_device(dec->audio);
 	kfree(dec);
 	return 0;
 }
 
+static struct i2c_device_id s2250_id[] = {
+	{ "s2250_board", 0 },
+	{ }
+};
+
 static struct i2c_driver s2250_driver = {
 	.driver = {
 		.name	= "Sensoray 2250 board driver",
 	},
-	.id		= I2C_DRIVERID_S2250,
-	.detach_client	= s2250_detach,
+	.probe		= s2250_probe,
+	.remove		= s2250_remove,
 	.command	= s2250_command,
+	.id_table	= s2250_id,
 };
 
 static int __init s2250_init(void)
@@ -613,13 +602,13 @@ static int __init s2250_init(void)
 
 	r = i2c_add_driver(&s2250_driver);
 	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(s2250_driver.id, s2250_detect);
+		s2250loader_cleanup();
+
+	return r;
 }
 
 static void __exit s2250_cleanup(void)
 {
-	wis_i2c_del_driver(s2250_detect);
 	i2c_del_driver(&s2250_driver);
 
 	s2250loader_cleanup();
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/go7007/wis-i2c.h
index 431f41dd3966..3c2b9be455df 100644
--- a/drivers/staging/go7007/wis-i2c.h
+++ b/drivers/staging/go7007/wis-i2c.h
@@ -24,21 +24,12 @@
 #define	I2C_DRIVERID_WIS_OV7640		0xf0f5
 #define	I2C_DRIVERID_WIS_TW2804		0xf0f6
 #define	I2C_DRIVERID_S2250		0xf0f7
-#define	I2C_ALGO_GO7007			0xf00000
-#define	I2C_ALGO_GO7007_USB		0xf10000
 
 /* Flag to indicate that the client needs to be accessed with SCCB semantics */
 /* We re-use the I2C_M_TEN value so the flag passes through the masks in the
  * core I2C code.  Major kludge, but the I2C layer ain't exactly flexible. */
 #define	I2C_CLIENT_SCCB			0x10
 
-typedef int (*found_proc) (struct i2c_adapter *, int, int);
-int wis_i2c_add_driver(unsigned int id, found_proc found_proc);
-void wis_i2c_del_driver(found_proc found_proc);
-
-int wis_i2c_probe_device(struct i2c_adapter *adapter,
-				unsigned int id, int addr);
-
 /* Definitions for new video decoder commands */
 
 struct video_decoder_resolution {
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
index 2f9efca04606..04d6d3a498a3 100644
--- a/drivers/staging/go7007/wis-ov7640.c
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -50,76 +50,54 @@ static int write_regs(struct i2c_client *client, u8 *regs)
 	return 0;
 }
 
-static struct i2c_driver wis_ov7640_driver;
-
-static struct i2c_client wis_ov7640_client_templ = {
-	.name		= "OV7640 (WIS)",
-	.driver		= &wis_ov7640_driver,
-};
-
-static int wis_ov7640_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_ov7640_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_ov7640_client_templ,
-			sizeof(wis_ov7640_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
+
 	client->flags = I2C_CLIENT_SCCB;
 
 	printk(KERN_DEBUG
 		"wis-ov7640: initializing OV7640 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
 	if (write_regs(client, initial_registers) < 0) {
 		printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
-		kfree(client);
-		return 0;
+		return -ENODEV;
 	}
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_ov7640_detach(struct i2c_client *client)
+static int wis_ov7640_remove(struct i2c_client *client)
 {
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
-
-	kfree(client);
 	return 0;
 }
 
+static struct i2c_device_id wis_ov7640_id[] = {
+	{ "wis_ov7640", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_ov7640_driver = {
 	.driver = {
 		.name	= "WIS OV7640 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_OV7640,
-	.detach_client	= wis_ov7640_detach,
+	.probe		= wis_ov7640_probe,
+	.remove		= wis_ov7640_remove,
+	.id_table	= wis_ov7640_id,
 };
 
 static int __init wis_ov7640_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_ov7640_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_ov7640_driver.id, wis_ov7640_detect);
+	return i2c_add_driver(&wis_ov7640_driver);
 }
 
 static void __exit wis_ov7640_cleanup(void)
 {
-	wis_i2c_del_driver(wis_ov7640_detect);
 	i2c_del_driver(&wis_ov7640_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
index 11689723945e..9ab893bd204e 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -261,34 +261,19 @@ static int wis_saa7113_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver wis_saa7113_driver;
-
-static struct i2c_client wis_saa7113_client_templ = {
-	.name		= "SAA7113 (WIS)",
-	.driver		= &wis_saa7113_driver,
-};
-
-static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_saa7113_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 	struct wis_saa7113 *dec;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_saa7113_client_templ,
-			sizeof(wis_saa7113_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
-	if (dec == NULL) {
-		kfree(client);
+	if (dec == NULL)
 		return -ENOMEM;
-	}
+
 	dec->norm = V4L2_STD_NTSC;
 	dec->brightness = 128;
 	dec->contrast = 71;
@@ -298,56 +283,49 @@ static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind)
 
 	printk(KERN_DEBUG
 		"wis-saa7113: initializing SAA7113 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
 	if (write_regs(client, initial_registers) < 0) {
 		printk(KERN_ERR
 			"wis-saa7113: error initializing SAA7113\n");
-		kfree(client);
 		kfree(dec);
-		return 0;
+		return -ENODEV;
 	}
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_saa7113_detach(struct i2c_client *client)
+static int wis_saa7113_remove(struct i2c_client *client)
 {
 	struct wis_saa7113 *dec = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
-	kfree(client);
+	i2c_set_clientdata(client, NULL);
 	kfree(dec);
 	return 0;
 }
 
+static struct i2c_device_id wis_saa7113_id[] = {
+	{ "wis_saa7113", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_saa7113_driver = {
 	.driver = {
 		.name	= "WIS SAA7113 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_SAA7113,
-	.detach_client	= wis_saa7113_detach,
+	.probe		= wis_saa7113_probe,
+	.remove		= wis_saa7113_remove,
 	.command	= wis_saa7113_command,
+	.id_table	= wis_saa7113_id,
 };
 
 static int __init wis_saa7113_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_saa7113_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_saa7113_driver.id, wis_saa7113_detect);
+	return i2c_add_driver(&wis_saa7113_driver);
 }
 
 static void __exit wis_saa7113_cleanup(void)
 {
-	wis_i2c_del_driver(wis_saa7113_detect);
 	i2c_del_driver(&wis_saa7113_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
index 59417a7174d7..8687ad2de761 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -394,34 +394,19 @@ static int wis_saa7115_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver wis_saa7115_driver;
-
-static struct i2c_client wis_saa7115_client_templ = {
-	.name		= "SAA7115 (WIS)",
-	.driver		= &wis_saa7115_driver,
-};
-
-static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_saa7115_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 	struct wis_saa7115 *dec;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_saa7115_client_templ,
-			sizeof(wis_saa7115_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
-	if (dec == NULL) {
-		kfree(client);
+	if (dec == NULL)
 		return -ENOMEM;
-	}
+
 	dec->norm = V4L2_STD_NTSC;
 	dec->brightness = 128;
 	dec->contrast = 64;
@@ -431,56 +416,49 @@ static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind)
 
 	printk(KERN_DEBUG
 		"wis-saa7115: initializing SAA7115 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
 	if (write_regs(client, initial_registers) < 0) {
 		printk(KERN_ERR
 			"wis-saa7115: error initializing SAA7115\n");
-		kfree(client);
 		kfree(dec);
-		return 0;
+		return -ENODEV;
 	}
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_saa7115_detach(struct i2c_client *client)
+static int wis_saa7115_remove(struct i2c_client *client)
 {
 	struct wis_saa7115 *dec = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
-	kfree(client);
+	i2c_set_clientdata(client, NULL);
 	kfree(dec);
 	return 0;
 }
 
+static struct i2c_device_id wis_saa7115_id[] = {
+	{ "wis_saa7115", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_saa7115_driver = {
 	.driver = {
 		.name	= "WIS SAA7115 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_SAA7115,
-	.detach_client	= wis_saa7115_detach,
+	.probe		= wis_saa7115_probe,
+	.remove		= wis_saa7115_remove,
 	.command	= wis_saa7115_command,
+	.id_table	= wis_saa7115_id,
 };
 
 static int __init wis_saa7115_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_saa7115_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_saa7115_driver.id, wis_saa7115_detect);
+	return i2c_add_driver(&wis_saa7115_driver);
 }
 
 static void __exit wis_saa7115_cleanup(void)
 {
-	wis_i2c_del_driver(wis_saa7115_detect);
 	i2c_del_driver(&wis_saa7115_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
index 58fddb122372..c965c601ac90 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -386,6 +386,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 	struct wis_sony_tuner *t = i2c_get_clientdata(client);
 
 	switch (cmd) {
+#if 0
 #ifdef TUNER_SET_TYPE_ADDR
 	case TUNER_SET_TYPE_ADDR:
 	{
@@ -463,6 +464,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 				t->type, sony_tuners[t->type - 200].name);
 		break;
 	}
+#endif
 	case VIDIOC_G_FREQUENCY:
 	{
 		struct v4l2_frequency *f = arg;
@@ -651,35 +653,19 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 	return 0;
 }
 
-static struct i2c_driver wis_sony_tuner_driver;
-
-static struct i2c_client wis_sony_tuner_client_templ = {
-	.name		= "Sony TV Tuner (WIS)",
-	.driver		= &wis_sony_tuner_driver,
-};
-
-static int wis_sony_tuner_detect(struct i2c_adapter *adapter,
-					int addr, int kind)
+static int wis_sony_tuner_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 	struct wis_sony_tuner *t;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_sony_tuner_client_templ,
-			sizeof(wis_sony_tuner_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
-	if (t == NULL) {
-		kfree(client);
+	if (t == NULL)
 		return -ENOMEM;
-	}
+
 	t->type = -1;
 	t->freq = 0;
 	t->mpxmode = 0;
@@ -688,50 +674,42 @@ static int wis_sony_tuner_detect(struct i2c_adapter *adapter,
 
 	printk(KERN_DEBUG
 		"wis-sony-tuner: initializing tuner at address %d on %s\n",
-		addr, adapter->name);
-
-	i2c_attach_client(client);
+		client->addr, adapter->name);
 
 	return 0;
 }
 
-static int wis_sony_tuner_detach(struct i2c_client *client)
+static int wis_sony_tuner_remove(struct i2c_client *client)
 {
 	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
+	i2c_set_clientdata(client, NULL);
 	kfree(t);
-	kfree(client);
 	return 0;
 }
 
+static struct i2c_device_id wis_sony_tuner_id[] = {
+	{ "wis_sony_tuner", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_sony_tuner_driver = {
 	.driver = {
 		.name	= "WIS Sony TV Tuner I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_SONY_TUNER,
-	.detach_client	= wis_sony_tuner_detach,
+	.probe		= wis_sony_tuner_probe,
+	.remove		= wis_sony_tuner_remove,
 	.command	= tuner_command,
+	.id_table	= wis_sony_tuner_id,
 };
 
 static int __init wis_sony_tuner_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_sony_tuner_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_sony_tuner_driver.id,
-					wis_sony_tuner_detect);
+	return i2c_add_driver(&wis_sony_tuner_driver);
 }
 
 static void __exit wis_sony_tuner_cleanup(void)
 {
-	wis_i2c_del_driver(wis_sony_tuner_detect);
 	i2c_del_driver(&wis_sony_tuner_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
index 57b8f2b1caa3..e15794a2a0ae 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -291,34 +291,19 @@ static int wis_tw2804_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver wis_tw2804_driver;
-
-static struct i2c_client wis_tw2804_client_templ = {
-	.name		= "TW2804 (WIS)",
-	.driver		= &wis_tw2804_driver,
-};
-
-static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_tw2804_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 	struct wis_tw2804 *dec;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_tw2804_client_templ,
-			sizeof(wis_tw2804_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
-	if (dec == NULL) {
-		kfree(client);
+	if (dec == NULL)
 		return -ENOMEM;
-	}
+
 	dec->channel = -1;
 	dec->norm = V4L2_STD_NTSC;
 	dec->brightness = 128;
@@ -328,48 +313,42 @@ static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind)
 	i2c_set_clientdata(client, dec);
 
 	printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_tw2804_detach(struct i2c_client *client)
+static int wis_tw2804_remove(struct i2c_client *client)
 {
 	struct wis_tw2804 *dec = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
-	kfree(client);
+	i2c_set_clientdata(client, NULL);
 	kfree(dec);
 	return 0;
 }
 
+static struct i2c_device_id wis_tw2804_id[] = {
+	{ "wis_tw2804", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_tw2804_driver = {
 	.driver = {
 		.name	= "WIS TW2804 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_TW2804,
-	.detach_client	= wis_tw2804_detach,
+	.probe		= wis_tw2804_probe,
+	.remove		= wis_tw2804_remove,
 	.command	= wis_tw2804_command,
+	.id_table	= wis_tw2804_id,
 };
 
 static int __init wis_tw2804_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_tw2804_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_tw2804_driver.id, wis_tw2804_detect);
+	return i2c_add_driver(&wis_tw2804_driver);
 }
 
 static void __exit wis_tw2804_cleanup(void)
 {
-	wis_i2c_del_driver(wis_tw2804_detect);
 	i2c_del_driver(&wis_tw2804_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 40627b282cb4..6c3427bb6f4c 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -267,34 +267,19 @@ static int wis_tw9903_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver wis_tw9903_driver;
-
-static struct i2c_client wis_tw9903_client_templ = {
-	.name		= "TW9903 (WIS)",
-	.driver		= &wis_tw9903_driver,
-};
-
-static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_tw9903_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 	struct wis_tw9903 *dec;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_tw9903_client_templ,
-			sizeof(wis_tw9903_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
-	if (dec == NULL) {
-		kfree(client);
+	if (dec == NULL)
 		return -ENOMEM;
-	}
+
 	dec->norm = V4L2_STD_NTSC;
 	dec->brightness = 0;
 	dec->contrast = 0x60;
@@ -303,55 +288,48 @@ static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind)
 
 	printk(KERN_DEBUG
 		"wis-tw9903: initializing TW9903 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
 	if (write_regs(client, initial_registers) < 0) {
 		printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
-		kfree(client);
 		kfree(dec);
-		return 0;
+		return -ENODEV;
 	}
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_tw9903_detach(struct i2c_client *client)
+static int wis_tw9903_remove(struct i2c_client *client)
 {
 	struct wis_tw9903 *dec = i2c_get_clientdata(client);
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
 
-	kfree(client);
+	i2c_set_clientdata(client, NULL);
 	kfree(dec);
 	return 0;
 }
 
+static struct i2c_device_id wis_tw9903_id[] = {
+	{ "wis_tw9903", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_tw9903_driver = {
 	.driver = {
 		.name	= "WIS TW9903 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_TW9903,
-	.detach_client	= wis_tw9903_detach,
+	.probe		= wis_tw9903_probe,
+	.remove		= wis_tw9903_remove,
 	.command	= wis_tw9903_command,
+	.id_table	= wis_tw9903_id,
 };
 
 static int __init wis_tw9903_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_tw9903_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_tw9903_driver.id, wis_tw9903_detect);
+	return i2c_add_driver(&wis_tw9903_driver);
 }
 
 static void __exit wis_tw9903_cleanup(void)
 {
-	wis_i2c_del_driver(wis_tw9903_detect);
 	i2c_del_driver(&wis_tw9903_driver);
 }
 
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
index 555645c0cc1a..739c7ae8913f 100644
--- a/drivers/staging/go7007/wis-uda1342.c
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -59,73 +59,51 @@ static int wis_uda1342_command(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver wis_uda1342_driver;
-
-static struct i2c_client wis_uda1342_client_templ = {
-	.name		= "UDA1342 (WIS)",
-	.driver		= &wis_uda1342_driver,
-};
-
-static int wis_uda1342_detect(struct i2c_adapter *adapter, int addr, int kind)
+static int wis_uda1342_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
+	struct i2c_adapter *adapter = client->adapter;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
-		return 0;
-
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &wis_uda1342_client_templ,
-			sizeof(wis_uda1342_client_templ));
-	client->adapter = adapter;
-	client->addr = addr;
+		return -ENODEV;
 
 	printk(KERN_DEBUG
 		"wis-uda1342: initializing UDA1342 at address %d on %s\n",
-		addr, adapter->name);
+		client->addr, adapter->name);
 
 	write_reg(client, 0x00, 0x8000); /* reset registers */
 	write_reg(client, 0x00, 0x1241); /* select input 1 */
 
-	i2c_attach_client(client);
 	return 0;
 }
 
-static int wis_uda1342_detach(struct i2c_client *client)
+static int wis_uda1342_remove(struct i2c_client *client)
 {
-	int r;
-
-	r = i2c_detach_client(client);
-	if (r < 0)
-		return r;
-
-	kfree(client);
 	return 0;
 }
 
+static struct i2c_device_id wis_uda1342_id[] = {
+	{ "wis_uda1342", 0 },
+	{ }
+};
+
 static struct i2c_driver wis_uda1342_driver = {
 	.driver = {
 		.name	= "WIS UDA1342 I2C driver",
 	},
-	.id		= I2C_DRIVERID_WIS_UDA1342,
-	.detach_client	= wis_uda1342_detach,
+	.probe		= wis_uda1342_probe,
+	.remove		= wis_uda1342_remove,
 	.command	= wis_uda1342_command,
+	.id_table	= wis_uda1342_id,
 };
 
 static int __init wis_uda1342_init(void)
 {
-	int r;
-
-	r = i2c_add_driver(&wis_uda1342_driver);
-	if (r < 0)
-		return r;
-	return wis_i2c_add_driver(wis_uda1342_driver.id, wis_uda1342_detect);
+	return i2c_add_driver(&wis_uda1342_driver);
 }
 
 static void __exit wis_uda1342_cleanup(void)
 {
-	wis_i2c_del_driver(wis_uda1342_detect);
 	i2c_del_driver(&wis_uda1342_driver);
 }
 
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
index 3aa946899ced..e2ac8d60f8c2 100644
--- a/drivers/staging/line6/audio.c
+++ b/drivers/staging/line6/audio.c
@@ -27,11 +27,12 @@ int line6_init_audio(struct usb_line6 *line6)
 {
 	static int dev;
 	struct snd_card *card;
+	int err;
 
-	card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0);
-
-	if (card == NULL)
-		return -ENOMEM;
+	err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0,
+			      &card);
+	if (err < 0)
+		return err;
 
 	line6->card = card;
 
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index 565a839589f5..540cbbb826f9 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -822,6 +822,21 @@ int zfLnxVapXmitFrame(struct sk_buff *skb, struct net_device *dev)
     return 0;
 }
 
+static const struct net_device_ops vap_netdev_ops = {
+	.ndo_open		= zfLnxVapOpen,
+	.ndo_stop		= zfLnxVapClose,
+	.ndo_start_xmit		= zfLnxVapXmitFrame,
+	.ndo_get_stats		= usbdrv_get_stats,
+	.ndo_change_mtu		= usbdrv_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+#ifdef ZM_HOSTAPD_SUPPORT
+	.ndo_do_ioctl		= usbdrv_ioctl,
+#else
+	.ndo_do_ioctl		= NULL,
+#endif
+};
+
 int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId)
 {
     /* Allocate net device structure */
@@ -846,16 +861,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId)
     vap[vapId].dev->ml_priv = parentDev->ml_priv;
 
     //dev->hard_start_xmit = &zd1212_wds_xmit_frame;
-    vap[vapId].dev->hard_start_xmit = &zfLnxVapXmitFrame;
-    vap[vapId].dev->open = &zfLnxVapOpen;
-    vap[vapId].dev->stop = &zfLnxVapClose;
-    vap[vapId].dev->get_stats = &usbdrv_get_stats;
-    vap[vapId].dev->change_mtu = &usbdrv_change_mtu;
-#ifdef ZM_HOSTAPD_SUPPORT
-    vap[vapId].dev->do_ioctl = usbdrv_ioctl;
-#else
-    vap[vapId].dev->do_ioctl = NULL;
-#endif
+    vap[vapId].dev->netdev_ops = &vap_netdev_ops;
     vap[vapId].dev->destructor = free_netdev;
 
     vap[vapId].dev->tx_queue_len = 0;
@@ -1068,6 +1074,18 @@ void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp)
     usb_unlink_urb(macp->RegInUrb);
 }
 
+static const struct net_device_ops otus_netdev_ops = {
+	.ndo_open		= usbdrv_open,
+	.ndo_stop		= usbdrv_close,
+	.ndo_start_xmit		= usbdrv_xmit_frame,
+	.ndo_change_mtu		= usbdrv_change_mtu,
+	.ndo_get_stats		= usbdrv_get_stats,
+	.ndo_set_multicast_list	= usbdrv_set_multi,
+	.ndo_set_mac_address	= usbdrv_set_mac,
+	.ndo_do_ioctl		= usbdrv_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp)
 {
     //unsigned char addr[6];
@@ -1092,14 +1110,7 @@ u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp)
     dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def;
 #endif
 
-    dev->open = usbdrv_open;
-    dev->hard_start_xmit = usbdrv_xmit_frame;
-    dev->stop = usbdrv_close;
-    dev->change_mtu = &usbdrv_change_mtu;
-    dev->get_stats = usbdrv_get_stats;
-    dev->set_multicast_list = usbdrv_set_multi;
-    dev->set_mac_address = usbdrv_set_mac;
-    dev->do_ioctl = usbdrv_ioctl;
+    dev->netdev_ops = &otus_netdev_ops;
 
     dev->flags |= IFF_MULTICAST;
 
diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c
index 78f1d2224fa1..2a6d937ba5e8 100644
--- a/drivers/staging/otus/zdusb.c
+++ b/drivers/staging/otus/zdusb.c
@@ -48,7 +48,8 @@ static const char driver_name[] = "Otus";
 static struct usb_device_id zd1221_ids [] = {
 	{ USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
         { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
-	{ USB_DEVICE(0x0846, 0x9010) },
+	{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
+	{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) },
 	{ }					/* Terminating entry */
 };
 
diff --git a/drivers/staging/otus/zdusb.h b/drivers/staging/otus/zdusb.h
index 656dc212ade5..9f8ab2e96169 100644
--- a/drivers/staging/otus/zdusb.h
+++ b/drivers/staging/otus/zdusb.h
@@ -40,4 +40,8 @@
 #define VENDOR_DLINK            0x07D1  //Dlink
 #define PRODUCT_DWA160A         0x3C10
 
+#define	VENDOR_NETGEAR		0x0846	/* NetGear */
+#define	PRODUCT_WNDA3100	0x9010
+#define	PRODUCT_WN111v2		0x9001
+
 #endif
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index 3e67da9ea381..a6eaa42fb669 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned
 	return g;
 }
 
+static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst)
+{
+	struct pohmelfs_config *tmp;
+
+	INIT_LIST_HEAD(&dst->config_entry);
+
+	list_for_each_entry(tmp, &psb->state_list, config_entry) {
+		if (dst->state.ctl.prio > tmp->state.ctl.prio)
+			list_add_tail(&dst->config_entry, &tmp->config_entry);
+	}
+	if (list_empty(&dst->config_entry))
+		list_add_tail(&dst->config_entry, &psb->state_list);
+}
+
+static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb,
+		struct pohmelfs_config *dst, struct pohmelfs_config *new)
+{
+	if ((dst->state.ctl.prio == new->state.ctl.prio) &&
+		(dst->state.ctl.perm == new->state.ctl.perm))
+		return 0;
+
+	dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n",
+			__func__, dst->state.ctl.prio, dst->state.ctl.perm,
+			new->state.ctl.prio, new->state.ctl.perm);
+	dst->state.ctl.prio = new->state.ctl.prio;
+	dst->state.ctl.perm = new->state.ctl.perm;
+
+	list_del_init(&dst->config_entry);
+	pohmelfs_insert_config_entry(psb, dst);
+	return 0;
+}
+
+/*
+ * pohmelfs_copy_config() is used to copy new state configs from the
+ * config group (controlled by the netlink messages) into the superblock.
+ * This happens either at startup time where no transactions can access
+ * the list of the configs (and thus list of the network states), or at
+ * run-time, where it is protected by the psb->state_lock.
+ */
 int pohmelfs_copy_config(struct pohmelfs_sb *psb)
 {
 	struct pohmelfs_config_group *g;
@@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)
 		err = 0;
 		list_for_each_entry(dst, &psb->state_list, config_entry) {
 			if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
-				err = -EEXIST;
+				err = pohmelfs_move_config_entry(psb, dst, c);
+				if (!err)
+					err = -EEXIST;
 				break;
 			}
 		}
@@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)
 
 		memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
 
-		list_add_tail(&dst->config_entry, &psb->state_list);
+		pohmelfs_insert_config_entry(psb, dst);
 
 		err = pohmelfs_state_init_one(psb, dst);
 		if (err) {
@@ -248,6 +289,13 @@ out_unlock:
         return err;
 }
 
+static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
+{
+	old->perm = new->perm;
+	old->prio = new->prio;
+	return 0;
+}
+
 static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
 {
 	struct pohmelfs_config_group *g;
@@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
 				g->num_entry--;
 				kfree(c);
 				goto out_unlock;
+			} else if (action == POHMELFS_FLAGS_MODIFY) {
+				err = pohmelfs_modify_config(sc, ctl);
+				goto out_unlock;
 			} else {
 				err = -EEXIST;
 				goto out_unlock;
@@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
 	}
 	memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
 	g->num_entry++;
+
 	list_add_tail(&c->config_entry, &g->config_list);
 
 out_unlock:
@@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data)
 
 	switch (msg->flags) {
 		case POHMELFS_FLAGS_ADD:
-			err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
-			break;
 		case POHMELFS_FLAGS_DEL:
-			err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL);
+		case POHMELFS_FLAGS_MODIFY:
+			err = pohmelfs_cn_ctl(msg, msg->flags);
 			break;
 		case POHMELFS_FLAGS_SHOW:
 			err = pohmelfs_cn_disp(msg);
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
index 7a41183a32e1..b5799842fb84 100644
--- a/drivers/staging/pohmelfs/dir.c
+++ b/drivers/staging/pohmelfs/dir.c
@@ -328,7 +328,7 @@ static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
 {
 	struct inode *inode = &pi->vfs_inode;
 	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	long ret = msecs_to_jiffies(25000);
+	long ret = psb->wait_on_page_timeout;
 	int err;
 
 	dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
@@ -389,11 +389,11 @@ static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
 	dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
 			__func__, pi->ino, (u64)file->f_pos,
 			(unsigned long)file->private_data);
-
+#if 0
 	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
 	if (err)
 		return err;
-
+#endif
 	err = pohmelfs_sync_remote_dir(pi);
 	if (err)
 		return err;
@@ -513,10 +513,6 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 
 	need_lock = pohmelfs_need_lock(parent, lock_type);
 
-	err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
-	if (err)
-		goto out;
-
 	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
 
 	mutex_lock(&parent->offset_lock);
@@ -525,8 +521,8 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 		ino = n->ino;
 	mutex_unlock(&parent->offset_lock);
 
-	dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n",
-			__func__, ino, inode, str.name, str.hash, parent->state);
+	dprintk("%s: start ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx, need_lock: %d.\n",
+			__func__, ino, inode, str.name, str.hash, parent->state, need_lock);
 
 	if (ino) {
 		inode = ilookup(dir->i_sb, ino);
@@ -534,7 +530,7 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 			goto out;
 	}
 
-	dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
+	dprintk("%s: no inode dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
 			__func__, dir, parent->ino,
 			str.name, str.len, parent->state, ino);
 
@@ -543,6 +539,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 			goto out;
 	}
 
+	err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
+	if (err)
+		goto out;
+
 	err = pohmelfs_lookup_single(parent, &str, ino);
 	if (err)
 		goto out;
@@ -557,10 +557,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 
 	if (ino) {
 		inode = ilookup(dir->i_sb, ino);
-		printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
+		dprintk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
 				__func__, ino, inode, str.name, str.hash);
 		if (!inode) {
-			printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
+			dprintk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
 				__func__, ino, str.name, str.hash);
 			//return NULL;
 			return ERR_PTR(-EACCES);
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index 5bf16504cd6f..b2eaf9047266 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -1169,16 +1169,17 @@ err_out_put:
 static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
+#if 0
 	struct pohmelfs_inode *pi = POHMELFS_I(inode);
 	int err;
 
 	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
 	if (err)
 		return err;
-
 	dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
 			__func__, pi->ino, inode->i_mode, inode->i_uid,
 			inode->i_gid, inode->i_size);
+#endif
 
 	generic_fillattr(inode, stat);
 	return 0;
@@ -1342,14 +1343,6 @@ static void pohmelfs_put_super(struct super_block *sb)
 
 	kfree(psb);
 	sb->s_fs_info = NULL;
-
-	pohmelfs_ftrans_exit();
-}
-
-static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
-{
-	*flags |= MS_RDONLY;
-	return 0;
 }
 
 static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -1394,42 +1387,33 @@ static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
 	return 0;
 }
 
-static const struct super_operations pohmelfs_sb_ops = {
-	.alloc_inode	= pohmelfs_alloc_inode,
-	.destroy_inode	= pohmelfs_destroy_inode,
-	.drop_inode	= pohmelfs_drop_inode,
-	.write_inode	= pohmelfs_write_inode,
-	.put_super	= pohmelfs_put_super,
-	.remount_fs	= pohmelfs_remount,
-	.statfs		= pohmelfs_statfs,
-	.show_options	= pohmelfs_show_options,
-};
-
 enum {
 	pohmelfs_opt_idx,
+	pohmelfs_opt_crypto_thread_num,
+	pohmelfs_opt_trans_max_pages,
+	pohmelfs_opt_crypto_fail_unsupported,
+
+	/* Remountable options */
 	pohmelfs_opt_trans_scan_timeout,
 	pohmelfs_opt_drop_scan_timeout,
 	pohmelfs_opt_wait_on_page_timeout,
 	pohmelfs_opt_trans_retries,
-	pohmelfs_opt_crypto_thread_num,
-	pohmelfs_opt_trans_max_pages,
-	pohmelfs_opt_crypto_fail_unsupported,
 	pohmelfs_opt_mcache_timeout,
 };
 
 static struct match_token pohmelfs_tokens[] = {
 	{pohmelfs_opt_idx, "idx=%u"},
+	{pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
+	{pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
+	{pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
 	{pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
 	{pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
 	{pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
 	{pohmelfs_opt_trans_retries, "trans_retries=%u"},
-	{pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
-	{pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
-	{pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
 	{pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
 };
 
-static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
+static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int remount)
 {
 	char *p;
 	substring_t args[MAX_OPT_ARGS];
@@ -1449,6 +1433,9 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
 		if (err)
 			return err;
 
+		if (remount && token <= pohmelfs_opt_crypto_fail_unsupported)
+			continue;
+
 		switch (token) {
 			case pohmelfs_opt_idx:
 				psb->idx = option;
@@ -1485,6 +1472,25 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
 	return 0;
 }
 
+static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
+{
+	int err;
+	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+	unsigned long old_sb_flags = sb->s_flags;
+
+	err = pohmelfs_parse_options(data, psb, 1);
+	if (err)
+		goto err_out_restore;
+
+	if (!(*flags & MS_RDONLY))
+		sb->s_flags &= ~MS_RDONLY;
+	return 0;
+
+err_out_restore:
+	sb->s_flags = old_sb_flags;
+	return err;
+}
+
 static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
 {
 	struct inode *inode = &pi->vfs_inode;
@@ -1753,6 +1759,57 @@ err_out_exit:
 	return err;
 }
 
+static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
+{
+	struct netfs_state *st;
+	struct pohmelfs_ctl *ctl;
+	struct pohmelfs_sb *psb = POHMELFS_SB(mnt->mnt_sb);
+	struct pohmelfs_config *c;
+
+	mutex_lock(&psb->state_lock);
+
+	seq_printf(m, "\nidx addr(:port) socket_type protocol active priority permissions\n");
+
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+		ctl = &st->ctl;
+
+		seq_printf(m, "%u ", ctl->idx);
+		if (ctl->addr.sa_family == AF_INET) {
+			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
+			//seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
+			seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+		} else if (ctl->addr.sa_family == AF_INET6) {
+			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
+			seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
+		} else {
+			unsigned int i;
+			for (i=0; i<ctl->addrlen; ++i)
+				seq_printf(m, "%02x.", ctl->addr.addr[i]);
+		}
+
+		seq_printf(m, " %u %u %d %u %x\n",
+				ctl->type, ctl->proto,
+				st->socket != NULL,
+				ctl->prio, ctl->perm);
+	}
+	mutex_unlock(&psb->state_lock);
+
+	return 0;
+}
+
+static const struct super_operations pohmelfs_sb_ops = {
+	.alloc_inode	= pohmelfs_alloc_inode,
+	.destroy_inode	= pohmelfs_destroy_inode,
+	.drop_inode	= pohmelfs_drop_inode,
+	.write_inode	= pohmelfs_write_inode,
+	.put_super	= pohmelfs_put_super,
+	.remount_fs	= pohmelfs_remount,
+	.statfs		= pohmelfs_statfs,
+	.show_options	= pohmelfs_show_options,
+	.show_stats	= pohmelfs_show_stats,
+};
+
 /*
  * Allocate private superblock and create root dir.
  */
@@ -1764,8 +1821,6 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
 	struct pohmelfs_inode *npi;
 	struct qstr str;
 
-	pohmelfs_ftrans_init();
-
 	psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
 	if (!psb)
 		goto err_out_exit;
@@ -1816,7 +1871,7 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
 	mutex_init(&psb->state_lock);
 	INIT_LIST_HEAD(&psb->state_list);
 
-	err = pohmelfs_parse_options((char *) data, psb);
+	err = pohmelfs_parse_options((char *) data, psb, 0);
 	if (err)
 		goto err_out_free_sb;
 
@@ -1845,6 +1900,8 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
 		err = PTR_ERR(npi);
 		goto err_out_crypto_exit;
 	}
+	set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+	clear_bit(NETFS_INODE_OWNED, &npi->state);
 
 	root = &npi->vfs_inode;
 
@@ -1887,11 +1944,29 @@ static int pohmelfs_get_sb(struct file_system_type *fs_type,
 				mnt);
 }
 
+/*
+ * We need this to sync all inodes earlier, since when writeback
+ * is invoked from the umount/mntput path dcache is already shrunk,
+ * see generic_shutdown_super(), and no inodes can access the path.
+ */
+static void pohmelfs_kill_super(struct super_block *sb)
+{
+	struct writeback_control wbc = {
+		.sync_mode	= WB_SYNC_ALL,
+		.range_start	= 0,
+		.range_end	= LLONG_MAX,
+		.nr_to_write	= LONG_MAX,
+	};
+	generic_sync_sb_inodes(sb, &wbc);
+
+	kill_anon_super(sb);
+}
+
 static struct file_system_type pohmel_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "pohmel",
 	.get_sb		= pohmelfs_get_sb,
-	.kill_sb 	= kill_anon_super,
+	.kill_sb 	= pohmelfs_kill_super,
 };
 
 /*
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
index ad4a18559bdd..22fef18cae90 100644
--- a/drivers/staging/pohmelfs/lock.c
+++ b/drivers/staging/pohmelfs/lock.c
@@ -41,7 +41,8 @@ static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
 	path_len = err;
 
 	err = -ENOMEM;
-	t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0);
+	t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize,
+			NETFS_TRANS_SINGLE_DST, 0);
 	if (!t)
 		goto err_out_exit;
 
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
index c9b8540c1efe..11ecac026ca7 100644
--- a/drivers/staging/pohmelfs/net.c
+++ b/drivers/staging/pohmelfs/net.c
@@ -26,55 +26,6 @@
 
 #include "netfs.h"
 
-static int pohmelfs_ftrans_size = 10240;
-static u32 *pohmelfs_ftrans;
-
-int pohmelfs_ftrans_init(void)
-{
-	pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4);
-	if (!pohmelfs_ftrans)
-		return -ENOMEM;
-
-	return 0;
-}
-
-void pohmelfs_ftrans_exit(void)
-{
-	vfree(pohmelfs_ftrans);
-}
-
-void pohmelfs_ftrans_clean(u64 id)
-{
-	if (pohmelfs_ftrans) {
-		u32 i = id & 0xffffffff;
-		int idx = i % pohmelfs_ftrans_size;
-
-		pohmelfs_ftrans[idx] = 0;
-	}
-}
-
-void pohmelfs_ftrans_update(u64 id)
-{
-	if (pohmelfs_ftrans) {
-		u32 i = id & 0xffffffff;
-		int idx = i % pohmelfs_ftrans_size;
-
-		pohmelfs_ftrans[idx] = i;
-	}
-}
-
-int pohmelfs_ftrans_check(u64 id)
-{
-	if (pohmelfs_ftrans) {
-		u32 i = id & 0xffffffff;
-		int idx = i % pohmelfs_ftrans_size;
-
-		return (pohmelfs_ftrans[idx] == i);
-	}
-
-	return -1;
-}
-
 /*
  * Async machinery lives here.
  * All commands being sent to server do _not_ require sync reply,
@@ -450,8 +401,24 @@ static int pohmelfs_readdir_response(struct netfs_state *st)
 			if (err != -EEXIST)
 				goto err_out_put;
 		} else {
+			struct dentry *dentry, *alias, *pd;
+
 			set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
 			clear_bit(NETFS_INODE_OWNED, &npi->state);
+
+			pd = d_find_alias(&parent->vfs_inode);
+			if (pd) {
+				str.hash = full_name_hash(str.name, str.len);
+				dentry = d_alloc(pd, &str);
+				if (dentry) {
+					alias = d_materialise_unique(dentry, &npi->vfs_inode);
+					if (alias)
+						dput(dentry);
+				}
+
+				dput(dentry);
+				dput(pd);
+			}
 		}
 	}
 out:
@@ -638,15 +605,12 @@ static int pohmelfs_transaction_response(struct netfs_state *st)
 	if (dst) {
 		netfs_trans_remove_nolock(dst, st);
 		t = dst->trans;
-
-		pohmelfs_ftrans_update(cmd->start);
 	}
 	mutex_unlock(&st->trans_lock);
 
 	if (!t) {
-		int check = pohmelfs_ftrans_check(cmd->start);
-		printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n",
-				__func__, cmd->start, cmd->id, cmd->size, cmd->ext, check);
+		printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n",
+				__func__, cmd->start, cmd->id, cmd->size, cmd->ext);
 		err = -EINVAL;
 		goto out;
 	}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
index 2ff21ae5bb12..c78cfcb042fb 100644
--- a/drivers/staging/pohmelfs/netfs.h
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -87,6 +87,7 @@ enum {
 	POHMELFS_FLAGS_DEL,     /* Network state control message for DEL */
 	POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
 	POHMELFS_FLAGS_CRYPTO,	/* Crypto data control message */
+	POHMELFS_FLAGS_MODIFY,	/* Network state modification message */
 };
 
 /*
@@ -116,16 +117,20 @@ struct pohmelfs_crypto
 	unsigned char		data[0];	/* Algorithm string, key and IV */
 };
 
+#define POHMELFS_IO_PERM_READ		(1<<0)
+#define POHMELFS_IO_PERM_WRITE		(1<<1)
+
 /*
  * Configuration command used to create table of different remote servers.
  */
 struct pohmelfs_ctl
 {
-	unsigned int		idx;		/* Config index */
-	unsigned int		type;		/* Socket type */
-	unsigned int		proto;		/* Socket protocol */
-	unsigned int		addrlen;	/* Size of the address */
-	unsigned short		unused;		/* Align structure by 4 bytes */
+	__u32			idx;		/* Config index */
+	__u32			type;		/* Socket type */
+	__u32			proto;		/* Socket protocol */
+	__u16			addrlen;	/* Size of the address */
+	__u16			perm;		/* IO permission */
+	__u16			prio;		/* IO priority */
 	struct saddr		addr;		/* Remote server address */
 };
 
@@ -921,12 +926,6 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
 		pohmelfs_mcache_free(psb, m);
 }
 
-int pohmelfs_ftrans_init(void);
-void pohmelfs_ftrans_exit(void);
-void pohmelfs_ftrans_update(u64 id);
-int pohmelfs_ftrans_check(u64 id);
-void pohmelfs_ftrans_clean(u64 id);
-
 #endif /* __KERNEL__*/
 
 #endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
index bcb59425a21c..fef5f9bd6920 100644
--- a/drivers/staging/pohmelfs/trans.c
+++ b/drivers/staging/pohmelfs/trans.c
@@ -456,34 +456,25 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
 		__func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
 #endif
 	mutex_lock(&psb->state_lock);
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
 
-	if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) {
-		st = &psb->active_state->state;
-
-		err = -EPIPE;
-		if (netfs_state_poll(st) & POLLOUT) {
-			err = netfs_trans_push_dst(t, st);
-			if (!err) {
-				err = netfs_trans_send(t, st);
-				if (err) {
-					netfs_trans_drop_last(t, st);
-				} else {
-					pohmelfs_switch_active(psb);
-					goto out;
-				}
-			}
+		if (t->flags & NETFS_TRANS_SINGLE_DST) {
+			if (!(st->ctl.perm & POHMELFS_IO_PERM_READ))
+				continue;
+		} else {
+			if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE))
+				continue;
 		}
-		pohmelfs_switch_active(psb);
-	}
 
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
+		if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio))
+			st = &psb->active_state->state;
 
 		err = netfs_trans_push(t, st);
 		if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
 			break;
 	}
-out:
+
 	mutex_unlock(&psb->state_lock);
 #if 0
 	dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
@@ -501,8 +492,6 @@ int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
 
 	t->gen = atomic_inc_return(&psb->trans_gen);
 
-	pohmelfs_ftrans_clean(t->gen);
-
 	cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
 		t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
 	cmd->cmd = NETFS_TRANS;
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index cf17bcdd7333..6c4396f0903b 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -722,6 +722,20 @@ err:
 	return (-1);
 } /* End of rt28xx_open */
 
+static const struct net_device_ops rt2860_netdev_ops = {
+	.ndo_open		= MainVirtualIF_open,
+	.ndo_stop		= MainVirtualIF_close,
+	.ndo_do_ioctl		= rt28xx_ioctl,
+	.ndo_get_stats		= RT28xx_get_ether_stats,
+	.ndo_validate_addr	= NULL,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef IKANOS_VX_1X0
+	.ndo_start_xmit		= IKANOS_DataFramesTx,
+#else
+	.ndo_start_xmit		= rt28xx_send_packets,
+#endif
+};
 
 /* Must not be called for mdev and apdev */
 static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
@@ -733,11 +747,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 
 
 	//ether_setup(dev);
-	dev->hard_start_xmit = rt28xx_send_packets;
-
-#ifdef IKANOS_VX_1X0
-	dev->hard_start_xmit = IKANOS_DataFramesTx;
-#endif // IKANOS_VX_1X0 //
 
 #ifdef CONFIG_STA_SUPPORT
 #if WIRELESS_EXT >= 12
@@ -760,12 +769,8 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 #if WIRELESS_EXT < 21
 		dev->get_wireless_stats = rt28xx_get_wireless_stats;
 #endif
-	dev->get_stats = RT28xx_get_ether_stats;
-	dev->open = MainVirtualIF_open; //rt28xx_open;
-	dev->stop = MainVirtualIF_close; //rt28xx_close;
 	dev->priv_flags = INT_MAIN;
-	dev->do_ioctl = rt28xx_ioctl;
-	dev->validate_addr = NULL;
+	dev->netdev_ops = &rt2860_netdev_ops;
 	// find available device name
 	for (i = 0; i < 8; i++)
 	{
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index 5dd15aac9ce7..a42caa370808 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -96,6 +96,7 @@
 	{USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */		\
 	{USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */		\
 	{USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */		\
 	{USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */		\
 	{USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */		\
 	{USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */		\
diff --git a/drivers/staging/rt2870/rt_main_dev.c b/drivers/staging/rt2870/rt_main_dev.c
index 313ecea0bfa8..48ad41136d0f 100644
--- a/drivers/staging/rt2870/rt_main_dev.c
+++ b/drivers/staging/rt2870/rt_main_dev.c
@@ -855,6 +855,20 @@ err:
 	return (-1);
 } /* End of rt28xx_open */
 
+static const struct net_device_ops rt2870_netdev_ops = {
+	.ndo_open		= MainVirtualIF_open,
+	.ndo_stop		= MainVirtualIF_close,
+	.ndo_do_ioctl		= rt28xx_ioctl,
+	.ndo_get_stats		= RT28xx_get_ether_stats,
+	.ndo_validate_addr	= NULL,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef IKANOS_VX_1X0
+	.ndo_start_xmit		= IKANOS_DataFramesTx,
+#else
+	.ndo_start_xmit		= rt28xx_send_packets,
+#endif
+};
 
 /* Must not be called for mdev and apdev */
 static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
@@ -866,12 +880,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 
 
 	//ether_setup(dev);
-	dev->hard_start_xmit = rt28xx_send_packets;
-
-#ifdef IKANOS_VX_1X0
-	dev->hard_start_xmit = IKANOS_DataFramesTx;
-#endif // IKANOS_VX_1X0 //
-
 //	dev->set_multicast_list = ieee80211_set_multicast_list;
 //	dev->change_mtu = ieee80211_change_mtu;
 #ifdef CONFIG_STA_SUPPORT
@@ -895,16 +903,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 #if WIRELESS_EXT < 21
 		dev->get_wireless_stats = rt28xx_get_wireless_stats;
 #endif
-	dev->get_stats = RT28xx_get_ether_stats;
-	dev->open = MainVirtualIF_open; //rt28xx_open;
-	dev->stop = MainVirtualIF_close; //rt28xx_close;
 //	dev->uninit = ieee80211_if_reinit;
 //	dev->destructor = ieee80211_if_free;
 	dev->priv_flags = INT_MAIN;
-	dev->do_ioctl = rt28xx_ioctl;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-    dev->validate_addr = NULL;
-#endif
+	dev->netdev_ops = &rt2870_netdev_ops;
 	// find available device name
 	for (i = 0; i < 8; i++)
 	{
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
index c000646286e6..81f769cf1096 100644
--- a/drivers/staging/rt3070/rt_main_dev.c
+++ b/drivers/staging/rt3070/rt_main_dev.c
@@ -436,7 +436,6 @@ static int rt28xx_init(IN struct net_device *net_dev)
 //    OID_SET_HT_PHYMODE		SetHT;
 //	WPDMA_GLO_CFG_STRUC     GloCfg;
 	UINT32 		MacCsr0 = 0;
-	UINT32		MacValue = 0;
 
 #ifdef RT2870
 #ifdef INF_AMAZON_SE
@@ -849,6 +848,20 @@ err:
 	return (-1);
 } /* End of rt28xx_open */
 
+static const struct net_device_ops rt3070_netdev_ops = {
+	.ndo_open		= MainVirtualIF_open,
+	.ndo_stop		= MainVirtualIF_close,
+	.ndo_do_ioctl		= rt28xx_ioctl,
+	.ndo_get_stats		= RT28xx_get_ether_stats,
+	.ndo_validate_addr	= NULL,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef IKANOS_VX_1X0
+	.ndo_start_xmit		= IKANOS_DataFramesTx,
+#else
+	.ndo_start_xmit		= rt28xx_send_packets,
+#endif
+};
 
 /* Must not be called for mdev and apdev */
 static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
@@ -860,12 +873,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 
 
 	//ether_setup(dev);
-	dev->hard_start_xmit = rt28xx_send_packets;
-
-#ifdef IKANOS_VX_1X0
-	dev->hard_start_xmit = IKANOS_DataFramesTx;
-#endif // IKANOS_VX_1X0 //
-
 //	dev->set_multicast_list = ieee80211_set_multicast_list;
 //	dev->change_mtu = ieee80211_change_mtu;
 #ifdef CONFIG_STA_SUPPORT
@@ -889,16 +896,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 #if WIRELESS_EXT < 21
 		dev->get_wireless_stats = rt28xx_get_wireless_stats;
 #endif
-	dev->get_stats = RT28xx_get_ether_stats;
-	dev->open = MainVirtualIF_open; //rt28xx_open;
-	dev->stop = MainVirtualIF_close; //rt28xx_close;
 //	dev->uninit = ieee80211_if_reinit;
 //	dev->destructor = ieee80211_if_free;
 	dev->priv_flags = INT_MAIN;
-	dev->do_ioctl = rt28xx_ioctl;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-    dev->validate_addr = NULL;
-#endif
+	dev->netdev_ops = &rt3070_netdev_ops;
 	// find available device name
 	for (i = 0; i < 8; i++)
 	{
diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README
index 2d5b1127ce51..70f49099c065 100644
--- a/drivers/staging/slicoss/README
+++ b/drivers/staging/slicoss/README
@@ -10,7 +10,36 @@ TODO:
 	- move firmware loading to request_firmware()
 	- remove direct memory access of structures
 	- any remaining sparse and checkpatch.pl warnings
-	- any netdev recommended changes
+
+	- use net_device_ops
+	- use dev->stats rather than adapter->stats
+	- don't cast netdev_priv it is already void
+	- use compare_ether_addr
+	- GET RID OF MACROS
+	- work on all architectures
+	   - without CONFIG_X86_64 confusion
+	   - do 64 bit correctly
+	   - don't depend on order of union
+	- get rid of ASSERT(), use BUG() instead but only where necessary
+	  looks like most aren't really useful
+	- no new SIOCDEVPRIVATE ioctl allowed
+	- don't use module_param for configuring interrupt mitigation
+	  use ethtool instead
+	- reorder code to elminate use of forward declarations
+	- don't keep private linked list of drivers.
+	- remove all the gratiutous debug infrastructure
+	- use PCI_DEVICE()
+	- do ethtool correctly using ethtool_ops
+	- NAPI?
+	- wasted overhead of extra stats
+	- state variables for things that are
+	  easily availble and shouldn't be kept in card structure, cardnum, ...
+	  slotnumber, events, ...
+	- get rid of slic_spinlock wrapper
+	- volatile == bad design => bad code
+	- locking too fine grained, not designed just throw more locks
+	  at problem
+
 
 Please send patches to:
         Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index 948156348478..6f5d0bff4358 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -345,6 +345,19 @@ static void slic_init_adapter(struct net_device *netdev,
 	return;
 }
 
+static const struct net_device_ops slic_netdev_ops = {
+	.ndo_open		= slic_entry_open,
+	.ndo_stop		= slic_entry_halt,
+	.ndo_start_xmit		= slic_xmit_start,
+	.ndo_do_ioctl		= slic_ioctl,
+	.ndo_set_mac_address	= slic_mac_set_address,
+	.ndo_get_stats		= slic_get_stats,
+	.ndo_set_multicast_list	= slic_mcast_set_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int __devinit slic_entry_probe(struct pci_dev *pcidev,
 			       const struct pci_device_id *pci_tbl_entry)
 {
@@ -442,13 +455,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
 
 	netdev->base_addr = (unsigned long)adapter->memorybase;
 	netdev->irq = adapter->irq;
-	netdev->open = slic_entry_open;
-	netdev->stop = slic_entry_halt;
-	netdev->hard_start_xmit = slic_xmit_start;
-	netdev->do_ioctl = slic_ioctl;
-	netdev->set_mac_address = slic_mac_set_address;
-	netdev->get_stats = slic_get_stats;
-	netdev->set_multicast_list = slic_mcast_set_list;
+	netdev->netdev_ops = &slic_netdev_ops;
 
 	slic_debug_adapter_create(adapter);
 
@@ -1260,7 +1267,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address)
 	}
 
 	/* Doesn't already exist.  Allocate a structure to hold it */
-	mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL);
+	mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
 	if (mcaddr == NULL)
 		return 1;
 
@@ -2284,7 +2291,7 @@ static u32 slic_card_locate(struct adapter *adapter)
 	}
 	if (!physcard) {
 		/* no structure allocated for this physical card yet */
-		physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL);
+		physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
 		ASSERT(physcard);
 
 		physcard->next = slic_global.phys_card;
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
index 8d3f46f190e8..947fb75a9c68 100644
--- a/drivers/staging/stlc45xx/Kconfig
+++ b/drivers/staging/stlc45xx/Kconfig
@@ -1,6 +1,6 @@
 config STLC45XX
 	tristate "stlc4550/4560 support"
-	depends on MAC80211 && WLAN_80211 && SPI_MASTER
+	depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS
 	---help---
 	  This is a driver for stlc4550 and stlc4560 chipsets.
 
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
index 891f6e334672..076b3f7d39eb 100644
--- a/drivers/staging/sxg/sxg.c
+++ b/drivers/staging/sxg/sxg.c
@@ -322,6 +322,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter)
 	int ret,i;
 
 	if (!adapter->intrregistered) {
+		spin_unlock_irqrestore(&sxg_global.driver_lock,
+					sxg_global.flags);
 		for (i=0; i<adapter->nr_msix_entries; i++) {
 			ret = request_irq (adapter->msi_entries[i].vector,
 					sxg_isr,
@@ -329,6 +331,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter)
 					adapter->netdev->name,
 					adapter->netdev);
 			if (ret) {
+				spin_lock_irqsave(&sxg_global.driver_lock,
+						 sxg_global.flags);
 				DBG_ERROR("sxg: MSI-X request_irq (%s) "
 					"FAILED [%x]\n", adapter->netdev->name,
 					 ret);
@@ -336,6 +340,7 @@ int sxg_add_msi_isr(struct adapter_t *adapter)
 			}
 		}
 	}
+	spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
 	adapter->msi_enabled = TRUE;
 	adapter->intrregistered = 1;
 	adapter->IntRegistered = TRUE;
@@ -896,6 +901,22 @@ static inline int sxg_read_config(struct adapter_t *adapter)
 	return status;
 }
 
+static const struct net_device_ops sxg_netdev_ops = {
+	.ndo_open		= sxg_entry_open,
+	.ndo_stop		= sxg_entry_halt,
+	.ndo_start_xmit		= sxg_send_packets,
+	.ndo_do_ioctl		= sxg_ioctl,
+	.ndo_change_mtu		= sxg_change_mtu,
+	.ndo_get_stats		= sxg_get_stats,
+	.ndo_set_multicast_list	= sxg_mcast_set_list,
+	.ndo_validate_addr	= eth_validate_addr,
+#if XXXTODO
+	.ndo_set_mac_address	= sxg_mac_set_address,
+#else
+	.ndo_set_mac_address	= eth_mac_addr,
+#endif
+};
+
 static int sxg_entry_probe(struct pci_dev *pcidev,
 			   const struct pci_device_id *pci_tbl_entry)
 {
@@ -1095,16 +1116,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
 
 	netdev->base_addr = (unsigned long)adapter->base_addr;
 	netdev->irq = adapter->irq;
-	netdev->open = sxg_entry_open;
-	netdev->stop = sxg_entry_halt;
-	netdev->hard_start_xmit = sxg_send_packets;
-	netdev->do_ioctl = sxg_ioctl;
-	netdev->change_mtu = sxg_change_mtu;
-#if XXXTODO
-	netdev->set_mac_address = sxg_mac_set_address;
-#endif
-	netdev->get_stats = sxg_get_stats;
-	netdev->set_multicast_list = sxg_mcast_set_list;
+	netdev->netdev_ops = &sxg_netdev_ops;
 	SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
  	netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	err = sxg_set_interrupt_capability(adapter);
@@ -2247,6 +2259,8 @@ static int sxg_entry_open(struct net_device *dev)
 	DBG_ERROR("sxg: %s EXIT\n", __func__);
 
 	spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+	mod_timer(&adapter->watchdog_timer, jiffies);
+
 	return STATUS_SUCCESS;
 }
 
@@ -2568,6 +2582,7 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
 	u64 phys_addr;
 	unsigned long flags;
 	unsigned long queue_id=0;
+	int offload_cksum = 0;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
 		  pSgl, SxgSgl, 0, 0);
@@ -2606,7 +2621,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
                 struct iphdr *ip;
 
                 ip = ip_hdr(skb);
-		if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof(
+		if (ip->protocol == IPPROTO_TCP)
+			offload_cksum = 1;
+		if (!offload_cksum || !tcp_hdr(skb))
+			queue_id = 0;
+		else if (offload_cksum && (DataLength >= sizeof(
 							struct tcphdr))){
 			queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
 					(ntohs (tcp_hdr(skb)->source) &
@@ -2615,8 +2634,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
 						SXG_LARGE_SEND_QUEUE_MASK));
 		}
 	} else if (skb->protocol == htons(ETH_P_IPV6)) {
-		if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
-						 sizeof(struct tcphdr)) ) {
+		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+			offload_cksum = 1;
+		if (!offload_cksum || !tcp_hdr(skb))
+			queue_id = 0;
+		else if (offload_cksum && (DataLength>=sizeof(struct tcphdr))){
 			queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
 					(ntohs (tcp_hdr(skb)->source) &
 					SXG_LARGE_SEND_QUEUE_MASK):
@@ -2645,23 +2667,38 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
 	}
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
 		  XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
-	/* Update stats */
-	adapter->stats.tx_packets++;
-	adapter->stats.tx_bytes += DataLength;
-#if XXXTODO			/* Stats stuff */
-	if (SXG_MULTICAST_PACKET(EtherHdr)) {
-		if (SXG_BROADCAST_PACKET(EtherHdr)) {
-			adapter->Stats.DumbXmtBcastPkts++;
-			adapter->Stats.DumbXmtBcastBytes += DataLength;
+	memset(XmtCmd, '\0', sizeof(*XmtCmd));
+	XmtCmd->SgEntries = 1;
+	XmtCmd->Flags = 0;
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		/*
+		 * We need to set the Checkum in IP  header to 0. This is
+		 * required by hardware.
+		 */
+		if (offload_cksum) {
+			ip_hdr(skb)->check = 0x0;
+			XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
+			XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
+			/*
+			 * Dont know if length will require a change in
+			 * case of VLAN
+			 */
+			XmtCmd->CsumFlags.MacLen = ETH_HLEN;
+			XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
+							SXG_NW_HDR_LEN_SHIFT;
 		} else {
-			adapter->Stats.DumbXmtMcastPkts++;
-			adapter->Stats.DumbXmtMcastBytes += DataLength;
+			if (skb_checksum_help(skb)){
+				printk(KERN_EMERG "Dropped UDP packet for"
+					" incorrect checksum calculation\n");
+				if (XmtCmd)
+					SXG_ABORT_CMD(XmtRingInfo);
+				spin_unlock_irqrestore(&adapter->XmtZeroLock,
+							 flags);
+				return STATUS_SUCCESS;
+			}
 		}
-	} else {
-		adapter->Stats.DumbXmtUcastPkts++;
-		adapter->Stats.DumbXmtUcastBytes += DataLength;
 	}
-#endif
+
 	/*
 	 * Fill in the command
 	 * Copy out the first SGE to the command and adjust for offset
@@ -2679,31 +2716,17 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
 		(SXG_INVALID_SGL(phys_addr,skb->data_len)))
 	{
 		spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+		if (XmtCmd)
+			SXG_ABORT_CMD(XmtRingInfo);
 		/* Silently drop this packet */
 		printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n");
 		return STATUS_SUCCESS;
 	}
-	memset(XmtCmd, '\0', sizeof(*XmtCmd));
 	XmtCmd->Buffer.FirstSgeAddress = phys_addr;
 	XmtCmd->Buffer.FirstSgeLength = DataLength;
 	XmtCmd->Buffer.SgeOffset = 0;
 	XmtCmd->Buffer.TotalLength = DataLength;
-	XmtCmd->SgEntries = 1;
-	XmtCmd->Flags = 0;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		/*
-		 * We need to set the Checkum in IP  header to 0. This is
-		 * required by hardware.
-		 */
-		ip_hdr(skb)->check = 0x0;
-		XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
-		XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
-		/* Dont know if length will require a change in case of VLAN */
-		XmtCmd->CsumFlags.MacLen = ETH_HLEN;
-		XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
-							SXG_NW_HDR_LEN_SHIFT;
-	}
 	/*
 	 * Advance transmit cmd descripter by 1.
 	 * NOTE - See comments in SxgTcpOutput where we write
@@ -2715,6 +2738,24 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
 	ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0);
 	WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE);
 	adapter->Stats.XmtQLen++;	/* Stats within lock */
+	/* Update stats */
+	adapter->stats.tx_packets++;
+	adapter->stats.tx_bytes += DataLength;
+#if XXXTODO			/* Stats stuff */
+	if (SXG_MULTICAST_PACKET(EtherHdr)) {
+		if (SXG_BROADCAST_PACKET(EtherHdr)) {
+			adapter->Stats.DumbXmtBcastPkts++;
+			adapter->Stats.DumbXmtBcastBytes += DataLength;
+		} else {
+			adapter->Stats.DumbXmtMcastPkts++;
+			adapter->Stats.DumbXmtMcastBytes += DataLength;
+		}
+	} else {
+		adapter->Stats.DumbXmtUcastPkts++;
+		adapter->Stats.DumbXmtUcastBytes += DataLength;
+	}
+#endif
+
 	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
 		  XmtCmd, pSgl, SxgSgl, 0);
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
index 85b705453066..9c62f787cc9c 100644
--- a/drivers/staging/uc2322/aten2011.c
+++ b/drivers/staging/uc2322/aten2011.c
@@ -603,10 +603,9 @@ static void ATEN2011_bulk_out_data_callback(struct urb *urb)
 
 	tty = tty_port_tty_get(&ATEN2011_port->port->port);
 
-	if (tty && ATEN2011_port->open) {
+	if (tty && ATEN2011_port->open)
 		/* tell the tty driver that something has changed */
-		wake_up_interruptible(&tty->write_wait);
-	}
+		tty_wakeup(tty);
 
 	/* schedule_work(&ATEN2011_port->port->work); */
 	tty_kref_put(tty);
@@ -825,12 +824,6 @@ static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port,
 	status = 0;
 	status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
 
-	/* force low_latency on so that our tty_push actually forces *
-	 * the data through,otherwise it is scheduled, and with      *
-	 * high data rates (like with OHCI) data can get lost.       */
-
-	if (tty)
-		tty->low_latency = 1;
 	/*
 	 * Check to see if we've set up our endpoint info yet
 	 * (can't set it up in ATEN2011_startup as the structures
@@ -1473,22 +1466,7 @@ static void ATEN2011_set_termios(struct tty_struct *tty,
 
 	cflag = tty->termios->c_cflag;
 
-	if (!cflag) {
-		dbg("%s %s", __func__, "cflag is NULL");
-		return;
-	}
-
-	/* check that they really want us to change something */
-	if (old_termios) {
-		if ((cflag == old_termios->c_cflag) &&
-		    (RELEVANT_IFLAG(tty->termios->c_iflag) ==
-		     RELEVANT_IFLAG(old_termios->c_iflag))) {
-			dbg("%s", "Nothing to change");
-			return;
-		}
-	}
-
-	dbg("%s - clfag %08x iflag %08x", __func__,
+	dbg("%s - cflag %08x iflag %08x", __func__,
 	    tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
 
 	if (old_termios) {
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index b2a606a36936..393e4df70dfd 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -711,6 +711,20 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
 	return 0;
 }
 
+static const struct net_device_ops p80211_netdev_ops = {
+	.ndo_init		= p80211knetdev_init,
+	.ndo_open		= p80211knetdev_open,
+	.ndo_stop		= p80211knetdev_stop,
+	.ndo_get_stats		= p80211knetdev_get_stats,
+	.ndo_start_xmit		= p80211knetdev_hard_start_xmit,
+	.ndo_set_multicast_list	= p80211knetdev_set_multicast_list,
+	.ndo_do_ioctl		= p80211knetdev_do_ioctl,
+	.ndo_set_mac_address	= p80211knetdev_set_mac_address,
+	.ndo_tx_timeout		= p80211knetdev_tx_timeout,
+	.ndo_change_mtu		= wlan_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*----------------------------------------------------------------
 * wlan_setup
 *
@@ -756,11 +770,7 @@ int wlan_setup(wlandevice_t *wlandev)
 	} else {
 		wlandev->netdev = dev;
 		dev->ml_priv = wlandev;
-		dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
-		dev->get_stats = p80211knetdev_get_stats;
-		dev->init = p80211knetdev_init;
-		dev->open = p80211knetdev_open;
-		dev->stop = p80211knetdev_stop;
+		dev->netdev_ops = &p80211_netdev_ops;
 
 		mutex_init(&wlandev->ioctl_lock);
 		/* block ioctls until fully initialised. Don't forget to call
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index c60b8fcf0e3e..28034c812914 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -147,5 +147,6 @@ static void __exit hilscher_exit_module(void)
 module_init(hilscher_init_module);
 module_exit(hilscher_exit_module);
 
+MODULE_DEVICE_TABLE(pci, hilscher_pci_ids);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 869d47cb6db3..0a69c0977e3f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -546,10 +546,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 	tty->driver_data = acm;
 	acm->tty = tty;
 
-	/* force low_latency on so that our tty_push actually forces the data through,
-	   otherwise it is scheduled, and with high data rates data can get lost. */
-	tty->low_latency = 1;
-
 	if (usb_autopm_get_interface(acm->control) < 0)
 		goto early_bail;
 	else
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 3771d6e6d0cc..0fe434505ac4 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -3,7 +3,7 @@
  *
  * This driver supports USB CDC WCM Device Management.
  *
- * Copyright (c) 2007-2008 Oliver Neukum
+ * Copyright (c) 2007-2009 Oliver Neukum
  *
  * Some code taken from cdc-acm.c
  *
@@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	if (!buffer)
 		goto out;
 
-	while (buflen > 0) {
+	while (buflen > 2) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
 			dev_err(&intf->dev, "skipping garbage\n");
 			goto next_desc;
@@ -646,16 +646,18 @@ next_desc:
 	spin_lock_init(&desc->iuspin);
 	init_waitqueue_head(&desc->wait);
 	desc->wMaxCommand = maxcom;
+	/* this will be expanded and needed in hardware endianness */
 	desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
 	desc->intf = intf;
 	INIT_WORK(&desc->rxwork, wdm_rxwork);
 
-	iface = &intf->altsetting[0];
+	rv = -EINVAL;
+	iface = intf->cur_altsetting;
+	if (iface->desc.bNumEndpoints != 1)
+		goto err;
 	ep = &iface->endpoint[0].desc;
-	if (!usb_endpoint_is_int_in(ep)) {
-		rv = -EINVAL;
+	if (!ep || !usb_endpoint_is_int_in(ep))
 		goto err;
-	}
 
 	desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
 	desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
@@ -711,12 +713,19 @@ next_desc:
 
 	usb_set_intfdata(intf, desc);
 	rv = usb_register_dev(intf, &wdm_class);
-	dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
-		 intf->minor - WDM_MINOR_BASE);
 	if (rv < 0)
-		goto err;
+		goto err3;
+	else
+		dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
+			intf->minor - WDM_MINOR_BASE);
 out:
 	return rv;
+err3:
+	usb_set_intfdata(intf, NULL);
+	usb_buffer_free(interface_to_usbdev(desc->intf),
+			desc->bMaxPacketSize0,
+			desc->inbuf,
+			desc->response->transfer_dma);
 err2:
 	usb_buffer_free(interface_to_usbdev(desc->intf),
 			desc->wMaxPacketSize,
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index cadb2dc1d28a..3ba2fff71490 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -119,7 +119,7 @@ void *hcd_buffer_alloc(
 		if (size <= pool_max [i])
 			return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
 	}
-	return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
+	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
 }
 
 void hcd_buffer_free(
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index df3c539f652a..308609039c73 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)
 	ret = checkintf(ps, ret);
 	if (ret)
 		return ret;
-	usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0);
+	usb_reset_endpoint(ps->dev, ep);
 	return 0;
 }
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 81fa8506825d..42b93da1085d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev,
 		hcd->driver->endpoint_disable(hcd, ep);
 }
 
+/**
+ * usb_hcd_reset_endpoint - reset host endpoint state
+ * @udev: USB device.
+ * @ep:   the endpoint to reset.
+ *
+ * Resets any host endpoint state such as the toggle bit, sequence
+ * number and current window.
+ */
+void usb_hcd_reset_endpoint(struct usb_device *udev,
+			    struct usb_host_endpoint *ep)
+{
+	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+
+	if (hcd->driver->endpoint_reset)
+		hcd->driver->endpoint_reset(hcd, ep);
+	else {
+		int epnum = usb_endpoint_num(&ep->desc);
+		int is_out = usb_endpoint_dir_out(&ep->desc);
+		int is_control = usb_endpoint_xfer_control(&ep->desc);
+
+		usb_settoggle(udev, epnum, is_out, 0);
+		if (is_control)
+			usb_settoggle(udev, epnum, !is_out, 0);
+	}
+}
+
 /* Protect against drivers that try to unlink URBs after the device
  * is gone, by waiting until all unlinks for @udev are finished.
  * Since we don't currently track URBs by device, simply wait until
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index f750eb1ab595..e7d4479de41c 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -206,6 +206,11 @@ struct hc_driver {
 	void 	(*endpoint_disable)(struct usb_hcd *hcd,
 			struct usb_host_endpoint *ep);
 
+	/* (optional) reset any endpoint state such as sequence number
+	   and current window */
+	void 	(*endpoint_reset)(struct usb_hcd *hcd,
+			struct usb_host_endpoint *ep);
+
 	/* root hub support */
 	int	(*hub_status_data) (struct usb_hcd *hcd, char *buf);
 	int	(*hub_control) (struct usb_hcd *hcd,
@@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
 		struct usb_host_endpoint *ep);
 extern void usb_hcd_disable_endpoint(struct usb_device *udev,
 		struct usb_host_endpoint *ep);
+extern void usb_hcd_reset_endpoint(struct usb_device *udev,
+		struct usb_host_endpoint *ep);
 extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
 extern int usb_hcd_get_frame_number(struct usb_device *udev);
 
@@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
 extern void usb_hc_died(struct usb_hcd *hcd);
 extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
 
+/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
+#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
+#define	usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << (ep)))
+#define usb_settoggle(dev, ep, out, bit) \
+		((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
+		 ((bit) << (ep)))
+
 /* -------------------------------------------------------------------------- */
 
 /* Enumeration is only for the hub driver, or HCD virtual root hubs */
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 30a0690f3683..b62628377654 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
 	 * the copy in usb-storage, for as long as we need two copies.
 	 */
 
-	/* toggle was reset by the clear */
-	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+	usb_reset_endpoint(dev, endp);
 
 	return 0;
 }
@@ -1076,6 +1075,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
 }
 
 /**
+ * usb_reset_endpoint - Reset an endpoint's state.
+ * @dev: the device whose endpoint is to be reset
+ * @epaddr: the endpoint's address.  Endpoint number for output,
+ *	endpoint number + USB_DIR_IN for input
+ *
+ * Resets any host-side endpoint state such as the toggle bit,
+ * sequence number or current window.
+ */
+void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr)
+{
+	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+	struct usb_host_endpoint *ep;
+
+	if (usb_endpoint_out(epaddr))
+		ep = dev->ep_out[epnum];
+	else
+		ep = dev->ep_in[epnum];
+	if (ep)
+		usb_hcd_reset_endpoint(dev, ep);
+}
+EXPORT_SYMBOL_GPL(usb_reset_endpoint);
+
+
+/**
  * usb_disable_interface -- Disable all endpoints for an interface
  * @dev: the device whose interface is being disabled
  * @intf: pointer to the interface descriptor
@@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
 		usb_disable_endpoint(dev, i, true);
 		usb_disable_endpoint(dev, i + USB_DIR_IN, true);
 	}
-	dev->toggle[0] = dev->toggle[1] = 0;
 
 	/* getting rid of interfaces will disconnect
 	 * any drivers bound to them (a key side effect)
@@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
  * usb_enable_endpoint - Enable an endpoint for USB communications
  * @dev: the device whose interface is being enabled
  * @ep: the endpoint
- * @reset_toggle: flag to set the endpoint's toggle back to 0
+ * @reset_ep: flag to reset the endpoint state
  *
- * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
+ * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers.
  * For control endpoints, both the input and output sides are handled.
  */
 void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
-		bool reset_toggle)
+		bool reset_ep)
 {
 	int epnum = usb_endpoint_num(&ep->desc);
 	int is_out = usb_endpoint_dir_out(&ep->desc);
 	int is_control = usb_endpoint_xfer_control(&ep->desc);
 
-	if (is_out || is_control) {
-		if (reset_toggle)
-			usb_settoggle(dev, epnum, 1, 0);
+	if (reset_ep)
+		usb_hcd_reset_endpoint(dev, ep);
+	if (is_out || is_control)
 		dev->ep_out[epnum] = ep;
-	}
-	if (!is_out || is_control) {
-		if (reset_toggle)
-			usb_settoggle(dev, epnum, 0, 0);
+	if (!is_out || is_control)
 		dev->ep_in[epnum] = ep;
-	}
 	ep->enabled = 1;
 }
 
@@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
  * usb_enable_interface - Enable all the endpoints for an interface
  * @dev: the device whose interface is being enabled
  * @intf: pointer to the interface descriptor
- * @reset_toggles: flag to set the endpoints' toggles back to 0
+ * @reset_eps: flag to reset the endpoints' state
  *
  * Enables all the endpoints for the interface's current altsetting.
  */
 void usb_enable_interface(struct usb_device *dev,
-		struct usb_interface *intf, bool reset_toggles)
+		struct usb_interface *intf, bool reset_eps)
 {
 	struct usb_host_interface *alt = intf->cur_altsetting;
 	int i;
 
 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
-		usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
+		usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps);
 }
 
 /**
@@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
  * This issues a standard SET_CONFIGURATION request to the device using
  * the current configuration.  The effect is to reset most USB-related
  * state in the device, including interface altsettings (reset to zero),
- * endpoint halts (cleared), and data toggle (only for bulk and interrupt
+ * endpoint halts (cleared), and endpoint state (only for bulk and interrupt
  * endpoints).  Other usbcore state is unchanged, including bindings of
  * usb device drivers to interfaces.
  *
@@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
  * (multi-interface) devices.  Instead, the driver for each interface may
  * use usb_set_interface() on the interfaces it claims.  Be careful though;
  * some devices don't support the SET_INTERFACE request, and others won't
- * reset all the interface state (notably data toggles).  Resetting the whole
+ * reset all the interface state (notably endpoint state).  Resetting the whole
  * configuration would affect other drivers' interfaces.
  *
  * The caller must own the device lock.
@@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev)
 	if (retval < 0)
 		return retval;
 
-	dev->toggle[0] = dev->toggle[1] = 0;
-
 	/* re-init hc/hcd interface/endpoint state */
 	for (i = 0; i < config->desc.bNumInterfaces; i++) {
 		struct usb_interface *intf = config->interface[i];
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index dcfc072630c1..7eee400d3e32 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
 	dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
 	/* ep0 maxpacket comes later, from device descriptor */
-	usb_enable_endpoint(dev, &dev->ep0, true);
+	usb_enable_endpoint(dev, &dev->ep0, false);
 	dev->can_submit = 1;
 
 	/* Save readable and stable topology id, distinguishing devices
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 22c65960c429..38e531ecae4d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -51,6 +51,7 @@
  * - Gadget API (majority of optional features)
  * - Suspend & Remote Wakeup
  */
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
@@ -142,7 +143,7 @@ static struct {
 #define CAP_DEVICEADDR      (0x014UL)
 #define CAP_ENDPTLISTADDR   (0x018UL)
 #define CAP_PORTSC          (0x044UL)
-#define CAP_DEVLC           (0x0B4UL)
+#define CAP_DEVLC           (0x084UL)
 #define CAP_USBMODE         (hw_bank.lpm ? 0x0C8UL : 0x068UL)
 #define CAP_ENDPTSETUPSTAT  (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
 #define CAP_ENDPTPRIME      (hw_bank.lpm ? 0x0DCUL : 0x070UL)
@@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep,
 	do {
 		dbg_event(_usb_addr(mEp), "ENABLE", 0);
 
+		mEp->qh[mEp->dir].ptr->cap = 0;
+
 		if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
 			mEp->qh[mEp->dir].ptr->cap |=  QH_IOS;
 		else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 5c030b080d4c..381a53b3e11c 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -738,7 +738,6 @@ static struct fsg_dev			*the_fsg;
 static struct usb_gadget_driver		fsg_driver;
 
 static void	close_backing_file(struct lun *curlun);
-static void	close_all_backing_files(struct fsg_dev *fsg);
 
 
 /*-------------------------------------------------------------------------*/
@@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_)
 	fsg->thread_task = NULL;
 	spin_unlock_irq(&fsg->lock);
 
-	/* In case we are exiting because of a signal, unregister the
-	 * gadget driver and close the backing file. */
-	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
+	/* If we are exiting because of a signal, unregister the
+	 * gadget driver. */
+	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
 		usb_gadget_unregister_driver(&fsg_driver);
-		close_all_backing_files(fsg);
-	}
 
 	/* Let the unbind and cleanup routines know the thread has exited */
 	complete_and_exit(&fsg->thread_notifier, 0);
@@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun)
 	}
 }
 
-static void close_all_backing_files(struct fsg_dev *fsg)
-{
-	int	i;
-
-	for (i = 0; i < fsg->nluns; ++i)
-		close_backing_file(&fsg->luns[i]);
-}
-
 
 static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
 		if (curlun->registered) {
 			device_remove_file(&curlun->dev, &dev_attr_ro);
 			device_remove_file(&curlun->dev, &dev_attr_file);
+			close_backing_file(curlun);
 			device_unregister(&curlun->dev);
 			curlun->registered = 0;
 		}
@@ -4190,7 +4180,6 @@ autoconf_fail:
 out:
 	fsg->state = FSG_STATE_TERMINATED;	// The thread is dead
 	fsg_unbind(gadget);
-	close_all_backing_files(fsg);
 	complete(&fsg->thread_notifier);
 	return rc;
 }
@@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void)
 	/* Wait for the thread to finish up */
 	wait_for_completion(&fsg->thread_notifier);
 
-	close_all_backing_files(fsg);
 	kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 57d9641c6bf8..a2db0e174f2c 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev)
 /*-------------------------------------------------------------------------*/
 
 static struct platform_driver udc_driver = {
-	.probe		= omap_udc_probe,
 	.remove		= __exit_p(omap_udc_remove),
 	.suspend	= omap_udc_suspend,
 	.resume		= omap_udc_resume,
@@ -3122,7 +3121,7 @@ static int __init udc_init(void)
 #endif
 		"%s\n", driver_desc,
 		use_dma ?  " (dma)" : "");
-	return platform_driver_register(&udc_driver);
+	return platform_driver_probe(&udc_driver, omap_udc_probe);
 }
 module_init(udc_init);
 
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 96d65ca06ecd..4007770f7ed2 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
 	strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
 }
 
-static u32 eth_get_link(struct net_device *net)
-{
-	struct eth_dev	*dev = netdev_priv(net);
-	return dev->gadget->speed != USB_SPEED_UNKNOWN;
-}
-
 /* REVISIT can also support:
  *   - WOL (by tracking suspends and issuing remote wakeup)
  *   - msglevel (implies updated messaging)
@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net)
 
 static struct ethtool_ops ops = {
 	.get_drvinfo = eth_get_drvinfo,
-	.get_link = eth_get_link
+	.get_link = ethtool_op_get_link,
 };
 
 static void defer_kevent(struct eth_dev *dev, int flag)
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index ada5d2ba297b..556d0ec0c1f8 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -323,7 +323,7 @@ static int tt_available (
 		 * already scheduled transactions
 		 */
 		if (125 < usecs) {
-			int ufs = (usecs / 125) - 1;
+			int ufs = (usecs / 125);
 			int i;
 			for (i = uframe; i < (uframe + ufs) && i < 8; i++)
 				if (0 < tt_usecs[i]) {
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 4ed228a89943..bb5e6f671578 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -280,7 +280,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 		 * are always powered while this driver is active, and use
 		 * active-low power switches.
 		 */
-		for (i = 0; i < pdata->ports; i++) {
+		for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
 			if (pdata->vbus_pin[i] <= 0)
 				continue;
 			gpio_request(pdata->vbus_pin[i], "ohci_vbus");
@@ -298,7 +298,7 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
 	int			i;
 
 	if (pdata) {
-		for (i = 0; i < pdata->ports; i++) {
+		for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
 			if (pdata->vbus_pin[i] <= 0)
 				continue;
 			gpio_direction_output(pdata->vbus_pin[i], 1);
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 958751ccea43..c2050785a819 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -122,7 +122,8 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
 		process_inactive_qtd(whc, qset, td);
 	}
 
-	update |= qset_add_qtds(whc, qset);
+	if (!qset->remove)
+		update |= qset_add_qtds(whc, qset);
 
 done:
 	/*
@@ -254,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
 
 	spin_lock_irqsave(&whc->lock, flags);
 
+	err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
+	if (err < 0) {
+		spin_unlock_irqrestore(&whc->lock, flags);
+		return err;
+	}
+
 	qset = get_qset(whc, urb, GFP_ATOMIC);
 	if (qset == NULL)
 		err = -ENOMEM;
 	else
 		err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
 	if (!err) {
-		usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
 		if (!qset->in_sw_list)
 			asl_qset_insert_begin(whc, qset);
-	}
+	} else
+		usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
 
 	spin_unlock_irqrestore(&whc->lock, flags);
 
 	if (!err)
 		queue_work(whc->workqueue, &whc->async_work);
 
-	return 0;
+	return err;
 }
 
 /**
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 1569afd6245b..e019a5058ab8 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -186,6 +186,28 @@ static void whc_endpoint_disable(struct usb_hcd *usb_hcd,
 	}
 }
 
+static void whc_endpoint_reset(struct usb_hcd *usb_hcd,
+			       struct usb_host_endpoint *ep)
+{
+	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
+	struct whc *whc = wusbhc_to_whc(wusbhc);
+	struct whc_qset *qset;
+
+	qset = ep->hcpriv;
+	if (qset) {
+		qset->remove = 1;
+
+		if (usb_endpoint_xfer_bulk(&ep->desc)
+		    || usb_endpoint_xfer_control(&ep->desc))
+			queue_work(whc->workqueue, &whc->async_work);
+		else
+			queue_work(whc->workqueue, &whc->periodic_work);
+
+		qset_reset(whc, qset);
+	}
+}
+
+
 static struct hc_driver whc_hc_driver = {
 	.description = "whci-hcd",
 	.product_desc = "Wireless host controller",
@@ -200,6 +222,7 @@ static struct hc_driver whc_hc_driver = {
 	.urb_enqueue = whc_urb_enqueue,
 	.urb_dequeue = whc_urb_dequeue,
 	.endpoint_disable = whc_endpoint_disable,
+	.endpoint_reset = whc_endpoint_reset,
 
 	.hub_status_data = wusbhc_rh_status_data,
 	.hub_control = wusbhc_rh_control,
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index df8b85f07092..ff4ef9e910d9 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -128,7 +128,8 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
 		process_inactive_qtd(whc, qset, td);
 	}
 
-	update |= qset_add_qtds(whc, qset);
+	if (!qset->remove)
+		update |= qset_add_qtds(whc, qset);
 
 done:
 	/*
@@ -282,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
 
 	spin_lock_irqsave(&whc->lock, flags);
 
+	err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
+	if (err < 0) {
+		spin_unlock_irqrestore(&whc->lock, flags);
+		return err;
+	}
+
 	qset = get_qset(whc, urb, GFP_ATOMIC);
 	if (qset == NULL)
 		err = -ENOMEM;
 	else
 		err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
 	if (!err) {
-		usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
 		if (!qset->in_sw_list)
 			qset_insert_in_sw_list(whc, qset);
-	}
+	} else
+		usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
 
 	spin_unlock_irqrestore(&whc->lock, flags);
 
 	if (!err)
 		queue_work(whc->workqueue, &whc->periodic_work);
 
-	return 0;
+	return err;
 }
 
 /**
@@ -353,7 +360,6 @@ void pzl_qset_delete(struct whc *whc, struct whc_qset *qset)
 	qset_delete(whc, qset);
 }
 
-
 /**
  * pzl_init - initialize the periodic zone list
  * @whc: the WHCI host controller
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 7be74314ee12..640b38fbd051 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -89,11 +89,16 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
 		QH_INFO3_TX_RATE_53_3
 		| QH_INFO3_TX_PWR(0) /* 0 == max power */
 		);
+
+	qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
 }
 
 /**
  * qset_clear - clear fields in a qset so it may be reinserted into a
- * schedule
+ * schedule.
+ *
+ * The sequence number and current window are not cleared (see
+ * qset_reset()).
  */
 void qset_clear(struct whc *whc, struct whc_qset *qset)
 {
@@ -101,9 +106,8 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
 	qset->remove = 0;
 
 	qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
-	qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start));
+	qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
 	qset->qh.err_count = 0;
-	qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
 	qset->qh.scratch[0] = 0;
 	qset->qh.scratch[1] = 0;
 	qset->qh.scratch[2] = 0;
@@ -114,6 +118,20 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
 }
 
 /**
+ * qset_reset - reset endpoint state in a qset.
+ *
+ * Clears the sequence number and current window.  This qset must not
+ * be in the ASL or PZL.
+ */
+void qset_reset(struct whc *whc, struct whc_qset *qset)
+{
+	wait_for_completion(&qset->remove_complete);
+
+	qset->qh.status &= ~QH_STATUS_SEQ_MASK;
+	qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1);
+}
+
+/**
  * get_qset - get the qset for an async endpoint
  *
  * A new qset is created if one does not already exist.
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index d3543a181dc9..24e94d983c5e 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -184,6 +184,7 @@ void qset_free(struct whc *whc, struct whc_qset *qset);
 struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags);
 void qset_delete(struct whc *whc, struct whc_qset *qset);
 void qset_clear(struct whc *whc, struct whc_qset *qset);
+void qset_reset(struct whc *whc, struct whc_qset *qset);
 int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
 		 gfp_t mem_flags);
 void qset_free_std(struct whc *whc, struct whc_std *std);
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
index 51df7e313b38..794dba0d0f0a 100644
--- a/drivers/usb/host/whci/whci-hc.h
+++ b/drivers/usb/host/whci/whci-hc.h
@@ -185,6 +185,7 @@ struct whc_qhead {
 #define QH_STATUS_FLOW_CTRL      (1 << 15)
 #define QH_STATUS_ICUR(i)        ((i) << 5)
 #define QH_STATUS_TO_ICUR(s)     (((s) >> 5) & 0x7)
+#define QH_STATUS_SEQ_MASK       0x1f
 
 /**
  * usb_pipe_to_qh_type - USB core pipe type to QH transfer type
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 569ef0fed0f6..1976e9b41800 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -579,6 +579,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)
 	 * trigger the "send a ZLP?" confusion.
 	 */
 	rndis = (maxpacket & 0x3f) == 0
+		&& length > maxpacket
 		&& length < 0xffff
 		&& (length % maxpacket) != 0;
 
@@ -1228,27 +1229,7 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx)
 
 				hw_ep = tx_ch->hw_ep;
 
-				/* Peripheral role never repurposes the
-				 * endpoint, so immediate completion is
-				 * safe.  Host role waits for the fifo
-				 * to empty (TXPKTRDY irq) before going
-				 * to the next queued bulk transfer.
-				 */
-				if (is_host_active(cppi->musb)) {
-#if 0
-					/* WORKAROUND because we may
-					 * not always get TXKPTRDY ...
-					 */
-					int	csr;
-
-					csr = musb_readw(hw_ep->regs,
-						MUSB_TXCSR);
-					if (csr & MUSB_TXCSR_TXPKTRDY)
-#endif
-						completed = false;
-				}
-				if (completed)
-					musb_dma_completion(musb, index + 1, 1);
+				musb_dma_completion(musb, index + 1, 1);
 
 			} else {
 				/* Bigger transfer than we could fit in
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 338cd1611ab3..4000cf6d1e81 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2170,32 +2170,28 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
 	return 0;
 }
 
-static int musb_resume(struct platform_device *pdev)
+static int musb_resume_early(struct platform_device *pdev)
 {
-	unsigned long	flags;
 	struct musb	*musb = dev_to_musb(&pdev->dev);
 
 	if (!musb->clock)
 		return 0;
 
-	spin_lock_irqsave(&musb->lock, flags);
-
 	if (musb->set_clock)
 		musb->set_clock(musb->clock, 1);
 	else
 		clk_enable(musb->clock);
 
 	/* for static cmos like DaVinci, register values were preserved
-	 * unless for some reason the whole soc powered down and we're
-	 * not treating that as a whole-system restart (e.g. swsusp)
+	 * unless for some reason the whole soc powered down or the USB
+	 * module got reset through the PSC (vs just being disabled).
 	 */
-	spin_unlock_irqrestore(&musb->lock, flags);
 	return 0;
 }
 
 #else
 #define	musb_suspend	NULL
-#define	musb_resume	NULL
+#define	musb_resume_early	NULL
 #endif
 
 static struct platform_driver musb_driver = {
@@ -2207,7 +2203,7 @@ static struct platform_driver musb_driver = {
 	.remove		= __devexit_p(musb_remove),
 	.shutdown	= musb_shutdown,
 	.suspend	= musb_suspend,
-	.resume		= musb_resume,
+	.resume_early	= musb_resume_early,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index c7ebd0867fcc..f79440cdfe7e 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status)
 	if (is_dma_capable() && ep->dma) {
 		struct dma_controller	*c = ep->musb->dma_controller;
 		int value;
+
 		if (ep->is_in) {
+			/*
+			 * The programming guide says that we must not clear
+			 * the DMAMODE bit before DMAENAB, so we only
+			 * clear it in the second write...
+			 */
 			musb_writew(epio, MUSB_TXCSR,
-					0 | MUSB_TXCSR_FLUSHFIFO);
+				    MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
 			musb_writew(epio, MUSB_TXCSR,
 					0 | MUSB_TXCSR_FLUSHFIFO);
 		} else {
@@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
 		  |	IN token(s) are recd from Host.
 		  |		-> DMA interrupt on completion
 		  |		   calls TxAvail.
-		  |		      -> stop DMA, ~DmaEenab,
+		  |		      -> stop DMA, ~DMAENAB,
 		  |		      -> set TxPktRdy for last short pkt or zlp
 		  |		      -> Complete Request
 		  |		      -> Continue next request (call txstate)
@@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req)
 					request->dma, request_size);
 			if (use_dma) {
 				if (musb_ep->dma->desired_mode == 0) {
-					/* ASSERT: DMAENAB is clear */
-					csr &= ~(MUSB_TXCSR_AUTOSET |
-							MUSB_TXCSR_DMAMODE);
+					/*
+					 * We must not clear the DMAMODE bit
+					 * before the DMAENAB bit -- and the
+					 * latter doesn't always get cleared
+					 * before we get here...
+					 */
+					csr &= ~(MUSB_TXCSR_AUTOSET
+						| MUSB_TXCSR_DMAENAB);
+					musb_writew(epio, MUSB_TXCSR, csr
+						| MUSB_TXCSR_P_WZC_BITS);
+					csr &= ~MUSB_TXCSR_DMAMODE;
 					csr |= (MUSB_TXCSR_DMAENAB |
 							MUSB_TXCSR_MODE);
 					/* against programming guide */
@@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
 
 #elif defined(CONFIG_USB_TI_CPPI_DMA)
 		/* program endpoint CSR first, then setup DMA */
-		csr &= ~(MUSB_TXCSR_AUTOSET
-				| MUSB_TXCSR_DMAMODE
-				| MUSB_TXCSR_P_UNDERRUN
-				| MUSB_TXCSR_TXPKTRDY);
+		csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
 		csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
 		musb_writew(epio, MUSB_TXCSR,
 			(MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
@@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req)
 		if (!use_dma) {
 			c->channel_release(musb_ep->dma);
 			musb_ep->dma = NULL;
-			/* ASSERT: DMAENAB clear */
-			csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
+			csr &= ~MUSB_TXCSR_DMAENAB;
+			musb_writew(epio, MUSB_TXCSR, csr);
 			/* invariant: prequest->buf is non-null */
 		}
 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 499c431a6d62..db1b57415ec7 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -4,6 +4,7 @@
  * Copyright 2005 Mentor Graphics Corporation
  * Copyright (C) 2005-2006 by Texas Instruments
  * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -96,8 +97,8 @@
 
 
 static void musb_ep_program(struct musb *musb, u8 epnum,
-			struct urb *urb, unsigned int nOut,
-			u8 *buf, u32 len);
+			struct urb *urb, int is_out,
+			u8 *buf, u32 offset, u32 len);
 
 /*
  * Clear TX fifo. Needed to avoid BABBLE errors.
@@ -125,6 +126,29 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
 	}
 }
 
+static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep)
+{
+	void __iomem	*epio = ep->regs;
+	u16		csr;
+	int		retries = 5;
+
+	/* scrub any data left in the fifo */
+	do {
+		csr = musb_readw(epio, MUSB_TXCSR);
+		if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY)))
+			break;
+		musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO);
+		csr = musb_readw(epio, MUSB_TXCSR);
+		udelay(10);
+	} while (--retries);
+
+	WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n",
+			ep->epnum, csr);
+
+	/* and reset for the next transfer */
+	musb_writew(epio, MUSB_TXCSR, 0);
+}
+
 /*
  * Start transmit. Caller is responsible for locking shared resources.
  * musb must be locked.
@@ -145,13 +169,15 @@ static inline void musb_h_tx_start(struct musb_hw_ep *ep)
 
 }
 
-static inline void cppi_host_txdma_start(struct musb_hw_ep *ep)
+static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep)
 {
 	u16	txcsr;
 
 	/* NOTE: no locks here; caller should lock and select EP */
 	txcsr = musb_readw(ep->regs, MUSB_TXCSR);
 	txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
+	if (is_cppi_enabled())
+		txcsr |= MUSB_TXCSR_DMAMODE;
 	musb_writew(ep->regs, MUSB_TXCSR, txcsr);
 }
 
@@ -166,9 +192,10 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
 {
 	u16			frame;
 	u32			len;
-	void			*buf;
 	void __iomem		*mbase =  musb->mregs;
 	struct urb		*urb = next_urb(qh);
+	void			*buf = urb->transfer_buffer;
+	u32			offset = 0;
 	struct musb_hw_ep	*hw_ep = qh->hw_ep;
 	unsigned		pipe = urb->pipe;
 	u8			address = usb_pipedevice(pipe);
@@ -191,7 +218,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
 	case USB_ENDPOINT_XFER_ISOC:
 		qh->iso_idx = 0;
 		qh->frame = 0;
-		buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset;
+		offset = urb->iso_frame_desc[0].offset;
 		len = urb->iso_frame_desc[0].length;
 		break;
 	default:		/* bulk, interrupt */
@@ -209,14 +236,14 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
 			case USB_ENDPOINT_XFER_ISOC:	s = "-iso"; break;
 			default:			s = "-intr"; break;
 			}; s; }),
-			epnum, buf, len);
+			epnum, buf + offset, len);
 
 	/* Configure endpoint */
 	if (is_in || hw_ep->is_shared_fifo)
 		hw_ep->in_qh = qh;
 	else
 		hw_ep->out_qh = qh;
-	musb_ep_program(musb, epnum, urb, !is_in, buf, len);
+	musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len);
 
 	/* transmit may have more work: start it when it is time */
 	if (is_in)
@@ -227,7 +254,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
 	case USB_ENDPOINT_XFER_ISOC:
 	case USB_ENDPOINT_XFER_INT:
 		DBG(3, "check whether there's still time for periodic Tx\n");
-		qh->iso_idx = 0;
 		frame = musb_readw(mbase, MUSB_FRAME);
 		/* FIXME this doesn't implement that scheduling policy ...
 		 * or handle framecounter wrapping
@@ -256,7 +282,7 @@ start:
 		if (!hw_ep->tx_channel)
 			musb_h_tx_start(hw_ep);
 		else if (is_cppi_enabled() || tusb_dma_omap())
-			cppi_host_txdma_start(hw_ep);
+			musb_h_tx_dma_start(hw_ep);
 	}
 }
 
@@ -567,10 +593,17 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 		csr = musb_readw(ep->regs, MUSB_TXCSR);
 		if (csr & MUSB_TXCSR_MODE) {
 			musb_h_tx_flush_fifo(ep);
+			csr = musb_readw(ep->regs, MUSB_TXCSR);
 			musb_writew(ep->regs, MUSB_TXCSR,
-					MUSB_TXCSR_FRCDATATOG);
+				    csr | MUSB_TXCSR_FRCDATATOG);
 		}
-		/* clear mode (and everything else) to enable Rx */
+
+		/*
+		 * Clear the MODE bit (and everything else) to enable Rx.
+		 * NOTE: we mustn't clear the DMAMODE bit before DMAENAB.
+		 */
+		if (csr & MUSB_TXCSR_DMAMODE)
+			musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE);
 		musb_writew(ep->regs, MUSB_TXCSR, 0);
 
 	/* scrub all previous state, clearing toggle */
@@ -601,14 +634,68 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 	ep->rx_reinit = 0;
 }
 
+static bool musb_tx_dma_program(struct dma_controller *dma,
+		struct musb_hw_ep *hw_ep, struct musb_qh *qh,
+		struct urb *urb, u32 offset, u32 length)
+{
+	struct dma_channel	*channel = hw_ep->tx_channel;
+	void __iomem		*epio = hw_ep->regs;
+	u16			pkt_size = qh->maxpacket;
+	u16			csr;
+	u8			mode;
+
+#ifdef	CONFIG_USB_INVENTRA_DMA
+	if (length > channel->max_len)
+		length = channel->max_len;
+
+	csr = musb_readw(epio, MUSB_TXCSR);
+	if (length > pkt_size) {
+		mode = 1;
+		csr |= MUSB_TXCSR_AUTOSET
+			| MUSB_TXCSR_DMAMODE
+			| MUSB_TXCSR_DMAENAB;
+	} else {
+		mode = 0;
+		csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE);
+		csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */
+	}
+	channel->desired_mode = mode;
+	musb_writew(epio, MUSB_TXCSR, csr);
+#else
+	if (!is_cppi_enabled() && !tusb_dma_omap())
+		return false;
+
+	channel->actual_len = 0;
+
+	/*
+	 * TX uses "RNDIS" mode automatically but needs help
+	 * to identify the zero-length-final-packet case.
+	 */
+	mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0;
+#endif
+
+	qh->segsize = length;
+
+	if (!dma->channel_program(channel, pkt_size, mode,
+			urb->transfer_dma + offset, length)) {
+		dma->channel_release(channel);
+		hw_ep->tx_channel = NULL;
+
+		csr = musb_readw(epio, MUSB_TXCSR);
+		csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
+		musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS);
+		return false;
+	}
+	return true;
+}
 
 /*
  * Program an HDRC endpoint as per the given URB
  * Context: irqs blocked, controller lock held
  */
 static void musb_ep_program(struct musb *musb, u8 epnum,
-			struct urb *urb, unsigned int is_out,
-			u8 *buf, u32 len)
+			struct urb *urb, int is_out,
+			u8 *buf, u32 offset, u32 len)
 {
 	struct dma_controller	*dma_controller;
 	struct dma_channel	*dma_channel;
@@ -667,12 +754,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
 		/* general endpoint setup */
 		if (epnum) {
-			/* ASSERT:  TXCSR_DMAENAB was already cleared */
-
 			/* flush all old state, set default */
 			musb_h_tx_flush_fifo(hw_ep);
+
+			/*
+			 * We must not clear the DMAMODE bit before or in
+			 * the same cycle with the DMAENAB bit, so we clear
+			 * the latter first...
+			 */
 			csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
-					| MUSB_TXCSR_DMAMODE
+					| MUSB_TXCSR_AUTOSET
+					| MUSB_TXCSR_DMAENAB
 					| MUSB_TXCSR_FRCDATATOG
 					| MUSB_TXCSR_H_RXSTALL
 					| MUSB_TXCSR_H_ERROR
@@ -680,24 +772,20 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 					);
 			csr |= MUSB_TXCSR_MODE;
 
-			if (usb_gettoggle(urb->dev,
-					qh->epnum, 1))
+			if (usb_gettoggle(urb->dev, qh->epnum, 1))
 				csr |= MUSB_TXCSR_H_WR_DATATOGGLE
 					| MUSB_TXCSR_H_DATATOGGLE;
 			else
 				csr |= MUSB_TXCSR_CLRDATATOG;
 
-			/* twice in case of double packet buffering */
 			musb_writew(epio, MUSB_TXCSR, csr);
 			/* REVISIT may need to clear FLUSHFIFO ... */
+			csr &= ~MUSB_TXCSR_DMAMODE;
 			musb_writew(epio, MUSB_TXCSR, csr);
 			csr = musb_readw(epio, MUSB_TXCSR);
 		} else {
 			/* endpoint 0: just flush */
-			musb_writew(epio, MUSB_CSR0,
-				csr | MUSB_CSR0_FLUSHFIFO);
-			musb_writew(epio, MUSB_CSR0,
-				csr | MUSB_CSR0_FLUSHFIFO);
+			musb_h_ep0_flush_fifo(hw_ep);
 		}
 
 		/* target addr and (for multipoint) hub addr/port */
@@ -734,113 +822,14 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 		else
 			load_count = min((u32) packet_sz, len);
 
-#ifdef CONFIG_USB_INVENTRA_DMA
-		if (dma_channel) {
-
-			/* clear previous state */
-			csr = musb_readw(epio, MUSB_TXCSR);
-			csr &= ~(MUSB_TXCSR_AUTOSET
-				| MUSB_TXCSR_DMAMODE
-				| MUSB_TXCSR_DMAENAB);
-			csr |= MUSB_TXCSR_MODE;
-			musb_writew(epio, MUSB_TXCSR,
-				csr | MUSB_TXCSR_MODE);
-
-			qh->segsize = min(len, dma_channel->max_len);
-
-			if (qh->segsize <= packet_sz)
-				dma_channel->desired_mode = 0;
-			else
-				dma_channel->desired_mode = 1;
-
-
-			if (dma_channel->desired_mode == 0) {
-				csr &= ~(MUSB_TXCSR_AUTOSET
-					| MUSB_TXCSR_DMAMODE);
-				csr |= (MUSB_TXCSR_DMAENAB);
-					/* against programming guide */
-			} else
-				csr |= (MUSB_TXCSR_AUTOSET
-					| MUSB_TXCSR_DMAENAB
-					| MUSB_TXCSR_DMAMODE);
-
-			musb_writew(epio, MUSB_TXCSR, csr);
-
-			dma_ok = dma_controller->channel_program(
-					dma_channel, packet_sz,
-					dma_channel->desired_mode,
-					urb->transfer_dma,
-					qh->segsize);
-			if (dma_ok) {
-				load_count = 0;
-			} else {
-				dma_controller->channel_release(dma_channel);
-				if (is_out)
-					hw_ep->tx_channel = NULL;
-				else
-					hw_ep->rx_channel = NULL;
-				dma_channel = NULL;
-			}
-		}
-#endif
-
-		/* candidate for DMA */
-		if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
-
-			/* program endpoint CSRs first, then setup DMA.
-			 * assume CPPI setup succeeds.
-			 * defer enabling dma.
-			 */
-			csr = musb_readw(epio, MUSB_TXCSR);
-			csr &= ~(MUSB_TXCSR_AUTOSET
-					| MUSB_TXCSR_DMAMODE
-					| MUSB_TXCSR_DMAENAB);
-			csr |= MUSB_TXCSR_MODE;
-			musb_writew(epio, MUSB_TXCSR,
-				csr | MUSB_TXCSR_MODE);
-
-			dma_channel->actual_len = 0L;
-			qh->segsize = len;
-
-			/* TX uses "rndis" mode automatically, but needs help
-			 * to identify the zero-length-final-packet case.
-			 */
-			dma_ok = dma_controller->channel_program(
-					dma_channel, packet_sz,
-					(urb->transfer_flags
-							& URB_ZERO_PACKET)
-						== URB_ZERO_PACKET,
-					urb->transfer_dma,
-					qh->segsize);
-			if (dma_ok) {
-				load_count = 0;
-			} else {
-				dma_controller->channel_release(dma_channel);
-				hw_ep->tx_channel = NULL;
-				dma_channel = NULL;
-
-				/* REVISIT there's an error path here that
-				 * needs handling:  can't do dma, but
-				 * there's no pio buffer address...
-				 */
-			}
-		}
+		if (dma_channel && musb_tx_dma_program(dma_controller,
+					hw_ep, qh, urb, offset, len))
+			load_count = 0;
 
 		if (load_count) {
-			/* ASSERT:  TXCSR_DMAENAB was already cleared */
-
 			/* PIO to load FIFO */
 			qh->segsize = load_count;
 			musb_write_fifo(hw_ep, load_count, buf);
-			csr = musb_readw(epio, MUSB_TXCSR);
-			csr &= ~(MUSB_TXCSR_DMAENAB
-				| MUSB_TXCSR_DMAMODE
-				| MUSB_TXCSR_AUTOSET);
-			/* write CSR */
-			csr |= MUSB_TXCSR_MODE;
-
-			if (epnum)
-				musb_writew(epio, MUSB_TXCSR, csr);
 		}
 
 		/* re-enable interrupt */
@@ -895,7 +884,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 						dma_channel, packet_sz,
 						!(urb->transfer_flags
 							& URB_SHORT_NOT_OK),
-						urb->transfer_dma,
+						urb->transfer_dma + offset,
 						qh->segsize);
 				if (!dma_ok) {
 					dma_controller->channel_release(
@@ -1063,11 +1052,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
 			csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
 			musb_writew(epio, MUSB_CSR0, csr);
 		} else {
-			csr |= MUSB_CSR0_FLUSHFIFO;
-			musb_writew(epio, MUSB_CSR0, csr);
-			musb_writew(epio, MUSB_CSR0, csr);
-			csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
-			musb_writew(epio, MUSB_CSR0, csr);
+			musb_h_ep0_flush_fifo(hw_ep);
 		}
 
 		musb_writeb(epio, MUSB_NAKLIMIT0, 0);
@@ -1081,10 +1066,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
 		 * SHOULD NEVER HAPPEN! */
 		ERR("no URB for end 0\n");
 
-		musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
-		musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
-		musb_writew(epio, MUSB_CSR0, 0);
-
+		musb_h_ep0_flush_fifo(hw_ep);
 		goto done;
 	}
 
@@ -1145,8 +1127,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 	int			pipe;
 	bool			done = false;
 	u16			tx_csr;
-	size_t			wLength = 0;
-	u8			*buf = NULL;
+	size_t			length = 0;
+	size_t			offset = 0;
 	struct urb		*urb;
 	struct musb_hw_ep	*hw_ep = musb->endpoints + epnum;
 	void __iomem		*epio = hw_ep->regs;
@@ -1164,7 +1146,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 	/* with CPPI, DMA sometimes triggers "extra" irqs */
 	if (!urb) {
 		DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
-		goto finish;
+		return;
 	}
 
 	pipe = urb->pipe;
@@ -1201,7 +1183,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 		musb_writew(epio, MUSB_TXCSR,
 				MUSB_TXCSR_H_WZC_BITS
 				| MUSB_TXCSR_TXPKTRDY);
-		goto finish;
+		return;
 	}
 
 	if (status) {
@@ -1233,29 +1215,89 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 	/* second cppi case */
 	if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
 		DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
-		goto finish;
+		return;
+	}
+
+	if (is_dma_capable() && dma && !status) {
+		/*
+		 * DMA has completed.  But if we're using DMA mode 1 (multi
+		 * packet DMA), we need a terminal TXPKTRDY interrupt before
+		 * we can consider this transfer completed, lest we trash
+		 * its last packet when writing the next URB's data.  So we
+		 * switch back to mode 0 to get that interrupt; we'll come
+		 * back here once it happens.
+		 */
+		if (tx_csr & MUSB_TXCSR_DMAMODE) {
+			/*
+			 * We shouldn't clear DMAMODE with DMAENAB set; so
+			 * clear them in a safe order.  That should be OK
+			 * once TXPKTRDY has been set (and I've never seen
+			 * it being 0 at this moment -- DMA interrupt latency
+			 * is significant) but if it hasn't been then we have
+			 * no choice but to stop being polite and ignore the
+			 * programmer's guide... :-)
+			 *
+			 * Note that we must write TXCSR with TXPKTRDY cleared
+			 * in order not to re-trigger the packet send (this bit
+			 * can't be cleared by CPU), and there's another caveat:
+			 * TXPKTRDY may be set shortly and then cleared in the
+			 * double-buffered FIFO mode, so we do an extra TXCSR
+			 * read for debouncing...
+			 */
+			tx_csr &= musb_readw(epio, MUSB_TXCSR);
+			if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
+				tx_csr &= ~(MUSB_TXCSR_DMAENAB |
+					    MUSB_TXCSR_TXPKTRDY);
+				musb_writew(epio, MUSB_TXCSR,
+					    tx_csr | MUSB_TXCSR_H_WZC_BITS);
+			}
+			tx_csr &= ~(MUSB_TXCSR_DMAMODE |
+				    MUSB_TXCSR_TXPKTRDY);
+			musb_writew(epio, MUSB_TXCSR,
+				    tx_csr | MUSB_TXCSR_H_WZC_BITS);
+
+			/*
+			 * There is no guarantee that we'll get an interrupt
+			 * after clearing DMAMODE as we might have done this
+			 * too late (after TXPKTRDY was cleared by controller).
+			 * Re-read TXCSR as we have spoiled its previous value.
+			 */
+			tx_csr = musb_readw(epio, MUSB_TXCSR);
+		}
 
+		/*
+		 * We may get here from a DMA completion or TXPKTRDY interrupt.
+		 * In any case, we must check the FIFO status here and bail out
+		 * only if the FIFO still has data -- that should prevent the
+		 * "missed" TXPKTRDY interrupts and deal with double-buffered
+		 * FIFO mode too...
+		 */
+		if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) {
+			DBG(2, "DMA complete but packet still in FIFO, "
+			    "CSR %04x\n", tx_csr);
+			return;
+		}
 	}
 
-	/* REVISIT this looks wrong... */
 	if (!status || dma || usb_pipeisoc(pipe)) {
 		if (dma)
-			wLength = dma->actual_len;
+			length = dma->actual_len;
 		else
-			wLength = qh->segsize;
-		qh->offset += wLength;
+			length = qh->segsize;
+		qh->offset += length;
 
 		if (usb_pipeisoc(pipe)) {
 			struct usb_iso_packet_descriptor	*d;
 
 			d = urb->iso_frame_desc + qh->iso_idx;
-			d->actual_length = qh->segsize;
+			d->actual_length = length;
+			d->status = status;
 			if (++qh->iso_idx >= urb->number_of_packets) {
 				done = true;
 			} else {
 				d++;
-				buf = urb->transfer_buffer + d->offset;
-				wLength = d->length;
+				offset = d->offset;
+				length = d->length;
 			}
 		} else if (dma) {
 			done = true;
@@ -1268,10 +1310,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 						& URB_ZERO_PACKET))
 				done = true;
 			if (!done) {
-				buf = urb->transfer_buffer
-						+ qh->offset;
-				wLength = urb->transfer_buffer_length
-						- qh->offset;
+				offset = qh->offset;
+				length = urb->transfer_buffer_length - offset;
 			}
 		}
 	}
@@ -1290,28 +1330,31 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 		urb->status = status;
 		urb->actual_length = qh->offset;
 		musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
+		return;
+	} else	if (usb_pipeisoc(pipe) && dma) {
+		if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
+				offset, length))
+			return;
+	} else	if (tx_csr & MUSB_TXCSR_DMAENAB) {
+		DBG(1, "not complete, but DMA enabled?\n");
+		return;
+	}
 
-	} else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) {
-		/* WARN_ON(!buf); */
-
-		/* REVISIT:  some docs say that when hw_ep->tx_double_buffered,
-		 * (and presumably, fifo is not half-full) we should write TWO
-		 * packets before updating TXCSR ... other docs disagree ...
-		 */
-		/* PIO:  start next packet in this URB */
-		if (wLength > qh->maxpacket)
-			wLength = qh->maxpacket;
-		musb_write_fifo(hw_ep, wLength, buf);
-		qh->segsize = wLength;
-
-		musb_ep_select(mbase, epnum);
-		musb_writew(epio, MUSB_TXCSR,
-				MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
-	} else
-		DBG(1, "not complete, but dma enabled?\n");
+	/*
+	 * PIO: start next packet in this URB.
+	 *
+	 * REVISIT: some docs say that when hw_ep->tx_double_buffered,
+	 * (and presumably, FIFO is not half-full) we should write *two*
+	 * packets before updating TXCSR; other docs disagree...
+	 */
+	if (length > qh->maxpacket)
+		length = qh->maxpacket;
+	musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset);
+	qh->segsize = length;
 
-finish:
-	return;
+	musb_ep_select(mbase, epnum);
+	musb_writew(epio, MUSB_TXCSR,
+			MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
 }
 
 
@@ -1841,7 +1884,7 @@ static int musb_urb_enqueue(
 	unsigned long			flags;
 	struct musb			*musb = hcd_to_musb(hcd);
 	struct usb_host_endpoint	*hep = urb->ep;
-	struct musb_qh			*qh = hep->hcpriv;
+	struct musb_qh			*qh;
 	struct usb_endpoint_descriptor	*epd = &hep->desc;
 	int				ret;
 	unsigned			type_reg;
@@ -1853,22 +1896,21 @@ static int musb_urb_enqueue(
 
 	spin_lock_irqsave(&musb->lock, flags);
 	ret = usb_hcd_link_urb_to_ep(hcd, urb);
+	qh = ret ? NULL : hep->hcpriv;
+	if (qh)
+		urb->hcpriv = qh;
 	spin_unlock_irqrestore(&musb->lock, flags);
-	if (ret)
-		return ret;
 
 	/* DMA mapping was already done, if needed, and this urb is on
-	 * hep->urb_list ... so there's little to do unless hep wasn't
-	 * yet scheduled onto a live qh.
+	 * hep->urb_list now ... so we're done, unless hep wasn't yet
+	 * scheduled onto a live qh.
 	 *
 	 * REVISIT best to keep hep->hcpriv valid until the endpoint gets
 	 * disabled, testing for empty qh->ring and avoiding qh setup costs
 	 * except for the first urb queued after a config change.
 	 */
-	if (qh) {
-		urb->hcpriv = qh;
-		return 0;
-	}
+	if (qh || ret)
+		return ret;
 
 	/* Allocate and initialize qh, minimizing the work done each time
 	 * hw_ep gets reprogrammed, or with irqs blocked.  Then schedule it.
@@ -2044,7 +2086,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
 		 * endpoint's irq status here to avoid bogus irqs.
 		 * clearing that status is platform-specific...
 		 */
-	} else {
+	} else if (ep->epnum) {
 		musb_h_tx_flush_fifo(ep);
 		csr = musb_readw(epio, MUSB_TXCSR);
 		csr &= ~(MUSB_TXCSR_AUTOSET
@@ -2058,6 +2100,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
 		musb_writew(epio, MUSB_TXCSR, csr);
 		/* flush cpu writebuffer */
 		csr = musb_readw(epio, MUSB_TXCSR);
+	} else  {
+		musb_h_ep0_flush_fifo(ep);
 	}
 	if (status == 0)
 		musb_advance_schedule(ep->musb, urb, ep, is_in);
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 8662e9e159c3..5e83f96d6b77 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel)
 	void __iomem *mbase = musb_channel->controller->base;
 
 	u8 bchannel = musb_channel->idx;
+	int offset;
 	u16 csr;
 
 	if (channel->status == MUSB_DMA_STATUS_BUSY) {
 		if (musb_channel->transmit) {
-
-			csr = musb_readw(mbase,
-				MUSB_EP_OFFSET(musb_channel->epnum,
-						MUSB_TXCSR));
-			csr &= ~(MUSB_TXCSR_AUTOSET |
-				 MUSB_TXCSR_DMAENAB |
-				 MUSB_TXCSR_DMAMODE);
-			musb_writew(mbase,
-				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
-				csr);
+			offset = MUSB_EP_OFFSET(musb_channel->epnum,
+						MUSB_TXCSR);
+
+			/*
+			 * The programming guide says that we must clear
+			 * the DMAENAB bit before the DMAMODE bit...
+			 */
+			csr = musb_readw(mbase, offset);
+			csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
+			musb_writew(mbase, offset, csr);
+			csr &= ~MUSB_TXCSR_DMAMODE;
+			musb_writew(mbase, offset, csr);
 		} else {
-			csr = musb_readw(mbase,
-				MUSB_EP_OFFSET(musb_channel->epnum,
-						MUSB_RXCSR));
+			offset = MUSB_EP_OFFSET(musb_channel->epnum,
+						MUSB_RXCSR);
+
+			csr = musb_readw(mbase, offset);
 			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
 				 MUSB_RXCSR_DMAENAB |
 				 MUSB_RXCSR_DMAMODE);
-			musb_writew(mbase,
-				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
-				csr);
+			musb_writew(mbase, offset, csr);
 		}
 
 		musb_writew(mbase,
@@ -296,20 +298,28 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
 					&& ((channel->desired_mode == 0)
 					    || (channel->actual_len &
 					    (musb_channel->max_packet_sz - 1)))
-					 ) {
+				    ) {
+					u8  epnum  = musb_channel->epnum;
+					int offset = MUSB_EP_OFFSET(epnum,
+								    MUSB_TXCSR);
+					u16 txcsr;
+
+					/*
+					 * The programming guide says that we
+					 * must clear DMAENAB before DMAMODE.
+					 */
+					musb_ep_select(mbase, epnum);
+					txcsr = musb_readw(mbase, offset);
+					txcsr &= ~(MUSB_TXCSR_DMAENAB
+							| MUSB_TXCSR_AUTOSET);
+					musb_writew(mbase, offset, txcsr);
 					/* Send out the packet */
-					musb_ep_select(mbase,
-						musb_channel->epnum);
-					musb_writew(mbase, MUSB_EP_OFFSET(
-							musb_channel->epnum,
-							MUSB_TXCSR),
-						MUSB_TXCSR_TXPKTRDY);
-				} else {
-					musb_dma_completion(
-						musb,
-						musb_channel->epnum,
-						musb_channel->transmit);
+					txcsr &= ~MUSB_TXCSR_DMAMODE;
+					txcsr |=  MUSB_TXCSR_TXPKTRDY;
+					musb_writew(mbase, offset, txcsr);
 				}
+				musb_dma_completion(musb, musb_channel->epnum,
+						    musb_channel->transmit);
 			}
 		}
 	}
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 901dffdf23b1..60924ce08493 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -3,7 +3,6 @@
  * Some code has been taken from tusb6010.c
  * Copyrights for that are attributable to:
  * Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
  * Tony Lindgren <tony@atomide.com>
  *
  * This file is part of the Inventra Controller Driver for Linux.
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 9e20fd070d71..4ac1477d3569 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -2,7 +2,6 @@
  * TUSB6010 USB 2.0 OTG Dual Role controller
  *
  * Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
  * Tony Lindgren <tony@atomide.com>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h
index ab8c96286ce6..35c933a5d991 100644
--- a/drivers/usb/musb/tusb6010.h
+++ b/drivers/usb/musb/tusb6010.h
@@ -2,7 +2,6 @@
  * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
  *
  * Copyright (C) 2006 Nokia Corporation
- * Jarkko Nikula <jarkko.nikula@nokia.com>
  * Tony Lindgren <tony@atomide.com>
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index 4b933f646f2e..c567168f89af 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -36,14 +36,14 @@ struct nop_usb_xceiv {
 	struct device		*dev;
 };
 
-static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device nop_xceiv_device = {
 	.name           = "nop_usb_xceiv",
 	.id             = -1,
 	.dev = {
 		.dma_mask               = &nop_xceiv_dmamask,
-		.coherent_dma_mask      = DMA_32BIT_MASK,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
 		.platform_data          = NULL,
 	},
 };
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index ff318fae7d4d..0a43a7db750f 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -43,7 +43,8 @@ EXPORT_SYMBOL(otg_get_transceiver);
  */
 void otg_put_transceiver(struct otg_transceiver *x)
 {
-	put_device(x->dev);
+	if (x)
+		put_device(x->dev);
 }
 EXPORT_SYMBOL(otg_put_transceiver);
 
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 858bdd038fbc..dd501bb63ed6 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -175,13 +175,6 @@ static int  cyberjack_open(struct tty_struct *tty,
 	dbg("%s - usb_clear_halt", __func__);
 	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
 
-	/* force low_latency on so that our tty_push actually forces
-	 * the data through, otherwise it is scheduled, and with high
-	 * data rates (like with OHCI) data can get lost.
-	 */
-	if (tty)
-		tty->low_latency = 1;
-
 	priv = usb_get_serial_port_data(port);
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->rdtodo = 0;
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index eae4740d448c..e568710b263f 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -656,10 +656,6 @@ static int cypress_open(struct tty_struct *tty,
 	priv->rx_flags = 0;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* setting to zero could cause data loss */
-	if (tty)
-		tty->low_latency = 1;
-
 	/* raise both lines and set termios */
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->line_control = CONTROL_DTR | CONTROL_RTS;
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 8a69cce40b6d..c709ec474a80 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -478,12 +478,6 @@ static void empeg_set_termios(struct tty_struct *tty,
 	termios->c_cflag
 		|= CS8;		/* character size 8 bits */
 
-	/*
-	 * Force low_latency on; otherwise the pushes are scheduled;
-	 * this is bad as it opens up the possibility of dropping bytes
-	 * on the floor.  We don't want to drop bytes on the floor. :)
-	 */
-	tty->low_latency = 1;
 	tty_encode_baud_rate(tty, 115200, 115200);
 }
 
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index dcc87aaa8628..8100f1d25904 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -668,6 +668,7 @@ static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(DE_VID, WHT_PID) },
 	{ USB_DEVICE(ADI_VID, ADI_GNICE_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index daaf63db0b50..c09f658a448b 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -913,6 +913,13 @@
 #define ADI_GNICE_PID 		0xF000
 
 /*
+ * JETI SPECTROMETER SPECBOS 1201
+ * http://www.jeti.com/products/sys/scb/scb1201.php
+ */
+#define JETI_VID		0x0c6c
+#define JETI_SPC1201_PID	0x04b2
+
+/*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
  *   wValue:         0
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index a26a0e2cdb4a..586d30ff450b 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -973,14 +973,6 @@ static int garmin_open(struct tty_struct *tty,
 
 	dbg("%s - port %d", __func__, port->number);
 
-	/*
-	 * Force low_latency on so that our tty_push actually forces the data
-	 * through, otherwise it is scheduled, and with high data rates (like
-	 * with OHCI) data can get lost.
-	 */
-	if (tty)
-		tty->low_latency = 1;
-
 	spin_lock_irqsave(&garmin_data_p->lock, flags);
 	garmin_data_p->mode  = initial_mode;
 	garmin_data_p->count = 0;
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 9d57cace3731..4cec9906ccf3 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -122,12 +122,6 @@ int usb_serial_generic_open(struct tty_struct *tty,
 
 	dbg("%s - port %d", __func__, port->number);
 
-	/* force low_latency on so that our tty_push actually forces the data
-	   through, otherwise it is scheduled, and with high data rates (like
-	   with OHCI) data can get lost. */
-	if (tty)
-		tty->low_latency = 1;
-
 	/* clear the throttle flags */
 	spin_lock_irqsave(&port->lock, flags);
 	port->throttled = 0;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index e85c8c0d1ad9..fb4a73d090f6 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -193,8 +193,6 @@ static const struct divisor_table_entry divisor_table[] = {
 /* local variables */
 static int debug;
 
-static int low_latency = 1;	/* tty low latency flag, on by default */
-
 static atomic_t CmdUrbs;	/* Number of outstanding Command Write Urbs */
 
 
@@ -867,9 +865,6 @@ static int edge_open(struct tty_struct *tty,
 	if (edge_port == NULL)
 		return -ENODEV;
 
-	if (tty)
-		tty->low_latency = low_latency;
-
 	/* see if we've set up our endpoint info yet (can't set it up
 	   in edge_startup as the structures were not set up at that time.) */
 	serial = port->serial;
@@ -3299,6 +3294,3 @@ MODULE_FIRMWARE("edgeport/down2.fw");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index c3cdd00ddc41..513b25e044c1 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -76,7 +76,6 @@ struct edgeport_uart_buf_desc {
 #define EDGE_READ_URB_STOPPING	1
 #define EDGE_READ_URB_STOPPED	2
 
-#define EDGE_LOW_LATENCY	1
 #define EDGE_CLOSING_WAIT	4000	/* in .01 sec */
 
 #define EDGE_OUT_BUF_SIZE	1024
@@ -232,7 +231,6 @@ static unsigned short OperationalBuildNumber;
 
 static int debug;
 
-static int low_latency = EDGE_LOW_LATENCY;
 static int closing_wait = EDGE_CLOSING_WAIT;
 static int ignore_cpu_rev;
 static int default_uart_mode;		/* RS232 */
@@ -1850,9 +1848,6 @@ static int edge_open(struct tty_struct *tty,
 	if (edge_port == NULL)
 		return -ENODEV;
 
-	if (tty)
-		tty->low_latency = low_latency;
-
 	port_number = port->number - port->serial->minor;
 	switch (port_number) {
 	case 0:
@@ -3008,9 +3003,6 @@ MODULE_FIRMWARE("edgeport/down3.bin");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
-
 module_param(closing_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
 
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index ef92095b0732..cd62825a9ac3 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -631,13 +631,7 @@ static int ipaq_open(struct tty_struct *tty,
 		priv->free_len += PACKET_SIZE;
 	}
 
-	/*
-	 * Force low latency on. This will immediately push data to the line
-	 * discipline instead of queueing.
-	 */
-
 	if (tty) {
-		tty->low_latency = 1;
 		/* FIXME: These two are bogus */
 		tty->raw = 1;
 		tty->real_raw = 1;
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index f530032ed93d..da2a2b46644a 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -207,9 +207,6 @@ static int ipw_open(struct tty_struct *tty,
 	if (!buf_flow_init)
 		return -ENOMEM;
 
-	if (tty)
-		tty->low_latency = 1;
-
 	/* --1: Tell the modem to initialize (we think) From sniffs this is
 	 *	always the first thing that gets sent to the modem during
 	 *	opening of the device */
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 2314c6ae4fc2..4473d442b2aa 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -1051,7 +1051,6 @@ static int iuu_open(struct tty_struct *tty,
 		tty->termios->c_oflag = 0;
 		tty->termios->c_iflag = 0;
 		priv->termios_initialized = 1;
-		tty->low_latency = 1;
 		priv->poll = 0;
 	 }
 	spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 6286baad9392..c148544953b3 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -231,13 +231,7 @@ static int kobil_open(struct tty_struct *tty,
 	/* someone sets the dev to 0 if the close method has been called */
 	port->interrupt_in_urb->dev = port->serial->dev;
 
-
-	/* force low_latency on so that our tty_push actually forces
-	 * the data through, otherwise it is scheduled, and with high
-	 * data rates (like with OHCI) data can get lost.
-	 */
 	if (tty) {
-		tty->low_latency = 1;
 
 		/* Default to echo off and other sane device settings */
 		tty->termios->c_lflag = 0;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index e772cc0a97fd..24e3b5d4b4d4 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -446,13 +446,6 @@ static int mos7720_open(struct tty_struct *tty,
 	data = 0x0c;
 	send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
 
-	/* force low_latency on so that our tty_push actually forces *
-	 * the data through,otherwise it is scheduled, and with      *
-	 * high data rates (like with OHCI) data can get lost.       */
-
-	if (tty)
-		tty->low_latency = 1;
-
 	/* see if we've set up our endpoint info yet   *
 	 * (can't set it up in mos7720_startup as the  *
 	 * structures were not set up at that time.)   */
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 2c20e88a91b3..84fb1dcd30dc 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -38,7 +38,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "1.3.1"
+#define DRIVER_VERSION "1.3.2"
 #define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
 
 /*
@@ -123,6 +123,11 @@
 #define BANDB_DEVICE_ID_USOPTL4_4       0xAC44
 #define BANDB_DEVICE_ID_USOPTL4_2       0xAC42
 
+/* This driver also supports the ATEN UC2324 device since it is mos7840 based
+ *  - if I knew the device id it would also support the ATEN UC2322 */
+#define USB_VENDOR_ID_ATENINTL		0x0557
+#define ATENINTL_DEVICE_ID_UC2324	0x2011
+
 /* Interrupt Routine Defines    */
 
 #define SERIAL_IIR_RLS      0x06
@@ -170,6 +175,7 @@ static struct usb_device_id moschip_port_id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 	{}			/* terminating entry */
 };
 
@@ -178,6 +184,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 	{}			/* terminating entry */
 };
 
@@ -1000,12 +1007,6 @@ static int mos7840_open(struct tty_struct *tty,
 	status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
 									Data);
 
-	/* force low_latency on so that our tty_push actually forces *
-	 * the data through,otherwise it is scheduled, and with      *
-	 * high data rates (like with OHCI) data can get lost.       */
-	if (tty)
-		tty->low_latency = 1;
-
 	/* Check to see if we've set up our endpoint info yet    *
 	 * (can't set it up in mos7840_startup as the structures *
 	 * were not set up at that time.)                        */
@@ -2477,9 +2478,14 @@ static int mos7840_startup(struct usb_serial *serial)
 		mos7840_set_port_private(serial->port[i], mos7840_port);
 		spin_lock_init(&mos7840_port->pool_lock);
 
-		mos7840_port->port_num = ((serial->port[i]->number -
-					   (serial->port[i]->serial->minor)) +
-					  1);
+		/* minor is not initialised until later by
+		 * usb-serial.c:get_free_serial() and cannot therefore be used
+		 * to index device instances */
+		mos7840_port->port_num = i + 1;
+		dbg ("serial->port[i]->number = %d", serial->port[i]->number);
+		dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
+		dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
+		dbg ("serial->minor = %d", serial->minor);
 
 		if (mos7840_port->port_num == 1) {
 			mos7840_port->SpRegOffset = 0x0;
@@ -2690,13 +2696,16 @@ static void mos7840_shutdown(struct usb_serial *serial)
 
 	for (i = 0; i < serial->num_ports; ++i) {
 		mos7840_port = mos7840_get_port_private(serial->port[i]);
-		spin_lock_irqsave(&mos7840_port->pool_lock, flags);
-		mos7840_port->zombie = 1;
-		spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
-		usb_kill_urb(mos7840_port->control_urb);
-		kfree(mos7840_port->ctrl_buf);
-		kfree(mos7840_port->dr);
-		kfree(mos7840_port);
+		dbg ("mos7840_port %d = %p", i, mos7840_port);
+		if (mos7840_port) {
+			spin_lock_irqsave(&mos7840_port->pool_lock, flags);
+			mos7840_port->zombie = 1;
+			spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
+			usb_kill_urb(mos7840_port->control_urb);
+			kfree(mos7840_port->ctrl_buf);
+			kfree(mos7840_port->dr);
+			kfree(mos7840_port);
+		}
 		mos7840_set_port_private(serial->port[i], NULL);
 	}
 
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c
index 2e8e05462ef7..b66b71ccd12b 100644
--- a/drivers/usb/serial/moto_modem.c
+++ b/drivers/usb/serial/moto_modem.c
@@ -25,6 +25,7 @@ static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x05c6, 0x3197) },	/* unknown Motorola phone */
 	{ USB_DEVICE(0x0c44, 0x0022) },	/* unknown Mororola phone */
 	{ USB_DEVICE(0x22b8, 0x2a64) },	/* Motorola KRZR K1m */
+	{ USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 839583dc8b6a..b500ad10b758 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -159,14 +159,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
 	priv->port = port;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/*
-	 * Force low_latency on so that our tty_push actually forces the data
-	 * through, otherwise it is scheduled, and with high data rates (like
-	 * with OHCI) data can get lost.
-	 */
-	if (tty)
-		tty->low_latency = 1;
-
 	/* Start reading from the device */
 	usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
 			  usb_rcvbulkpipe(priv->udev,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index d560c0b54e6e..7817b82889ca 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -300,6 +300,10 @@ static int  option_resume(struct usb_serial *serial);
 #define BENQ_VENDOR_ID				0x04a5
 #define BENQ_PRODUCT_H10			0x4068
 
+#define DLINK_VENDOR_ID				0x1186
+#define DLINK_PRODUCT_DWM_652			0x3e04
+
+
 static struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -516,6 +520,7 @@ static struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
 	{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
 	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
+	{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
 	{ USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
 	{ } /* Terminating entry */
 };
@@ -931,9 +936,6 @@ static int option_open(struct tty_struct *tty,
 				usb_pipeout(urb->pipe), 0); */
 	}
 
-	if (tty)
-		tty->low_latency = 1;
-
 	option_send_setup(tty, port);
 
 	return 0;
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index e6d6b0c17fd9..7528b8d57f1c 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -26,6 +26,27 @@ static struct usb_device_id id_table[] = {
 	{USB_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
 	{USB_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */
 	{USB_DEVICE(0x03f0, 0x201d)},	/* HP un2400 Gobi QDL Device */
+	{USB_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */
+	{USB_DEVICE(0x04da, 0x250c)},	/* Panasonic Gobi QDL device */
+	{USB_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */
+	{USB_DEVICE(0x413c, 0x8171)},	/* Dell Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */
+	{USB_DEVICE(0x1410, 0xa008)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x0b05, 0x1776)},	/* Asus Gobi Modem device */
+	{USB_DEVICE(0x0b05, 0x1774)},	/* Asus Gobi QDL device */
+	{USB_DEVICE(0x19d2, 0xfff3)},	/* ONDA Gobi Modem device */
+	{USB_DEVICE(0x19d2, 0xfff2)},	/* ONDA Gobi QDL device */
+	{USB_DEVICE(0x1557, 0x0a80)},	/* OQO Gobi QDL device */
+	{USB_DEVICE(0x05c6, 0x9001)},   /* Generic Gobi Modem device */
+	{USB_DEVICE(0x05c6, 0x9002)},	/* Generic Gobi Modem device */
+	{USB_DEVICE(0x05c6, 0x9202)},	/* Generic Gobi Modem device */
+	{USB_DEVICE(0x05c6, 0x9203)},	/* Generic Gobi Modem device */
+	{USB_DEVICE(0x05c6, 0x9222)},	/* Generic Gobi Modem device */
+	{USB_DEVICE(0x05c6, 0x9008)},	/* Generic Gobi QDL device */
+	{USB_DEVICE(0x05c6, 0x9201)},	/* Generic Gobi QDL device */
+	{USB_DEVICE(0x05c6, 0x9221)},	/* Generic Gobi QDL device */
+	{USB_DEVICE(0x05c6, 0x9231)},	/* Generic Gobi QDL device */
+	{USB_DEVICE(0x1f45, 0x0001)},	/* Unknown Gobi QDL device */
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index d9bf9a5c20ec..913225c61610 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -14,7 +14,7 @@
   Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
 */
 
-#define DRIVER_VERSION "v.1.3.2"
+#define DRIVER_VERSION "v.1.3.3"
 #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -259,9 +259,21 @@ static int sierra_send_setup(struct tty_struct *tty,
 			val |= 0x02;
 
 		/* If composite device then properly report interface */
-		if (serial->num_ports == 1)
+		if (serial->num_ports == 1) {
 			interface = sierra_calc_interface(serial);
 
+			/* Control message is sent only to interfaces with
+			 * interrupt_in endpoints
+			 */
+			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);
+			}
+		}
+
 		/* Otherwise the need to do non-composite mapping */
 		else {
 			if (port->bulk_out_endpointAddress == 2)
@@ -270,12 +282,13 @@ static int sierra_send_setup(struct tty_struct *tty,
 				interface = 1;
 			else if (port->bulk_out_endpointAddress == 5)
 				interface = 2;
-		}
 
-		return usb_control_msg(serial->dev,
+			return usb_control_msg(serial->dev,
 				usb_rcvctrlpipe(serial->dev, 0),
 				0x22, 0x21, val, interface,
 				NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+		}
 	}
 
 	return 0;
@@ -585,9 +598,6 @@ static int sierra_open(struct tty_struct *tty,
 		}
 	}
 
-	if (tty)
-		tty->low_latency = 1;
-
 	sierra_send_setup(tty, port);
 
 	/* start up the interrupt endpoint if we have one */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 2620bf6fe5e1..0a64bac306ee 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -50,11 +50,10 @@
 
 #define TI_TRANSFER_TIMEOUT	2
 
-#define TI_DEFAULT_LOW_LATENCY	0
 #define TI_DEFAULT_CLOSING_WAIT	4000		/* in .01 secs */
 
 /* supported setserial flags */
-#define TI_SET_SERIAL_FLAGS	(ASYNC_LOW_LATENCY)
+#define TI_SET_SERIAL_FLAGS	0
 
 /* read urb states */
 #define TI_READ_URB_RUNNING	0
@@ -161,7 +160,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
 
 /* module parameters */
 static int debug;
-static int low_latency = TI_DEFAULT_LOW_LATENCY;
 static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
 static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
 static unsigned int vendor_3410_count;
@@ -296,10 +294,6 @@ MODULE_FIRMWARE("mts_edge.fw");
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
 
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency,
-		"TTY low_latency flag, 0=off, 1=on, default is off");
-
 module_param(closing_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(closing_wait,
     "Maximum wait for data to drain in close, in .01 secs, default is 4000");
@@ -448,7 +442,6 @@ static int ti_startup(struct usb_serial *serial)
 		spin_lock_init(&tport->tp_lock);
 		tport->tp_uart_base_addr = (i == 0 ?
 				TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
-		tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
 		tport->tp_closing_wait = closing_wait;
 		init_waitqueue_head(&tport->tp_msr_wait);
 		init_waitqueue_head(&tport->tp_write_wait);
@@ -528,10 +521,6 @@ static int ti_open(struct tty_struct *tty,
 	if (mutex_lock_interruptible(&tdev->td_open_close_lock))
 		return -ERESTARTSYS;
 
-	if (tty)
-		tty->low_latency =
-				(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
 	port_number = port->number - port->serial->minor;
 
 	memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
@@ -1215,20 +1204,22 @@ static void ti_bulk_in_callback(struct urb *urb)
 	}
 
 	tty = tty_port_tty_get(&port->port);
-	if (tty && urb->actual_length) {
-		usb_serial_debug_data(debug, dev, __func__,
-			urb->actual_length, urb->transfer_buffer);
-
-		if (!tport->tp_is_open)
-			dbg("%s - port closed, dropping data", __func__);
-		else
-			ti_recv(&urb->dev->dev, tty,
+	if (tty) {
+		if (urb->actual_length) {
+			usb_serial_debug_data(debug, dev, __func__,
+				urb->actual_length, urb->transfer_buffer);
+
+			if (!tport->tp_is_open)
+				dbg("%s - port closed, dropping data",
+					__func__);
+			else
+				ti_recv(&urb->dev->dev, tty,
 						urb->transfer_buffer,
 						urb->actual_length);
-
-		spin_lock(&tport->tp_lock);
-		tport->tp_icount.rx += urb->actual_length;
-		spin_unlock(&tport->tp_lock);
+			spin_lock(&tport->tp_lock);
+			tport->tp_icount.rx += urb->actual_length;
+			spin_unlock(&tport->tp_lock);
+		}
 		tty_kref_put(tty);
 	}
 
@@ -1452,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
 		return -EFAULT;
 
 	tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
-	tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 	tport->tp_closing_wait = new_serial.closing_wait;
 
 	return 0;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 2a70563bbee1..0a566eea49c0 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -137,22 +137,10 @@ static void destroy_serial(struct kref *kref)
 
 	dbg("%s - %s", __func__, serial->type->description);
 
-	serial->type->shutdown(serial);
-
 	/* return the minor range that this device had */
 	if (serial->minor != SERIAL_TTY_NO_MINOR)
 		return_serial(serial);
 
-	for (i = 0; i < serial->num_ports; ++i)
-		serial->port[i]->port.count = 0;
-
-	/* the ports are cleaned up and released in port_release() */
-	for (i = 0; i < serial->num_ports; ++i)
-		if (serial->port[i]->dev.parent != NULL) {
-			device_unregister(&serial->port[i]->dev);
-			serial->port[i] = NULL;
-		}
-
 	/* If this is a "fake" port, we have to clean it up here, as it will
 	 * not get cleaned up in port_release() as it was never registered with
 	 * the driver core */
@@ -187,7 +175,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 	struct usb_serial *serial;
 	struct usb_serial_port *port;
 	unsigned int portNumber;
-	int retval;
+	int retval = 0;
 
 	dbg("%s", __func__);
 
@@ -198,21 +186,24 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 	}
 
+	mutex_lock(&serial->disc_mutex);
 	portNumber = tty->index - serial->minor;
 	port = serial->port[portNumber];
-	if (!port) {
-		retval = -ENODEV;
-		goto bailout_kref_put;
-	}
-
-	if (port->serial->disconnected) {
+	if (!port || serial->disconnected)
 		retval = -ENODEV;
-		goto bailout_kref_put;
-	}
+	else
+		get_device(&port->dev);
+	/*
+	 * Note: Our locking order requirement does not allow port->mutex
+	 * to be acquired while serial->disc_mutex is held.
+	 */
+	mutex_unlock(&serial->disc_mutex);
+	if (retval)
+		goto bailout_serial_put;
 
 	if (mutex_lock_interruptible(&port->mutex)) {
 		retval = -ERESTARTSYS;
-		goto bailout_kref_put;
+		goto bailout_port_put;
 	}
 
 	++port->port.count;
@@ -232,14 +223,20 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 			goto bailout_mutex_unlock;
 		}
 
-		retval = usb_autopm_get_interface(serial->interface);
+		mutex_lock(&serial->disc_mutex);
+		if (serial->disconnected)
+			retval = -ENODEV;
+		else
+			retval = usb_autopm_get_interface(serial->interface);
 		if (retval)
 			goto bailout_module_put;
+
 		/* only call the device specific open if this
 		 * is the first time the port is opened */
 		retval = serial->type->open(tty, port, filp);
 		if (retval)
 			goto bailout_interface_put;
+		mutex_unlock(&serial->disc_mutex);
 	}
 
 	mutex_unlock(&port->mutex);
@@ -248,13 +245,16 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 bailout_interface_put:
 	usb_autopm_put_interface(serial->interface);
 bailout_module_put:
+	mutex_unlock(&serial->disc_mutex);
 	module_put(serial->type->driver.owner);
 bailout_mutex_unlock:
 	port->port.count = 0;
 	tty->driver_data = NULL;
 	tty_port_tty_set(&port->port, NULL);
 	mutex_unlock(&port->mutex);
-bailout_kref_put:
+bailout_port_put:
+	put_device(&port->dev);
+bailout_serial_put:
 	usb_serial_put(serial);
 	return retval;
 }
@@ -262,6 +262,9 @@ bailout_kref_put:
 static void serial_close(struct tty_struct *tty, struct file *filp)
 {
 	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial;
+	struct module *owner;
+	int count;
 
 	if (!port)
 		return;
@@ -269,6 +272,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
 	dbg("%s - port %d", __func__, port->number);
 
 	mutex_lock(&port->mutex);
+	serial = port->serial;
+	owner = serial->type->driver.owner;
 
 	if (port->port.count == 0) {
 		mutex_unlock(&port->mutex);
@@ -281,7 +286,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
 		 * this before we drop the port count. The call is protected
 		 * by the port mutex
 		 */
-		port->serial->type->close(tty, port, filp);
+		serial->type->close(tty, port, filp);
 
 	if (port->port.count == (port->console ? 2 : 1)) {
 		struct tty_struct *tty = tty_port_tty_get(&port->port);
@@ -295,17 +300,23 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
 		}
 	}
 
-	if (port->port.count == 1) {
-		mutex_lock(&port->serial->disc_mutex);
-		if (!port->serial->disconnected)
-			usb_autopm_put_interface(port->serial->interface);
-		mutex_unlock(&port->serial->disc_mutex);
-		module_put(port->serial->type->driver.owner);
-	}
 	--port->port.count;
-
+	count = port->port.count;
 	mutex_unlock(&port->mutex);
-	usb_serial_put(port->serial);
+	put_device(&port->dev);
+
+	/* Mustn't dereference port any more */
+	if (count == 0) {
+		mutex_lock(&serial->disc_mutex);
+		if (!serial->disconnected)
+			usb_autopm_put_interface(serial->interface);
+		mutex_unlock(&serial->disc_mutex);
+	}
+	usb_serial_put(serial);
+
+	/* Mustn't dereference serial any more */
+	if (count == 0)
+		module_put(owner);
 }
 
 static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -549,7 +560,13 @@ static void kill_traffic(struct usb_serial_port *port)
 
 static void port_free(struct usb_serial_port *port)
 {
+	/*
+	 * Stop all the traffic before cancelling the work, so that
+	 * nobody will restart it by calling usb_serial_port_softint.
+	 */
 	kill_traffic(port);
+	cancel_work_sync(&port->work);
+
 	usb_free_urb(port->read_urb);
 	usb_free_urb(port->write_urb);
 	usb_free_urb(port->interrupt_in_urb);
@@ -558,7 +575,6 @@ static void port_free(struct usb_serial_port *port)
 	kfree(port->bulk_out_buffer);
 	kfree(port->interrupt_in_buffer);
 	kfree(port->interrupt_out_buffer);
-	flush_scheduled_work();		/* port->work */
 	kfree(port);
 }
 
@@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_interface *interface)
 	usb_set_intfdata(interface, NULL);
 	/* must set a flag, to signal subdrivers */
 	serial->disconnected = 1;
+	mutex_unlock(&serial->disc_mutex);
+
+	/* Unfortunately, many of the sub-drivers expect the port structures
+	 * to exist when their shutdown method is called, so we have to go
+	 * through this awkward two-step unregistration procedure.
+	 */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
 		if (port) {
@@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_interface *interface)
 				tty_kref_put(tty);
 			}
 			kill_traffic(port);
+			cancel_work_sync(&port->work);
+			device_del(&port->dev);
+		}
+	}
+	serial->type->shutdown(serial);
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		if (port) {
+			put_device(&port->dev);
+			serial->port[i] = NULL;
 		}
 	}
+
 	/* let the last holder of this object
 	 * cause it to be cleaned up */
-	mutex_unlock(&serial->disc_mutex);
 	usb_serial_put(serial);
 	dev_info(dev, "device disconnected\n");
 }
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 4facce3d9364..5ac414bda718 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -296,14 +296,6 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
 	priv->throttled = 0;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/*
-	 * Force low_latency on so that our tty_push actually forces the data
-	 * through, otherwise it is scheduled, and with high data rates (like
-	 * with OHCI) data can get lost.
-	 */
-	if (tty)
-		tty->low_latency = 1;
-
 	/* Start reading from the device */
 	usb_fill_bulk_urb(port->read_urb, serial->dev,
 			   usb_rcvbulkpipe(serial->dev,
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 5be54c019662..ef7e5a8ceab5 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -17,7 +17,8 @@ usb-storage-objs :=	scsiglue.o protocol.o transport.o usb.o \
 ifeq ($(CONFIG_USB_LIBUSUAL),)
 	usb-storage-objs	+= usual-tables.o
 else
-	obj-$(CONFIG_USB)	+= libusual.o usual-tables.o
+	obj-$(CONFIG_USB)	+= usb-libusual.o
+	usb-libusual-objs	:= libusual.o usual-tables.o
 endif
 
 obj-$(CONFIG_USB_STORAGE_ALAUDA)	+= ums-alauda.o
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 49aedb36dc19..fcb320217218 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -247,10 +247,8 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
 		USB_ENDPOINT_HALT, endp,
 		NULL, 0, 3*HZ);
 
-	/* reset the endpoint toggle */
 	if (result >= 0)
-		usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
-				usb_pipeout(pipe), 0);
+		usb_reset_endpoint(us->pusb_dev, endp);
 
 	US_DEBUGP("%s: result = %d\n", __func__, result);
 	return result;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 1c1f643e8a78..fa65a3b08601 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -975,12 +975,14 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ),
 
-/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
+/* Reported by Rauch Wolke <rauchwolke@gmx.net>
+ * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882)
+ */
 UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
 		"Simple Tech/Datafab",
 		"CF+SM Reader",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
+		US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ),
 
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
  * to the USB storage specification in two ways:
@@ -1376,6 +1378,14 @@ UNUSUAL_DEV(  0x10d6, 0x2200, 0x0100, 0x0100,
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		0),
 
+/* Reported by Pascal Terjan <pterjan@mandriva.com>
+ * Ignore driver CD mode and force into modem mode by default.
+ */
+UNUSUAL_DEV(  0x1186, 0x3e04, 0x0000, 0x0000,
+           "D-Link",
+           "USB Mass Storage",
+           US_SC_DEVICE, US_PR_DEVICE, option_ms_init, 0),
+
 /* Reported by Kevin Lloyd <linux@sierrawireless.com>
  * Entry is needed for the initializer function override,
  * which instructs the device to load as a modem
@@ -1841,6 +1851,12 @@ UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_CAPACITY_HEURISTICS),
 
+/* Reported by Alessio Treglia <quadrispro@ubuntu.com> */
+UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001,
+		"TGE",
+		"Digital MP3 Audio Player",
+		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
+
 /* Control/Bulk transport for all SubClass values */
 USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
 USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 386eaa22d215..4ac4300a3f9a 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -267,6 +267,8 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work)
 	mutex_lock(&wusbhc->mutex);
 	wusbhc_devconnect_acked(wusbhc, wusb_dev);
 	mutex_unlock(&wusbhc->mutex);
+
+	wusb_dev_put(wusb_dev);
 }
 
 /*
@@ -396,7 +398,8 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
 
 	/* After a device disconnects, change the GTK (see [WUSB]
 	 * section 6.2.11.2). */
-	wusbhc_gtk_rekey(wusbhc);
+	if (wusbhc->active)
+		wusbhc_gtk_rekey(wusbhc);
 
 	/* The Wireless USB part has forgotten about the device already; now
 	 * khubd's timer will pick up the disconnection and remove the USB
@@ -1084,15 +1087,21 @@ error_mmcie_set:
  * wusbhc_devconnect_stop - stop managing connected devices
  * @wusbhc: the WUSB HC
  *
- * Removes the Host Info IE and stops the keep alives.
- *
- * FIXME: should this disconnect all devices?
+ * Disconnects any devices still connected, stops the keep alives and
+ * removes the Host Info IE.
  */
 void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
 {
-	cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
-	WARN_ON(!list_empty(&wusbhc->cack_list));
+	int i;
 
+	mutex_lock(&wusbhc->mutex);
+	for (i = 0; i < wusbhc->ports_max; i++) {
+		if (wusbhc->port[i].wusb_dev)
+			__wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]);
+	}
+	mutex_unlock(&wusbhc->mutex);
+
+	cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
 	wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
 	kfree(wusbhc->wuie_host_info);
 	wusbhc->wuie_host_info = NULL;
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c
index 07c63a31c799..ee6256f23636 100644
--- a/drivers/usb/wusbcore/wusbhc.c
+++ b/drivers/usb/wusbcore/wusbhc.c
@@ -88,33 +88,31 @@ static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show,
 					     wusb_trust_timeout_store);
 
 /*
- * Show & store the current WUSB CHID
+ * Show the current WUSB CHID.
  */
 static ssize_t wusb_chid_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 {
 	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
+	const struct wusb_ckhdid *chid;
 	ssize_t result = 0;
 
 	if (wusbhc->wuie_host_info != NULL)
-		result += ckhdid_printf(buf, PAGE_SIZE,
-					&wusbhc->wuie_host_info->CHID);
+		chid = &wusbhc->wuie_host_info->CHID;
+	else
+		chid = &wusb_ckhdid_zero;
+
+	result += ckhdid_printf(buf, PAGE_SIZE, chid);
+	result += sprintf(buf + result, "\n");
+
 	return result;
 }
 
 /*
- * Store a new CHID
- *
- * This will (FIXME) trigger many changes.
- *
- * - Send an all zeros CHID and it will stop the controller
- * - Send a non-zero CHID and it will start it
- *   (unless it was started, it will just change the CHID,
- *   diconnecting all devices first).
+ * Store a new CHID.
  *
- * So first we scan the MMC we are sent and then we act on it.  We
- * read it in the same format as we print it, an ASCII string of 16
- * hex bytes.
+ * - Write an all zeros CHID and it will stop the controller
+ * - Write a non-zero CHID and it will start it.
  *
  * See wusbhc_chid_set() for more info.
  */
@@ -339,13 +337,15 @@ void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status)
 {
 	struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
 
-	if (status == 0) {
+	if (status == 0 && wusb_dev) {
 		wusb_dev->entry_ts = jiffies;
 
-		/* wusbhc_devconnect_acked() can't be called from from
+		/* wusbhc_devconnect_acked() can't be called from
 		   atomic context so defer it to a work queue. */
 		if (!list_empty(&wusb_dev->cack_node))
 			queue_work(wusbd, &wusb_dev->devconnect_acked_work);
+		else
+			wusb_dev_put(wusb_dev);
 	}
 
 	usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status);
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 1a1f946d8fef..9fe90ce928fb 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -533,6 +533,7 @@ static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
 
 	writeb(0xff, mmio_base + 0x78c);
 	chips_hw_init(p);
+	return 0;
 }
 
 static int __devinit
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 16bb7e3c0310..6c37e8ee5efe 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -698,8 +698,8 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
 found:
 	/*
 	 * Some methods fail to retrieve SCLK and MCLK values, we apply default
-	 * settings in this case (200Mhz). If that really happne often, we could
-	 * fetch from registers instead...
+	 * settings in this case (200Mhz). If that really happens often, we
+	 * could fetch from registers instead...
 	 */
 	if (rinfo->pll.mclk == 0)
 		rinfo->pll.mclk = 20000;
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index dd37cbcaf8ce..157057c79ca3 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,8 +35,6 @@ static int fb_notifier_callback(struct notifier_block *self,
 		return 0;
 
 	bd = container_of(self, struct backlight_device, fb_notif);
-	if (!lock_fb_info(evdata->info))
-		return -ENODEV;
 	mutex_lock(&bd->ops_lock);
 	if (bd->ops)
 		if (!bd->ops->check_fb ||
@@ -49,7 +47,6 @@ static int fb_notifier_callback(struct notifier_block *self,
 			backlight_update_status(bd);
 		}
 	mutex_unlock(&bd->ops_lock);
-	unlock_fb_info(evdata->info);
 	return 0;
 }
 
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 0bb13df0fa89..b6449470106c 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,8 +40,6 @@ static int fb_notifier_callback(struct notifier_block *self,
 	if (!ld->ops)
 		return 0;
 
-	if (!lock_fb_info(evdata->info))
-		return -ENODEV;
 	mutex_lock(&ld->ops_lock);
 	if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
 		if (event == FB_EVENT_BLANK) {
@@ -53,7 +51,6 @@ static int fb_notifier_callback(struct notifier_block *self,
 		}
 	}
 	mutex_unlock(&ld->ops_lock);
-	unlock_fb_info(evdata->info);
 	return 0;
 }
 
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index d42e385f091c..4c2bf923418c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -567,9 +567,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
 	default:
 		dev_dbg(info->device,
 			"Unsupported bpp size: %d\n", var->bits_per_pixel);
-		assert(false);
-		/* should never occur */
-		break;
+		return -EINVAL;
 	}
 
 	if (var->xres_virtual < var->xres)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2cd500a304f2..471a9a60376a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2263,9 +2263,12 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
 	}
 
 
+	if (!lock_fb_info(info))
+		return;
 	event.info = info;
 	event.data = &blank;
 	fb_notifier_call_chain(FB_EVENT_CONBLANK, &event);
+	unlock_fb_info(info);
 }
 
 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
@@ -2956,8 +2959,6 @@ static int fbcon_fb_unregistered(struct fb_info *info)
 {
 	int i, idx;
 
-	if (!lock_fb_info(info))
-		return -ENODEV;
 	idx = info->node;
 	for (i = first_fb_vc; i <= last_fb_vc; i++) {
 		if (con2fb_map[i] == idx)
@@ -2985,8 +2986,6 @@ static int fbcon_fb_unregistered(struct fb_info *info)
 	if (primary_device == idx)
 		primary_device = -1;
 
-	unlock_fb_info(info);
-
 	if (!num_registered_fb)
 		unregister_con_driver(&fb_con);
 
@@ -3027,11 +3026,8 @@ static int fbcon_fb_registered(struct fb_info *info)
 {
 	int ret = 0, i, idx;
 
-	if (!lock_fb_info(info))
-		return -ENODEV;
 	idx = info->node;
 	fbcon_select_primary(info);
-	unlock_fb_info(info);
 
 	if (info_idx == -1) {
 		for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3152,53 +3148,23 @@ static int fbcon_event_notify(struct notifier_block *self,
 
 	switch(action) {
 	case FB_EVENT_SUSPEND:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_suspended(info);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_RESUME:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_resumed(info);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_CHANGE:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_modechanged(info);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_CHANGE_ALL:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_set_all_vcs(info);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_DELETE:
 		mode = event->data;
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		ret = fbcon_mode_deleted(info, mode);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_FB_UNBIND:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		idx = info->node;
-		unlock_fb_info(info);
 		ret = fbcon_fb_unbind(idx);
 		break;
 	case FB_EVENT_FB_REGISTERED:
@@ -3217,29 +3183,14 @@ static int fbcon_event_notify(struct notifier_block *self,
 		con2fb->framebuffer = con2fb_map[con2fb->console - 1];
 		break;
 	case FB_EVENT_BLANK:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_fb_blanked(info, *(int *)event->data);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_NEW_MODELIST:
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_new_modelist(info);
-		unlock_fb_info(info);
 		break;
 	case FB_EVENT_GET_REQ:
 		caps = event->data;
-		if (!lock_fb_info(info)) {
-			ret = -ENODEV;
-			goto done;
-		}
 		fbcon_get_requirement(info, caps);
-		unlock_fb_info(info);
 		break;
 	}
 done:
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 0c5b9a9fd56f..8dea2bc92705 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -210,12 +210,15 @@ static int __init efifb_probe(struct platform_device *dev)
 	unsigned int size_total;
 	int request_succeeded = 0;
 
-	printk(KERN_INFO "efifb: probing for efifb\n");
-
 	if (!screen_info.lfb_depth)
 		screen_info.lfb_depth = 32;
 	if (!screen_info.pages)
 		screen_info.pages = 1;
+	if (!screen_info.lfb_base) {
+		printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
+		return -ENODEV;
+	}
+	printk(KERN_INFO "efifb: probing for efifb\n");
 
 	/* just assume they're all unset if any are */
 	if (!screen_info.blue_size) {
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2ac32e6b5953..d412a1ddc12f 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1097,8 +1097,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			return -EINVAL;
 		con2fb.framebuffer = -1;
 		event.data = &con2fb;
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		event.info = info;
 		fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
+		unlock_fb_info(info);
 		ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
 		break;
 	case FBIOPUT_CON2FBMAP:
@@ -1115,8 +1118,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			break;
 		}
 		event.data = &con2fb;
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		event.info = info;
 		ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
+		unlock_fb_info(info);
 		break;
 	case FBIOBLANK:
 		if (!lock_fb_info(info))
@@ -1521,7 +1527,10 @@ register_framebuffer(struct fb_info *fb_info)
 	registered_fb[i] = fb_info;
 
 	event.info = fb_info;
+	if (!lock_fb_info(fb_info))
+		return -ENODEV;
 	fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
+	unlock_fb_info(fb_info);
 	return 0;
 }
 
@@ -1555,8 +1564,12 @@ unregister_framebuffer(struct fb_info *fb_info)
 		goto done;
 	}
 
+
+	if (!lock_fb_info(fb_info))
+		return -ENODEV;
 	event.info = fb_info;
 	ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+	unlock_fb_info(fb_info);
 
 	if (ret) {
 		ret = -EINVAL;
@@ -1590,6 +1603,8 @@ void fb_set_suspend(struct fb_info *info, int state)
 {
 	struct fb_event event;
 
+	if (!lock_fb_info(info))
+		return;
 	event.info = info;
 	if (state) {
 		fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
@@ -1598,6 +1613,7 @@ void fb_set_suspend(struct fb_info *info, int state)
 		info->state = FBINFO_STATE_RUNNING;
 		fb_notifier_call_chain(FB_EVENT_RESUME, &event);
 	}
+	unlock_fb_info(info);
 }
 
 /**
@@ -1667,8 +1683,11 @@ int fb_new_modelist(struct fb_info *info)
 	err = 1;
 
 	if (!list_empty(&info->modelist)) {
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		event.info = info;
 		err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
+		unlock_fb_info(info);
 	}
 
 	return err;
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index a50bea614804..40984551c927 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -53,6 +53,7 @@
 #define PCI_DEVICE_ID_INTEL_830M	0x3577
 #define PCI_DEVICE_ID_INTEL_845G	0x2562
 #define PCI_DEVICE_ID_INTEL_85XGM	0x3582
+#define PCI_DEVICE_ID_INTEL_854		0x358E
 #define PCI_DEVICE_ID_INTEL_865G	0x2572
 #define PCI_DEVICE_ID_INTEL_915G	0x2582
 #define PCI_DEVICE_ID_INTEL_915GM	0x2592
@@ -154,6 +155,7 @@ enum intel_chips {
 	INTEL_85XGM,
 	INTEL_852GM,
 	INTEL_852GME,
+	INTEL_854,
 	INTEL_855GM,
 	INTEL_855GME,
 	INTEL_865G,
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index b3065492bb20..487f2be47460 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -156,6 +156,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
 	switch(dinfo->chipset) {
 	case INTEL_830M:
 	case INTEL_845G:
+	case INTEL_854:
 	case INTEL_855GM:
 	case INTEL_865G:
 		dinfo->output[i].type = INTELFB_OUTPUT_DVO;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6d8e5415c809..ace14fe02fc4 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -182,6 +182,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_854, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_854 },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 8b26b27c2db6..0689f97c5238 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -84,6 +84,11 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
 		dinfo->mobile = 0;
 		dinfo->pll_index = PLLS_I8xx;
 		return 0;
+	case PCI_DEVICE_ID_INTEL_854:
+		dinfo->mobile = 1;
+		dinfo->name = "Intel(R) 854";
+		dinfo->chipset = INTEL_854;
+		return 0;
 	case PCI_DEVICE_ID_INTEL_85XGM:
 		tmp = 0;
 		dinfo->mobile = 1;
diff --git a/drivers/video/logo/logo_linux_clut224.ppm b/drivers/video/logo/logo_linux_clut224.ppm
index de93ff3fc1ad..3c14e43b82fe 100644
--- a/drivers/video/logo/logo_linux_clut224.ppm
+++ b/drivers/video/logo/logo_linux_clut224.ppm
@@ -1,2828 +1,1604 @@
 P3
-145 113
+# Standard 224-color Linux logo
+80 80
 255
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  3 4 4  6 7 7
-8 10 10  8 10 10  6 8 8  6 7 7  3 4 4  2 2 2
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  4 5 5  17 18 17
-27 29 28  35 37 36  40 43 41  43 45 43  40 43 41  37 39 37
-32 34 33  27 30 29  23 25 24  17 21 21  15 18 18  12 15 15
-11 13 13  8 10 10  6 7 7  3 4 4  1 1 1  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  13 13 13  32 34 33  49 51 48  60 60 56  58 59 55
-55 57 54  55 56 53  49 51 48  43 45 43  39 40 39  33 37 35
-28 31 30  23 27 26  20 23 23  17 20 20  14 17 17  13 16 16
-11 14 14  10 13 13  10 12 12  9 11 11  8 10 10  6 7 7
-2 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  6 7 7  12 15 15
-12 15 15  8 9 9  2 3 3  0 0 0  1 1 1  25 27 26
-55 56 53  68 70 65  65 66 61  65 66 61  63 64 60  63 64 60
-58 59 55  51 52 50  47 48 46  41 42 42  35 37 36  30 32 31
-26 28 27  20 24 24  18 22 22  16 19 19  14 17 17  13 16 16
-12 15 15  11 14 14  10 13 13  10 12 12  9 11 11  8 10 10
-8 9 9  6 8 8  3 3 3  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  6 7 7  20 24 24  23 27 26
-23 27 26  18 22 22  11 13 13  23 24 24  61 63 57  72 73 67
-72 73 67  68 70 65  68 70 65  68 70 65  63 64 60  58 59 55
-55 56 53  47 48 46  41 42 42  35 37 36  30 32 31  26 28 27
-20 24 24  18 22 22  16 20 20  15 19 19  14 17 17  13 16 16
-12 15 15  12 15 15  11 14 14  10 13 13  10 12 12  9 11 11
-8 10 10  8 9 9  7 9 9  6 7 7  1 2 2  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 1  4 5 5  5 6 5  4 5 5
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  15 19 19  40 41 39  53 55 47
-33 36 34  27 30 29  51 52 50  72 73 67  72 73 67  72 73 67
-72 73 67  68 70 65  68 70 65  63 64 60  58 59 55  51 52 50
-47 48 46  40 43 41  33 37 35  30 32 31  26 28 27  20 24 24
-18 22 22  17 21 21  16 19 19  14 18 18  14 17 17  13 17 17
-13 16 16  12 15 15  12 15 15  11 14 14  10 13 13  10 12 12
-9 11 11  8 10 10  8 9 9  7 9 9  6 8 8  3 4 4
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-2 2 2  6 8 8  10 12 12  10 12 12  10 12 12  10 12 12
-6 8 8  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  20 23 23  71 71 57  131 127 93
-115 113 82  63 64 60  72 73 67  72 73 67  72 73 67  72 73 67
-68 70 65  65 66 61  61 63 57  55 57 54  49 51 48  43 45 43
-39 40 39  33 36 34  28 31 30  23 27 26  20 24 24  20 23 23
-17 21 21  16 20 20  15 19 19  15 18 18  14 18 18  14 17 17
-13 17 17  13 16 16  12 15 15  12 15 15  11 14 14  10 13 13
-10 12 12  9 11 11  8 10 10  7 9 9  7 9 9  6 8 8
-4 5 5  0 0 0  0 0 0  0 0 0  1 1 1  6 7 7
-10 12 12  10 12 12  10 12 12  10 12 12  10 12 12  10 12 12
-10 12 12  3 4 4  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  18 22 22  71 71 57  144 139 99
-84 83 72  68 70 65  72 73 67  72 73 67  68 70 65  65 66 61
-63 64 60  55 57 54  51 52 50  47 48 46  40 43 41  35 37 36
-30 32 31  27 29 28  23 27 26  20 24 24  18 22 22  17 21 21
-16 20 20  15 19 19  15 19 19  15 19 19  15 18 18  14 18 18
-14 17 17  13 17 17  13 16 16  12 15 15  12 15 15  11 14 14
-10 13 13  9 12 12  9 11 11  8 10 10  7 9 9  6 8 8
-6 8 8  3 4 4  0 0 0  2 2 2  8 10 10  10 12 12
-10 12 12  10 12 12  11 13 13  36 38 35  61 61 53  48 49 45
-10 12 12  7 9 9  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  15 19 19  61 61 53  84 83 72
-68 70 65  72 73 67  68 70 65  68 70 65  63 64 60  58 59 55
-51 52 50  47 48 46  41 42 42  37 39 37  32 35 33  28 31 30
-23 27 26  20 24 24  20 23 23  18 22 22  17 21 21  17 21 21
-17 21 21  17 21 21  17 20 20  16 20 20  16 20 20  16 19 19
-15 18 18  14 18 18  13 17 17  13 16 16  12 15 15  12 15 15
-11 14 14  10 13 13  9 12 12  9 11 11  8 10 10  7 9 9
-6 8 8  6 8 8  5 6 5  9 11 11  10 12 12  10 12 12
-19 20 18  82 81 62  149 145 103  160 154 106  142 137 94  96 95 69
-10 12 12  10 12 12  1 1 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  10 12 12  44 46 43  68 70 65
-72 73 67  68 70 65  68 70 65  63 64 60  55 57 54  49 51 48
-43 45 43  39 40 39  33 37 35  30 32 31  26 28 27  23 27 26
-20 24 24  18 22 22  18 22 22  18 22 22  18 22 22  20 23 23
-20 24 24  23 25 24  23 25 24  22 24 23  20 23 23  18 22 22
-17 20 20  15 19 19  15 18 18  14 17 17  13 16 16  12 15 15
-11 14 14  11 13 13  10 12 12  9 11 11  8 10 10  8 9 9
-7 9 9  7 9 9  10 12 12  10 12 12  10 12 12  71 71 57
-164 159 111  186 182 128  186 182 128  171 165 117  151 147 98  96 95 69
-10 12 12  10 12 12  3 3 3  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  8 10 10  63 64 60  68 70 65
-72 73 67  68 70 65  63 64 60  55 57 54  47 48 46  40 43 41
-33 37 35  30 32 31  27 29 28  23 27 26  20 24 24  20 23 23
-18 22 22  18 22 22  20 23 22  21 25 23  23 27 26  27 29 28
-28 31 30  31 33 31  31 33 31  31 33 31  28 31 30  26 28 27
-23 25 24  20 23 22  16 20 20  15 18 18  14 17 17  13 16 16
-12 15 15  11 14 14  10 13 13  10 12 12  9 11 11  8 10 10
-10 12 12  10 13 13  10 12 12  12 14 14  96 95 69  165 161 109
-186 182 128  192 187 134  192 187 134  176 171 126  160 154 106  103 101 77
-10 12 12  10 12 12  5 6 5  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  35 37 36  68 70 65  72 73 67
-68 70 65  65 66 61  58 59 55  49 51 48  40 43 41  33 37 35
-28 31 30  23 27 26  20 24 24  20 23 23  18 22 22  18 22 22
-18 22 22  20 23 23  23 27 26  27 30 29  32 35 33  37 39 37
-40 43 41  44 46 43  46 47 43  44 46 43  40 43 41  36 38 35
-31 33 31  27 29 28  22 24 23  17 21 21  15 18 18  14 17 17
-13 16 16  12 15 15  11 14 14  11 14 14  11 13 13  13 16 16
-13 16 16  11 14 14  10 12 12  79 78 62  142 137 94  164 159 111
-178 174 128  192 187 134  192 187 134  176 171 126  160 154 106  96 95 69
-10 12 12  10 12 12  6 7 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  55 57 54  68 70 65  72 73 67
-68 70 65  63 64 60  55 56 53  43 45 43  35 37 36  28 31 30
-23 27 26  20 24 24  18 22 22  17 21 21  17 21 21  17 21 21
-20 24 24  25 27 26  31 33 31  38 39 37  46 47 43  53 55 47
-61 61 53  66 65 55  66 65 55  66 65 55  61 61 53  53 55 47
-46 47 43  37 39 37  30 33 30  24 26 24  17 21 21  15 18 18
-13 17 17  12 15 15  12 15 15  13 16 16  14 18 18  14 18 18
-14 17 17  12 15 15  30 31 28  118 116 76  134 131 96  160 154 106
-174 170 121  178 174 128  178 174 128  171 165 117  151 147 98  96 95 69
-10 12 12  10 12 12  6 8 8  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  63 64 60  68 70 65  68 70 65
-65 66 61  58 59 55  49 51 48  39 40 39  30 32 31  23 27 26
-20 24 24  18 22 22  17 21 21  16 20 20  17 21 21  20 23 23
-25 27 26  32 35 33  43 44 41  53 55 47  66 65 55  75 75 61
-82 81 62  84 83 72  87 86 72  87 86 72  82 81 62  75 75 61
-66 65 55  53 55 47  40 41 39  31 33 31  23 25 24  17 20 20
-14 18 18  13 16 16  12 15 15  12 15 15  13 17 17  14 18 18
-14 18 18  13 16 16  46 47 43  96 95 69  125 122 87  142 137 94
-160 154 106  165 161 109  164 159 111  155 149 109  142 137 94  75 75 61
-10 12 12  10 12 12  6 8 8  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  60 60 56  68 70 65  68 70 65
-63 64 60  55 57 54  46 47 45  35 37 36  27 30 29  23 25 24
-18 22 22  17 21 21  16 20 20  17 21 21  18 22 22  23 27 26
-31 33 31  43 44 41  55 56 53  71 71 57  84 83 72  92 91 72
-103 101 77  92 91 72  82 81 62  82 81 62  87 86 72  92 91 72
-84 83 72  71 71 57  55 56 53  43 44 41  30 33 30  22 24 23
-16 19 19  14 17 17  12 15 15  12 15 15  13 16 16  14 18 18
-14 18 18  14 17 17  43 44 41  82 81 62  118 116 76  125 122 87
-142 137 94  144 139 99  144 139 99  134 131 96  118 116 76  53 55 47
-10 12 12  10 12 12  6 8 8  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  47 48 46  63 64 60  63 64 60
-55 57 54  49 51 48  40 43 41  32 34 33  26 28 27  20 24 24
-18 22 22  16 20 20  16 20 20  17 21 21  20 24 24  28 31 30
-40 41 39  53 55 47  75 75 61  90 89 73  87 86 72  48 49 45
-14 14 13  2 2 2  1 2 2  1 1 1  1 1 1  2 2 2
-19 20 18  43 44 41  66 65 55  53 55 47  38 39 37  26 28 27
-18 22 22  14 18 18  13 16 16  12 15 15  12 15 15  13 17 17
-14 18 18  14 18 18  30 31 28  66 65 55  96 95 69  103 101 77
-118 116 76  118 116 76  118 116 76  118 116 76  103 101 77  36 38 35
-10 12 12  10 12 12  6 7 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  28 31 30  55 57 54  51 52 50
-49 51 48  41 42 42  35 37 36  28 31 30  23 27 26  20 23 23
-17 21 21  16 20 20  16 20 20  18 22 22  23 27 26  33 36 34
-48 49 45  71 71 57  82 81 62  43 44 41  8 9 9  6 7 7
-6 7 7  6 7 7  6 7 7  5 6 5  4 5 5  3 4 4
-2 3 3  1 2 2  4 5 4  36 38 35  48 49 45  32 35 33
-21 25 23  16 19 19  13 17 17  12 15 15  12 15 15  13 16 16
-14 18 18  14 18 18  16 18 16  36 38 35  61 61 53  82 81 62
-96 95 69  96 95 69  96 95 69  96 95 69  79 78 62  19 20 18
-10 12 12  10 12 12  4 5 5  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  13 13 13  46 47 45  43 45 43
-40 43 41  35 37 36  30 32 31  23 27 26  20 24 24  18 22 22
-17 21 21  16 20 20  17 21 21  20 23 23  27 30 29  40 41 39
-61 61 53  53 55 47  16 17 16  9 11 11  10 12 12  10 12 12
-10 12 12  10 12 12  10 12 12  9 11 11  8 10 10  8 9 9
-6 8 8  5 6 5  4 5 5  2 3 3  19 20 18  38 39 37
-26 28 27  17 21 21  14 17 17  13 16 16  12 15 15  12 15 15
-13 17 17  14 18 18  12 15 15  13 12 7  30 31 28  46 47 43
-53 55 47  66 65 55  66 65 55  53 55 47  36 38 35  10 12 12
-10 12 12  10 12 12  2 3 3  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  1 1 1  33 37 35  35 37 36
-32 35 33  28 31 30  23 27 26  20 24 24  18 22 22  17 21 21
-16 20 20  16 20 20  17 21 21  21 25 23  31 33 31  44 46 43
-31 33 31  11 13 13  12 14 14  12 15 15  13 16 16  14 17 17
-14 17 17  14 17 17  14 17 17  13 16 16  12 15 15  12 14 14
-11 13 13  9 11 11  8 10 10  6 8 8  4 5 5  17 18 17
-30 33 30  20 23 22  15 18 18  13 16 16  12 15 15  12 14 14
-13 16 16  14 17 17  14 18 18  11 12 11  7 7 5  16 17 12
-21 22 20  30 31 28  25 27 25  21 22 20  14 14 13  10 12 12
-10 12 12  9 11 11  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  18 22 22  27 30 29
-27 29 28  40 41 39  53 55 47  53 55 47  53 55 47  46 47 43
-25 27 25  16 20 20  17 21 21  23 25 24  31 33 31  20 20 20
-12 15 15  14 17 17  15 19 19  16 20 20  17 21 21  18 22 22
-18 22 22  18 22 22  18 22 22  17 21 21  17 21 21  16 19 19
-15 18 18  13 16 16  12 15 15  10 12 12  8 10 10  6 8 8
-21 22 21  22 24 23  15 19 19  13 17 17  13 16 16  12 15 15
-12 15 15  13 17 17  14 18 18  14 18 18  13 15 14  10 9 6
-7 7 5  7 7 5  7 7 5  9 11 11  10 12 12  10 12 12
-10 12 12  6 7 7  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  16 17 12  82 81 62
-118 116 76  118 116 76  161 156 96  161 156 96  161 156 96  118 116 76
-118 116 76  96 95 69  53 55 47  22 24 23  14 17 17  13 16 16
-15 19 19  17 21 21  18 22 22  20 24 24  20 24 24  23 27 26
-23 27 26  23 27 26  23 27 26  23 27 26  23 27 26  20 24 24
-20 23 23  17 21 21  16 19 19  14 17 17  12 15 15  10 12 12
-9 11 11  20 23 22  16 19 19  14 17 17  13 16 16  12 15 15
-11 14 14  13 16 16  14 17 17  14 18 18  14 17 17  12 15 15
-10 12 12  10 12 12  10 12 12  10 12 12  10 12 12  10 12 12
-9 11 11  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  53 55 47  161 156 96
-161 156 96  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  161 156 96  118 116 76  96 95 69  21 22 20  16 19 19
-18 22 22  20 24 24  23 27 26  23 27 26  26 28 27  27 30 29
-27 30 29  18 22 22  12 14 14  8 10 10  9 11 11  17 21 21
-23 27 26  23 27 26  20 24 24  18 22 22  16 20 20  14 17 17
-12 14 14  14 17 17  16 20 20  14 17 17  13 17 17  13 16 16
-12 15 15  12 15 15  13 17 17  14 18 18  14 17 17  13 16 16
-11 13 13  10 12 12  10 12 12  10 12 12  10 12 12  10 12 12
-4 5 5  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  13 12 7  118 116 76  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  161 156 96  118 116 76  30 31 28
-20 24 24  23 27 26  27 30 29  28 31 30  30 32 31  23 27 26
-16 19 19  17 21 21  12 15 15  9 11 11  10 12 12  9 11 11
-20 24 24  28 31 30  26 28 27  23 27 26  20 24 24  17 21 21
-15 19 19  13 16 16  16 19 19  14 18 18  14 17 17  13 16 16
-12 15 15  11 14 14  13 16 16  14 17 17  14 18 18  14 17 17
-12 15 15  10 12 12  10 12 12  10 12 12  10 12 12  8 9 9
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  82 81 62  161 156 96  230 229 82
-230 229 82  233 233 100  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  161 156 96  118 116 76
-27 29 28  27 30 29  30 32 31  30 32 31  23 27 26  20 24 24
-26 28 27  17 21 21  6 7 7  72 73 67  145 141 105  15 15 15
-14 17 17  33 37 35  30 32 31  28 31 30  26 28 27  23 27 26
-20 23 23  16 20 20  15 19 19  14 18 18  14 17 17  13 16 16
-12 15 15  11 14 14  12 15 15  13 17 17  14 18 18  14 17 17
-13 16 16  11 13 13  10 12 12  10 12 12  9 11 11  1 1 1
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  16 17 12  161 156 96  230 229 82  230 229 82
-243 242 120  235 234 117  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  161 156 96
-82 81 62  28 31 30  28 31 30  27 30 29  28 31 30  30 32 31
-33 37 35  13 16 16  3 3 3  105 104 92  210 208 158  12 14 14
-17 21 21  33 37 35  33 37 35  32 35 33  30 32 31  27 30 29
-23 27 26  20 23 23  17 20 20  15 18 18  14 18 18  13 17 17
-13 16 16  12 15 15  11 14 14  13 16 16  14 17 17  14 18 18
-13 17 17  12 15 15  10 12 12  10 12 12  3 4 4  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  96 95 69  230 229 82  230 229 82  244 244 132
-241 241 143  243 242 120  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-161 156 96  46 47 43  32 35 33  33 37 35  33 37 35  33 37 35
-40 43 41  23 27 26  1 1 1  2 2 2  24 26 24  14 17 17
-23 27 26  33 37 35  33 37 35  33 37 35  33 37 35  30 32 31
-27 30 29  23 27 26  20 23 23  15 18 18  14 18 18  14 17 17
-13 16 16  12 15 15  11 14 14  12 15 15  13 17 17  14 17 17
-14 17 17  13 16 16  11 13 13  6 8 8  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  16 17 12  161 156 96  230 229 82  235 234 117  239 239 170
-239 239 170  236 236 101  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  118 116 76  33 37 35  33 37 35  37 39 37  37 39 37
-43 45 43  49 51 48  20 24 24  8 10 10  17 20 20  35 37 36
-33 37 35  40 43 41  37 39 37  35 37 36  33 37 35  33 37 35
-30 32 31  27 30 29  23 27 26  15 19 19  14 18 18  14 17 17
-13 17 17  13 16 16  12 15 15  11 14 14  13 16 16  14 17 17
-14 17 17  13 17 17  11 14 14  4 5 5  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  96 95 69  230 229 82  230 229 82  239 239 170  251 251 187
-241 241 143  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  161 156 96  36 38 35  33 37 35  33 37 35  33 37 35
-37 39 37  47 48 46  55 57 54  55 57 54  49 51 48  43 45 43
-43 45 43  43 45 43  40 43 41  40 43 41  37 39 37  33 37 35
-33 37 35  28 31 30  26 28 27  16 20 20  15 18 18  14 18 18
-14 17 17  13 16 16  12 15 15  11 14 14  12 15 15  13 17 17
-14 17 17  14 17 17  8 10 10  5 7 7  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-16 17 12  230 229 82  230 229 82  243 242 120  251 251 187  251 251 187
-246 246 123  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  66 65 55  30 32 31  32 35 33  33 37 35
-33 37 35  37 39 37  40 43 41  47 48 46  49 51 48  51 52 50
-55 57 54  55 57 54  51 52 50  47 48 46  43 45 43  39 40 39
-33 37 35  30 32 31  26 28 27  17 21 21  15 19 19  14 18 18
-14 17 17  13 16 16  12 15 15  12 14 14  11 14 14  13 16 16
-14 17 17  12 15 15  7 9 9  6 8 8  1 1 1  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-96 95 69  230 229 82  230 229 82  239 239 170  251 251 187  239 239 170
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  96 95 69  27 30 29  28 31 30  30 32 31
-33 37 35  40 43 41  46 47 45  55 57 54  63 64 60  72 73 67
-72 73 67  72 73 67  72 73 67  65 66 61  55 57 54  47 48 46
-39 40 39  32 35 33  27 30 29  17 21 21  15 19 19  15 18 18
-14 18 18  13 17 17  13 16 16  12 15 15  11 14 14  12 14 14
-13 16 16  9 11 11  7 9 9  9 11 11  66 65 55  115 113 82
-21 22 20  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  13 12 7
-230 229 82  230 229 82  236 236 101  251 251 187  251 251 187  246 246 123
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  118 116 76  23 27 26  26 28 27  32 35 33
-51 52 50  90 89 73  110 109 94  145 141 105  168 163 120  177 172 135
-177 172 135  188 184 146  188 184 146  181 176 137  194 191 148  188 184 146
-184 179 149  188 184 146  188 184 146  156 151 111  177 172 135  181 176 137
-177 172 135  168 163 120  168 163 120  158 153 112  156 151 111  158 153 112
-156 151 111  158 153 112  177 172 135  188 184 146  188 184 146  194 189 146
-36 38 35  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  82 81 62
-230 229 82  230 229 82  244 244 132  251 251 187  244 244 132  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  161 156 96  82 81 62
-96 95 69  230 229 82  181 178 103  110 109 94  156 151 111  188 184 146
-188 184 146  197 193 154  188 184 146  184 181 136  188 184 146  168 163 120
-168 163 120  178 174 128  156 151 111  158 153 112  174 170 121  156 151 111
-156 151 111  158 153 112  156 151 111  168 163 120  178 174 128  181 176 137
-176 171 126  178 174 128  184 181 136  176 171 126  178 174 128  184 181 136
-176 171 126  178 174 128  184 181 136  164 159 111  155 149 109  96 95 69
-1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  2 2 1  161 156 96
-230 229 82  230 229 82  244 244 132  244 244 132  236 236 101  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  46 47 43  82 81 62
-158 153 112  197 193 154  194 189 146  184 181 136  188 184 146  168 163 120
-156 151 111  137 133 100  131 127 93  137 133 100  137 133 100  158 153 112
-121 119 87  137 133 100  156 151 111  145 141 105  99 98 80  84 83 72
-63 64 60  52 53 49  40 43 41  33 36 34  36 38 35  36 38 35
-38 39 37  43 44 41  43 44 41  46 47 43  48 49 45  48 49 45
-46 47 43  36 38 35  30 31 28  19 20 18  6 7 7  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  36 38 35  230 229 82
-230 229 82  230 229 82  246 246 123  236 236 101  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  53 55 47  121 119 87
-176 171 126  171 165 117  161 156 96  82 81 62  53 55 47  33 37 35
-39 40 39  63 64 60  99 98 80  121 119 87  137 133 100  177 172 135
-176 171 126  184 181 136  131 127 93  131 127 93  110 109 94  84 83 72
-51 52 50  39 40 39  27 29 28  18 22 22  16 19 19  15 19 19
-15 19 19  14 18 18  14 17 17  13 16 16  12 15 15  11 14 14
-10 13 13  9 12 12  9 11 11  8 9 9  7 9 9  1 1 1
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  118 116 76  230 229 82
-230 229 82  230 229 82  236 236 101  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  96 95 69  71 71 57
-36 38 35  118 116 76  118 116 76  12 15 15  15 18 18  20 24 24
-33 37 35  55 56 53  84 83 72  110 109 94  145 141 105  110 109 94
-168 163 120  121 119 87  156 151 111  131 127 93  87 86 72  61 63 57
-47 48 46  28 31 30  18 22 22  15 19 19  15 18 18  15 19 19
-15 19 19  14 18 18  14 17 17  13 17 17  13 16 16  12 15 15
-11 13 13  10 12 12  9 11 11  8 10 10  7 9 9  3 3 3
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  1 1 0  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  161 156 96
-161 156 96  230 229 82  118 116 76  11 14 14  14 17 17  18 22 22
-27 30 29  40 43 41  60 60 56  84 83 72  105 104 92  110 109 94
-110 109 94  110 109 94  99 98 80  90 89 73  68 70 65  47 48 46
-32 34 33  23 25 24  20 23 23  17 21 21  15 19 19  14 17 17
-15 19 19  15 18 18  14 18 18  13 17 17  13 16 16  12 15 15
-11 14 14  10 12 12  9 11 11  8 10 10  7 9 9  4 5 5
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  16 17 12  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  161 156 96  118 116 76  11 13 13  13 16 16  15 19 19
-20 24 24  30 32 31  40 43 41  51 52 50  63 64 60  72 73 67
-65 66 61  65 66 61  65 66 61  55 57 54  46 47 45  33 37 35
-27 29 28  20 24 24  17 21 21  16 20 20  16 20 20  15 19 19
-15 19 19  15 19 19  14 18 18  14 17 17  13 16 16  12 15 15
-11 14 14  10 13 13  9 12 12  8 10 10  7 9 9  6 7 7
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  53 55 47  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-161 156 96  118 116 76  53 55 47  10 13 13  12 15 15  14 17 17
-17 20 20  20 24 24  27 29 28  32 34 33  37 39 37  40 43 41
-43 45 43  41 42 42  35 37 36  30 32 31  28 31 30  23 27 26
-20 23 23  17 21 21  16 20 20  16 20 20  16 20 20  16 19 19
-15 19 19  15 19 19  14 18 18  14 17 17  13 16 16  12 15 15
-11 14 14  10 13 13  9 12 12  9 11 11  8 10 10  10 12 12
-1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  82 81 62  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  161 156 96  161 156 96
-118 116 76  82 81 62  13 14 12  10 13 13  12 15 15  13 17 17
-15 19 19  16 20 20  20 23 23  20 24 24  23 27 26  26 28 27
-26 28 27  26 28 27  23 27 26  18 22 22  20 23 23  17 21 21
-17 21 21  16 20 20  16 20 20  16 20 20  16 20 20  16 19 19
-15 19 19  15 19 19  15 18 18  14 17 17  13 17 17  13 16 16
-12 15 15  12 14 14  12 14 14  12 14 14  12 14 14  23 24 24
-6 8 8  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  118 116 76  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  161 156 96  161 156 96  118 116 76
-71 71 57  13 14 12  9 12 12  10 13 13  12 15 15  13 17 17
-15 18 18  15 19 19  16 20 20  17 21 21  17 21 21  18 22 22
-18 22 22  18 22 22  17 21 21  16 19 19  15 18 18  14 18 18
-16 19 19  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-15 19 19  15 19 19  15 18 18  14 18 18  16 20 20  23 25 24
-17 21 21  25 27 26  47 48 46  47 48 46  51 52 50  72 73 67
-33 36 34  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  118 116 76  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  161 156 96  118 116 76  118 116 76  46 47 43
-9 11 11  9 11 11  10 12 12  11 13 13  12 15 15  14 17 17
-15 18 18  15 19 19  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-15 19 19  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-15 19 19  16 20 20  20 24 24  55 56 53  32 34 33  84 83 72
-90 89 73  110 109 94  110 109 94  105 104 92  110 109 94  110 109 94
-72 73 67  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  96 95 69  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  161 156 96  118 116 76  82 81 62  16 17 12  9 11 11
-9 11 11  9 12 12  10 13 13  12 14 14  13 16 16  14 18 18
-15 19 19  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 19 19  33 36 34  99 98 80  156 151 111  145 141 105  184 179 149
-168 163 120  184 179 149  177 172 135  156 151 111  145 141 105  110 109 94
-90 89 73  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  71 71 57  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  230 229 82
-230 229 82  161 156 96  230 229 82  230 229 82  230 229 82  161 156 96
-118 116 76  82 81 62  30 31 28  9 11 11  9 11 11  9 11 11
-10 12 12  10 13 13  11 14 14  13 16 16  14 17 17  15 18 18
-15 19 19  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-18 22 22  58 59 55  137 133 100  197 193 154  214 212 158  210 208 158
-197 193 154  184 179 149  184 179 149  137 133 100  110 109 94  99 98 80
-84 83 72  10 10 9  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  16 17 12  230 229 82  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  230 229 82  161 156 96
-161 156 96  161 156 96  161 156 96  161 156 96  118 116 76  71 71 57
-21 22 20  12 14 14  11 13 13  10 12 12  10 12 12  10 13 13
-11 13 13  12 15 15  13 16 16  14 17 17  14 18 18  15 19 19
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  17 21 21
-23 27 26  84 83 72  184 179 149  251 251 187  210 208 158  184 179 149
-184 179 149  156 151 111  110 109 94  84 83 72  63 64 60  51 52 50
-18 22 22  6 8 8  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  118 116 76  230 229 82
-230 229 82  230 229 82  230 229 82  230 229 82  161 156 96  161 156 96
-161 156 96  161 156 96  118 116 76  53 55 47  20 23 22  16 19 19
-13 16 16  12 15 15  12 14 14  11 14 14  11 14 14  11 14 14
-12 15 15  13 16 16  14 17 17  15 19 19  16 20 20  17 21 21
-23 27 26  18 22 22  20 24 24  23 27 26  30 32 31  17 21 21
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-23 27 26  33 37 35  137 133 100  156 151 111  158 153 112  105 104 92
-105 104 92  68 70 65  39 40 39  18 22 22  12 14 14  12 15 15
-9 11 11  4 5 5  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  16 17 12  230 229 82
-230 229 82  230 229 82  230 229 82  161 156 96  118 116 76  118 116 76
-118 116 76  66 65 55  43 45 43  32 34 33  25 27 26  20 23 22
-17 20 20  15 18 18  14 17 17  15 18 18  13 16 16  14 17 17
-14 18 18  16 20 20  32 34 33  55 57 54  58 59 55  72 73 67
-105 104 92  55 57 54  65 66 61  63 64 60  40 43 41  33 37 35
-41 42 42  20 24 24  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-17 21 21  26 28 27  30 32 31  35 37 36  68 70 65  39 40 39
-23 27 26  15 18 18  13 16 16  11 14 14  9 12 12  8 10 10
-7 9 9  6 7 7  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 38 35
-230 229 82  230 229 82  230 229 82  96 95 69  30 31 28  49 51 48
-90 89 73  68 70 65  55 57 54  47 48 46  47 48 46  43 45 43
-32 34 33  43 45 43  43 45 43  23 27 26  25 27 26  40 43 41
-40 43 41  90 89 73  110 109 94  145 141 105  156 151 111  156 151 111
-184 179 149  184 179 149  177 172 135  184 179 149  137 133 100  84 83 72
-105 104 92  63 64 60  49 51 48  47 48 46  28 31 30  18 22 22
-16 20 20  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  15 19 19  15 19 19  15 19 19  18 22 22  15 19 19
-13 16 16  12 15 15  11 14 14  10 13 13  9 12 12  9 11 11
-8 10 10  6 8 8  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-30 31 28  230 229 82  71 71 57  2 2 1  0 0 0  58 59 55
-105 104 92  84 83 72  65 66 61  84 83 72  110 109 94  110 109 94
-145 141 105  105 104 92  110 109 94  110 109 94  84 83 72  110 109 94
-158 153 112  197 193 154  197 193 154  239 239 170  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  210 208 158  197 193 154
-197 193 154  184 179 149  145 141 105  137 133 100  105 104 92  47 48 46
-20 23 23  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 19 19  15 19 19  15 19 19  14 18 18  14 17 17
-13 17 17  13 16 16  12 14 14  12 14 14  13 13 13  13 13 13
-13 13 13  12 12 12  10 10 9  6 7 7  2 2 2  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 0  0 0 0  0 0 0  65 66 61
-105 104 92  84 83 72  84 83 72  110 109 94  184 179 149  210 208 158
-210 208 158  210 208 158  214 212 158  197 193 154  214 212 158  210 208 158
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  239 239 170  251 251 187  184 179 149  84 83 72
-26 28 27  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  15 19 19  15 19 19  15 18 18  14 18 18
-13 17 17  13 16 16  15 15 15  14 14 13  14 14 13  14 14 13
-13 13 13  13 13 13  12 12 12  12 12 12  12 12 12  3 4 4
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  72 73 67
-105 104 92  99 98 80  84 83 72  99 98 80  177 172 135  197 193 154
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  214 212 158  197 193 154  99 98 80
-23 27 26  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  15 19 19  15 19 19  15 18 18  14 18 18
-14 17 17  16 16 16  16 16 16  16 16 16  15 15 15  14 14 13
-14 14 13  13 13 13  13 13 13  12 12 12  12 12 12  12 12 12
-3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  84 83 72
-110 109 94  99 98 80  72 73 67  63 64 60  99 98 80  177 172 135
-184 179 149  210 208 158  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  210 208 158  184 179 149  177 172 135  110 109 94  33 37 35
-17 21 21  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-16 20 20  16 20 20  15 19 19  15 19 19  15 19 19  14 18 18
-15 18 18  18 19 18  18 19 18  17 17 17  16 16 16  15 15 15
-14 14 13  13 13 13  13 13 13  12 12 12  12 12 12  12 12 12
-10 10 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  105 104 92
-108 107 93  99 98 80  72 73 67  63 64 60  51 52 50  87 86 72
-105 104 92  110 109 94  108 107 93  156 151 111  184 179 149  184 179 149
-197 193 154  197 193 154  197 193 154  184 179 149  184 179 149  177 172 135
-197 193 154  156 151 111  177 172 135  184 179 149  168 163 120  137 133 100
-145 141 105  110 109 94  99 98 80  47 48 46  55 57 54  15 19 19
-16 19 19  16 20 20  16 20 20  16 20 20  16 20 20  16 20 20
-17 20 20  17 21 21  16 20 20  16 19 19  15 19 19  16 19 19
-20 20 20  21 22 21  20 20 20  19 20 19  18 19 18  16 16 16
-15 15 15  14 14 13  13 13 13  13 13 13  12 12 12  12 12 12
-12 12 12  4 5 5  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  58 59 55  110 109 94
-105 104 92  90 89 73  72 73 67  55 57 54  43 45 43  39 40 39
-43 45 43  46 47 45  43 45 43  68 70 65  65 66 61  63 64 60
-108 107 93  72 73 67  105 104 92  90 89 73  72 73 67  40 43 41
-72 73 67  68 70 65  68 70 65  58 59 55  63 64 60  49 51 48
-43 45 43  33 36 34  27 30 29  20 24 24  16 20 20  15 19 19
-15 19 19  15 19 19  15 19 19  16 19 19  16 20 20  16 20 20
-17 21 21  20 24 24  20 23 22  17 21 21  17 20 20  20 20 20
-21 22 21  21 22 21  21 22 21  21 22 21  20 20 20  18 19 18
-16 16 16  15 15 15  13 13 13  13 13 13  12 12 12  12 12 12
-12 12 12  10 10 9  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  21 22 21  110 109 94  110 109 94
-105 104 92  84 83 72  68 70 65  51 52 50  41 42 42  33 37 35
-28 31 30  23 27 26  20 23 23  18 22 22  17 20 20  25 27 26
-26 28 27  27 30 29  25 27 26  20 23 23  23 27 26  30 32 31
-20 24 24  17 21 21  18 22 22  15 19 19  26 28 27  20 23 23
-14 18 18  15 19 19  15 18 18  15 19 19  15 19 19  15 19 19
-15 19 19  15 19 19  15 19 19  15 19 19  15 19 19  16 19 19
-16 20 20  22 24 23  24 26 24  22 24 23  20 23 22  22 24 23
-24 26 24  24 26 24  23 24 24  22 24 23  21 22 21  19 20 19
-17 17 17  15 15 15  14 14 13  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  2 2 2  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  2 2 2  99 98 80  110 109 94  108 107 93
-105 104 92  84 83 72  63 64 60  49 51 48  39 40 39  32 34 33
-27 30 29  23 25 24  20 23 23  17 20 20  15 19 19  14 18 18
-14 17 17  13 17 17  13 17 17  13 17 17  13 17 17  13 17 17
-14 17 17  14 17 17  14 17 17  14 17 17  14 17 17  14 17 17
-14 18 18  14 18 18  14 18 18  14 18 18  15 18 18  15 19 19
-15 19 19  15 19 19  15 19 19  15 19 19  15 19 19  15 19 19
-15 19 19  17 21 21  27 29 28  26 28 27  25 27 26  25 27 26
-27 29 28  27 29 28  26 28 27  24 26 24  21 22 21  20 20 20
-18 19 18  16 16 16  14 14 13  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  4 5 5  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  51 52 50  110 109 94  110 109 94  105 104 92
-90 89 73  72 73 67  55 57 54  43 45 43  35 37 36  30 32 31
-26 28 27  20 24 24  17 21 21  16 19 19  15 18 18  14 17 17
-13 16 16  13 16 16  13 16 16  13 16 16  13 16 16  13 16 16
-13 16 16  13 16 16  13 16 16  13 17 17  13 17 17  14 17 17
-14 17 17  14 17 17  14 17 17  14 18 18  14 18 18  14 18 18
-15 18 18  15 18 18  15 19 19  15 19 19  15 19 19  15 19 19
-15 19 19  15 19 19  27 29 28  32 34 33  28 31 30  27 29 28
-30 32 31  30 32 31  30 31 28  26 28 27  23 24 24  21 22 21
-19 20 19  16 16 16  14 14 13  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  6 7 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  3 3 3  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  10 10 9  108 107 93  110 109 94  108 107 93  99 98 80
-84 83 72  63 64 60  49 51 48  40 43 41  33 36 34  27 30 29
-23 27 26  18 22 22  17 20 20  15 18 18  14 17 17  13 16 16
-13 16 16  13 16 16  12 15 15  12 15 15  12 15 15  12 15 15
-13 16 16  13 16 16  13 16 16  13 16 16  13 16 16  13 16 16
-13 17 17  13 17 17  14 17 17  14 17 17  14 17 17  14 18 18
-14 18 18  14 18 18  15 18 18  15 18 18  15 19 19  15 19 19
-15 19 19  15 19 19  17 21 21  33 36 34  32 34 33  31 33 31
-33 36 34  33 36 34  31 33 31  27 29 28  25 27 26  21 22 21
-19 20 19  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  8 8 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  63 64 60  137 133 100  43 45 43  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  68 70 65  110 109 94  110 109 94  105 104 92  84 83 72
-68 70 65  55 57 54  43 45 43  35 37 36  30 32 31  26 28 27
-20 24 24  17 21 21  16 19 19  14 17 17  13 16 16  12 15 15
-12 15 15  12 15 15  12 15 15  12 15 15  12 15 15  12 15 15
-12 15 15  12 15 15  12 15 15  12 15 15  12 15 15  13 16 16
-13 16 16  13 16 16  13 16 16  13 17 17  13 17 17  14 17 17
-14 17 17  14 17 17  14 18 18  14 18 18  14 18 18  15 18 18
-15 19 19  15 19 19  15 19 19  20 24 24  32 34 33  35 37 36
-37 39 37  35 37 36  33 36 34  30 32 31  26 28 27  22 24 23
-20 20 20  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  8 8 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-1 1 1  99 98 80  184 179 149  184 179 149  68 70 65  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-15 15 15  110 109 94  110 109 94  108 107 93  99 98 80  72 73 67
-61 63 57  49 51 48  39 40 39  33 36 34  27 30 29  23 25 24
-18 22 22  16 19 19  14 17 17  13 16 16  12 15 15  12 15 15
-11 14 14  11 14 14  11 14 14  11 14 14  11 14 14  11 14 14
-11 14 14  11 14 14  12 14 14  12 15 15  12 15 15  12 15 15
-12 15 15  13 16 16  13 16 16  13 16 16  13 16 16  13 16 16
-13 17 17  14 17 17  14 17 17  14 17 17  14 18 18  14 18 18
-14 18 18  15 18 18  15 19 19  15 19 19  30 32 31  38 39 37
-39 40 39  39 40 39  35 37 36  31 33 31  27 29 28  22 24 23
-20 20 20  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  8 8 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  3 3 3
-110 109 94  197 193 154  210 208 158  184 179 149  68 70 65  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-68 70 65  110 109 94  110 109 94  105 104 92  84 83 72  65 66 61
-51 52 50  43 45 43  35 37 36  30 32 31  25 27 26  20 23 23
-17 20 20  15 18 18  13 16 16  12 15 15  12 15 15  11 14 14
-11 14 14  11 14 14  11 13 13  11 13 13  11 13 13  11 13 13
-11 14 14  11 14 14  11 14 14  11 14 14  11 14 14  11 14 14
-12 15 15  12 15 15  12 15 15  12 15 15  13 16 16  13 16 16
-13 16 16  13 16 16  13 17 17  13 17 17  14 17 17  14 17 17
-14 18 18  14 18 18  14 18 18  16 19 19  37 39 37  41 42 42
-41 42 42  41 42 42  38 39 37  32 34 33  27 29 28  23 24 24
-21 22 21  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  8 8 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  11 11 11  137 133 100
-197 193 154  251 251 187  239 239 170  184 179 149  31 33 31  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  12 12 12
-110 109 94  110 109 94  105 104 92  90 89 73  72 73 67  58 59 55
-46 47 45  37 39 37  31 33 31  26 28 27  20 24 24  17 21 21
-15 18 18  13 16 16  12 15 15  12 14 14  11 13 13  11 13 13
-10 13 13  10 13 13  10 13 13  10 13 13  10 13 13  10 13 13
-10 13 13  10 13 13  11 13 13  11 13 13  11 14 14  11 14 14
-11 14 14  11 14 14  12 14 14  12 15 15  12 15 15  12 15 15
-13 16 16  13 16 16  13 16 16  13 16 16  13 17 17  13 17 17
-14 17 17  14 17 17  14 18 18  23 27 26  41 42 42  41 42 42
-43 45 43  41 42 42  39 40 39  33 36 34  27 29 28  23 24 24
-21 22 21  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  6 7 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  27 29 28  168 163 120  210 208 158
-251 251 187  251 251 187  210 208 158  137 133 100  1 1 1  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  60 60 56
-110 109 94  105 104 92  105 104 92  84 83 72  65 66 61  51 52 50
-40 43 41  33 36 34  27 30 29  23 25 24  18 22 22  16 19 19
-14 17 17  12 15 15  11 14 14  11 14 14  10 13 13  10 13 13
-10 13 13  10 12 12  10 12 12  10 12 12  10 12 12  10 12 12
-10 12 12  10 12 12  10 13 13  10 13 13  10 13 13  11 13 13
-11 13 13  11 14 14  11 14 14  11 14 14  11 14 14  12 15 15
-12 15 15  12 15 15  12 15 15  13 16 16  13 16 16  13 16 16
-13 17 17  13 17 17  14 17 17  32 34 33  43 45 43  43 45 43
-43 45 43  43 45 43  39 40 39  33 36 34  27 29 28  23 24 24
-21 22 21  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  6 7 7  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  1 1 1  68 70 65  184 179 149  210 208 158  251 251 187
-251 251 187  214 212 158  184 179 149  37 39 37  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  6 7 7  105 104 92
-105 104 92  105 104 92  99 98 80  72 73 67  58 59 55  46 47 45
-35 37 36  30 32 31  25 27 26  20 23 23  16 19 19  14 17 17
-12 15 15  12 14 14  11 13 13  10 13 13  10 12 12  10 12 12
-10 12 12  10 12 12  9 12 12  9 12 12  9 12 12  9 12 12
-10 12 12  10 12 12  10 12 12  10 12 12  10 12 12  10 13 13
-10 13 13  10 13 13  11 13 13  11 13 13  11 14 14  11 14 14
-11 14 14  12 15 15  12 15 15  12 15 15  12 15 15  13 16 16
-13 16 16  13 16 16  17 20 20  41 42 42  46 47 45  46 47 45
-46 47 45  43 45 43  40 41 39  33 36 34  27 29 28  23 24 24
-20 20 20  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  4 5 5  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-15 15 15  110 109 94  197 193 154  214 212 158  251 251 187  251 251 187
-239 239 170  184 179 149  84 83 72  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  47 48 46  105 104 92
-105 104 92  99 98 80  84 83 72  68 70 65  51 52 50  40 43 41
-32 34 33  27 29 28  22 24 23  17 21 21  15 18 18  13 16 16
-12 15 15  11 13 13  10 13 13  10 12 12  9 12 12  9 12 12
-9 12 12  9 12 12  9 11 11  9 11 11  9 11 11  9 11 11
-9 12 12  9 12 12  9 12 12  9 12 12  10 12 12  10 12 12
-10 12 12  10 12 12  10 13 13  10 13 13  10 13 13  11 13 13
-11 14 14  11 14 14  11 14 14  12 14 14  12 15 15  12 15 15
-12 15 15  13 16 16  28 31 30  43 45 43  47 48 46  47 48 46
-47 48 46  43 45 43  40 41 39  33 36 34  27 29 28  22 24 23
-20 20 20  17 17 17  15 15 15  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  3 4 4  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  60 60 56
-177 172 135  197 193 154  251 251 187  251 251 187  251 251 187  251 251 187
-184 179 149  110 109 94  3 4 4  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  1 1 1  99 98 80  105 104 92
-99 98 80  87 86 72  84 83 72  63 64 60  46 47 45  35 37 36
-30 32 31  25 27 26  18 22 22  16 19 19  14 17 17  12 15 15
-11 14 14  10 13 13  9 12 12  9 12 12  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 12 12  9 12 12
-9 12 12  10 12 12  10 12 12  10 12 12  10 13 13  10 13 13
-10 13 13  11 13 13  11 14 14  11 14 14  11 14 14  12 15 15
-12 15 15  14 17 17  41 42 42  47 48 46  49 51 48  51 52 50
-47 48 46  43 45 43  40 41 39  33 36 34  27 29 28  22 24 23
-19 20 19  16 16 16  14 14 13  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  2 2 2  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  23 24 24  137 133 100  184 179 149
-210 208 158  251 251 187  251 251 187  251 251 187  251 251 187  184 179 149
-110 109 94  13 13 13  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  30 32 31  105 104 92  99 98 80
-84 83 72  84 83 72  72 73 67  55 57 54  41 42 42  32 34 33
-27 29 28  20 24 24  17 20 20  14 17 17  13 16 16  12 14 14
-10 13 13  10 12 12  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 12 12  9 12 12  10 12 12  10 12 12  10 12 12
-10 13 13  10 13 13  10 13 13  11 13 13  11 14 14  11 14 14
-11 14 14  27 29 28  55 56 53  72 73 67  51 52 50  51 52 50
-49 51 48  43 45 43  39 40 39  32 34 33  26 28 27  21 22 21
-19 20 19  16 16 16  18 19 17  13 13 13  12 12 12  12 12 12
-12 12 12  12 12 12  1 1 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  8 8 7  84 83 72  184 179 149  197 193 154  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  184 179 149  145 141 105
-19 20 19  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  14 14 13  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  72 73 67  105 104 92  84 83 72
-72 73 67  84 83 72  68 70 65  49 51 48  39 40 39  30 32 31
-25 27 26  18 22 22  15 18 18  13 16 16  12 15 15  11 13 13
-10 12 12  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 12 12  9 12 12  9 12 12
-10 12 12  10 12 12  10 12 12  10 13 13  10 13 13  11 13 13
-13 16 16  41 42 42  99 98 80  158 153 112  65 66 61  51 52 50
-49 51 48  43 45 43  39 40 39  31 33 31  25 27 26  21 22 21
-21 22 21  68 70 65  55 56 53  13 13 13  12 12 12  12 12 12
-12 12 12  11 11 11  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  3 3 3
-63 64 60  158 153 112  184 179 149  210 208 158  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  184 179 149  137 133 100  27 29 28
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-21 22 21  110 109 94  5 6 5  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  13 13 13  105 104 92  90 89 73  72 73 67
-68 70 65  84 83 72  63 64 60  46 47 45  35 37 36  27 29 28
-22 24 23  17 20 20  14 17 17  12 15 15  11 14 14  10 12 12
-10 12 12  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 12 12  9 12 12  10 12 12  10 12 12  10 13 13  10 13 13
-30 32 31  47 48 46  177 172 135  210 208 158  137 133 100  55 56 53
-49 51 48  43 45 43  38 39 37  31 33 31  25 27 26  22 24 23
-110 109 94  184 179 149  63 64 60  13 13 13  12 12 12  12 12 12
-12 12 12  8 9 9  0 0 0  1 1 1  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  21 22 21  105 104 92
-184 179 149  210 208 158  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  251 251 187  184 179 149  145 141 105  23 24 24  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-68 70 65  184 179 149  105 104 92  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  51 52 50  99 98 80  84 83 72  63 64 60
-68 70 65  72 73 67  55 57 54  41 42 42  32 34 33  25 27 26
-20 23 23  16 19 19  13 16 16  12 14 14  10 13 13  10 12 12
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 12 12  9 12 12  10 12 12  17 20 20
-46 47 45  72 73 67  210 208 158  251 251 187  210 208 158  63 64 60
-49 51 48  43 45 43  37 39 37  30 32 31  24 26 24  105 104 92
-210 208 158  197 193 154  47 48 46  13 13 13  12 12 12  12 12 12
-12 12 12  6 7 7  33 36 34  48 49 45  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  8 8 7  23 24 24  55 56 53  110 109 94
-210 208 158  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  184 179 149  110 109 94  20 20 20  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-110 109 94  251 251 187  210 208 158  47 48 46  0 0 0  0 0 0
-0 0 0  1 1 1  90 89 73  90 89 73  72 73 67  55 56 53
-72 73 67  68 70 65  51 52 50  37 39 37  28 31 30  23 25 24
-17 21 21  15 18 18  12 15 15  11 14 14  10 13 13  9 12 12
-9 11 11  9 11 11  9 11 11  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  9 11 11  9 11 11  9 11 11  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  9 12 12  13 16 16  41 42 42
-49 51 48  110 109 94  251 251 187  251 251 187  251 251 187  105 104 92
-49 51 48  43 45 43  35 37 36  30 31 28  47 48 46  197 193 154
-251 251 187  197 193 154  31 33 31  12 12 12  12 12 12  12 12 12
-12 12 12  51 52 50  184 179 149  72 73 67  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  2 2 2
-11 11 11  21 22 21  30 32 31  40 41 39  60 60 56  145 141 105
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  214 212 158
-184 179 149  110 109 94  13 13 13  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  4 5 4  61 61 53  48 49 45  3 4 3
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-156 151 111  251 251 187  251 251 187  184 179 149  11 11 11  0 0 0
-0 0 0  26 28 27  99 98 80  84 83 72  60 60 56  43 45 43
-72 73 67  65 66 61  49 51 48  35 37 36  27 29 28  20 24 24
-17 20 20  14 17 17  12 15 15  11 13 13  10 12 12  9 11 11
-9 11 11  9 11 11  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  9 11 11  9 11 11
-9 11 11  9 11 11  9 11 11  11 13 13  37 39 37  47 48 46
-51 52 50  184 179 149  251 251 187  251 251 187  251 251 187  145 141 105
-47 48 46  41 42 42  35 37 36  27 29 28  137 133 100  251 251 187
-251 251 187  197 193 154  19 20 19  12 12 12  12 12 12  12 12 12
-27 29 28  184 179 149  214 212 158  63 64 60  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 1  6 7 7  16 16 16  24 26 24
-30 32 31  38 39 37  47 48 46  55 57 54  68 70 65  110 109 94
-197 193 154  251 251 187  251 251 187  251 251 187  210 208 158  184 179 149
-105 104 92  8 8 7  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  65 66 61  184 179 149  156 151 111
-30 32 31  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-168 163 120  251 251 187  251 251 187  251 251 187  110 109 94  0 0 0
-0 0 0  60 60 56  84 83 72  68 70 65  51 52 50  38 39 37
-84 83 72  63 64 60  43 45 43  33 36 34  25 27 26  20 23 22
-15 18 18  13 16 16  12 14 14  10 13 13  9 12 12  9 11 11
-9 11 11  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-9 11 11  9 11 11  10 12 12  33 36 34  46 47 45  51 52 50
-72 73 67  210 208 158  251 251 187  251 251 187  251 251 187  177 172 135
-47 48 46  41 42 42  35 37 36  37 39 37  184 179 149  251 251 187
-251 251 187  197 193 154  13 13 13  12 12 12  12 12 12  12 12 12
-110 109 94  251 251 187  251 251 187  37 39 37  0 0 0  0 0 0
-0 0 0  21 22 20  2 2 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-4 5 5  12 12 12  21 22 21  25 27 26  30 32 31  38 39 37
-46 47 45  55 56 53  60 60 56  65 66 61  68 70 65  105 104 92
-110 109 94  197 193 154  210 208 158  197 193 154  184 179 149  84 83 72
-2 2 2  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  13 13 13  184 179 149  251 251 187
-197 193 154  43 44 41  0 0 0  0 0 0  0 0 0  0 0 0
-145 141 105  251 251 187  251 251 187  251 251 187  214 212 158  43 45 43
-2 2 2  84 83 72  72 73 67  58 59 55  41 42 42  38 39 37
-72 73 67  58 59 55  41 42 42  31 33 31  25 27 26  18 22 22
-14 17 17  12 15 15  12 14 14  10 12 12  9 12 12  9 11 11
-9 11 11  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  9 12 12  31 33 31  43 45 43  49 51 48  55 56 53
-110 109 94  251 251 187  251 251 187  251 251 187  251 251 187  168 163 120
-47 48 46  41 42 42  33 36 34  63 64 60  197 193 154  251 251 187
-251 251 187  184 179 149  13 13 13  12 12 12  12 12 12  16 16 16
-197 193 154  251 251 187  239 239 170  20 20 20  0 0 0  2 2 1
-108 107 93  110 109 94  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 1  4 5 5  11 11 11  18 19 18
-22 24 23  26 28 27  32 34 33  39 40 39  46 47 45  51 52 50
-55 57 54  60 60 56  63 64 60  63 64 60  63 64 60  58 59 55
-63 64 60  99 98 80  145 141 105  137 133 100  43 45 43  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  3 4 3  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  110 109 94  251 251 187
-251 251 187  184 179 149  25 27 26  0 0 0  0 0 0  0 0 0
-99 98 80  251 251 187  251 251 187  251 251 187  251 251 187  156 151 111
-25 27 26  84 83 72  65 66 61  47 48 46  32 34 33  39 40 39
-72 73 67  55 57 54  40 41 39  30 32 31  23 25 24  18 22 22
-14 17 17  12 15 15  11 13 13  10 12 12  9 11 11  9 11 11
-9 11 11  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-9 11 11  28 31 30  41 42 42  47 48 46  55 56 53  58 59 55
-137 133 100  251 251 187  251 251 187  251 251 187  210 208 158  137 133 100
-47 48 46  40 41 39  32 34 33  75 75 61  184 179 149  239 239 170
-251 251 187  177 172 135  13 13 13  12 12 12  12 12 12  43 44 41
-197 193 154  251 251 187  210 208 158  10 10 9  0 0 0  84 83 72
-251 251 187  84 83 72  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
-6 7 7  11 11 11  17 17 17  20 20 20  23 24 24  27 29 28
-32 34 33  38 39 37  43 45 43  47 48 46  51 52 50  55 56 53
-58 59 55  58 59 55  55 57 54  55 56 53  47 48 46  41 42 42
-35 37 36  31 33 31  47 48 46  14 14 13  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  66 65 55  99 98 80  20 20 20
-0 0 0  0 0 0  0 0 0  0 0 0  43 45 43  214 212 158
-251 251 187  251 251 187  145 141 105  3 3 3  0 0 0  0 0 0
-48 49 45  184 179 149  239 239 170  251 251 187  239 239 170  177 172 135
-84 83 72  72 73 67  55 56 53  39 40 39  26 28 27  39 40 39
-68 70 65  51 52 50  39 40 39  28 31 30  22 24 23  17 20 20
-14 17 17  12 14 14  10 13 13  9 11 11  9 11 11  9 11 11
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-27 29 28  40 41 39  46 47 45  51 52 50  55 57 54  63 64 60
-131 127 93  197 193 154  210 208 158  197 193 154  168 163 120  96 95 69
-47 48 46  40 41 39  32 34 33  71 71 57  145 141 105  184 179 149
-184 179 149  131 127 93  13 13 13  12 12 12  12 12 12  48 49 45
-168 163 120  184 179 149  156 151 111  6 7 7  14 14 13  177 172 135
-239 239 170  40 41 39  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  3 3 3  6 7 7  11 11 11  16 16 16
-18 19 18  21 22 21  23 24 24  27 29 28  32 34 33  37 39 37
-41 42 42  43 45 43  47 48 46  51 52 50  51 52 50  51 52 50
-51 52 50  49 51 48  46 47 45  40 41 39  32 34 33  25 27 26
-20 20 20  14 14 13  2 2 2  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  33 36 34  197 193 154  184 179 149
-41 42 42  0 0 0  0 0 0  0 0 0  3 3 3  184 179 149
-251 251 187  251 251 187  184 179 149  48 49 45  0 0 0  0 0 0
-16 17 12  121 119 87  177 172 135  194 189 146  188 184 146  145 141 105
-82 81 62  63 64 60  46 47 45  31 33 31  21 22 21  35 37 36
-68 70 65  51 52 50  37 39 37  27 30 29  22 24 23  17 20 20
-13 16 16  12 14 14  10 13 13  9 11 11  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  25 27 26
-38 39 37  43 45 43  51 52 50  55 56 53  60 60 56  63 64 60
-92 91 72  158 153 112  176 171 126  171 165 117  149 143 98  82 81 62
-44 46 43  38 39 37  30 32 31  71 71 57  131 127 93  160 154 106
-149 143 98  82 81 62  13 13 13  12 12 12  12 12 12  46 47 43
-121 119 87  134 131 96  96 95 69  7 7 6  38 39 37  131 127 93
-145 141 105  12 13 12  0 0 0  1 1 1  3 3 3  6 7 7
-10 10 9  12 12 12  14 14 13  16 16 16  18 19 18  21 22 21
-22 24 23  26 28 27  30 31 28  33 36 34  37 39 37  40 41 39
-41 42 42  43 45 43  46 47 45  46 47 45  46 47 45  43 45 43
-41 42 42  37 39 37  31 33 31  26 28 27  21 22 21  16 16 16
-6 7 7  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  177 172 135  251 251 187
-197 193 154  27 29 28  0 0 0  0 0 0  0 0 0  110 109 94
-239 239 170  239 239 170  184 179 149  87 86 72  2 2 1  0 0 0
-1 1 1  82 81 62  142 137 94  165 161 109  165 161 109  131 127 93
-75 75 61  55 56 53  37 39 37  25 27 26  19 20 19  32 34 33
-65 66 61  49 51 48  35 37 36  27 29 28  20 23 23  16 19 19
-13 16 16  13 13 13  10 12 12  9 11 11  8 10 10  8 10 10
-8 9 9  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  22 24 23  35 37 36
-41 42 42  47 48 46  55 56 53  58 59 55  63 64 60  65 66 61
-71 71 57  131 127 93  160 154 106  160 154 106  142 137 94  82 81 62
-46 47 43  40 41 39  33 36 34  66 65 55  125 122 87  149 143 98
-142 137 94  82 81 62  17 17 17  18 19 17  14 14 13  46 47 43
-118 116 76  125 122 87  96 95 69  16 17 12  71 71 57  103 101 77
-82 81 62  11 11 11  11 11 11  13 13 13  14 14 13  14 14 13
-15 15 15  16 16 16  17 17 17  19 20 19  21 22 21  23 24 24
-26 28 27  27 29 28  31 33 31  33 36 34  35 37 36  38 39 37
-39 40 39  39 40 39  38 39 37  37 39 37  35 37 36  31 33 31
-27 29 28  24 26 24  21 22 21  17 17 17  12 12 12  2 2 2
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  68 70 65  251 251 187
-251 251 187  156 151 111  2 2 1  0 0 0  0 0 0  43 44 41
-177 172 135  184 179 149  158 153 112  103 101 77  19 20 18  0 0 0
-0 0 0  46 47 43  131 127 93  160 154 106  160 154 106  131 127 93
-71 71 57  43 45 43  30 32 31  21 22 21  16 16 16  26 28 27
-63 64 60  47 48 46  35 37 36  26 28 27  20 23 23  16 19 19
-13 16 16  13 13 13  10 12 12  9 11 11  8 10 10  8 10 10
-7 9 9  7 9 9  8 9 9  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  20 20 20  33 36 34  40 41 39
-46 47 45  51 52 50  55 57 54  60 60 56  63 64 60  65 66 61
-66 65 55  118 116 76  151 147 98  165 161 109  151 147 98  121 119 87
-96 95 69  96 95 69  96 95 69  103 101 77  142 137 94  151 147 98
-142 137 94  103 101 77  82 81 62  82 81 62  82 81 62  96 95 69
-131 127 93  142 137 94  103 101 77  46 47 43  96 95 69  118 116 76
-71 71 57  14 14 13  14 14 13  15 15 15  15 15 15  16 16 16
-16 16 16  17 17 17  18 19 18  20 20 20  21 22 21  23 24 24
-25 27 26  27 29 28  30 31 28  30 32 31  31 33 31  31 33 31
-31 33 31  31 33 31  30 31 28  27 29 28  25 27 26  22 24 23
-20 20 20  16 16 16  13 13 13  6 7 7  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-58 59 55  68 70 65  8 8 7  0 0 0  10 10 9  210 208 158
-251 251 187  184 179 149  38 39 37  0 0 0  0 0 0  8 8 7
-103 101 77  149 143 98  149 143 98  118 116 76  40 41 39  25 27 25
-53 55 47  82 81 62  144 139 99  165 161 109  165 161 109  142 137 94
-71 71 57  35 37 36  24 26 24  18 19 18  15 15 15  22 24 23
-63 64 60  46 47 45  33 36 34  26 28 27  20 23 22  17 18 17
-12 15 15  11 13 13  10 12 12  9 11 11  8 10 10  8 10 10
-7 9 9  7 9 9  7 9 9  7 9 9  8 9 9  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  16 16 16  30 31 28  35 37 36  41 42 42
-47 48 46  55 56 53  58 59 55  63 64 60  65 66 61  65 66 61
-61 61 53  103 101 77  151 147 98  171 165 117  171 165 117  168 163 120
-158 153 112  158 153 112  155 149 109  151 147 98  151 147 98  160 154 106
-151 147 98  149 143 98  142 137 94  149 143 98  149 143 98  149 143 98
-155 149 109  151 147 98  131 127 93  103 101 77  125 122 87  118 116 76
-71 71 57  16 16 16  16 16 16  16 16 16  17 17 17  17 17 17
-17 17 17  17 17 17  18 19 18  19 20 19  20 20 20  21 22 21
-23 24 24  24 26 24  25 27 26  26 28 27  26 28 27  26 28 27
-25 27 26  24 26 24  22 24 23  21 22 21  19 20 19  16 16 16
-14 14 13  8 8 7  1 1 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-20 20 20  184 179 149  168 163 120  21 22 21  0 0 0  105 104 92
-177 172 135  145 141 105  71 71 57  0 0 0  0 0 0  0 0 0
-66 65 55  131 127 93  151 147 98  142 137 94  118 116 76  121 119 87
-145 141 105  158 153 112  176 171 126  178 174 128  176 171 126  149 145 103
-96 95 69  31 33 31  21 22 21  16 16 16  14 14 13  18 19 18
-60 60 56  46 47 45  33 36 34  25 27 26  21 22 21  15 18 18
-12 15 15  11 13 13  9 11 11  8 10 10  8 10 10  8 9 9
-7 9 9  7 9 9  7 9 9  7 9 9  7 9 9  8 9 9
-8 9 9  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  10 12 12  26 28 27  31 33 31  38 39 37  43 45 43
-51 52 50  55 56 53  60 60 56  63 64 60  65 66 61  68 70 65
-63 64 60  96 95 69  158 153 112  178 174 128  188 184 146  194 189 146
-194 189 146  188 184 146  184 181 136  176 171 126  171 165 117  173 167 111
-173 167 111  165 161 109  171 165 117  174 170 121  176 171 126  178 174 128
-178 174 128  174 170 121  160 154 106  149 143 98  149 143 98  125 122 87
-71 71 57  16 16 16  16 16 16  17 17 17  17 17 17  17 17 17
-17 17 17  17 17 17  17 17 17  18 19 18  19 20 19  20 20 20
-21 22 21  21 22 21  21 22 21  22 24 23  21 22 21  21 22 21
-21 22 21  19 20 19  18 19 18  16 16 16  14 14 13  11 11 11
-3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  105 104 92  197 193 154  110 109 94  9 9 8  36 38 35
-121 119 87  131 127 93  96 95 69  18 19 17  30 31 28  66 65 55
-96 95 69  142 137 94  160 154 106  160 154 106  160 154 106  168 163 120
-184 181 136  194 191 148  197 193 154  197 193 154  194 189 146  168 163 120
-125 122 87  46 47 43  18 19 18  15 15 15  13 13 13  14 14 13
-55 57 54  43 45 43  32 34 33  25 27 26  18 22 22  17 17 17
-12 14 14  10 12 12  9 11 11  8 10 10  8 9 9  7 9 9
-6 8 8  7 9 9  7 9 9  7 9 9  7 9 9  7 9 9
-7 9 9  8 9 9  8 9 9  8 10 10  8 10 10  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  32 34 33  41 42 42  35 37 36  39 40 39  37 39 37
-35 37 36  55 57 54  60 60 56  63 64 60  65 66 61  65 66 61
-61 63 57  115 113 82  168 163 120  194 191 148  204 201 155  210 208 158
-210 208 158  210 208 158  197 193 154  194 189 146  186 182 128  176 171 126
-174 170 121  176 171 126  186 182 128  190 186 136  194 191 148  197 193 154
-197 193 154  188 184 146  181 176 137  174 170 121  165 161 109  142 137 94
-82 81 62  24 26 24  16 16 16  16 16 16  16 16 16  16 16 16
-17 17 17  17 17 17  17 17 17  17 17 17  18 19 18  19 20 19
-19 20 19  19 20 19  20 20 20  19 20 19  19 20 19  18 19 18
-17 17 17  15 15 15  13 13 13  12 12 12  6 7 7  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  17 18 17  137 133 100  115 113 82  53 55 47  19 20 18
-103 101 77  144 139 99  137 133 100  115 113 82  137 133 100  156 151 111
-158 153 112  164 159 111  171 165 117  174 170 121  178 174 128  194 189 146
-204 201 155  214 212 158  214 212 158  214 212 158  210 208 158  188 184 146
-158 153 112  87 86 72  17 17 17  13 13 13  13 13 13  15 15 15
-55 56 53  43 45 43  32 34 33  24 26 24  17 20 20  16 16 16
-12 14 14  10 12 12  8 10 10  8 10 10  7 9 9  6 8 8
-6 8 8  6 8 8  6 8 8  7 9 9  7 9 9  7 9 9
-7 9 9  7 9 9  7 9 9  7 9 9  8 9 9  8 10 10
-8 10 10  8 10 10  8 10 10  8 10 10  8 10 10  8 10 10
-8 10 10  110 109 94  84 83 72  49 51 48  26 28 27  8 10 10
-8 9 9  51 52 50  58 59 55  63 64 60  63 64 60  63 64 60
-66 65 55  134 131 96  181 176 137  210 208 158  214 212 158  239 239 170
-239 239 170  224 223 159  210 208 158  204 201 155  194 189 146  186 182 128
-186 182 128  184 181 136  194 189 146  204 201 155  210 208 158  210 208 158
-210 208 158  210 208 158  197 193 154  190 186 136  176 171 126  155 149 109
-118 116 76  36 38 35  15 15 15  16 16 16  16 16 16  16 16 16
-16 16 16  16 16 16  16 16 16  16 16 16  16 16 16  17 17 17
-17 17 17  17 17 17  17 17 17  16 16 16  16 16 16  15 15 15
-13 13 13  12 12 12  8 8 7  2 2 2  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  53 55 47  103 101 77  96 95 69  53 55 47
-103 101 77  158 153 112  177 172 135  184 179 149  188 184 146  197 193 154
-194 189 146  190 186 136  184 181 136  184 181 136  194 189 146  210 208 158
-214 212 158  239 239 170  251 251 187  251 251 187  224 223 159  204 201 155
-177 172 135  121 119 87  30 31 28  13 13 13  12 12 12  39 40 39
-60 60 56  43 45 43  32 34 33  23 25 24  18 19 18  13 16 16
-13 13 13  9 11 11  8 10 10  8 9 9  6 8 8  6 8 8
-6 8 8  6 8 8  6 8 8  6 8 8  6 8 8  7 9 9
-7 9 9  7 9 9  7 9 9  7 9 9  7 9 9  7 9 9
-7 9 9  8 9 9  8 9 9  8 10 10  8 10 10  8 10 10
-14 17 17  197 193 154  158 153 112  55 57 54  7 9 9  7 9 9
-8 10 10  51 52 50  58 59 55  60 60 56  63 64 60  63 64 60
-71 71 57  155 149 109  194 191 148  214 212 158  251 251 187  251 251 187
-251 251 187  251 251 187  239 239 170  210 208 158  197 193 154  190 186 136
-190 186 136  194 189 146  204 201 155  210 208 158  224 223 159  239 239 170
-239 239 170  224 223 159  210 208 158  204 201 155  190 186 136  164 159 111
-125 122 87  40 41 39  15 15 15  15 15 15  15 15 15  15 15 15
-16 16 16  16 16 16  16 16 16  16 16 16  16 16 16  16 16 16
-16 16 16  16 16 16  15 15 15  14 14 13  13 13 13  12 12 12
-8 9 9  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  21 22 20  96 95 69  125 122 87  121 119 87
-144 139 99  177 172 135  197 193 154  210 208 158  214 212 158  214 212 158
-210 208 158  204 201 155  194 191 148  194 189 146  204 201 155  214 212 158
-239 239 170  251 251 187  251 251 187  251 251 187  251 251 187  214 212 158
-188 184 146  145 141 105  53 55 47  12 12 12  15 15 15  63 64 60
-63 64 60  41 42 42  31 33 31  23 24 24  17 18 17  12 15 15
-11 13 13  9 11 11  8 9 9  7 9 9  6 8 8  6 8 8
-6 7 7  6 7 7  6 8 8  6 8 8  6 8 8  6 8 8
-6 8 8  7 9 9  7 9 9  7 9 9  7 9 9  7 9 9
-7 9 9  7 9 9  7 9 9  7 9 9  7 9 9  8 8 7
-43 45 43  251 251 187  156 151 111  8 10 10  7 9 9  7 9 9
-21 22 21  51 52 50  55 56 53  55 57 54  58 59 55  58 59 55
-75 75 61  158 153 112  197 193 154  224 223 159  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  214 212 158  204 201 155  194 189 146
-190 186 136  197 193 154  210 208 158  224 223 159  251 251 187  251 251 187
-251 251 187  251 251 187  239 239 170  210 208 158  197 193 154  176 171 126
-125 122 87  36 38 35  14 14 13  14 14 13  15 15 15  15 15 15
-15 15 15  15 15 15  15 15 15  15 15 15  15 15 15  15 15 15
-15 15 15  14 14 13  13 13 13  12 12 12  10 10 9  3 4 4
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  7 7 5  71 71 57  131 127 93  158 153 112
-177 172 135  197 193 154  214 212 158  239 239 170  251 251 187  251 251 187
-238 237 168  210 208 158  204 201 155  197 193 154  204 201 155  214 212 158
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  214 212 158
-197 193 154  156 151 111  66 65 55  12 12 12  37 39 37  58 59 55
-58 59 55  41 42 42  31 33 31  22 24 23  17 17 17  12 14 14
-10 12 12  8 10 10  6 8 8  6 8 8  6 7 7  6 7 7
-6 7 7  5 7 7  6 7 7  6 7 7  6 8 8  6 8 8
-6 8 8  6 8 8  6 8 8  7 9 9  7 9 9  7 9 9
-7 9 9  6 8 8  6 8 8  6 8 8  6 8 8  6 8 8
-61 63 57  197 193 154  16 19 19  6 8 8  6 8 8  8 9 9
-41 42 42  47 48 46  51 52 50  51 52 50  55 56 53  55 56 53
-71 71 57  158 153 112  197 193 154  224 223 159  251 251 187  251 251 187
-251 251 187  251 251 187  239 239 170  214 212 158  204 201 155  194 189 146
-190 186 136  197 193 154  210 208 158  239 239 170  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  224 223 159  204 201 155  177 172 135
-121 119 87  30 31 28  13 13 13  14 14 13  14 14 13  14 14 13
-14 14 13  14 14 13  15 15 15  15 15 15  14 14 13  13 13 13
-12 12 12  12 12 12  10 10 9  4 5 5  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  48 49 45  131 127 93  174 170 121
-194 189 146  210 208 158  239 239 170  251 251 187  251 251 187  251 251 187
-251 251 187  214 212 158  204 201 155  197 193 154  204 201 155  210 208 158
-239 239 170  251 251 187  251 251 187  251 251 187  239 239 170  214 212 158
-194 191 148  156 151 111  71 71 57  19 20 19  51 52 50  51 52 50
-51 52 50  41 42 42  30 32 31  21 22 21  17 17 17  13 13 13
-9 11 11  8 9 9  6 8 8  6 7 7  6 7 7  5 7 7
-5 6 5  5 6 5  5 7 7  5 7 7  6 7 7  6 7 7
-6 8 8  6 8 8  6 8 8  6 7 7  6 7 7  6 7 7
-6 7 7  6 8 8  6 8 8  6 8 8  6 8 8  6 8 8
-55 56 53  43 45 43  6 8 8  6 8 8  6 8 8  47 48 46
-60 60 56  47 48 46  46 47 45  47 48 46  38 39 37  10 12 12
-66 65 55  145 141 105  197 193 154  214 212 158  251 251 187  251 251 187
-251 251 187  251 251 187  224 223 159  210 208 158  194 191 148  184 181 136
-184 181 136  194 189 146  204 201 155  224 223 159  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  239 239 170  210 208 158  181 176 137
-115 113 82  21 22 20  13 13 13  13 13 13  13 13 13  13 13 13
-14 14 13  13 13 13  13 13 13  13 13 13  12 12 12  11 11 11
-10 10 9  6 7 7  1 1 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  2 2 1  66 65 55  144 139 99  178 174 128
-204 201 155  214 212 158  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  214 212 158  204 201 155  194 191 148  197 193 154  204 201 155
-214 212 158  239 239 170  239 239 170  239 239 170  214 212 158  210 208 158
-184 181 136  149 145 103  66 65 55  41 42 42  47 48 46  46 47 45
-43 45 43  39 40 39  28 31 30  21 22 21  16 16 16  10 12 12
-8 10 10  6 8 8  6 7 7  6 7 7  5 6 5  5 6 5
-5 6 5  5 6 5  5 6 5  5 6 5  5 7 7  5 7 7
-6 7 7  6 7 7  6 7 7  5 7 7  5 7 7  5 7 7
-5 7 7  6 7 7  6 7 7  6 7 7  6 7 7  6 8 8
-6 8 8  6 8 8  6 7 7  6 7 7  46 47 45  156 151 111
-105 104 92  58 59 55  43 45 43  32 34 33  6 8 8  6 8 8
-49 51 48  125 122 87  181 176 137  204 201 155  214 212 158  239 239 170
-239 239 170  214 212 158  210 208 158  197 193 154  181 176 137  176 171 126
-176 171 126  184 181 136  197 193 154  210 208 158  239 239 170  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  210 208 158  177 172 135
-99 98 80  13 13 13  12 12 12  12 12 12  13 13 13  12 12 12
-12 12 12  12 12 12  11 11 11  11 11 11  8 9 9  4 5 5
-1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  1 1 0  61 61 53  142 137 94  181 176 137
-204 201 155  224 223 159  251 251 187  251 251 187  251 251 187  251 251 187
-251 251 187  214 212 158  197 193 154  190 186 136  184 181 136  188 184 146
-197 193 154  204 201 155  210 208 158  210 208 158  204 201 155  194 189 146
-176 171 126  134 131 96  66 65 55  43 45 43  41 42 42  39 40 39
-35 37 36  33 36 34  27 29 28  20 20 20  15 15 15  9 11 11
-8 9 9  6 7 7  5 6 5  5 6 5  4 5 5  4 5 5
-4 5 5  4 5 5  4 5 5  4 5 5  5 6 5  4 5 5
-4 5 5  5 6 5  4 5 5  5 6 5  5 6 5  5 6 5
-5 7 7  5 7 7  5 7 7  5 7 7  5 7 7  5 7 7
-6 7 7  6 7 7  6 7 7  28 31 30  184 179 149  184 179 149
-145 141 105  84 83 72  27 29 28  5 7 7  5 6 5  16 16 16
-43 44 41  96 95 69  158 153 112  188 184 146  204 201 155  210 208 158
-204 201 155  197 193 154  184 179 149  177 172 135  168 163 120  164 159 111
-164 159 111  174 170 121  184 181 136  197 193 154  214 212 158  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  210 208 158  177 172 135
-71 71 57  11 11 11  12 12 12  11 11 11  11 11 11  11 11 11
-10 10 9  10 10 9  8 8 7  3 4 4  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  31 33 31  121 119 87  176 171 126
-197 193 154  214 212 158  251 251 187  251 251 187  251 251 187  251 251 187
-239 239 170  210 208 158  194 189 146  178 174 128  174 170 121  176 171 126
-177 172 135  181 176 137  184 179 149  184 179 149  181 176 137  178 174 128
-158 153 112  121 119 87  53 55 47  37 39 37  33 36 34  30 32 31
-27 29 28  25 27 26  24 26 24  19 20 19  13 13 13  8 10 10
-6 8 8  6 7 7  5 6 5  4 5 5  4 5 5  4 5 5
-4 5 5  4 5 5  4 5 5  3 4 4  3 4 4  4 5 5
-4 5 5  4 5 5  4 5 5  4 5 5  4 5 5  4 5 5
-5 6 5  5 6 5  5 6 5  5 6 5  5 6 5  5 6 5
-5 6 5  5 6 5  12 14 14  145 141 105  184 179 149  177 172 135
-90 89 73  21 22 21  5 6 5  5 6 5  4 5 5  37 39 37
-38 39 37  61 61 53  134 131 96  168 163 120  184 181 136  188 184 146
-184 179 149  177 172 135  168 163 120  164 159 111  155 149 109  151 147 98
-151 147 98  164 159 111  176 171 126  184 179 149  210 208 158  239 239 170
-251 251 187  251 251 187  251 251 187  239 239 170  210 208 158  158 153 112
-46 47 43  10 10 9  10 10 9  10 10 9  8 9 9  8 9 9
-6 7 7  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  13 12 7  82 81 62  158 153 112
-188 184 146  210 208 158  239 239 170  251 251 187  251 251 187  251 251 187
-224 223 159  204 201 155  184 181 136  171 165 117  164 159 111  160 154 106
-158 153 112  164 159 111  168 163 120  168 163 120  168 163 120  164 159 111
-142 137 94  96 95 69  43 44 41  27 29 28  26 28 27  23 24 24
-21 22 21  18 19 18  17 17 17  18 19 18  13 13 13  8 8 7
-6 7 7  5 6 5  4 5 5  3 4 4  3 4 4  3 4 4
-3 4 4  3 4 4  3 3 3  3 3 3  3 4 4  3 4 4
-3 4 4  3 4 4  4 5 5  4 5 5  4 5 5  4 5 5
-4 5 5  4 5 5  4 5 5  4 5 5  4 5 5  4 5 5
-4 5 5  4 5 5  4 5 5  4 5 5  4 5 5  4 5 5
-4 5 5  4 5 5  4 5 5  4 5 5  31 33 31  65 66 61
-37 39 37  38 39 37  96 95 69  144 139 99  168 163 120  174 170 121
-168 163 120  164 159 111  155 149 109  149 145 103  149 143 98  142 137 94
-149 143 98  151 147 98  164 159 111  177 172 135  197 193 154  210 208 158
-251 251 187  251 251 187  251 251 187  239 239 170  197 193 154  137 133 100
-24 26 24  8 9 9  8 9 9  8 8 7  6 7 7  2 2 2
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  46 47 43  125 122 87
-176 171 126  197 193 154  210 208 158  239 239 170  251 251 187  239 239 170
-214 212 158  197 193 154  181 176 137  164 159 111  151 147 98  149 143 98
-149 143 98  149 143 98  149 145 103  155 149 109  160 154 106  149 143 98
-118 116 76  82 81 62  30 31 28  21 22 21  19 20 19  17 17 17
-14 14 13  12 12 12  10 10 9  12 12 12  10 12 12  6 8 8
-4 5 5  3 4 4  3 4 4  3 4 4  3 3 3  3 3 3
-3 3 3  3 3 3  3 3 3  3 3 3  2 3 3  2 3 3
-3 4 4  3 4 4  3 4 4  3 4 4  3 4 4  4 5 5
-4 5 5  3 4 4  3 4 4  3 4 4  3 4 4  3 4 4
-4 5 5  4 5 5  4 5 5  4 5 5  4 5 5  4 5 5
-4 5 5  3 4 4  3 4 4  23 24 24  110 109 94  72 73 67
-39 40 39  22 24 23  46 47 43  103 101 77  142 137 94  155 149 109
-160 154 106  155 149 109  149 143 98  142 137 94  142 137 94  142 137 94
-142 137 94  149 143 98  155 149 109  176 171 126  184 179 149  210 208 158
-239 239 170  251 251 187  251 251 187  214 212 158  184 179 149  105 104 92
-10 10 9  6 7 7  3 4 4  1 1 1  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  12 12 9  82 81 62
-149 145 103  181 176 137  197 193 154  210 208 158  214 212 158  214 212 158
-210 208 158  197 193 154  177 172 135  158 153 112  149 143 98  142 137 94
-142 137 94  142 137 94  149 143 98  151 147 98  151 147 98  131 127 93
-103 101 77  71 71 57  22 24 23  15 15 15  13 13 13  11 11 11
-8 9 9  6 7 7  6 7 7  4 5 5  8 9 9  6 7 7
-4 5 5  3 3 3  3 3 3  3 3 3  3 3 3  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 3 3
-2 3 3  2 3 3  2 3 3  3 4 4  3 4 4  3 4 4
-3 4 4  3 4 4  3 3 3  3 4 4  3 4 4  3 4 4
-3 4 4  3 4 4  3 4 4  3 4 4  3 4 4  3 4 4
-3 4 4  3 4 4  21 22 21  145 141 105  145 141 105  72 73 67
-17 18 17  3 4 4  21 22 20  66 65 55  118 116 76  142 137 94
-149 143 98  151 147 98  149 143 98  142 137 94  142 137 94  142 137 94
-142 137 94  149 143 98  155 149 109  168 163 120  184 179 149  210 208 158
-239 239 170  251 251 187  251 251 187  210 208 158  177 172 135  71 71 57
-3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 38 35
-115 113 82  158 153 112  181 176 137  197 193 154  204 201 155  210 208 158
-204 201 155  188 184 146  177 172 135  164 159 111  149 145 103  142 137 94
-142 137 94  142 137 94  149 143 98  151 147 98  149 143 98  125 122 87
-96 95 69  61 61 53  16 17 12  8 9 9  8 8 7  6 7 7
-4 5 5  3 4 4  3 3 3  3 3 3  3 3 3  5 6 5
-3 4 4  2 3 3  2 2 2  2 2 2  2 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  1 2 2
-2 2 2  2 2 2  2 3 3  2 3 3  2 3 3  2 3 3
-3 3 3  3 3 3  3 3 3  3 3 3  3 3 3  3 3 3
-3 3 3  2 3 3  2 3 3  3 4 4  3 4 4  3 4 4
-3 4 4  3 4 4  3 4 4  8 9 9  8 8 7  3 3 3
-3 3 3  3 3 3  9 9 8  36 38 35  82 81 62  118 116 76
-142 137 94  151 147 98  151 147 98  151 147 98  149 143 98  149 143 98
-149 143 98  151 147 98  160 154 106  176 171 126  188 184 146  210 208 158
-239 239 170  251 251 187  239 239 170  210 208 158  156 151 111  31 33 31
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  7 7 5
-66 65 55  125 122 87  158 153 112  181 176 137  194 189 146  197 193 154
-197 193 154  184 179 149  177 172 135  168 163 120  156 151 111  151 147 98
-151 147 98  151 147 98  151 147 98  161 156 96  149 143 98  118 116 76
-82 81 62  53 55 47  12 12 9  4 5 5  3 4 4  3 3 3
-3 3 3  3 3 3  2 2 2  2 2 2  1 1 1  1 2 2
-3 3 3  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-1 1 1  1 1 1  1 1 1  1 1 1  1 2 2  1 2 2
-1 2 2  1 2 2  1 2 2  2 2 2  2 2 2  2 3 3
-2 3 3  2 3 3  2 3 3  2 3 3  2 2 2  2 2 2
-2 3 3  2 3 3  2 3 3  2 3 3  2 3 3  2 3 3
-2 3 3  2 3 3  2 3 3  2 3 3  2 3 3  3 3 3
-3 3 3  3 3 3  72 73 67  61 61 53  53 55 47  96 95 69
-131 127 93  151 147 98  161 156 96  161 156 96  151 147 98  151 147 98
-161 156 96  160 154 106  164 159 111  177 172 135  197 193 154  210 208 158
-239 239 170  251 251 187  224 223 159  197 193 154  131 127 93  9 9 8
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-24 26 24  82 81 62  131 127 93  164 159 111  178 174 128  188 184 146
-188 184 146  188 184 146  181 176 137  176 171 126  168 163 120  164 159 111
-160 154 106  160 154 106  160 154 106  160 154 106  151 147 98  125 122 87
-82 81 62  61 61 53  12 12 9  3 3 3  3 3 3  2 2 2
-2 2 2  1 1 1  1 1 1  1 1 1  0 0 0  0 0 0
-0 0 0  2 2 2  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 2 2  1 2 2  1 2 2  1 2 2
-1 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-2 3 3  2 3 3  2 3 3  2 3 3  2 3 3  2 3 3
-2 3 3  30 32 31  72 73 67  31 33 31  36 38 35  82 81 62
-118 116 76  149 143 98  161 156 96  161 156 96  161 156 96  160 154 106
-165 161 109  165 161 109  176 171 126  188 184 146  204 201 155  214 212 158
-239 239 170  239 239 170  214 212 158  184 179 149  82 81 62  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-2 2 2  43 44 41  96 95 69  131 127 93  160 154 106  176 171 126
-184 181 136  184 181 136  184 181 136  181 176 137  178 174 128  174 170 121
-171 165 117  173 167 111  173 167 111  173 167 111  160 154 106  131 127 93
-96 95 69  66 65 55  16 17 12  2 2 2  1 1 1  1 1 1
-1 1 1  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 2 2  1 2 2  1 2 2  1 2 2  1 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  10 9 6  30 31 28  71 71 57
-118 116 76  149 143 98  165 161 109  165 161 109  165 161 109  173 167 111
-173 167 111  176 171 126  184 181 136  197 193 154  210 208 158  224 223 159
-251 251 187  239 239 170  210 208 158  168 163 120  40 41 39  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  13 12 7  61 61 53  96 95 69  131 127 93  160 154 106
-176 171 126  184 181 136  184 181 136  188 184 146  184 181 136  184 181 136
-184 181 136  186 182 128  186 182 128  178 174 128  174 170 121  149 145 103
-118 116 76  82 81 62  21 22 20  1 1 1  1 1 1  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 2 2
-1 2 2  1 2 2  1 2 2  1 2 2  1 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  2 2 2  2 2 2  2 2 2
-2 2 2  2 2 2  2 2 2  3 3 3  30 31 28  66 65 55
-118 116 76  149 143 98  165 161 109  173 167 111  173 167 111  174 170 121
-186 182 128  190 186 136  197 193 154  210 208 158  224 223 159  251 251 187
-251 251 187  239 239 170  197 193 154  137 133 100  12 12 9  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  30 31 28  71 71 57  103 101 77  134 131 96
-164 159 111  176 171 126  184 181 136  188 184 146  194 189 146  197 193 154
-197 193 154  197 193 154  194 191 148  194 189 146  190 186 136  176 171 126
-145 141 105  103 101 77  40 41 39  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 2 2  1 2 2
-1 2 2  1 2 2  1 2 2  1 2 2  1 2 2  1 2 2
-1 2 2  1 2 2  1 2 2  1 2 2  30 31 28  71 71 57
-118 116 76  160 154 106  173 167 111  178 174 128  186 182 128  190 186 136
-194 191 148  204 201 155  210 208 158  224 223 159  251 251 187  251 251 187
-251 251 187  214 212 158  184 179 149  84 83 72  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  5 5 3  43 44 41  82 81 62  103 101 77
-142 137 94  165 161 109  178 174 128  190 186 136  197 193 154  204 201 155
-210 208 158  210 208 158  210 208 158  210 208 158  210 208 158  197 193 154
-177 172 135  145 141 105  79 78 62  5 4 3  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 2 2  1 2 2  30 31 28  82 81 62
-142 137 94  165 161 109  178 174 128  190 186 136  194 191 148  204 201 155
-210 208 158  214 212 158  239 239 170  251 251 187  251 251 187  251 251 187
-251 251 187  210 208 158  168 163 120  36 38 35  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  16 17 12  53 55 47  82 81 62
-118 116 76  151 147 98  171 165 117  184 181 136  194 191 148  210 208 158
-214 212 158  224 223 159  239 239 170  239 239 170  224 223 159  214 212 158
-197 193 154  176 171 126  115 113 82  24 26 24  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  40 41 39  103 101 77
-151 147 98  176 171 126  190 186 136  197 193 154  210 208 158  214 212 158
-239 239 170  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-239 239 170  197 193 154  110 109 94  3 4 3  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  30 31 28  66 65 55
-96 95 69  125 122 87  160 154 106  178 174 128  194 189 146  204 201 155
-214 212 158  239 239 170  251 251 187  251 251 187  251 251 187  239 239 170
-210 208 158  188 184 146  149 145 103  61 61 53  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  61 61 53  131 127 93
-164 159 111  184 181 136  197 193 154  210 208 158  224 223 159  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  251 251 187
-210 208 158  168 163 120  43 44 41  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  4 3 2  36 38 35
-71 71 57  96 95 69  142 137 94  165 161 109  184 181 136  197 193 154
-210 208 158  239 239 170  251 251 187  251 251 187  251 251 187  251 251 187
-214 212 158  197 193 154  168 163 120  103 101 77  7 7 5  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-1 1 1  0 0 0  0 0 0  0 0 0  82 81 62  142 137 94
-174 170 121  194 189 146  210 208 158  224 223 159  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  251 251 187  224 223 159
-184 179 149  99 98 80  3 3 3  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  7 7 5
-43 44 41  82 81 62  118 116 76  142 137 94  171 165 117  190 186 136
-204 201 155  224 223 159  251 251 187  251 251 187  251 251 187  251 251 187
-214 212 158  197 193 154  174 170 121  125 122 87  30 31 28  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
-1 1 1  1 1 1  1 1 1  1 1 1  1 1 1  1 1 1
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  3 4 3  82 81 62  149 143 98
-176 171 126  194 191 148  210 208 158  239 239 170  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  251 251 187  239 239 170  204 201 155
-145 141 105  30 31 28  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-10 9 6  46 47 43  82 81 62  118 116 76  149 143 98  174 170 121
-194 189 146  210 208 158  224 223 159  251 251 187  251 251 187  224 223 159
-210 208 158  194 191 148  174 170 121  134 131 96  53 55 47  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  7 7 5  96 95 69  149 143 98
-176 171 126  194 191 148  210 208 158  239 239 170  251 251 187  251 251 187
-251 251 187  251 251 187  251 251 187  239 239 170  210 208 158  177 172 135
-75 75 61  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  10 9 6  46 47 43  82 81 62  118 116 76  149 143 98
-176 171 126  194 191 148  210 208 158  214 212 158  214 212 158  210 208 158
-197 193 154  184 181 136  164 159 111  131 127 93  53 55 47  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  7 7 5  96 95 69  149 143 98
-174 170 121  194 189 146  204 201 155  214 212 158  239 239 170  251 251 187
-251 251 187  251 251 187  239 239 170  210 208 158  184 179 149  110 109 94
-12 12 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  10 9 6  43 44 41  82 81 62  115 113 82
-144 139 99  168 163 120  188 184 146  197 193 154  197 193 154  194 189 146
-184 181 136  174 170 121  151 147 98  118 116 76  36 38 35  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  4 3 2  82 81 62  142 137 94
-171 165 117  186 182 128  194 191 148  210 208 158  214 212 158  224 223 159
-239 239 170  224 223 159  210 208 158  184 179 149  137 133 100  36 38 35
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  7 7 5  36 38 35  71 71 57
-103 101 77  131 127 93  155 149 109  168 163 120  168 163 120  168 163 120
-164 159 111  149 143 98  125 122 87  82 81 62  13 12 7  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  61 61 53  125 122 87
-160 154 106  174 170 121  184 181 136  194 189 146  204 201 155  210 208 158
-210 208 158  204 201 155  184 179 149  145 141 105  61 61 53  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  3 3 2  30 31 28
-61 61 53  82 81 62  103 101 77  121 119 87  125 122 87  125 122 87
-118 116 76  103 101 77  79 78 62  24 26 24  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  25 27 25  96 95 69
-142 137 94  160 154 106  171 165 117  178 174 128  184 181 136  184 181 136
-181 176 137  177 172 135  145 141 105  75 75 61  5 5 3  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-16 17 12  40 41 39  61 61 53  71 71 57  71 71 57  71 71 57
-66 65 55  43 44 41  12 12 9  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  46 47 43
-96 95 69  125 122 87  142 137 94  149 145 103  155 149 109  155 149 109
-145 141 105  121 119 87  66 65 55  7 7 5  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  1 1 1  16 17 12  24 26 24  25 27 25  19 20 18
-7 7 5  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  2 2 1
-25 27 25  61 61 53  82 81 62  96 95 69  96 95 69  82 81 62
-61 61 53  25 27 25  2 2 1  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  5 6 5  13 12 7  10 9 6  3 4 3
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  14  10  10  10   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  26  26  26  42  42  42
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  42  26  26  26  18  18  18  10  10  10
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 22  22  22  42  42  42  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  42  42  42  82  82  82
+ 26  26  26   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 42  42  42  78  78  78  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  30  30  30  66  66  66  58  58  58
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 101 101 101  46  46  46  10  10  10
+  2   2   6  58  58  58  70  70  70  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  86  86  86  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  94  94  94  94  58  58  58  26  26  26
+  2   2   6   6   6   6  78  78  78  54  54  54
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  62  62  62  62  62  62   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  34  34  34  82  82  82
+ 38  38  38  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  54  54  54
+ 66  66  66  26  26  26   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  14  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  42  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 116 116 116  94  94  94  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  14  86  86  86 138 138 138 162 162 162
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  14  14  14
+134 134 134 198 198 198 195 195 195 116 116 116
+ 10  10  10   2   2   6   2   2   6   6   6   6
+101  98  89 187 187 187 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  14   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 195 195 195 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 253 253 253 174 174 174 123 123 123
+221 221 221 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  82  82  82   2   2   6 106 106 106
+170 170 170  26  26  26  86  86  86 226 226 226
+123 123 123  10  10  10  14  14  14  46  46  46
+231 231 231 190 190 190   6   6   6  70  70  70
+ 90  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  86  86  86   6   6   6 116 116 116
+106 106 106   6   6   6  70  70  70 149 149 149
+128 128 128  18  18  18  38  38  38  54  54  54
+221 221 221 106 106 106   2   2   6  14  14  14
+ 46  46  46 190 190 190 198 198 198   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  94  94  94  14  14  14 101 101 101
+128 128 128   2   2   6  18  18  18 116 116 116
+118  98  46 121  92   8 121  92   8  98  78  10
+162 162 162 106 106 106   2   2   6   2   2   6
+  2   2   6 195 195 195 195 195 195   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   1
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  90  90  90  14  14  14  58  58  58
+210 210 210  26  26  26  54  38   6 154 114  10
+226 170  11 236 186  11 225 175  15 184 144  12
+215 174  15 175 146  61  37  26   9   2   2   6
+ 70  70  70 246 246 246 138 138 138   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14  10  10  10
+195 195 195 188 164 115 192 133   9 225 175  15
+239 182  13 234 190  10 232 195  16 232 200  30
+245 207  45 241 208  19 232 195  16 184 144  12
+218 194 134 211 206 186  42  42  42   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  86  86  86  14  14  14   2   2   6
+121  87  25 192 133   9 219 162  10 239 182  13
+236 186  11 232 195  16 241 208  19 244 214  54
+246 218  60 246 218  38 246 215  20 241 208  19
+241 208  19 226 184  13 121  87  25   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  82  82  82  30  30  30  61  42   6
+180 123   7 206 145  10 230 174  11 239 182  13
+234 190  10 238 202  15 241 208  19 246 218  74
+246 218  38 246 215  20 246 215  20 246 215  20
+226 184  13 215 174  15 184 144  12   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  94  42  42  42  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  50  50  50 104  69   6
+192 133   9 216 158  10 236 178  12 236 186  11
+232 195  16 241 208  19 244 214  54 245 215  43
+246 215  20 246 215  20 241 208  19 198 155  10
+200 144  11 216 158  10 156 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  90  90  90  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+137  92   6 210 162  10 239 182  13 238 190  10
+238 202  15 241 208  19 246 215  20 246 215  20
+241 208  19 203 166  17 185 133  11 210 150  10
+216 158  10 210 150  10 102  78  10   2   2   6
+  6   6   6  54  54  54  14  14  14   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 94  70  30 139 102  15 190 146  13 226 184  13
+232 200  30 232 195  16 215 174  15 190 146  13
+168 122  10 192 133   9 210 150  10 213 154  11
+202 150  34 182 157 106 101  98  89   2   2   6
+  2   2   6  78  78  78 116 116 116  58  58  58
+  2   2   6  22  22  22  90  90  90  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+128 128 128 174 154 114 156 107  11 168 122  10
+198 155  10 184 144  12 197 138  11 200 144  11
+206 145  10 206 145  10 197 138  11 188 164 115
+195 195 195 198 198 198 174 174 174  14  14  14
+  2   2   6  22  22  22 116 116 116 116 116 116
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 101 101 101  26  26  26  10  10  10
+138 138 138 190 190 190 174 154 114 156 107  11
+197 138  11 200 144  11 197 138  11 192 133   9
+180 123   7 190 142  34 190 178 144 187 187 187
+202 202 202 221 221 221 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  90  90  90
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+144 144 144 198 198 198 190 190 190 178 166 146
+154 121  60 156 107  11 156 107  11 168 124  44
+174 154 114 187 187 187 190 190 190 210 210 210
+246 246 246 253 253 253 253 253 253 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  22  22  22  54  54  54
+ 94  94  94  18  18  18   2   2   6  46  46  46
+234 234 234 221 221 221 190 190 190 190 190 190
+190 190 190 187 187 187 187 187 187 190 190 190
+190 190 190 195 195 195 214 214 214 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 86  86  86  54  54  54  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  46  46  46  90  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+253 253 253 246 246 246 206 206 206 190 190 190
+190 190 190 190 190 190 190 190 190 190 190 190
+206 206 206 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+202 202 202  14  14  14   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  86  86  86  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  90  90  90 250 250 250
+253 253 253 253 253 253 238 238 238 198 198 198
+190 190 190 190 190 190 195 195 195 221 221 221
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+226 226 226 231 231 231 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 178 178 178   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  90  90  90  62  62  62
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 58  58  58  90  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  94
+ 54  54  54  26  26  26  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 90  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  14 195 195 195 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+ 86  86  86  50  50  50  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  38  38  38  82  82  82
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  42 195 195 195 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 242 242 242 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 246 246 246 238 238 238
+226 226 226 231 231 231 101 101 101   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 38  38  38  82  82  82  42  42  42  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  62  62  62  66  66  66
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 231 231 231 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 231 231 231
+214 214 214 206 206 206 202 202 202 202 202 202
+198 198 198 202 202 202 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  62  62  62  66  66  66  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  82  82  82  18  18  18
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  94 182 182 182 218 218 218 242 242 242
+250 250 250 253 253 253 253 253 253 250 250 250
+234 234 234 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+238 238 238 226 226 226 210 210 210 202 202 202
+195 195 195 195 195 195 210 210 210 158 158 158
+  6   6   6  14  14  14  50  50  50  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  86  86  86  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54  70  70  70   2   2   6
+  2   2   6  10  10  10   2   2   6  22  22  22
+166 166 166 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+231 231 231 206 206 206 198 198 198 226 226 226
+ 94  94  94   2   2   6   6   6   6  38  38  38
+ 30  30  30   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  62  62  62  66  66  66
+ 26  26  26  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74  50  50  50   2   2   6
+ 26  26  26  26  26  26   2   2   6 106 106 106
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246 218 218 218 202 202 202
+210 210 210  14  14  14   2   2   6   2   2   6
+ 30  30  30  22  22  22   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  86  86  86
+ 42  42  42  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  90  90  90  22  22  22   2   2   6
+ 42  42  42   2   2   6  18  18  18 218 218 218
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 221 221 221
+218 218 218 101 101 101   2   2   6  14  14  14
+ 18  18  18  38  38  38  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 58  58  58  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  82  82  82   2   2   6  26  26  26
+ 22  22  22   2   2   6 123 123 123 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+238 238 238 198 198 198   6   6   6  38  38  38
+ 58  58  58  26  26  26  38  38  38   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+ 78  78  78  30  30  30  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  30  30  30
+ 74  74  74  58  58  58   2   2   6  42  42  42
+  2   2   6  22  22  22 231 231 231 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246  46  46  46  38  38  38
+ 42  42  42  14  14  14  38  38  38  14  14  14
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  42  42  42
+ 90  90  90  18  18  18  18  18  18  26  26  26
+  2   2   6 116 116 116 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 238 238 238
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253  94  94  94   6   6   6
+  2   2   6   2   2   6  10  10  10  34  34  34
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  26  26  26  66  66  66
+ 82  82  82   2   2   6  38  38  38   6   6   6
+ 14  14  14 210 210 210 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 246 246 246 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 144 144 144   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  74  74  74  30  30  30  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  42  42  42  90  90  90
+ 26  26  26   6   6   6  42  42  42   2   2   6
+ 74  74  74 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 242 242 242 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 182 182 182   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  66  66  66  82  82  82
+  2   2   6  22  22  22  18  18  18   2   2   6
+149 149 149 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 206 206 206   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  46  46  46  86  86  86  18  18  18
+  2   2   6  34  34  34  10  10  10   6   6   6
+210 210 210 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 221 221 221   6   6   6
+  2   2   6   2   2   6   6   6   6  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+  2   2   6  38  38  38  10  10  10  26  26  26
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 238 238 238
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231   6   6   6
+  2   2   6   2   2   6  10  10  10  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+  2   2   6  46  46  46  14  14  14  42  42  42
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234  10  10  10
+  2   2   6   2   2   6  22  22  22  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  14  70  70  70  34  34  34  62  62  62
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234  14  14  14
+  2   2   6   2   2   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  30  30  30  46  46  46  70  70  70
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 226 226 226  10  10  10
+  2   2   6   6   6   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  30  30  30  78  78  78
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 206 206 206   2   2   6
+ 22  22  22  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  26  26  26
+ 62  62  62 106 106 106  74  54  14 185 133  11
+210 162  10 121  92   8   6   6   6  62  62  62
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 158 158 158  18  18  18
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  94  50  50  50  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 216 158  10 242 186  14
+246 190  14 246 190  14 156 118  10  10  10  10
+ 90  90  90 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 230 190
+238 204  91 238 204  91 181 142  44  37  26   9
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 106  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 106 190 142  34 226 170  11 242 186  14
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6  74  74  74 226 226 226 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 228 184  62
+241 196  14 241 208  19 232 195  16  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+203 166  17 154 142  90  66  66  66  26  26  26
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 101 101 101 123 123 123
+175 146  61 210 150  10 234 174  13 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+102  78  10   2   2   6  46  46  46 198 198 198
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 224 178  62
+242 186  14 241 196  14 210 166  10  22  18   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 121  92   8
+238 202  15 232 195  16  82  82  82  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  38  38  38  70  70  70 154 122  46
+190 142  34 200 144  11 197 138  11 197 138  11
+213 154  11 226 170  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+225 175  15  46  32   6   2   2   6  22  22  22
+158 158 158 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 242 242 242 224 178  62
+239 182  13 236 186  11 213 154  11  46  32   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 225 175  15
+238 190  10 236 186  11 112 100  78  42  42  42
+ 14  14  14   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54 154 122  46 213 154  11
+226 170  11 230 174  11 226 170  11 226 170  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 184 144  12  10  10  10   2   2   6
+  6   6   6 116 116 116 242 242 242 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231 198 198 198 214 170  54
+236 178  12 236 178  12 210 150  10 137  92   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  47   6 200 144  11 236 178  12
+239 182  13 239 182  13 124 112  88  58  58  58
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  70  70  70 180 133  36 226 170  11
+239 182  13 242 186  14 242 186  14 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 221 221 221
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 206 206 206 198 198 198 214 166  58
+230 174  11 230 174  11 216 158  10 192 133   9
+163 110   8 116  81   8 102  78  10 116  81   8
+167 114   7 197 138  11 226 170  11 239 182  13
+242 186  14 242 186  14 162 146  94  78  78  78
+ 34  34  34  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78 190 142  34 226 170  11
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 241 196  14 203 166  17  22  18   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+218 218 218 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 206 206 206 198 198 198 202 162  69
+226 170  11 236 178  12 224 166  10 210 150  10
+200 144  11 197 138  11 192 133   9 197 138  11
+210 150  10 226 170  11 242 186  14 246 190  14
+246 190  14 246 186  14 225 175  15 124 112  88
+ 62  62  62  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 174 135  50 224 166  10
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 139 102  15
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 214 214 214 198 198 198 190 150  46
+219 162  10 236 178  12 234 174  13 224 166  10
+216 158  10 213 154  11 213 154  11 216 158  10
+226 170  11 239 182  13 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 206 162  42
+101 101 101  58  58  58  30  30  30  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74 174 135  50 216 158  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 226 184  13
+ 61  42   6   2   2   6   2   2   6   2   2   6
+ 22  22  22 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 226 226 226 187 187 187 180 133  36
+216 158  10 236 178  12 239 182  13 236 178  12
+230 174  11 226 170  11 226 170  11 230 174  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 186  14 239 182  13
+206 162  42 106 106 106  66  66  66  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 213 154  11
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 241 196  14
+190 146  13  18  14   6   2   2   6   2   2   6
+ 46  46  46 246 246 246 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 221 221 221  86  86  86 156 107  11
+216 158  10 236 178  12 242 186  14 246 186  14
+242 186  14 239 182  13 239 182  13 242 186  14
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 225 175  15 142 122  72  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 210 150  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+232 195  16 121  92   8  34  34  34 106 106 106
+221 221 221 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+242 242 242  82  82  82  18  14   6 163 110   8
+216 158  10 236 178  12 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 163 133  67
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 163 133  67 210 150  10
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 215 174  15 190 178 144 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 218 218 218
+ 58  58  58   2   2   6  22  18   6 167 114   7
+216 158  10 236 178  12 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 186  14 242 186  14 190 150  46
+ 54  54  54  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 38  38  38  86  86  86 180 133  36 213 154  11
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16 190 146  13 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 170 170 170  26  26  26
+  2   2   6   2   2   6  37  26   9 163 110   8
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 224 166  10 142 122  72
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 109 106  95 192 133   9 224 166  10
+242 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 226 184  13 210 162  10 142 110  46
+226 226 226 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+198 198 198  66  66  66   2   2   6   2   2   6
+  2   2   6   2   2   6  50  34   6 156 107  11
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 242 186  14
+234 174  13 213 154  11 154 122  46  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58 154 121  60 206 145  10 234 174  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 210 162  10 163 110   8
+ 61  42   6 138 138 138 218 218 218 250 250 250
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 210 210 210 144 144 144  66  66  66
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 163 110   8
+216 158  10 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 239 182  13 230 174  11 216 158  10
+190 142  34 124 112  88  70  70  70  38  38  38
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 62  62  62 168 124  44 206 145  10 224 166  10
+236 178  12 239 182  13 242 186  14 242 186  14
+246 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 236 178  12 216 158  10 175 118   6
+ 80  54   7   2   2   6   6   6   6  30  30  30
+ 54  54  54  62  62  62  50  50  50  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 167 114   7
+213 154  11 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 242 186  14 239 182  13 239 182  13
+230 174  11 210 150  10 174 135  50 124 112  88
+ 82  82  82  54  54  54  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 158 118  36 192 133   9 200 144  11
+216 158  10 219 162  10 224 166  10 226 170  11
+230 174  11 236 178  12 239 182  13 239 182  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 230 174  11 210 150  10 163 110   8
+104  69   6  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  91  60   6 167 114   7
+206 145  10 230 174  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 186  14 242 186  14
+239 182  13 230 174  11 224 166  10 213 154  11
+180 133  36 124 112  88  86  86  86  58  58  58
+ 38  38  38  22  22  22  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  70  70  70 138 110  50 158 118  36
+167 114   7 180 123   7 192 133   9 197 138  11
+200 144  11 206 145  10 213 154  11 219 162  10
+224 166  10 230 174  11 239 182  13 242 186  14
+246 186  14 246 186  14 246 186  14 246 186  14
+239 182  13 216 158  10 185 133  11 152  99   6
+104  69   6  18  14   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 152  99   6
+192 133   9 219 162  10 236 178  12 239 182  13
+246 186  14 242 186  14 239 182  13 236 178  12
+224 166  10 206 145  10 192 133   9 154 121  60
+ 94  94  94  62  62  62  42  42  42  22  22  22
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  34  34  34  58  58  58  78  78  78
+101  98  89 124 112  88 142 110  46 156 107  11
+163 110   8 167 114   7 175 118   6 180 123   7
+185 133  11 197 138  11 210 150  10 219 162  10
+226 170  11 236 178  12 236 178  12 234 174  13
+219 162  10 197 138  11 163 110   8 130  83   6
+ 91  60   6  10  10  10   2   2   6   2   2   6
+ 18  18  18  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  26  26  26   2   2   6
+  2   2   6   6   6   6  70  47   6 137  92   6
+175 118   6 200 144  11 219 162  10 230 174  11
+234 174  13 230 174  11 219 162  10 210 150  10
+192 133   9 163 110   8 124 112  88  82  82  82
+ 50  50  50  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  22  22  22  34  34  34
+ 42  42  42  58  58  58  74  74  74  86  86  86
+101  98  89 122 102  70 130  98  46 121  87  25
+137  92   6 152  99   6 163 110   8 180 123   7
+185 133  11 197 138  11 206 145  10 200 144  11
+180 123   7 156 107  11 130  83   6 104  69   6
+ 50  34   6  54  54  54 110 110 110 101  98  89
+ 86  86  86  82  82  82  78  78  78  78  78  78
+ 78  78  78  78  78  78  78  78  78  78  78  78
+ 78  78  78  82  82  82  86  86  86  94  94  94
+106 106 106 101 101 101  86  66  34 124  80   6
+156 107  11 180 123   7 192 133   9 200 144  11
+206 145  10 200 144  11 192 133   9 175 118   6
+139 102  15 109 106  95  70  70  70  42  42  42
+ 22  22  22  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  10  10  10
+ 14  14  14  22  22  22  30  30  30  38  38  38
+ 50  50  50  62  62  62  74  74  74  90  90  90
+101  98  89 112 100  78 121  87  25 124  80   6
+137  92   6 152  99   6 152  99   6 152  99   6
+138  86   6 124  80   6  98  70   6  86  66  30
+101  98  89  82  82  82  58  58  58  46  46  46
+ 38  38  38  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  38  38  38  42  42  42
+ 54  54  54  82  82  82  94  86  76  91  60   6
+134  86   6 156 107  11 167 114   7 175 118   6
+175 118   6 167 114   7 152  99   6 121  87  25
+101  98  89  62  62  62  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6   6   6   6  10  10  10
+ 18  18  18  22  22  22  30  30  30  42  42  42
+ 50  50  50  66  66  66  86  86  86 101  98  89
+106  86  58  98  70   6 104  69   6 104  69   6
+104  69   6  91  60   6  82  62  34  90  90  90
+ 62  62  62  38  38  38  22  22  22  14  14  14
+ 10  10  10  10  10  10  10  10  10  10  10  10
+ 10  10  10  10  10  10   6   6   6  10  10  10
+ 10  10  10  10  10  10  10  10  10  14  14  14
+ 22  22  22  42  42  42  70  70  70  89  81  66
+ 80  54   7 104  69   6 124  80   6 137  92   6
+134  86   6 116  81   8 100  82  52  86  86  86
+ 58  58  58  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 18  18  18  26  26  26  38  38  38  54  54  54
+ 70  70  70  86  86  86  94  86  76  89  81  66
+ 89  81  66  86  86  86  74  74  74  50  50  50
+ 30  30  30  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  34  34  34  58  58  58
+ 82  82  82  89  81  66  89  81  66  89  81  66
+ 94  86  66  94  86  76  74  74  74  50  50  50
+ 26  26  26  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  14  14  14  18  18  18
+ 30  30  30  38  38  38  46  46  46  54  54  54
+ 50  50  50  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  26  26  26
+ 38  38  38  50  50  50  58  58  58  58  58  58
+ 54  54  54  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+  6   6   6  10  10  10  14  14  14  18  18  18
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  18  18  18  22  22  22  22  22  22
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff --git a/drivers/video/logo/logo_linux_vga16.ppm b/drivers/video/logo/logo_linux_vga16.ppm
index 12ac3a5454c0..1850c15e6feb 100644
--- a/drivers/video/logo/logo_linux_vga16.ppm
+++ b/drivers/video/logo/logo_linux_vga16.ppm
@@ -1,2739 +1,1604 @@
 P3
-142 114
+# Standard 16-color Linux logo
+80 80
 255
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  170 170 170  170 85 0  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-255 255 85  170 170 170  170 170 170  170 85 0  85 255 85  170 85 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  170 170 170  170 85 0
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  170 85 0  170 170 170
-170 170 170  170 85 0  170 170 170  170 170 170  170 85 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 255 85
-255 85 85  85 255 85  170 170 170  170 85 0  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 85 0  85 85 85  85 85 85
-170 170 170  170 85 0  170 170 170  85 85 85  170 85 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  85 85 85  170 85 0
-85 85 85  85 85 85  170 85 0  85 255 85  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  170 85 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 170 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 85 0  85 255 85  170 85 0  170 85 0  170 85 0  85 255 85
-170 85 0  170 85 0  0 170 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 170 0  170 85 0
-255 255 85  170 85 0  255 255 85  255 255 85  255 255 85  170 85 0
-255 255 85  85 255 85  170 85 0  170 85 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 85 0  255 255 85
-85 255 85  255 255 85  255 255 85  170 85 0  255 255 85  255 255 85
-255 255 85  170 85 0  255 255 85  85 255 85  170 85 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  85 255 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  170 170 170  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  170 85 0  255 255 85  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  85 255 85  255 255 85
-255 255 85  170 85 0  255 255 85  170 85 0  255 255 85  170 85 0
-170 85 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  170 85 0  255 255 85  85 255 85  255 255 85
-170 170 170  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  85 255 85  255 255 85  255 255 85  255 255 85
-85 255 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  170 85 0  255 255 85  255 255 85  255 255 85
-255 255 255  255 255 85  255 255 85  170 85 0  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  255 255 85
-170 85 0  170 85 0  0 170 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  170 85 0  85 255 85  255 255 85  170 170 170  255 255 255
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  85 255 85  255 255 85
-255 255 85  85 255 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  255 255 85  255 255 85  255 255 85  255 255 255  255 255 85
-255 255 85  255 255 85  85 255 85  255 255 85  255 255 85  85 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  170 85 0
-255 255 85  170 85 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  0 0 0  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-170 85 0  170 85 0  255 255 85  255 255 85  255 255 255  170 170 170
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-170 85 0  255 255 85  255 255 85  170 85 0  255 255 85  255 255 85
-255 255 85  85 255 85  170 85 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-255 255 85  85 255 85  255 255 85  170 170 170  255 255 255  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  85 255 85  170 85 0
-255 255 85  170 85 0  170 85 0  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  170 170 170  170 170 170  170 170 170
-85 255 85  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 170 0
-170 85 0  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  85 255 85  255 255 85  170 85 0  170 85 0
-170 85 0  85 255 85  255 255 85  85 85 85  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  85 255 85  170 170 170  170 170 170
-85 85 85  170 170 170  170 170 170  170 85 0  170 170 170  170 170 170
-85 255 85  170 170 170  170 85 0  170 170 170  85 255 85  255 85 85
-85 255 85  170 170 170  255 255 85  85 85 85  255 255 85  170 170 170
-85 255 85  170 170 170  255 255 85  170 170 170  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 255  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  170 85 0  0 170 0  85 85 85
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  85 255 85
-255 85 85  85 255 85  85 85 85  255 85 85  85 85 85  170 170 170
-170 85 0  170 170 170  85 85 85  85 255 85  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-170 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  255 255 85
-170 85 0  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  85 85 85  85 85 85
-255 255 85  170 170 170  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  170 170 170  170 85 0  170 170 170
-170 170 170  255 255 85  170 170 170  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 85 0  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  170 85 0  170 85 0  0 170 0
-0 0 0  170 85 0  170 85 0  0 170 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  170 170 170  85 85 85
-170 170 170  85 85 85  85 85 85  170 170 170  170 85 0  85 85 85
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  170 85 0
-255 255 85  255 255 85  255 255 85  170 85 0  255 255 85  255 255 85
-170 85 0  255 255 85  85 255 85  255 255 85  255 255 85  170 85 0
-170 85 0  255 255 85  170 85 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  255 255 85  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  170 85 0  255 255 85  255 255 85
-85 255 85  170 85 0  0 170 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 170 0  170 85 0  255 255 85
-85 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-170 85 0  255 255 85  85 255 85  255 255 85  255 255 85  170 85 0
-85 255 85  170 85 0  170 85 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  170 85 0  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  170 85 0  255 255 85  85 255 85  255 255 85  170 85 0
-255 255 85  255 255 85  170 85 0  255 255 85  170 85 0  85 255 85
-170 85 0  170 85 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  255 255 85  170 85 0
-255 255 85  170 85 0  255 255 85  170 85 0  255 255 85  85 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  170 85 0  255 255 85  85 255 85  170 85 0  170 85 0
-0 170 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  170 85 0  255 255 85  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  255 255 85  170 85 0  255 255 85  170 85 0  85 255 85
-255 255 85  85 255 85  170 85 0  170 85 0  85 255 85  170 85 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  255 255 85  85 255 85
-255 255 85  255 255 85  85 255 85  255 255 85  255 255 85  255 255 85
-255 255 85  170 85 0  255 255 85  85 255 85  255 255 85  255 255 85
-170 85 0  170 85 0  85 255 85  170 85 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  255 255 85  255 255 85
-170 85 0  255 255 85  255 255 85  170 85 0  255 255 85  170 85 0
-255 255 85  85 255 85  170 85 0  255 255 85  170 85 0  85 255 85
-170 85 0  170 85 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 85 0  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  85 255 85
-170 85 0  255 255 85  170 85 0  85 255 85  170 85 0  170 85 0
-0 170 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  170 170 170  170 170 170  255 255 255  170 170 170
-170 170 170  170 170 170  85 85 85  85 85 85  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 255 85  255 255 85
-170 85 0  255 255 85  255 255 85  170 85 0  85 255 85  170 85 0
-255 255 85  170 85 0  0 170 0  170 85 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  170 170 170  170 170 170  170 170 170  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  255 255 85
-255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  170 85 0
-0 170 0  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-255 255 85  255 255 85  170 85 0  0 170 0  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  170 170 170  170 170 170  85 85 85
-170 170 170  170 170 170  170 170 170  170 170 170  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  170 85 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  85 85 85  170 170 170  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-170 170 170  170 170 170  170 170 170  170 170 170  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  170 170 170
-170 170 170  170 170 170  170 170 170  85 85 85  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  170 170 170  170 170 170
-255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  170 170 170
-255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
-255 255 255  255 255 255  170 170 170  255 255 255  170 170 170  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  170 170 170  170 170 170
-255 255 255  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
-255 255 255  255 255 255  170 170 170  255 255 255  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  170 170 170
-170 170 170  170 170 170  255 255 255  170 170 170  255 255 255  170 170 170
-255 255 255  170 170 170  255 255 255  170 170 170  255 255 255  255 255 255
-255 255 255  170 170 170  255 255 255  170 170 170  255 255 255  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  85 85 85  170 170 170
-170 170 170  170 170 170  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-170 170 170  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  170 170 170  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  170 170 170  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  255 255 255  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
-170 170 170  255 255 255  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
-255 255 255  255 255 255  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 170 170  170 170 170  255 255 255
-255 255 255  170 170 170  170 170 170  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  255 255 255  255 255 255  255 255 255
-170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  170 170 170
-170 170 170  170 170 170  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
-170 170 170  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 170 170  170 170 170  170 170 170
-255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  170 170 170  255 255 255  255 255 255  255 255 255
-255 255 255  255 255 255  170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  170 170 170  255 255 255  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  170 170 170  255 255 255  170 170 170  255 255 255  255 255 255
-255 255 255  255 255 255  170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  170 170 170  255 255 255  170 170 170  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-255 255 255  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
-170 170 170  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  255 255 255  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  255 255 255  255 255 255  255 255 255  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  170 170 170
-255 255 255  170 170 170  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
-170 170 170  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-170 170 170  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  170 170 170  255 255 255  255 255 255  255 255 255  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  255 255 255
-255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  85 85 85
-170 170 170  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-170 170 170  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  170 170 170  255 255 255  255 255 255  255 255 255  170 170 170
-0 0 0  85 85 85  0 0 0  85 85 85  170 170 170  255 255 255
-255 255 255  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  85 85 85
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
-170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
-0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  85 85 85  170 170 170  255 255 255
-255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-170 170 170  255 255 255  170 170 170  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  170 170 170  85 85 85  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  255 255 255  255 255 255  255 255 255  170 170 170
-0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-170 170 170  170 170 170  255 255 255  170 170 170  255 255 255  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  170 170 170  255 255 255
-170 170 170  170 170 170  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  255 255 255  255 255 255  0 0 0  0 0 0  85 85 85
-255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
-255 255 255  255 255 255  170 170 170  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  255 255 255  170 170 170  170 170 170  170 170 170
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  170 170 170  255 255 255  170 170 170  170 170 170  85 85 85
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  170 170 170
-170 170 170  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
-170 170 170  170 170 170  85 85 85  0 0 0  0 0 0  170 170 170
-170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
-255 255 255  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  170 170 170  255 255 85  85 85 85
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  0 0 0  85 85 85
-85 85 85  170 170 170  170 170 170  170 170 170  170 85 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  170 170 170  170 85 0
-170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-170 85 0  170 170 170  85 85 85  0 0 0  85 85 85  85 85 85
-170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
-170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-255 255 255  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  170 85 0  170 170 170  170 170 170  85 85 85
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  170 85 0  85 255 85  170 85 0  170 170 170  85 85 85
-85 85 85  0 0 0  0 0 0  85 85 85  170 85 0  85 255 85
-170 85 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-85 85 85  85 85 85  170 85 0  0 0 0  85 85 85  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
-255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-170 170 170  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  170 170 170  170 85 0  170 170 170  170 85 0
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  255 85 85  170 170 170  85 255 85  170 85 0
-85 85 85  85 85 85  170 85 0  85 85 85  170 170 170  85 85 85
-170 170 170  170 85 0  85 85 85  85 85 85  85 85 85  85 85 85
-170 85 0  85 255 85  85 85 85  85 85 85  85 85 85  170 85 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  170 170 170
-255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 85 0  170 170 170  170 85 0  85 85 85  0 0 0
-85 85 85  85 85 85  85 255 85  170 170 170  170 170 170  170 85 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  85 255 85  255 85 85  170 170 170  170 170 170
-170 170 170  85 255 85  170 170 170  170 85 0  170 170 170  170 85 0
-170 170 170  85 85 85  85 255 85  170 85 0  170 170 170  170 85 0
-170 170 170  170 170 170  170 85 0  85 85 85  85 85 85  85 255 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  170 170 170  170 170 170  0 0 0  0 0 0  85 85 85
-170 170 170  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  255 255 85  85 85 85  85 85 85  85 85 85
-85 255 85  255 85 85  170 170 170  170 85 0  170 170 170  85 255 85
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  170 85 0  170 170 170  170 170 170  255 255 85
-170 170 170  255 85 85  170 170 170  170 170 170  255 255 85  170 170 170
-85 255 85  170 170 170  255 85 85  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 85 0  170 170 170  170 85 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  85 85 85  0 0 0  85 85 85
-85 85 85  170 85 0  85 85 85  0 0 0  85 85 85  85 85 85
-85 85 85  170 85 0  170 170 170  170 170 170  255 255 85  170 170 170
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  255 85 85
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  85 85 85  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  170 85 0
-170 170 170  255 255 85  170 170 170  255 255 85  170 170 170  255 255 85
-170 170 170  255 255 85  170 170 170  170 170 170  85 255 85  170 85 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  170 170 170  85 85 85  85 85 85  0 0 0
-85 85 85  85 85 85  170 170 170  85 85 85  170 170 170  170 85 0
-170 170 170  85 255 85  170 170 170  170 85 0  170 170 170  170 170 170
-255 255 85  170 170 170  170 170 170  255 255 255  255 255 85  170 170 170
-255 255 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  170 85 0  170 170 170  170 170 170  170 170 170  255 255 255
-170 170 170  255 255 255  255 255 85  170 170 170  255 255 85  170 170 170
-255 255 85  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  255 85 85  170 170 170  170 170 170
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  170 85 0  85 85 85
-85 85 85  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
-255 255 85  170 170 170  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  255 255 255  255 255 255  170 170 170  255 255 255  170 170 170
-170 170 170  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 255 85  170 170 170  255 255 85  255 255 255  255 255 255
-255 255 255  170 170 170  255 255 255  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  255 255 85  170 170 170  255 255 85  255 255 255
-255 255 85  255 255 255  255 255 85  170 170 170  170 170 170  170 85 0
-170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  170 170 170  255 255 85  170 170 170  255 255 85  170 170 170
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  255 255 85
-255 255 255  255 255 255  255 255 85  255 255 255  255 255 255  170 170 170
-255 255 85  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  170 170 170  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  170 170 170  170 170 170  170 170 170  255 255 255  170 170 170
-255 255 255  255 255 255  255 255 255  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 85  170 170 170  255 255 255  170 170 170  255 255 255
-255 255 255  255 255 255  170 170 170  255 255 85  170 170 170  255 255 85
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  170 85 0  170 170 170
-255 255 85  170 170 170  170 170 170  255 255 255  255 255 255  255 255 255
-170 170 170  170 170 170  170 170 170  255 255 85  170 170 170  170 170 170
-255 255 255  170 170 170  255 255 255  255 255 255  170 170 170  255 255 255
-170 170 170  170 170 170  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
-85 85 85  170 85 0  255 255 255  170 170 170  255 255 255  255 255 255
-255 255 85  255 255 255  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  255 255 85  255 255 255  255 255 255
-170 170 170  255 255 255  255 255 255  170 170 170  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 255 85  170 170 170
-170 170 170  255 255 85  170 170 170  255 255 255  170 170 170  255 255 255
-255 255 255  255 255 255  255 255 85  170 170 170  170 170 170  255 255 255
-170 170 170  255 255 255  255 255 255  170 170 170  255 255 255  255 255 85
-170 170 170  170 85 0  85 85 85  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  170 170 170  170 170 170  255 255 85  170 170 170  255 255 255
-255 255 255  170 170 170  255 255 255  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 85  170 170 170  255 255 255  170 170 170  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  255 255 85
-85 85 85  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  170 85 0  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
-170 170 170  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 85  255 255 255  170 170 170  255 255 255  170 170 170  170 170 170
-170 170 170  170 170 170  85 85 85  0 0 0  85 85 85  85 85 85
-0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-85 85 85  85 85 85  170 170 170  170 170 170  255 255 255  170 170 170
-255 255 255  170 170 170  255 255 85  170 170 170  170 170 170  170 170 170
-255 85 85  170 170 170  170 170 170  170 170 170  255 255 255  255 255 255
-170 170 170  255 255 255  255 255 255  170 170 170  255 255 255  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  170 170 170
-255 255 85  170 170 170  255 255 255  170 170 170  255 255 255  255 255 255
-255 255 85  255 255 255  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  255 255 85
-170 170 170  170 85 0  85 85 85  0 0 0  85 85 85  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
-170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  255 255 85  170 170 170  170 170 170
-255 255 85  170 170 170  170 170 170  170 170 170  170 170 170  255 85 85
-85 255 85  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 255  255 255 255  255 255 255  255 255 85  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 85
-170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  170 170 170
-255 255 255  170 170 170  170 170 170  170 170 170  170 170 170  255 85 85
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  85 85 85  85 85 85  0 0 0  85 85 85  0 0 0
-85 85 85  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  170 170 170  170 170 170  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  170 85 0  170 170 170  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 85 0  170 170 170  85 255 85
-255 85 85  170 170 170  255 255 85  170 170 170  170 170 170  255 255 255
-255 255 255  170 170 170  255 255 255  255 255 255  170 170 170  170 170 170
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-170 170 170  255 255 85  170 170 170  255 255 85  255 255 255  255 255 255
-170 170 170  170 170 170  255 255 85  170 170 170  255 85 85  85 255 85
-170 170 170  170 85 0  170 170 170  170 170 170  255 255 85  170 170 170
-170 85 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  85 85 85  85 85 85  85 85 85  170 170 170  255 255 85
-170 170 170  170 85 0  170 170 170  170 170 170  170 85 0  85 85 85
-170 170 170  170 85 0  85 85 85  170 170 170  170 170 170  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 85  170 170 170  170 170 170
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 85 0
-170 170 170  170 170 170  255 255 255  170 170 170  255 255 255  170 170 170
-255 255 255  170 170 170  170 170 170  170 85 0  170 170 170  85 85 85
-170 170 170  170 170 170  170 85 0  170 170 170  170 85 0  85 85 85
-85 255 85  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  85 85 85  170 85 0  85 85 85  170 170 170
-170 85 0  170 170 170  85 255 85  170 85 0  170 170 170  85 85 85
-170 85 0  170 170 170  170 170 170  255 255 85  170 170 170  255 255 255
-255 255 85  255 255 255  170 170 170  170 170 170  170 170 170  170 85 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 85  170 170 170  170 170 170  85 255 85  170 170 170
-170 85 0  170 85 0  170 170 170  85 255 85  85 85 85  170 170 170
-170 85 0  85 85 85  0 0 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  85 85 85  170 85 0  85 85 85
-170 170 170  170 85 0  170 170 170  85 85 85  170 170 170  170 85 0
-170 170 170  85 255 85  170 85 0  170 170 170  170 170 170  170 170 170
-255 255 255  170 170 170  255 255 255  255 255 255  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-170 85 0  170 170 170  255 255 85  170 170 170  255 255 255  170 170 170
-170 170 170  170 170 170  170 170 170  170 85 0  170 170 170  170 85 0
-170 170 170  85 255 85  170 85 0  170 170 170  170 85 0  85 85 85
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-85 255 85  170 170 170  170 85 0  170 170 170  170 85 0  85 255 85
-170 170 170  170 85 0  170 170 170  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 255  170 170 170  170 170 170  170 170 170  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 85 0  85 85 85  170 170 170  255 255 85  170 170 170
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  170 85 0
-170 170 170  85 85 85  170 170 170  170 85 0  170 170 170  85 85 85
-170 85 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  170 85 0
-85 85 85  255 85 85  85 255 85  170 85 0  170 170 170  170 170 170
-170 85 0  170 170 170  85 85 85  255 255 85  170 170 170  170 170 170
-255 255 255  170 170 170  255 255 255  255 255 85  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  170 170 170  170 85 0  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  255 255 85  85 85 85  170 170 170
-85 255 85  255 85 85  170 170 170  85 255 85  255 85 85  85 255 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  85 85 85
-85 85 85  85 255 85  255 85 85  170 170 170  85 255 85  170 85 0
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  255 255 255
-170 170 170  255 255 255  170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 170 170  85 85 85  255 255 85
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  255 255 85
-85 85 85  255 255 85  170 170 170  170 85 0  170 170 170  85 85 85
-170 85 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 170 170  170 85 0  170 170 170  170 85 0  170 170 170  170 170 170
-170 85 0  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 85  255 255 255  170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 85 0  85 85 85  170 170 170
-170 85 0  170 170 170  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  255 255 85  170 170 170  170 85 0
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-170 85 0  85 255 85  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 85  170 170 170  170 170 170  170 170 170  255 255 255  255 255 255
-255 255 255  170 170 170  255 255 85  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  170 85 0
-170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
-170 170 170  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  170 85 0  170 170 170  170 85 0  170 170 170  170 170 170
-170 170 170  255 255 85  170 170 170  255 255 85  170 170 170  255 255 255
-170 170 170  255 255 255  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
-170 85 0  170 170 170  170 85 0  255 255 85  170 170 170  170 170 170
-170 170 170  170 170 170  255 255 85  170 170 170  255 255 85  170 170 170
-255 255 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  170 170 170  255 255 85  170 170 170  255 255 85  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
-170 170 170  170 170 170  170 170 170  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 170 0  85 85 85
-170 85 0  85 255 85  170 170 170  170 170 170  170 170 170  255 255 85
-255 255 255  170 170 170  255 255 255  170 170 170  255 255 255  170 170 170
-170 170 170  255 255 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-170 85 0  170 170 170  170 170 170  170 170 170  170 170 170  255 255 85
-170 170 170  255 255 255  170 170 170  255 255 255  170 170 170  255 255 255
-255 255 255  255 255 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  170 85 0  170 170 170  170 170 170  255 255 85  170 170 170
-170 170 170  255 255 255  255 255 255  255 255 255  170 170 170  255 255 255
-170 170 170  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 255 85
-170 170 170  255 255 85  170 170 170  255 255 85  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
-170 170 170  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  170 85 0  170 170 170  170 170 170
-255 255 85  170 170 170  255 255 255  255 255 85  255 255 255  255 255 255
-170 170 170  255 255 85  170 170 170  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 85 0
-170 170 170  170 170 170  170 170 170  255 255 255  170 170 170  255 255 255
-170 170 170  255 255 255  170 170 170  255 255 255  255 255 85  255 255 255
-170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  170 85 0  85 85 85  170 170 170  170 170 170  170 170 170
-170 170 170  255 255 255  170 170 170  255 255 255  255 255 255  170 170 170
-255 255 85  170 170 170  170 170 170  170 85 0  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-255 255 85  170 170 170  255 255 85  170 170 170  255 255 255  255 255 255
-255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
-170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  170 85 0  170 170 170
-255 255 85  170 170 170  255 255 85  255 255 255  170 170 170  255 255 255
-170 170 170  170 170 170  170 170 170  170 170 170  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
-170 85 0  170 170 170  255 255 255  170 170 170  255 255 255  170 170 170
-255 255 255  255 255 255  170 170 170  255 255 255  255 255 85  170 170 170
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  85 85 85  170 85 0  85 85 85  170 170 170
-170 170 170  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 85  170 170 170  170 85 0  85 255 85  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 85 0
-170 170 170  170 170 170  255 255 85  170 170 170  255 255 255  255 255 255
-255 255 85  255 255 255  170 170 170  255 255 255  170 170 170  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-170 85 0  170 170 170  170 170 170  255 255 85  170 170 170  170 170 170
-170 170 170  170 170 170  170 170 170  170 85 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-255 255 85  170 170 170  170 170 170  170 170 170  255 255 85  170 170 170
-255 255 255  170 170 170  255 255 85  170 170 170  85 85 85  85 85 85
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-85 85 85  170 85 0  170 170 170  170 170 170  170 170 170  170 170 170
-170 85 0  170 170 170  170 85 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
-170 170 170  170 170 170  255 255 85  170 170 170  170 170 170  170 170 170
-170 170 170  255 255 255  170 170 170  170 170 170  85 85 85  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-85 85 85  85 85 85  85 85 85  170 85 0  85 85 85  170 85 0
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 85 0
-85 85 85  170 85 0  170 170 170  170 170 170  170 170 170  255 255 85
-170 170 170  170 170 170  170 85 0  85 85 85  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
-85 85 85  85 255 85  170 85 0  170 170 170  170 85 0  170 170 170
-85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
-85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
-0 0 0  0 0 0  0 0 0  0 0 0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170  85  85  85   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170 170 170 170 255 255 255 255 255 255
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 170 170 170 170 170 170
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255 170 170 170   0   0   0  85  85  85
+170 170 170 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 170 170 170
+ 85  85  85  85  85  85  85  85  85  85  85  85
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 170 170 170 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170 170 170 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170  85  85  85 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85  85  85  85  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+ 85  85  85   0   0   0   0   0   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 170  85   0 170  85   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85  85  85  85  85  85  85 170  85   0
+170  85   0 170  85   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 84f63205c46d..0889d50c3288 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1439,7 +1439,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
 static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
 {
 	struct pxafb_info *fbi = dev_id;
-	unsigned int lccr0, lcsr, lcsr1;
+	unsigned int lccr0, lcsr;
 
 	lcsr = lcd_readl(fbi, LCSR);
 	if (lcsr & LCSR_LDD) {
@@ -1455,14 +1455,16 @@ static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
 	lcd_writel(fbi, LCSR, lcsr);
 
 #ifdef CONFIG_FB_PXA_OVERLAY
-	lcsr1 = lcd_readl(fbi, LCSR1);
-	if (lcsr1 & LCSR1_BS(1))
-		complete(&fbi->overlay[0].branch_done);
+	{
+		unsigned int lcsr1 = lcd_readl(fbi, LCSR1);
+		if (lcsr1 & LCSR1_BS(1))
+			complete(&fbi->overlay[0].branch_done);
 
-	if (lcsr1 & LCSR1_BS(2))
-		complete(&fbi->overlay[1].branch_done);
+		if (lcsr1 & LCSR1_BS(2))
+			complete(&fbi->overlay[1].branch_done);
 
-	lcd_writel(fbi, LCSR1, lcsr1);
+		lcd_writel(fbi, LCSR1, lcsr1);
+	}
 #endif
 	return IRQ_HANDLED;
 }
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 4dcec48a1d78..c3fad34309ed 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -45,11 +45,11 @@ struct s3fb_info {
 static const struct svga_fb_format s3fb_formats[] = {
 	{ 0,  {0, 6, 0},  {0, 6, 0},  {0, 6, 0}, {0, 0, 0}, 0,
 		FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4,	FB_VISUAL_PSEUDOCOLOR, 8, 16},
-	{ 4,  {0, 6, 0},  {0, 6, 0},  {0, 6, 0}, {0, 0, 0}, 0,
+	{ 4,  {0, 4, 0},  {0, 4, 0},  {0, 4, 0}, {0, 0, 0}, 0,
 		FB_TYPE_PACKED_PIXELS, 0,		FB_VISUAL_PSEUDOCOLOR, 8, 16},
-	{ 4,  {0, 6, 0},  {0, 6, 0},  {0, 6, 0}, {0, 0, 0}, 1,
+	{ 4,  {0, 4, 0},  {0, 4, 0},  {0, 4, 0}, {0, 0, 0}, 1,
 		FB_TYPE_INTERLEAVED_PLANES, 1,		FB_VISUAL_PSEUDOCOLOR, 8, 16},
-	{ 8,  {0, 6, 0},  {0, 6, 0},  {0, 6, 0}, {0, 0, 0}, 0,
+	{ 8,  {0, 8, 0},  {0, 8, 0},  {0, 8, 0}, {0, 0, 0}, 0,
 		FB_TYPE_PACKED_PIXELS, 0,		FB_VISUAL_PSEUDOCOLOR, 4, 8},
 	{16,  {10, 5, 0}, {5, 5, 0},  {0, 5, 0}, {0, 0, 0}, 0,
 		FB_TYPE_PACKED_PIXELS, 0,		FB_VISUAL_TRUECOLOR, 2, 4},
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index fad58cf9ef73..10ddad8e17d6 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -199,16 +199,20 @@
 extern void (*sa1100fb_backlight_power)(int on);
 extern void (*sa1100fb_lcd_power)(int on);
 
-/*
- * IMHO this looks wrong.  In 8BPP, length should be 8.
- */
-static struct sa1100fb_rgb rgb_8 = {
+static struct sa1100fb_rgb rgb_4 = {
 	.red	= { .offset = 0,  .length = 4, },
 	.green	= { .offset = 0,  .length = 4, },
 	.blue	= { .offset = 0,  .length = 4, },
 	.transp	= { .offset = 0,  .length = 0, },
 };
 
+static struct sa1100fb_rgb rgb_8 = {
+	.red	= { .offset = 0,  .length = 8, },
+	.green	= { .offset = 0,  .length = 8, },
+	.blue	= { .offset = 0,  .length = 8, },
+	.transp	= { .offset = 0,  .length = 0, },
+};
+
 static struct sa1100fb_rgb def_rgb_16 = {
 	.red	= { .offset = 11, .length = 5, },
 	.green	= { .offset = 5,  .length = 6, },
@@ -613,7 +617,7 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 	DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
 	switch (var->bits_per_pixel) {
 	case 4:
-		rgbidx = RGB_8;
+		rgbidx = RGB_4;
 		break;
 	case 8:
 		rgbidx = RGB_8;
@@ -1382,6 +1386,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 	fbi->fb.monspecs	= monspecs;
 	fbi->fb.pseudo_palette	= (fbi + 1);
 
+	fbi->rgb[RGB_4]		= &rgb_4;
 	fbi->rgb[RGB_8]		= &rgb_8;
 	fbi->rgb[RGB_16]	= &def_rgb_16;
 
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index 86831db9a042..1c3b459865d8 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -57,9 +57,10 @@ struct sa1100fb_lcd_reg {
 	unsigned long lccr3;
 };
 
-#define RGB_8	(0)
-#define RGB_16	(1)
-#define NR_RGB	2
+#define RGB_4	(0)
+#define RGB_8	(1)
+#define RGB_16	(2)
+#define NR_RGB	3
 
 struct sa1100fb_info {
 	struct fb_info		fb;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 346d6458cf76..7e17ee95a97a 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1129,7 +1129,7 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
 	switch(var->bits_per_pixel) {
 	case 8:
 		var->red.offset = var->green.offset = var->blue.offset = 0;
-		var->red.length = var->green.length = var->blue.length = 6;
+		var->red.length = var->green.length = var->blue.length = 8;
 		break;
 	case 16:
 		var->red.offset = 11;
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index a439159204a8..89158bc71da2 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -308,9 +308,11 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
      *   color depth = SUM(var->{color}.length)
      *
      * Pseudocolor:
-     *    var->{color}.offset is 0
-     *    var->{color}.length contains width of DAC or the number of unique
-     *                        colors available (color depth)
+     *    var->{color}.offset is 0 unless the palette index takes less than
+     *                        bits_per_pixel bits and is stored in the upper
+     *                        bits of the pixel value
+     *    var->{color}.length is set so that 1 << length is the number of
+     *                        available palette entries
      *    pseudo_palette is not used
      *    RAMDAC[X] is programmed to (red, green, blue)
      *    color depth = var->{color}.length
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 0b370aebdbfd..421770b5e6ab 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -55,6 +55,7 @@ static u16 maxvf	__devinitdata; /* maximum vertical frequency */
 static u16 maxhf	__devinitdata; /* maximum horizontal frequency */
 static u16 vbemode	__devinitdata; /* force use of a specific VBE mode */
 static char *mode_option __devinitdata;
+static u8  dac_width	= 6;
 
 static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
 static DEFINE_MUTEX(uvfb_lock);
@@ -303,22 +304,10 @@ static void uvesafb_setup_var(struct fb_var_screeninfo *var,
 		var->blue.offset   = 0;
 		var->transp.offset = 0;
 
-		/*
-		 * We're assuming that we can switch the DAC to 8 bits. If
-		 * this proves to be incorrect, we'll update the fields
-		 * later in set_par().
-		 */
-		if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
-			var->red.length    = 8;
-			var->green.length  = 8;
-			var->blue.length   = 8;
-			var->transp.length = 0;
-		} else {
-			var->red.length    = 6;
-			var->green.length  = 6;
-			var->blue.length   = 6;
-			var->transp.length = 0;
-		}
+		var->red.length    = 8;
+		var->green.length  = 8;
+		var->blue.length   = 8;
+		var->transp.length = 0;
 	}
 }
 
@@ -1006,7 +995,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 		struct fb_info *info)
 {
 	struct uvesafb_pal_entry entry;
-	int shift = 16 - info->var.green.length;
+	int shift = 16 - dac_width;
 	int err = 0;
 
 	if (regno >= info->cmap.len)
@@ -1055,7 +1044,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
 {
 	struct uvesafb_pal_entry *entries;
-	int shift = 16 - info->var.green.length;
+	int shift = 16 - dac_width;
 	int i, err = 0;
 
 	if (info->var.bits_per_pixel == 8) {
@@ -1317,13 +1306,9 @@ setmode:
 		err = uvesafb_exec(task);
 		if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
 		    ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
-			/*
-			 * We've failed to set the DAC palette format -
-			 * time to correct var.
-			 */
-			info->var.red.length    = 6;
-			info->var.green.length  = 6;
-			info->var.blue.length   = 6;
+			dac_width = 6;
+		} else {
+			dac_width = 8;
 		}
 	}
 
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index cc919ae46571..050d432c7d95 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -318,13 +318,16 @@ static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 	 *   {hardwarespecific} contains width of RAMDAC
 	 *   cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
 	 *   RAMDAC[X] is programmed to (red, green, blue)
-	 * 
+	 *
 	 * Pseudocolor:
-	 *    uses offset = 0 && length = RAMDAC register width.
-	 *    var->{color}.offset is 0
-	 *    var->{color}.length contains widht of DAC
+	 *    var->{color}.offset is 0 unless the palette index takes less than
+	 *                        bits_per_pixel bits and is stored in the upper
+	 *                        bits of the pixel value
+	 *    var->{color}.length is set so that 1 << length is the number of available
+	 *                        palette entries
 	 *    cmap is not used
 	 *    RAMDAC[X] is programmed to (red, green, blue)
+	 *
 	 * Truecolor:
 	 *    does not use DAC. Usually 3 are present.
 	 *    var->{color}.offset contains start of bitfield
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 59268266b79a..9c76a061a04d 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -190,7 +190,8 @@ static int balloon(void *_vballoon)
 		try_to_freeze();
 		wait_event_interruptible(vb->config_change,
 					 (diff = towards_target(vb)) != 0
-					 || kthread_should_stop());
+					 || kthread_should_stop()
+					 || freezing(current));
 		if (diff > 0)
 			fill_balloon(vb, diff);
 		else if (diff < 0)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 63024145215d..5eb8f21da82e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -240,8 +240,6 @@ config ORION5X_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called orion5x_wdt.
 
-# ARM26 Architecture
-
 # AVR32 Architecture
 
 config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 806b3eb08536..7f8c56b14f58 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -42,8 +42,6 @@ obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
 obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
 obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o
 
-# ARM26 Architecture
-
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
 
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index e35d54589232..29e52c237a3b 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -197,7 +197,7 @@ static struct miscdevice at91wdt_miscdev = {
 	.fops		= &at91wdt_fops,
 };
 
-static int __init at91wdt_probe(struct platform_device *pdev)
+static int __devinit at91wdt_probe(struct platform_device *pdev)
 {
 	int res;
 
@@ -214,7 +214,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int __exit at91wdt_remove(struct platform_device *pdev)
+static int __devexit at91wdt_remove(struct platform_device *pdev)
 {
 	int res;
 
@@ -252,7 +252,7 @@ static int at91wdt_resume(struct platform_device *pdev)
 
 static struct platform_driver at91wdt_driver = {
 	.probe		= at91wdt_probe,
-	.remove		= __exit_p(at91wdt_remove),
+	.remove		= __devexit_p(at91wdt_remove),
 	.shutdown	= at91wdt_shutdown,
 	.suspend	= at91wdt_suspend,
 	.resume		= at91wdt_resume,
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 2dbe83570d65..7ba0b11ec525 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -52,10 +52,10 @@
 #define ESB_LOCK_REG    0x68            /* WDT lock register                 */
 
 /* Memory mapped registers */
-#define ESB_TIMER1_REG  BASEADDR + 0x00 /* Timer1 value after each reset     */
-#define ESB_TIMER2_REG  BASEADDR + 0x04 /* Timer2 value after each reset     */
-#define ESB_GINTSR_REG  BASEADDR + 0x08 /* General Interrupt Status Register */
-#define ESB_RELOAD_REG  BASEADDR + 0x0c /* Reload register                   */
+#define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset     */
+#define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset     */
+#define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */
+#define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register                   */
 
 /* Lock register bits */
 #define ESB_WDT_FUNC    (0x01 << 2)   /* Watchdog functionality            */
@@ -68,6 +68,7 @@
 #define ESB_WDT_INTTYPE (0x11 << 0)   /* Interrupt type on timer1 timeout  */
 
 /* Reload register bits */
+#define ESB_WDT_TIMEOUT (0x01 << 9)    /* Watchdog timed out                */
 #define ESB_WDT_RELOAD  (0x01 << 8)    /* prevent timeout                   */
 
 /* Magic constants */
@@ -87,7 +88,6 @@ static struct platform_device *esb_platform_device;
 /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
 #define WATCHDOG_HEARTBEAT 30
 static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
-
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat,
 		"Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
@@ -123,7 +123,7 @@ static int esb_timer_start(void)
 	esb_unlock_registers();
 	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
 	/* Enable or Enable + Lock? */
-	val = 0x02 | (nowayout ? 0x01 : 0x00);
+	val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00);
 	pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
 	spin_unlock(&esb_lock);
 	return 0;
@@ -143,7 +143,7 @@ static int esb_timer_stop(void)
 	spin_unlock(&esb_lock);
 
 	/* Returns 0 if the timer was disabled, non-zero otherwise */
-	return (val & 0x01);
+	return val & ESB_WDT_ENABLE;
 }
 
 static void esb_timer_keepalive(void)
@@ -190,18 +190,6 @@ static int esb_timer_set_heartbeat(int time)
 	return 0;
 }
 
-static int esb_timer_read(void)
-{
-	u32 count;
-
-	/* This isn't documented, and doesn't take into
-	 * acount which stage is running, but it looks
-	 * like a 20 bit count down, so we might as well report it.
-	 */
-	pci_read_config_dword(esb_pci, 0x64, &count);
-	return (int)count;
-}
-
 /*
  *	/dev/watchdog handling
  */
@@ -282,7 +270,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 					sizeof(ident)) ? -EFAULT : 0;
 
 	case WDIOC_GETSTATUS:
-		return put_user(esb_timer_read(), p);
+		return put_user(0, p);
 
 	case WDIOC_GETBOOTSTATUS:
 		return put_user(triggered, p);
@@ -362,8 +350,6 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
 
 static unsigned char __devinit esb_getdevice(void)
 {
-	u8 val1;
-	unsigned short val2;
 	/*
 	 *      Find the PCI device
 	 */
@@ -371,66 +357,79 @@ static unsigned char __devinit esb_getdevice(void)
 	esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
 					PCI_DEVICE_ID_INTEL_ESB_9, NULL);
 
-	if (esb_pci) {
-		if (pci_enable_device(esb_pci)) {
-			printk(KERN_ERR PFX "failed to enable device\n");
-			goto err_devput;
-		}
+	if (!esb_pci)
+		return 0;
 
-		if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
-			printk(KERN_ERR PFX "failed to request region\n");
-			goto err_disable;
-		}
+	if (pci_enable_device(esb_pci)) {
+		printk(KERN_ERR PFX "failed to enable device\n");
+		goto err_devput;
+	}
 
-		BASEADDR = pci_ioremap_bar(esb_pci, 0);
-		if (BASEADDR == NULL) {
-			/* Something's wrong here, BASEADDR has to be set */
-			printk(KERN_ERR PFX "failed to get BASEADDR\n");
-			goto err_release;
-		}
+	if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+		printk(KERN_ERR PFX "failed to request region\n");
+		goto err_disable;
+	}
 
-		/*
-		 * The watchdog has two timers, it can be setup so that the
-		 * expiry of timer1 results in an interrupt and the expiry of
-		 * timer2 results in a reboot. We set it to not generate
-		 * any interrupts as there is not much we can do with it
-		 * right now.
-		 *
-		 * We also enable reboots and set the timer frequency to
-		 * the PCI clock divided by 2^15 (approx 1KHz).
-		 */
-		pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
-
-		/* Check that the WDT isn't already locked */
-		pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
-		if (val1 & ESB_WDT_LOCK)
-			printk(KERN_WARNING PFX "nowayout already set\n");
-
-		/* Set the timer to watchdog mode and disable it for now */
-		pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
-
-		/* Check if the watchdog was previously triggered */
-		esb_unlock_registers();
-		val2 = readw(ESB_RELOAD_REG);
-		triggered = (val2 & (0x01 << 9) >> 9);
-
-		/* Reset trigger flag and timers */
-		esb_unlock_registers();
-		writew((0x11 << 8), ESB_RELOAD_REG);
-
-		/* Done */
-		return 1;
+	BASEADDR = pci_ioremap_bar(esb_pci, 0);
+	if (BASEADDR == NULL) {
+		/* Something's wrong here, BASEADDR has to be set */
+		printk(KERN_ERR PFX "failed to get BASEADDR\n");
+		goto err_release;
+	}
+
+	/* Done */
+	return 1;
 
 err_release:
-		pci_release_region(esb_pci, 0);
+	pci_release_region(esb_pci, 0);
 err_disable:
-		pci_disable_device(esb_pci);
+	pci_disable_device(esb_pci);
 err_devput:
-		pci_dev_put(esb_pci);
-	}
+	pci_dev_put(esb_pci);
 	return 0;
 }
 
+static void __devinit esb_initdevice(void)
+{
+	u8 val1;
+	u16 val2;
+
+	/*
+	 * Config register:
+	 * Bit    5 : 0 = Enable WDT_OUTPUT
+	 * Bit    2 : 0 = set the timer frequency to the PCI clock
+	 * divided by 2^15 (approx 1KHz).
+	 * Bits 1:0 : 11 = WDT_INT_TYPE Disabled.
+	 * The watchdog has two timers, it can be setup so that the
+	 * expiry of timer1 results in an interrupt and the expiry of
+	 * timer2 results in a reboot. We set it to not generate
+	 * any interrupts as there is not much we can do with it
+	 * right now.
+	 */
+	pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+
+	/* Check that the WDT isn't already locked */
+	pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+	if (val1 & ESB_WDT_LOCK)
+		printk(KERN_WARNING PFX "nowayout already set\n");
+
+	/* Set the timer to watchdog mode and disable it for now */
+	pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+
+	/* Check if the watchdog was previously triggered */
+	esb_unlock_registers();
+	val2 = readw(ESB_RELOAD_REG);
+	if (val2 & ESB_WDT_TIMEOUT)
+		triggered = WDIOF_CARDRESET;
+
+	/* Reset WDT_TIMEOUT flag and timers */
+	esb_unlock_registers();
+	writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG);
+
+	/* And set the correct timeout value */
+	esb_timer_set_heartbeat(heartbeat);
+}
+
 static int __devinit esb_probe(struct platform_device *dev)
 {
 	int ret;
@@ -441,13 +440,17 @@ static int __devinit esb_probe(struct platform_device *dev)
 
 	/* Check that the heartbeat value is within it's range;
 	   if not reset to the default */
-	if (esb_timer_set_heartbeat(heartbeat)) {
-		esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT);
+	if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) {
+		heartbeat = WATCHDOG_HEARTBEAT;
 		printk(KERN_INFO PFX
 			"heartbeat value must be 1<heartbeat<2046, using %d\n",
 								heartbeat);
 	}
 
+	/* Initialize the watchdog and make sure it does not run */
+	esb_initdevice();
+
+	/* Register the watchdog so that userspace has access to it */
 	ret = misc_register(&esb_miscdev);
 	if (ret != 0) {
 		printk(KERN_ERR PFX
@@ -455,7 +458,6 @@ static int __devinit esb_probe(struct platform_device *dev)
 							WATCHDOG_MINOR, ret);
 		goto err_unmap;
 	}
-	esb_timer_stop();
 	printk(KERN_INFO PFX
 		"initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
 						BASEADDR, heartbeat, nowayout);
@@ -463,11 +465,8 @@ static int __devinit esb_probe(struct platform_device *dev)
 
 err_unmap:
 	iounmap(BASEADDR);
-/* err_release: */
 	pci_release_region(esb_pci, 0);
-/* err_disable: */
 	pci_disable_device(esb_pci);
-/* err_devput: */
 	pci_dev_put(esb_pci);
 	return ret;
 }
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 74c92d384112..ae3832110acb 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -221,7 +221,7 @@ static struct miscdevice ks8695wdt_miscdev = {
 	.fops		= &ks8695wdt_fops,
 };
 
-static int __init ks8695wdt_probe(struct platform_device *pdev)
+static int __devinit ks8695wdt_probe(struct platform_device *pdev)
 {
 	int res;
 
@@ -238,7 +238,7 @@ static int __init ks8695wdt_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int __exit ks8695wdt_remove(struct platform_device *pdev)
+static int __devexit ks8695wdt_remove(struct platform_device *pdev)
 {
 	int res;
 
@@ -276,7 +276,7 @@ static int ks8695wdt_resume(struct platform_device *pdev)
 
 static struct platform_driver ks8695wdt_driver = {
 	.probe		= ks8695wdt_probe,
-	.remove		= __exit_p(ks8695wdt_remove),
+	.remove		= __devexit_p(ks8695wdt_remove),
 	.shutdown	= ks8695wdt_shutdown,
 	.suspend	= ks8695wdt_suspend,
 	.resume		= ks8695wdt_resume,
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index aa5ad6e33f02..f2713851aaab 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -258,7 +258,7 @@ static const struct file_operations omap_wdt_fops = {
 	.release = omap_wdt_release,
 };
 
-static int __init omap_wdt_probe(struct platform_device *pdev)
+static int __devinit omap_wdt_probe(struct platform_device *pdev)
 {
 	struct resource *res, *mem;
 	struct omap_wdt_dev *wdev;
@@ -367,7 +367,7 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
 		omap_wdt_disable(wdev);
 }
 
-static int omap_wdt_remove(struct platform_device *pdev)
+static int __devexit omap_wdt_remove(struct platform_device *pdev)
 {
 	struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -426,7 +426,7 @@ static int omap_wdt_resume(struct platform_device *pdev)
 
 static struct platform_driver omap_wdt_driver = {
 	.probe		= omap_wdt_probe,
-	.remove		= omap_wdt_remove,
+	.remove		= __devexit_p(omap_wdt_remove),
 	.shutdown	= omap_wdt_shutdown,
 	.suspend	= omap_wdt_suspend,
 	.resume		= omap_wdt_resume,
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c
index e81441f103dd..2cde568e4fb0 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -22,6 +22,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <mach/bridge-regs.h>
 #include <plat/orion5x_wdt.h>
 
 /*
@@ -42,7 +43,17 @@ static unsigned int wdt_tclk;
 static unsigned long wdt_status;
 static spinlock_t wdt_lock;
 
-static void wdt_enable(void)
+static void orion5x_wdt_ping(void)
+{
+	spin_lock(&wdt_lock);
+
+	/* Reload watchdog duration */
+	writel(wdt_tclk * heartbeat, WDT_VAL);
+
+	spin_unlock(&wdt_lock);
+}
+
+static void orion5x_wdt_enable(void)
 {
 	u32 reg;
 
@@ -69,7 +80,7 @@ static void wdt_enable(void)
 	spin_unlock(&wdt_lock);
 }
 
-static void wdt_disable(void)
+static void orion5x_wdt_disable(void)
 {
 	u32 reg;
 
@@ -101,7 +112,7 @@ static int orion5x_wdt_open(struct inode *inode, struct file *file)
 	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
 		return -EBUSY;
 	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
-	wdt_enable();
+	orion5x_wdt_enable();
 	return nonseekable_open(inode, file);
 }
 
@@ -122,18 +133,28 @@ static ssize_t orion5x_wdt_write(struct file *file, const char *data,
 					set_bit(WDT_OK_TO_CLOSE, &wdt_status);
 			}
 		}
-		wdt_enable();
+		orion5x_wdt_ping();
 	}
 	return len;
 }
 
-static struct watchdog_info ident = {
+static int orion5x_wdt_settimeout(int new_time)
+{
+	if ((new_time <= 0) || (new_time > wdt_max_duration))
+		return -EINVAL;
+
+	/* Set new watchdog time to be used when
+	 * orion5x_wdt_enable() or orion5x_wdt_ping() is called. */
+	heartbeat = new_time;
+	return 0;
+}
+
+static const struct watchdog_info ident = {
 	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
 			  WDIOF_KEEPALIVEPING,
 	.identity	= "Orion5x Watchdog",
 };
 
-
 static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
 				unsigned long arg)
 {
@@ -152,7 +173,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
 		break;
 
 	case WDIOC_KEEPALIVE:
-		wdt_enable();
+		orion5x_wdt_ping();
 		ret = 0;
 		break;
 
@@ -161,12 +182,11 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
 		if (ret)
 			break;
 
-		if (time <= 0 || time > wdt_max_duration) {
+		if (orion5x_wdt_settimeout(time)) {
 			ret = -EINVAL;
 			break;
 		}
-		heartbeat = time;
-		wdt_enable();
+		orion5x_wdt_ping();
 		/* Fall through */
 
 	case WDIOC_GETTIMEOUT:
@@ -187,7 +207,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
 static int orion5x_wdt_release(struct inode *inode, struct file *file)
 {
 	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
-		wdt_disable();
+		orion5x_wdt_disable();
 	else
 		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
 					"timer will not stop\n");
@@ -230,7 +250,7 @@ static int __devinit orion5x_wdt_probe(struct platform_device *pdev)
 	orion5x_wdt_miscdev.parent = &pdev->dev;
 
 	wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
-	if (heartbeat <= 0 || heartbeat > wdt_max_duration)
+	if (orion5x_wdt_settimeout(heartbeat))
 		heartbeat = wdt_max_duration;
 
 	ret = misc_register(&orion5x_wdt_miscdev);
@@ -247,7 +267,7 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
 	int ret;
 
 	if (test_bit(WDT_IN_USE, &wdt_status)) {
-		wdt_disable();
+		orion5x_wdt_disable();
 		clear_bit(WDT_IN_USE, &wdt_status);
 	}
 
@@ -258,9 +278,16 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
 	return ret;
 }
 
+static void orion5x_wdt_shutdown(struct platform_device *pdev)
+{
+	if (test_bit(WDT_IN_USE, &wdt_status))
+		orion5x_wdt_disable();
+}
+
 static struct platform_driver orion5x_wdt_driver = {
 	.probe		= orion5x_wdt_probe,
 	.remove		= __devexit_p(orion5x_wdt_remove),
+	.shutdown	= orion5x_wdt_shutdown,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "orion5x_wdt",
@@ -285,10 +312,11 @@ MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
 MODULE_DESCRIPTION("Orion5x Processor Watchdog");
 
 module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds");
+MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
 
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 5f54c01c1568..bdfd584ad853 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -21,29 +21,41 @@ static void disable_hotplug_cpu(int cpu)
 	set_cpu_present(cpu, false);
 }
 
-static void vcpu_hotplug(unsigned int cpu)
+static int vcpu_online(unsigned int cpu)
 {
 	int err;
 	char dir[32], state[32];
 
-	if (!cpu_possible(cpu))
-		return;
-
 	sprintf(dir, "cpu/%u", cpu);
 	err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
 	if (err != 1) {
 		printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
-		return;
+		return err;
 	}
 
-	if (strcmp(state, "online") == 0) {
+	if (strcmp(state, "online") == 0)
+		return 1;
+	else if (strcmp(state, "offline") == 0)
+		return 0;
+
+	printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", state, cpu);
+	return -EINVAL;
+}
+static void vcpu_hotplug(unsigned int cpu)
+{
+	if (!cpu_possible(cpu))
+		return;
+
+	switch (vcpu_online(cpu)) {
+	case 1:
 		enable_hotplug_cpu(cpu);
-	} else if (strcmp(state, "offline") == 0) {
+		break;
+	case 0:
 		(void)cpu_down(cpu);
 		disable_hotplug_cpu(cpu);
-	} else {
-		printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
-		       state, cpu);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -64,12 +76,20 @@ static void handle_vcpu_hotplug_event(struct xenbus_watch *watch,
 static int setup_cpu_watcher(struct notifier_block *notifier,
 			      unsigned long event, void *data)
 {
+	int cpu;
 	static struct xenbus_watch cpu_watch = {
 		.node = "cpu",
 		.callback = handle_vcpu_hotplug_event};
 
 	(void)register_xenbus_watch(&cpu_watch);
 
+	for_each_possible_cpu(cpu) {
+		if (vcpu_online(cpu) == 0) {
+			(void)cpu_down(cpu);
+			cpu_clear(cpu, cpu_present_map);
+		}
+	}
+
 	return NOTIFY_DONE;
 }
 
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 0d61db1e7b49..4b5b84837ee1 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -62,14 +62,15 @@ static int xen_suspend(void *data)
 	gnttab_resume();
 	xen_mm_unpin_all();
 
-	sysdev_resume();
-
 	if (!*cancelled) {
 		xen_irq_resume();
 		xen_console_resume();
 		xen_timer_resume();
 	}
 
+	sysdev_resume();
+	device_power_up(PMSG_RESUME);
+
 	return 0;
 }