Merge branches 'x86-fixes-for-linus', 'perf-fixes-for-linus' and 'sched-fixes-for...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 Dec 2010 14:40:59 +0000 (06:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 Dec 2010 14:40:59 +0000 (06:40 -0800)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86/pvclock: Zero last_value on resume

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf record: Fix eternal wait for stillborn child
  perf header: Don't assume there's no attr info if no sample ids is provided
  perf symbols: Figure out start address of kernel map from kallsyms
  perf symbols: Fix kallsyms kernel/module map splitting

* 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  nohz: Fix printk_needs_cpu() return value on offline cpus
  printk: Fix wake_up_klogd() vs cpu hotplug

1029 files changed:
Documentation/ABI/testing/sysfs-bus-rbd [new file with mode: 0644]
Documentation/ABI/testing/sysfs-platform-asus-laptop
Documentation/ABI/testing/sysfs-platform-eeepc-wmi [new file with mode: 0644]
Documentation/DocBook/sh.tmpl
Documentation/DocBook/uio-howto.tmpl
Documentation/development-process/2.Process
Documentation/driver-model/interface.txt [deleted file]
Documentation/edac.txt
Documentation/fb/00-INDEX
Documentation/filesystems/configfs/configfs_example_explicit.c
Documentation/filesystems/vfs.txt
Documentation/gpio.txt
Documentation/hwmon/lm93
Documentation/hwmon/max6650
Documentation/kernel-parameters.txt
Documentation/networking/ip-sysctl.txt
Documentation/power/opp.txt
Documentation/sh/clk.txt [deleted file]
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/Makefile
arch/arm/boot/bootp/init.S
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/vmlinux.lds.in
arch/arm/common/gic.c
arch/arm/configs/at91rm9200_defconfig [new file with mode: 0644]
arch/arm/configs/at91rm9200dk_defconfig [deleted file]
arch/arm/configs/at91rm9200ek_defconfig [deleted file]
arch/arm/configs/ateb9200_defconfig [deleted file]
arch/arm/configs/carmeva_defconfig [deleted file]
arch/arm/configs/cpuat91_defconfig [deleted file]
arch/arm/configs/csb337_defconfig [deleted file]
arch/arm/configs/csb637_defconfig [deleted file]
arch/arm/configs/ecbat91_defconfig [deleted file]
arch/arm/configs/kafa_defconfig [deleted file]
arch/arm/configs/kb9202_defconfig [deleted file]
arch/arm/configs/onearm_defconfig [deleted file]
arch/arm/configs/picotux200_defconfig [deleted file]
arch/arm/configs/yl9200_defconfig [deleted file]
arch/arm/include/asm/assembler.h
arch/arm/include/asm/mmu.h
arch/arm/include/asm/pgtable.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/relocate_kernel.S
arch/arm/lib/findbit.S
arch/arm/mach-aaec2000/include/mach/vmalloc.h
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/board-1arm.c
arch/arm/mach-at91/board-dk.c [deleted file]
arch/arm/mach-at91/board-ek.c [deleted file]
arch/arm/mach-at91/board-kafa.c
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-rm9200dk.c [new file with mode: 0644]
arch/arm/mach-at91/board-rm9200ek.c [new file with mode: 0644]
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-bcmring/include/mach/vmalloc.h
arch/arm/mach-clps711x/include/mach/vmalloc.h
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-ebsa110/include/mach/vmalloc.h
arch/arm/mach-footbridge/include/mach/vmalloc.h
arch/arm/mach-h720x/include/mach/vmalloc.h
arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
arch/arm/mach-integrator/include/mach/vmalloc.h
arch/arm/mach-msm/include/mach/vmalloc.h
arch/arm/mach-mx25/devices-imx25.h
arch/arm/mach-mx3/mach-pcm037_eet.c
arch/arm/mach-netx/include/mach/vmalloc.h
arch/arm/mach-omap1/include/mach/vmalloc.h
arch/arm/mach-omap2/include/mach/vmalloc.h
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-pnx4008/include/mach/vmalloc.h
arch/arm/mach-realview/headsmp.S
arch/arm/mach-rpc/include/mach/vmalloc.h
arch/arm/mach-s3c2410/h1940-bluetooth.c
arch/arm/mach-s3c2412/Kconfig
arch/arm/mach-s3c2416/Kconfig
arch/arm/mach-s3c2416/irq.c
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2440/s3c2442.c
arch/arm/mach-s3c2443/Kconfig
arch/arm/mach-s3c2443/irq.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-shark/include/mach/vmalloc.h
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-tegra/include/mach/debug-macro.S
arch/arm/mach-ux500/cpu.c
arch/arm/mach-versatile/include/mach/vmalloc.h
arch/arm/mach-vexpress/headsmp.S
arch/arm/mm/ioremap.c
arch/arm/mm/proc-v7.S
arch/arm/plat-iop/time.c
arch/arm/plat-mxc/devices/platform-imx-dma.c
arch/arm/plat-mxc/devices/platform-spi_imx.c
arch/arm/plat-nomadik/timer.c
arch/arm/plat-pxa/include/plat/sdhci.h
arch/arm/plat-s3c24xx/cpu.c
arch/arm/plat-s3c24xx/gpiolib.c
arch/arm/plat-s3c24xx/include/plat/s3c244x.h
arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
arch/arm/vfp/vfphw.S
arch/blackfin/kernel/process.c
arch/frv/kernel/process.c
arch/h8300/kernel/process.c
arch/ia64/hp/sim/simscsi.c
arch/m68k/kernel/process.c
arch/m68knommu/kernel/process.c
arch/mn10300/include/asm/syscall.h [new file with mode: 0644]
arch/mn10300/kernel/gdb-io-serial.c
arch/mn10300/kernel/gdb-io-ttysm.c
arch/mn10300/kernel/gdb-stub.c
arch/mn10300/kernel/process.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/sys_parisc32.c
arch/powerpc/Kconfig
arch/powerpc/boot/div64.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/pgtable.c
arch/powerpc/mm/tlb_low_64e.S
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/pci_dlpar.c
arch/s390/Kconfig.debug
arch/s390/include/asm/page.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/nmi.c
arch/s390/kernel/vtime.c
arch/s390/lib/delay.c
arch/s390/mm/gup.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/sh/include/asm/cacheflush.h
arch/sh/include/asm/processor_32.h
arch/sh/include/cpu-sh4/cpu/sh7724.h
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/sys_sh.c
arch/sh/kernel/vsyscall/vsyscall-trapa.S
arch/sh/mm/cache-sh4.c
arch/sh/mm/cache-sh7705.c
arch/sh/mm/cache.c
arch/sh/mm/kmap.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/sys_sparc32.c
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/unaligned_32.c
arch/sparc/kernel/windows.c
arch/tile/Kconfig
arch/tile/include/asm/cacheflush.h
arch/tile/include/asm/io.h
arch/tile/include/asm/pci-bridge.h [deleted file]
arch/tile/include/asm/pci.h
arch/tile/include/asm/processor.h
arch/tile/include/hv/drv_xgbe_impl.h [new file with mode: 0644]
arch/tile/include/hv/drv_xgbe_intf.h [new file with mode: 0644]
arch/tile/include/hv/netio_errors.h [new file with mode: 0644]
arch/tile/include/hv/netio_intf.h [new file with mode: 0644]
arch/tile/kernel/Makefile
arch/tile/kernel/compat.c
arch/tile/kernel/compat_signal.c
arch/tile/kernel/pci.c [new file with mode: 0644]
arch/tile/kernel/setup.c
arch/tile/kernel/signal.c
arch/tile/kernel/smpboot.c
arch/tile/kernel/sys.c
arch/tile/lib/memchr_32.c
arch/tile/lib/spinlock_32.c
arch/tile/mm/fault.c
arch/tile/mm/hugetlbpage.c
arch/um/drivers/line.c
arch/um/kernel/exec.c
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/pvclock.h
arch/x86/include/asm/uv/uv_hub.h
arch/x86/include/asm/uv/uv_mmrs.h
arch/x86/include/asm/xen/interface.h
arch/x86/include/asm/xen/interface_32.h
arch/x86/include/asm/xen/interface_64.h
arch/x86/include/asm/xen/page.h
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/kgdb.c
arch/x86/kernel/mmconf-fam10h_64.c
arch/x86/kernel/msr.c
arch/x86/kernel/pvclock.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/mm/tlb.c
arch/x86/pci/xen.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/platform/uv/uv_time.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/platform-pci-unplug.c
arch/x86/xen/setup.c
arch/x86/xen/suspend.c
arch/x86/xen/time.c
arch/x86/xen/xen-ops.h
block/blk-throttle.c
block/compat_ioctl.c
block/ioctl.c
drivers/ata/libata-scsi.c
drivers/ata/sata_via.c
drivers/base/power/main.c
drivers/block/amiflop.c
drivers/block/ataflop.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/block/rbd.c
drivers/block/xen-blkfront.c
drivers/char/agp/frontend.c
drivers/char/agp/intel-gtt.c
drivers/char/amiserial.c
drivers/char/briq_panel.c
drivers/char/hpet.c
drivers/char/hw_random/core.c
drivers/char/istallion.c
drivers/char/serial167.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/tpm/tpm_tis.c
drivers/char/uv_mmtimer.c
drivers/char/virtio_console.c
drivers/dma/shdma.c
drivers/edac/Makefile
drivers/edac/mce_amd_inj.c
drivers/firewire/net.c
drivers/firewire/sbp2.c
drivers/gpio/cs5535-gpio.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_acpi.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_hw.c
drivers/gpu/drm/nouveau/nouveau_hw.h
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_irq.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_pm.c
drivers/gpu/drm/nouveau/nouveau_ramht.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_temp.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv04_dfp.c
drivers/gpu/drm/nouveau/nv04_pm.c
drivers/gpu/drm/nouveau/nv50_calc.c
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_fifo.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600_reg.h
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_benchmark.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_irq.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_object.h
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/hid/hid-core.c
drivers/hid/hid-egalax.c
drivers/hid/hid-input.c
drivers/hid/hid-tmff.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hiddev.c
drivers/hwmon/i5k_amb.c
drivers/hwmon/lis3lv02d_i2c.c
drivers/i2c/Kconfig
drivers/i2c/algos/Kconfig
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/uverbs_marshall.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/input/input.c
drivers/input/joystick/turbografx.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/gpio_keys_polled.c [new file with mode: 0644]
drivers/input/mouse/synaptics.h
drivers/input/serio/gscps2.c
drivers/input/serio/serio_raw.c
drivers/input/tablet/aiptek.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/isdn/icn/icn.c
drivers/leds/Kconfig
drivers/leds/leds-lp5521.c
drivers/leds/leds-lp5523.c
drivers/leds/leds-ss4200.c
drivers/macintosh/Kconfig
drivers/md/md.c
drivers/md/raid1.c
drivers/media/common/tuners/Kconfig
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/ngene/ngene-core.c
drivers/media/dvb/ngene/ngene-dvb.c
drivers/media/dvb/ngene/ngene-i2c.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/radio-si4713.c
drivers/media/radio/si470x/radio-si470x.h
drivers/media/video/Kconfig
drivers/media/video/au0828/au0828-cards.c
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx18/cx18-i2c.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx23885/cx23885-cards.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/davinci/vpfe_capture.c
drivers/media/video/davinci/vpif_capture.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/fsl-viu.c
drivers/media/video/ivtv/ivtv-i2c.c
drivers/media/video/mxb.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/s2255drv.c
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7164/saa7164.h
drivers/media/video/sh_vou.c
drivers/media/video/soc_camera.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l2-common.c
drivers/media/video/v4l2-compat-ioctl32.c
drivers/media/video/via-camera.c
drivers/media/video/vino.c
drivers/media/video/zoran/zoran_card.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptspi.c
drivers/message/i2o/i2o_scsi.c
drivers/misc/isl29020.c
drivers/misc/sgi-xp/xpc_partition.c
drivers/mmc/core/core.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci-pxa.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mmc/host/ushc.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/scan.c
drivers/net/3c59x.c
drivers/net/8139cp.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/atl1c/atl1c_hw.c
drivers/net/au1000_eth.c
drivers/net/benet/be_main.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bonding/bond_main.c
drivers/net/caif/caif_spi.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/cxgb4vf/t4vf_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/ehea/ehea_main.c
drivers/net/gianfar.c
drivers/net/ipg.c
drivers/net/irda/sh_sir.c
drivers/net/mlx4/fw.c
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/pch_gbe/pch_gbe_param.c
drivers/net/phy/marvell.c
drivers/net/ppp_generic.c
drivers/net/qlge/qlge_main.c
drivers/net/r8169.c
drivers/net/tile/Makefile [new file with mode: 0644]
drivers/net/tile/tilepro.c [new file with mode: 0644]
drivers/net/ucc_geth.h
drivers/net/usb/hso.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/usb.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/parisc/dino.c
drivers/parisc/eisa.c
drivers/parisc/eisa_eeprom.c
drivers/parisc/gsc.c
drivers/parisc/iosapic.c
drivers/parisc/led.c
drivers/parisc/superio.c
drivers/pci/Makefile
drivers/pci/pci-sysfs.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pcmcia/soc_common.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/eeepc-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/ibm_rtl.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/wmi.c
drivers/pnp/isapnp/proc.c
drivers/regulator/core.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/twl-regulator.c
drivers/s390/block/dasd_eer.c
drivers/s390/char/fs3270.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_core.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmur.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/3w-xxxx.c
drivers/scsi/53c700.c
drivers/scsi/BusLogic.c
drivers/scsi/BusLogic.h
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/NCR53c406a.c
drivers/scsi/a100u2w.c
drivers/scsi/aacraid/linit.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aha1542.h
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/atp870u.c
drivers/scsi/bfa/bfad_im.c
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/dtc.h
drivers/scsi/eata.c
drivers/scsi/eata_pio.c
drivers/scsi/esp_scsi.c
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/fnic/fnic.h
drivers/scsi/fnic/fnic_scsi.c
drivers/scsi/g_NCR5380.h
drivers/scsi/gdth.c
drivers/scsi/hpsa.c
drivers/scsi/hptiop.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/imm.c
drivers/scsi/in2000.c
drivers/scsi/in2000.h
drivers/scsi/initio.c
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/mac53c94.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/mesh.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/nsp32.c
drivers/scsi/pas16.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pmcraid.c
drivers/scsi/ppa.c
drivers/scsi/ps3rom.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qlogicfas408.c
drivers/scsi/qlogicfas408.h
drivers/scsi/qlogicpti.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/sd.c
drivers/scsi/stex.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3_scsi.h
drivers/scsi/sym53c416.c
drivers/scsi/sym53c416.h
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/t128.h
drivers/scsi/tmscsim.c
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.h
drivers/scsi/vmw_pvscsi.c
drivers/scsi/wd33c93.c
drivers/scsi/wd33c93.h
drivers/scsi/wd7000.c
drivers/serial/8250.c
drivers/serial/crisv10.c
drivers/serial/mfd.c
drivers/serial/serial_core.c
drivers/sh/clk/core.c
drivers/sh/clk/cpg.c
drivers/spi/atmel_spi.c
drivers/ssb/b43_pci_bridge.c
drivers/staging/asus_oled/asus_oled.c
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/soft-interface.c
drivers/staging/brcm80211/README
drivers/staging/brcm80211/TODO
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/easycap/easycap.h
drivers/staging/frontier/tranzport.c
drivers/staging/go7007/go7007-driver.c
drivers/staging/hv/storvsc_drv.c
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/intel_sst/intel_sst_app_interface.c
drivers/staging/intel_sst/intel_sst_stream_encoded.c
drivers/staging/keucr/scsiglue.c
drivers/staging/line6/control.c
drivers/staging/line6/midi.c
drivers/staging/line6/pcm.c
drivers/staging/line6/pod.c
drivers/staging/line6/toneport.c
drivers/staging/line6/variax.c
drivers/staging/quickstart/quickstart.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8187se/r8185b_init.c
drivers/staging/rtl8712/osdep_service.h
drivers/staging/rtl8712/usb_halinit.c
drivers/staging/samsung-laptop/samsung-laptop.c
drivers/staging/speakup/buffers.c
drivers/staging/speakup/fakekey.c
drivers/staging/spectra/ffsport.c
drivers/staging/stradis/Kconfig
drivers/staging/tm6000/tm6000-cards.c
drivers/staging/udlfb/udlfb.c
drivers/staging/winbond/sysdef.h
drivers/staging/zram/zram_sysfs.c
drivers/tty/sysrq.c
drivers/tty/tty_io.c
drivers/tty/tty_ldisc.c
drivers/uio/uio.c
drivers/uio/uio_cif.c
drivers/uio/uio_netx.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/inode.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_hid.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/image/microtek.c
drivers/usb/misc/cypress_cy7c63.c
drivers/usb/misc/trancevibrator.c
drivers/usb/misc/usbled.c
drivers/usb/misc/usbsevseg.c
drivers/usb/misc/yurex.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_stat.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/otg/langwell_otg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/usb-serial.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/sierra_ms.c
drivers/usb/storage/uas.c
drivers/vhost/net.c
drivers/video/backlight/backlight.c
drivers/video/console/vgacon.c
drivers/video/da8xx-fb.c
drivers/video/fbcmap.c
drivers/video/geode/lxfb.h
drivers/video/geode/lxfb_ops.c
drivers/video/mx3fb.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/sis/init.c
drivers/video/sis/init.h
drivers/video/sis/init301.c
drivers/video/sis/init301.h
drivers/video/sis/initextlfb.c
drivers/video/sis/osdef.h [deleted file]
drivers/video/sis/sis.h
drivers/video/sis/sis_main.c
drivers/video/sis/vgatypes.h
drivers/video/sis/vstruct.h
drivers/virtio/virtio.c
drivers/virtio/virtio_ring.c
drivers/watchdog/Kconfig
drivers/watchdog/bcm63xx_wdt.c
drivers/watchdog/gef_wdt.c
drivers/watchdog/iTCO_wdt.c
drivers/xen/Makefile
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/evtchn.c
drivers/xen/manage.c
drivers/xen/xenfs/privcmd.c
drivers/xen/xenfs/super.c
drivers/zorro/proc.c
fs/autofs4/root.c
fs/block_dev.c
fs/btrfs/compression.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/super.h
fs/cifs/Kconfig
fs/cifs/cifsacl.c
fs/cifs/cifsfs.c
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/dns_resolve.c
fs/cifs/file.c
fs/cifs/fscache.c
fs/cifs/inode.c
fs/cifs/readdir.c
fs/cifs/xattr.c
fs/compat.c
fs/compat_ioctl.c
fs/ecryptfs/super.c
fs/exec.c
fs/ext3/super.c
fs/ext4/ioctl.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/fuse/file.c
fs/gfs2/quota.c
fs/ioctl.c
fs/ioprio.c
fs/jbd2/journal.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/host.c
fs/lockd/svc4proc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/locks.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/nfs/callback.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/internal.h
fs/nfs/nfs2xdr.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
fs/nfsd/nfs4state.c
fs/nilfs2/dat.c
fs/nilfs2/ioctl.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/dcache.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/ocfs2.h
fs/ocfs2/stack_user.c
fs/ocfs2/super.c
fs/pipe.c
fs/proc/base.c
fs/proc/inode.c
fs/proc/task_mmu.c
fs/read_write.c
fs/reiserfs/inode.c
fs/reiserfs/ioctl.c
fs/reiserfs/journal.c
fs/reiserfs/super.c
fs/reiserfs/xattr_acl.c
fs/splice.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h
fs/xfs/xfs_inode_item.c
include/drm/i915_drm.h
include/drm/nouveau_drm.h
include/linux/binfmts.h
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/ceph/osd_client.h
include/linux/cpu.h
include/linux/dmar.h
include/linux/fb.h
include/linux/fs.h
include/linux/gfp.h
include/linux/gpio_keys.h
include/linux/hardirq.h
include/linux/input.h
include/linux/libata.h
include/linux/lockd/lockd.h
include/linux/marvell_phy.h
include/linux/memory_hotplug.h
include/linux/mfd/wm8350/audio.h
include/linux/mmc/host.h
include/linux/module.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/node.h
include/linux/page_cgroup.h
include/linux/pci_ids.h
include/linux/pipe_fs_i.h
include/linux/reiserfs_fs.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/sh_clk.h
include/linux/smp_lock.h
include/linux/tty.h
include/linux/uio_driver.h
include/linux/usb.h
include/linux/vmalloc.h
include/media/v4l2-common.h
include/net/af_unix.h
include/net/cfg80211.h
include/net/neighbour.h
include/scsi/libfc.h
include/scsi/libiscsi.h
include/scsi/libsas.h
include/scsi/scsi_host.h
include/sound/sh_fsi.h
include/video/da8xx-fb.h
include/xen/events.h
include/xen/interface/memory.h
include/xen/interface/physdev.h
include/xen/page.h
include/xen/privcmd.h
init/Kconfig
init/main.c
kernel/debug/kdb/kdb_main.c
kernel/exit.c
kernel/futex.c
kernel/futex_compat.c
kernel/irq/proc.c
kernel/pm_qos_params.c
kernel/posix-cpu-timers.c
kernel/power/Kconfig
kernel/power/hibernate.c
kernel/power/suspend.c
kernel/power/swap.c
kernel/power/user.c
kernel/printk.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_stoptask.c
kernel/sysctl.c
kernel/trace/Kconfig
kernel/trace/trace.c
lib/debug_locks.c
mm/hugetlb.c
mm/ksm.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/nommu.c
mm/page_alloc.c
mm/pagewalk.c
mm/slub.c
mm/vmalloc.c
mm/vmstat.c
net/ceph/Makefile
net/ceph/buffer.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/ceph/pagevec.c
net/core/filter.c
net/core/net-sysfs.c
net/core/request_sock.c
net/dccp/input.c
net/decnet/af_decnet.c
net/econet/af_econet.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/inet_hashtables.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv6/addrconf.c
net/irda/af_irda.c
net/irda/irnet/irnet_ppp.c
net/irda/irttp.c
net/mac80211/Kconfig
net/netfilter/ipvs/Kconfig
net/rds/rdma.c
net/sunrpc/clnt.c
net/sunrpc/stats.c
net/sunrpc/svc_xprt.c
net/unix/af_unix.c
net/unix/garbage.c
net/wireless/chan.c
net/xfrm/xfrm_hash.c
scripts/gfp-translate
scripts/kconfig/expr.h
scripts/kconfig/lkc.h
scripts/kconfig/menu.c
scripts/kconfig/zconf.gperf
scripts/kconfig/zconf.hash.c_shipped
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y
scripts/kernel-doc
sound/atmel/abdac.c
sound/core/info.c
sound/core/oss/pcm_oss.c
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/core/sound.c
sound/oss/dev_table.c
sound/oss/midibuf.c
sound/oss/pss.c
sound/oss/sequencer.c
sound/pci/asihpi/hpioctl.c
sound/pci/azt3328.c
sound/pci/ctxfi/ctpcm.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/intel8x0.c
sound/pci/mixart/mixart_hwdep.h
sound/ppc/pmac.c
sound/soc/atmel/Kconfig
sound/soc/atmel/sam9g20_wm8731.c
sound/soc/atmel/snd-soc-afeb9260.c
sound/soc/codecs/max98088.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tpa6130a2.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-sffsdr.c
sound/soc/davinci/davinci-vcif.c
sound/soc/ep93xx/simone.c
sound/soc/fsl/efika-audio-fabric.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc5200_psc_i2s.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/p1022_ds.c
sound/soc/fsl/pcm030-audio-fabric.c
sound/soc/imx/eukrea-tlv320.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-ssi.c
sound/soc/imx/imx-ssi.h
sound/soc/imx/phycore-ac97.c
sound/soc/nuc900/nuc900-ac97.c
sound/soc/nuc900/nuc900-audio.h
sound/soc/nuc900/nuc900-pcm.c
sound/soc/omap/Kconfig
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap3pandora.c
sound/soc/omap/osk5912.c
sound/soc/pxa/Kconfig
sound/soc/pxa/corgi.c
sound/soc/pxa/magician.c
sound/soc/pxa/poodle.c
sound/soc/pxa/spitz.c
sound/soc/pxa/tosa.c
sound/soc/s3c24xx/Kconfig
sound/soc/s3c24xx/rx1950_uda1380.c
sound/soc/s3c24xx/smdk_spdif.c
sound/soc/s6000/s6000-i2s.c
sound/soc/s6000/s6000-pcm.c
sound/soc/s6000/s6105-ipcam.c
sound/soc/sh/fsi.c
sound/soc/sh/ssi.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/sound_core.c
sound/spi/at73c213.c
usr/initramfs_data.S

diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
new file mode 100644 (file)
index 0000000..90a87e2
--- /dev/null
@@ -0,0 +1,83 @@
+What:          /sys/bus/rbd/
+Date:          November 2010
+Contact:       Yehuda Sadeh <yehuda@hq.newdream.net>,
+               Sage Weil <sage@newdream.net>
+Description:
+
+Being used for adding and removing rbd block devices.
+
+Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
+
+ $ echo "192.168.0.1 name=admin rbd foo" > /sys/bus/rbd/add
+
+The snapshot name can be "-" or omitted to map the image read/write. A <dev-id>
+will be assigned for any registered block device. If snapshot is used, it will
+be mapped read-only.
+
+Removal of a device:
+
+  $ echo <dev-id> > /sys/bus/rbd/remove
+
+Entries under /sys/bus/rbd/devices/<dev-id>/
+--------------------------------------------
+
+client_id
+
+       The ceph unique client id that was assigned for this specific session.
+
+major
+
+       The block device major number.
+
+name
+
+       The name of the rbd image.
+
+pool
+
+       The pool where this rbd image resides. The pool-name pair is unique
+       per rados system.
+
+size
+
+       The size (in bytes) of the mapped block device.
+
+refresh
+
+       Writing to this file will reread the image header data and set
+       all relevant datastructures accordingly.
+
+current_snap
+
+       The current snapshot for which the device is mapped.
+
+create_snap
+
+       Create a snapshot:
+
+        $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
+
+rollback_snap
+
+       Rolls back data to the specified snapshot. This goes over the entire
+       list of rados blocks and sends a rollback command to each.
+
+        $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_rollback
+
+snap_*
+
+       A directory per each snapshot
+
+
+Entries under /sys/bus/rbd/devices/<dev-id>/snap_<snap-name>
+-------------------------------------------------------------
+
+id
+
+       The rados internal snapshot id assigned for this snapshot
+
+size
+
+       The size of the image when this snapshot was taken.
+
+
index 1d775390e8562dae8e4eb53d1db9959edff4b943..41ff8ae4dee0f852380f9e4007025293501b10c0 100644 (file)
@@ -47,6 +47,20 @@ Date:                January 2007
 KernelVersion: 2.6.20
 Contact:       "Corentin Chary" <corentincj@iksaif.net>
 Description:
-               Control the bluetooth device. 1 means on, 0 means off.
+               Control the wlan device. 1 means on, 0 means off.
                This may control the led, the device or both.
 Users:         Lapsus
+
+What:          /sys/devices/platform/asus_laptop/wimax
+Date:          October 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Control the wimax device. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/asus_laptop/wwan
+Date:          October 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Control the wwan (3G) device. 1 means on, 0 means off.
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
new file mode 100644 (file)
index 0000000..e4b5fef
--- /dev/null
@@ -0,0 +1,10 @@
+What:          /sys/devices/platform/eeepc-wmi/cpufv
+Date:          Oct 2010
+KernelVersion: 2.6.37
+Contact:       "Corentin Chary" <corentincj@iksaif.net>
+Description:
+               Change CPU clock configuration (write-only).
+               There are three available clock configuration:
+                   * 0 -> Super Performance Mode
+                   * 1 -> High Performance Mode
+                   * 2 -> Power Saving Mode
index d858d92cf6d9528a6122a1404589ec884c40ca9a..4a38f604fa661fe3b2383746b67f59bc45ed619c 100644 (file)
       </sect2>
     </sect1>
   </chapter>
-  <chapter id="clk">
-    <title>Clock Framework Extensions</title>
-!Iinclude/linux/sh_clk.h
-  </chapter>
   <chapter id="mach">
     <title>Machine Specific Interfaces</title>
     <sect1 id="dreamcast">
index 4d4ce0e61e424708a94db666e0496d7c0f3fc253..b4665b9c40b0ec46253b9ae6cf9bb1bbd06ec563 100644 (file)
@@ -16,7 +16,7 @@
        </orgname>
 
        <address>
-          <email>hjk@linutronix.de</email>
+          <email>hjk@hansjkoch.de</email>
        </address>
     </affiliation>
 </author>
@@ -114,7 +114,7 @@ GPL version 2.
 
 <para>If you know of any translations for this document, or you are
 interested in translating it, please email me
-<email>hjk@linutronix.de</email>.
+<email>hjk@hansjkoch.de</email>.
 </para>
 </sect1>
 
@@ -171,7 +171,7 @@ interested in translating it, please email me
 <title>Feedback</title>
        <para>Find something wrong with this document? (Or perhaps something
        right?) I would love to hear from you. Please email me at
-       <email>hjk@linutronix.de</email>.</para>
+       <email>hjk@hansjkoch.de</email>.</para>
 </sect1>
 </chapter>
 
index 97726eba6102ca31410028391d8f637b3d7a01c5..911a4518634048d9098a02865d328c18824c8248 100644 (file)
@@ -154,7 +154,7 @@ The stages that a patch goes through are, generally:
    inclusion, it should be accepted by a relevant subsystem maintainer -
    though this acceptance is not a guarantee that the patch will make it
    all the way to the mainline.  The patch will show up in the maintainer's
-   subsystem tree and into the staging trees (described below).  When the
+   subsystem tree and into the -next trees (described below).  When the
    process works, this step leads to more extensive review of the patch and
    the discovery of any problems resulting from the integration of this
    patch with work being done by others.
@@ -236,7 +236,7 @@ finding the right maintainer.  Sending patches directly to Linus is not
 normally the right way to go.
 
 
-2.4: STAGING TREES
+2.4: NEXT TREES
 
 The chain of subsystem trees guides the flow of patches into the kernel,
 but it also raises an interesting question: what if somebody wants to look
@@ -250,7 +250,7 @@ changes land in the mainline kernel.  One could pull changes from all of
 the interesting subsystem trees, but that would be a big and error-prone
 job.
 
-The answer comes in the form of staging trees, where subsystem trees are
+The answer comes in the form of -next trees, where subsystem trees are
 collected for testing and review.  The older of these trees, maintained by
 Andrew Morton, is called "-mm" (for memory management, which is how it got
 started).  The -mm tree integrates patches from a long list of subsystem
@@ -275,7 +275,7 @@ directory at:
 Use of the MMOTM tree is likely to be a frustrating experience, though;
 there is a definite chance that it will not even compile.
 
-The other staging tree, started more recently, is linux-next, maintained by
+The other -next tree, started more recently, is linux-next, maintained by
 Stephen Rothwell.  The linux-next tree is, by design, a snapshot of what
 the mainline is expected to look like after the next merge window closes.
 Linux-next trees are announced on the linux-kernel and linux-next mailing
@@ -303,12 +303,25 @@ volatility of linux-next tends to make it a difficult development target.
 See http://lwn.net/Articles/289013/ for more information on this topic, and
 stay tuned; much is still in flux where linux-next is involved.
 
-Besides the mmotm and linux-next trees, the kernel source tree now contains
-the drivers/staging/ directory and many sub-directories for drivers or
-filesystems that are on their way to being added to the kernel tree
-proper, but they remain in drivers/staging/ while they still need more
-work.
-
+2.4.1: STAGING TREES
+
+The kernel source tree now contains the drivers/staging/ directory, where
+many sub-directories for drivers or filesystems that are on their way to
+being added to the kernel tree live.  They remain in drivers/staging while
+they still need more work; once complete, they can be moved into the
+kernel proper.  This is a way to keep track of drivers that aren't
+up to Linux kernel coding or quality standards, but people may want to use
+them and track development.
+
+Greg Kroah-Hartman currently (as of 2.6.36) maintains the staging tree.
+Drivers that still need work are sent to him, with each driver having
+its own subdirectory in drivers/staging/.  Along with the driver source
+files, a TODO file should be present in the directory as well.  The TODO
+file lists the pending work that the driver needs for acceptance into
+the kernel proper, as well as a list of people that should be Cc'd for any
+patches to the driver.  Staging drivers that don't currently build should
+have their config entries depend upon CONFIG_BROKEN.  Once they can
+be successfully built without outside patches, CONFIG_BROKEN can be removed.
 
 2.5: TOOLS
 
diff --git a/Documentation/driver-model/interface.txt b/Documentation/driver-model/interface.txt
deleted file mode 100644 (file)
index c66912b..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-
-Device Interfaces
-
-Introduction
-~~~~~~~~~~~~
-
-Device interfaces are the logical interfaces of device classes that correlate
-directly to userspace interfaces, like device nodes. 
-   
-Each device class may have multiple interfaces through which you can 
-access the same device. An input device may support the mouse interface, 
-the 'evdev' interface, and the touchscreen interface. A SCSI disk would 
-support the disk interface, the SCSI generic interface, and possibly a raw 
-device interface. 
-
-Device interfaces are registered with the class they belong to. As devices
-are added to the class, they are added to each interface registered with
-the class. The interface is responsible for determining whether the device
-supports the interface or not. 
-
-
-Programming Interface
-~~~~~~~~~~~~~~~~~~~~~
-
-struct device_interface {
-       char                    * name;
-       rwlock_t                lock;
-       u32                     devnum;
-       struct device_class     * devclass;
-
-       struct list_head        node;
-       struct driver_dir_entry dir;
-
-       int (*add_device)(struct device *);
-       int (*add_device)(struct intf_data *);
-};
-
-int interface_register(struct device_interface *);
-void interface_unregister(struct device_interface *);
-
-
-An interface must specify the device class it belongs to. It is added
-to that class's list of interfaces on registration.
-
-
-Interfaces can be added to a device class at any time. Whenever it is
-added, each device in the class is passed to the interface's
-add_device callback. When an interface is removed, each device is
-removed from the interface.
-
-
-Devices
-~~~~~~~
-Once a device is added to a device class, it is added to each
-interface that is registered with the device class. The class
-is expected to place a class-specific data structure in 
-struct device::class_data. The interface can use that (along with
-other fields of struct device) to determine whether or not the driver
-and/or device support that particular interface.
-
-
-Data
-~~~~
-
-struct intf_data {
-       struct list_head        node;
-       struct device_interface * intf;
-       struct device           * dev;
-       u32                     intf_num;
-};
-
-int interface_add_data(struct interface_data *);
-
-The interface is responsible for allocating and initializing a struct 
-intf_data and calling interface_add_data() to add it to the device's list
-of interfaces it belongs to. This list will be iterated over when the device
-is removed from the class (instead of all possible interfaces for a class).
-This structure should probably be embedded in whatever per-device data 
-structure the interface is allocating anyway.
-   
-Devices are enumerated within the interface. This happens in interface_add_data()
-and the enumerated value is stored in the struct intf_data for that device. 
-
-sysfs
-~~~~~
-Each interface is given a directory in the directory of the device
-class it belongs to:
-
-Interfaces get a directory in the class's directory as well:
-
-   class/
-   `-- input
-       |-- devices
-       |-- drivers
-       |-- mouse
-       `-- evdev
-
-When a device is added to the interface, a symlink is created that points 
-to the device's directory in the physical hierarchy:
-
-   class/
-   `-- input
-       |-- devices
-       |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-       |-- drivers
-       |   `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/
-       |-- mouse
-       |   `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-       `-- evdev
-           `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/
-
-
-Future Plans
-~~~~~~~~~~~~
-A device interface is correlated directly with a userspace interface
-for a device, specifically a device node. For instance, a SCSI disk
-exposes at least two interfaces to userspace: the standard SCSI disk
-interface and the SCSI generic interface. It might also export a raw
-device interface. 
-
-Many interfaces have a major number associated with them and each
-device gets a minor number. Or, multiple interfaces might share one
-major number, and each will receive a range of minor numbers (like in
-the case of input devices).
-
-These major and minor numbers could be stored in the interface
-structure. Major and minor allocations could happen when the interface
-is registered with the class, or via a helper function. 
-
index 0b875e8da96965316d0bca49185d5a28b6d25649..9ee774de57cda04609dbf41b105c01069f0b2bcf 100644 (file)
@@ -196,7 +196,7 @@ csrow3.
 The representation of the above is reflected in the directory tree
 in EDAC's sysfs interface. Starting in directory
 /sys/devices/system/edac/mc each memory controller will be represented
-by its own 'mcX' directory, where 'X" is the index of the MC.
+by its own 'mcX' directory, where 'X' is the index of the MC.
 
 
        ..../edac/mc/
@@ -207,7 +207,7 @@ by its own 'mcX' directory, where 'X" is the index of the MC.
                   ....
 
 Under each 'mcX' directory each 'csrowX' is again represented by a
-'csrowX', where 'X" is the csrow index:
+'csrowX', where 'X' is the csrow index:
 
 
        .../mc/mc0/
@@ -232,7 +232,7 @@ EDAC control and attribute files.
 
 
 In 'mcX' directories are EDAC control and attribute files for
-this 'X" instance of the memory controllers:
+this 'X' instance of the memory controllers:
 
 
 Counter reset control file:
@@ -343,7 +343,7 @@ Sdram memory scrubbing rate:
 'csrowX' DIRECTORIES
 
 In the 'csrowX' directories are EDAC control and attribute files for
-this 'X" instance of csrow:
+this 'X' instance of csrow:
 
 
 Total Uncorrectable Errors count attribute file:
index a618fd99c9f0164298cd343ce404d04f3d38cd40..30a70542e8235d5939056e311dd933597ef49e2a 100644 (file)
@@ -4,33 +4,41 @@ please mail me.
                                    Geert Uytterhoeven <geert@linux-m68k.org>
 
 00-INDEX
-       - this file
+       - this file.
 arkfb.txt
        - info on the fbdev driver for ARK Logic chips.
 aty128fb.txt
        - info on the ATI Rage128 frame buffer driver.
 cirrusfb.txt
        - info on the driver for Cirrus Logic chipsets.
+cmap_xfbdev.txt
+       - an introduction to fbdev's cmap structures.
 deferred_io.txt
        - an introduction to deferred IO.
+efifb.txt
+       - info on the EFI platform driver for Intel based Apple computers.
+ep93xx-fb.txt
+       - info on the driver for EP93xx LCD controller.
 fbcon.txt
        - intro to and usage guide for the framebuffer console (fbcon).
 framebuffer.txt
        - introduction to frame buffer devices.
-imacfb.txt
-       - info on the generic EFI platform driver for Intel based Macs.
+gxfb.txt
+       - info on the framebuffer driver for AMD Geode GX2 based processors.
 intel810.txt
        - documentation for the Intel 810/815 framebuffer driver.
 intelfb.txt
        - docs for Intel 830M/845G/852GM/855GM/865G/915G/945G fb driver.
 internals.txt
        - quick overview of frame buffer device internals.
+lxfb.txt
+       - info on the framebuffer driver for AMD Geode LX based processors.
 matroxfb.txt
        - info on the Matrox framebuffer driver for Alpha, Intel and PPC.
+metronomefb.txt
+       - info on the driver for the Metronome display controller.
 modedb.txt
        - info on the video mode database.
-matroxfb.txt
-       - info on the Matrox frame buffer driver.
 pvr2fb.txt
        - info on the PowerVR 2 frame buffer driver.
 pxafb.txt
@@ -39,13 +47,23 @@ s3fb.txt
        - info on the fbdev driver for S3 Trio/Virge chips.
 sa1100fb.txt
        - information about the driver for the SA-1100 LCD controller.
+sh7760fb.txt
+       - info on the SH7760/SH7763 integrated LCDC Framebuffer driver.
 sisfb.txt
        - info on the framebuffer device driver for various SiS chips.
 sstfb.txt
        - info on the frame buffer driver for 3dfx' Voodoo Graphics boards.
 tgafb.txt
-       - info on the TGA (DECChip 21030) frame buffer driver
+       - info on the TGA (DECChip 21030) frame buffer driver.
+tridentfb.txt
+       info on the framebuffer driver for some Trident chip based cards.
+uvesafb.txt
+       - info on the userspace VESA (VBE2+ compliant) frame buffer device.
 vesafb.txt
-       - info on the VESA frame buffer device
+       - info on the VESA frame buffer device.
+viafb.modes
+       - list of modes for VIA Integration Graphic Chip.
+viafb.txt
+       - info on the VIA Integration Graphic Chip console framebuffer driver.
 vt8623fb.txt
        - info on the fb driver for the graphics core in VIA VT8623 chipsets.
index d428cc9f07f399141e643fc6d8df8ce88433365b..fd53869f5633f2994fe06365fe53c1754747dc6a 100644 (file)
@@ -89,7 +89,7 @@ static ssize_t childless_storeme_write(struct childless *childless,
        char *p = (char *) page;
 
        tmp = simple_strtoul(p, &p, 10);
-       if (!p || (*p && (*p != '\n')))
+       if ((*p != '\0') && (*p != '\n'))
                return -EINVAL;
 
        if (tmp > INT_MAX)
index ed7e5efc06d8fe33dc54a2122a059fdbec874092..55c28b79d8dce3afcb239f45cc1cc62c44685d3c 100644 (file)
@@ -660,11 +660,10 @@ struct address_space_operations {
   releasepage: releasepage is called on PagePrivate pages to indicate
         that the page should be freed if possible.  ->releasepage
         should remove any private data from the page and clear the
-        PagePrivate flag.  It may also remove the page from the
-        address_space.  If this fails for some reason, it may indicate
-        failure with a 0 return value.
-       This is used in two distinct though related cases.  The first
-        is when the VM finds a clean page with no active users and
+        PagePrivate flag. If releasepage() fails for some reason, it must
+       indicate failure with a 0 return value.
+       releasepage() is used in two distinct though related cases.  The
+       first is when the VM finds a clean page with no active users and
         wants to make it a free page.  If ->releasepage succeeds, the
         page will be removed from the address_space and become free.
 
index 9633da01ff46afb008566ccb53aa381606654e85..792faa3c06cf7ccda5ab081dbf568276324538e5 100644 (file)
@@ -617,6 +617,16 @@ and have the following read/write attributes:
                is configured as an output, this value may be written;
                any nonzero value is treated as high.
 
+               If the pin can be configured as interrupt-generating interrupt
+               and if it has been configured to generate interrupts (see the
+               description of "edge"), you can poll(2) on that file and
+               poll(2) will return whenever the interrupt was triggered. If
+               you use poll(2), set the events POLLPRI and POLLERR. If you
+               use select(2), set the file descriptor in exceptfds. After
+               poll(2) returns, either lseek(2) to the beginning of the sysfs
+               file and read the new value or close the file and re-open it
+               to read the value.
+
        "edge" ... reads as either "none", "rising", "falling", or
                "both". Write these strings to select the signal edge(s)
                that will make poll(2) on the "value" file return.
index ac711f357fafb0793d10c3cb31d2cd882647f767..7a10616d0b441c473e82d8c2c31489d7dd5e80c2 100644 (file)
@@ -11,7 +11,7 @@ Authors:
        Mark M. Hoffman <mhoffman@lightlink.com>
        Ported to 2.6 by Eric J. Bowersox <ericb@aspsys.com>
        Adapted to 2.6.20 by Carsten Emde <ce@osadl.org>
-       Modified for mainline integration by Hans J. Koch <hjk@linutronix.de>
+       Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de>
 
 Module Parameters
 -----------------
index 8be7beb9e3e81122d015a3eab8f634d22562bd91..c565650fcfc6f6949c8a24ae1bd2002ae9da86fa 100644 (file)
@@ -8,7 +8,7 @@ Supported chips:
     Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
 
 Authors:
-    Hans J. Koch <hjk@linutronix.de>
+    Hans J. Koch <hjk@hansjkoch.de>
     John Morris <john.morris@spirentcom.com>
     Claus Gindhart <claus.gindhart@kontron.com>
 
index 92e83e53148fe8b1d4848af9a8fd7442cc5624ba..cdd2a6e8a3b79ae9fabc67230a27a21927642c9b 100644 (file)
@@ -2385,6 +2385,11 @@ and is between 256 and 4096 characters. It is defined in the file
                        improve throughput, but will also increase the
                        amount of memory reserved for use by the client.
 
+       swapaccount[=0|1]
+                       [KNL] Enable accounting of swap in memory resource
+                       controller if no parameter or 1 is given or disable
+                       it if 0 is given (See Documentation/cgroups/memory.txt)
+
        swiotlb=        [IA-64] Number of I/O TLB slabs
 
        switches=       [HW,M68k]
index fe95105992c57f1c81248dd8d3c1c38c3272e0f9..3c5e465296e146b3089adfcec06f6c96c9805ddb 100644 (file)
@@ -144,6 +144,7 @@ tcp_adv_win_scale - INTEGER
        Count buffering overhead as bytes/2^tcp_adv_win_scale
        (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
        if it is <= 0.
+       Possible values are [-31, 31], inclusive.
        Default: 2
 
 tcp_allowed_congestion_control - STRING
index 44d87ad3cea9fd345a774e196578a0cc8bf4d779..cd445582d1f80a91abb619230d7b0a9dcb84e6e3 100644 (file)
@@ -37,6 +37,9 @@ Typical usage of the OPP library is as follows:
 SoC framework  -> modifies on required cases certain OPPs      -> OPP layer
                -> queries to search/retrieve information       ->
 
+Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
+to make the OPP layer available.
+
 OPP layer expects each domain to be represented by a unique device pointer. SoC
 framework registers a set of initial OPPs per device with the OPP layer. This
 list is expected to be an optimally small number typically around 5 per device.
diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt
deleted file mode 100644 (file)
index 114b595..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-Clock framework on SuperH architecture
-
-The framework on SH extends existing API by the function clk_set_rate_ex,
-which prototype is as follows:
-
-    clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id)
-
-The algo_id parameter is used to specify algorithm used to recalculate clocks,
-adjanced to clock, specified as first argument. It is assumed that algo_id==0
-means no changes to adjanced clock
-
-Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method,
-if it is present in ops structure. The method should set the clock rate and adjust
-all needed clocks according to the passed algo_id.
-Exact values for algo_id are machine-dependent. For the sh7722, the following
-values are defined:
-
-       NO_CHANGE       = 0,
-       IUS_N1_N1,      /* I:U = N:1, U:Sh = N:1 */
-       IUS_322,        /* I:U:Sh = 3:2:2        */
-       IUS_522,        /* I:U:Sh = 5:2:2        */
-       IUS_N11,        /* I:U:Sh = N:1:1        */
-       SB_N1,          /* Sh:B = N:1            */
-       SB3_N1,         /* Sh:B3 = N:1           */
-       SB3_32,         /* Sh:B3 = 3:2           */
-       SB3_43,         /* Sh:B3 = 4:3           */
-       SB3_54,         /* Sh:B3 = 5:4           */
-       BP_N1,          /* B:P   = N:1           */
-       IP_N1           /* I:P   = N:1           */
-
-Each of these constants means relation between clocks that can be set via the FRQCR
-register
index 8e6548dbd5db50c4e80f24fd9ae4bdd4597bd6c3..1a1c27b9c557b2e07af18cb9b8c4e97c53c95c86 100644 (file)
@@ -1359,7 +1359,7 @@ F:        include/net/bluetooth/
 
 BONDING DRIVER
 M:     Jay Vosburgh <fubar@us.ibm.com>
-L:     bonding-devel@lists.sourceforge.net
+L:     netdev@vger.kernel.org
 W:     http://sourceforge.net/projects/bonding/
 S:     Supported
 F:     drivers/net/bonding/
@@ -1829,6 +1829,13 @@ W:       http://www.chelsio.com
 S:     Supported
 F:     drivers/net/cxgb4vf/
 
+STMMAC ETHERNET DRIVER
+M:     Giuseppe Cavallaro <peppe.cavallaro@st.com>
+L:     netdev@vger.kernel.org
+W:     http://www.stlinux.com
+S:     Supported
+F:     drivers/net/stmmac/
+
 CYBERPRO FB DRIVER
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2008,6 +2015,7 @@ F:        drivers/hwmon/dme1737.c
 DOCBOOK FOR DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 S:     Maintained
+F:     scripts/kernel-doc
 
 DOCKING STATION DRIVER
 M:     Shaohua Li <shaohua.li@intel.com>
@@ -2018,6 +2026,7 @@ F:        drivers/acpi/dock.c
 DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 L:     linux-doc@vger.kernel.org
+T:     quilt oss.oracle.com/~rdunlap/kernel-doc-patches/current/
 S:     Maintained
 F:     Documentation/
 
@@ -2051,7 +2060,7 @@ F:        Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
 M:     Greg Kroah-Hartman <gregkh@suse.de>
-T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
 S:     Supported
 F:     Documentation/kobject.txt
 F:     drivers/base/
@@ -2071,7 +2080,7 @@ F:        include/drm/
 
 INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:     Chris Wilson <chris@chris-wilson.co.uk>
-L:     intel-gfx@lists.freedesktop.org
+L:     intel-gfx@lists.freedesktop.org (subscribers-only)
 L:     dri-devel@lists.freedesktop.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel.git
 S:     Supported
@@ -2435,10 +2444,12 @@ F:      drivers/net/wan/sdla.c
 FRAMEBUFFER LAYER
 L:     linux-fbdev@vger.kernel.org
 W:     http://linux-fbdev.sourceforge.net/
+Q:     http://patchwork.kernel.org/project/linux-fbdev/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git
 S:     Orphan
 F:     Documentation/fb/
-F:     drivers/video/fb*
+F:     drivers/video/
+F:     include/video/
 F:     include/linux/fb.h
 
 FREESCALE DMA DRIVER
@@ -4053,9 +4064,8 @@ F:        drivers/scsi/NCR_D700.*
 
 NETEFFECT IWARP RNIC DRIVER (IW_NES)
 M:     Faisal Latif <faisal.latif@intel.com>
-M:     Chien Tung <chien.tin.tung@intel.com>
 L:     linux-rdma@vger.kernel.org
-W:     http://www.neteffect.com
+W:     http://www.intel.com/Products/Server/Adapters/Server-Cluster/Server-Cluster-overview.htm
 S:     Supported
 F:     drivers/infiniband/hw/nes/
 
@@ -5828,6 +5838,8 @@ M:        Chris Metcalf <cmetcalf@tilera.com>
 W:     http://www.tilera.com/scm/
 S:     Supported
 F:     arch/tile/
+F:     drivers/char/hvc_tile.c
+F:     drivers/net/tile/
 
 TLAN NETWORK DRIVER
 M:     Samuel Chessman <chessman@tux.org>
index ab5359db3d177b2e4a83823baa15da908e5b395b..3d94974542eac52bec7078dc9f9a70bcb46596d5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 37
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc5
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index db524e75c4a21e4f45bc4b72e459adcdaf1dda4b..f1d9297b105084be1f3718213fd592e0dd0d1747 100644 (file)
@@ -9,7 +9,7 @@ config ARM
        select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
        select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
        select HAVE_ARCH_KGDB
-       select HAVE_KPROBES if (!XIP_KERNEL)
+       select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL)
        select HAVE_KRETPROBES if (HAVE_KPROBES)
        select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
        select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
index 4a590f4113e2af044ea1764aeb0681ad7f50a74c..4d26f2c52a7553c1f0c6f387c2e7f5ad9a25328c 100644 (file)
@@ -70,12 +70,7 @@ else
 $(obj)/uImage: LOADADDR=$(ZRELADDR)
 endif
 
-ifeq ($(CONFIG_THUMB2_KERNEL),y)
-# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
-$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
-else
 $(obj)/uImage: STARTADDR=$(LOADADDR)
-endif
 
 $(obj)/uImage: $(obj)/zImage FORCE
        $(call if_changed,uimage)
index 8b0de41c3dcbbe646877a9f31635bb5e48b8b4bd..78b508075161fd4967bdbb3821eab162aa9dd5bc 100644 (file)
@@ -73,6 +73,8 @@ move:         ldmia   r4!, {r7 - r10}         @ move 32-bytes at a time
 
                .size   _start, . - _start
 
+               .align
+
                .type   data,#object
 data:          .word   initrd_start            @ source initrd address
                .word   initrd_phys             @ destination initrd address
index 6825c34646d4e02f24b0eefe7ab4e012bca05208..7193884ed8b06c4452b6fe57f3c38821013d0af0 100644 (file)
@@ -125,9 +125,13 @@ wait:              mrc     p14, 0, pc, c0, c1, 0
  * sort out different calling conventions
  */
                .align
+               .arm                            @ Always enter in ARM state
 start:
                .type   start,#function
-               .rept   8
+ THUMB(                adr     r12, BSYM(1f)   )
+ THUMB(                bx      r12             )
+ THUMB(                .rept   6               )
+ ARM(          .rept   8               )
                mov     r0, r0
                .endr
 
@@ -135,6 +139,7 @@ start:
                .word   0x016f2818              @ Magic numbers to help the loader
                .word   start                   @ absolute load/run zImage address
                .word   _edata                  @ zImage end address
+ THUMB(                .thumb                  )
 1:             mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer
 
@@ -174,7 +179,8 @@ not_angel:
                ldr     sp, [r0, #28]
 #ifdef CONFIG_AUTO_ZRELADDR
                @ determine final kernel image address
-               and     r4, pc, #0xf8000000
+               mov     r4, pc
+               and     r4, r4, #0xf8000000
                add     r4, r4, #TEXT_OFFSET
 #else
                ldr     r4, =zreladdr
@@ -445,7 +451,8 @@ __setup_mmu:        sub     r3, r4, #16384          @ Page directory size
  */
                mov     r1, #0x1e
                orr     r1, r1, #3 << 10
-               mov     r2, pc, lsr #20
+               mov     r2, pc
+               mov     r2, r2, lsr #20
                orr     r1, r1, r2, lsl #20
                add     r0, r3, r2, lsl #2
                str     r1, [r0], #4
@@ -1084,6 +1091,6 @@ memdump:  mov     r12, r0
 reloc_end:
 
                .align
-               .section ".stack", "w"
+               .section ".stack", "aw", %nobits
 user_stack:    .space  4096
 user_stack_end:
index d08168941bd686b6f7a112f0668e96503c2ba667..366a924019ac6dcf1ccaad07b605f6c6ec1b74c6 100644 (file)
@@ -57,7 +57,7 @@ SECTIONS
   .bss                 : { *(.bss) }
   _end = .;
 
-  .stack (NOLOAD)      : { *(.stack) }
+  .stack               : { *(.stack) }
 
   .stab 0              : { *(.stab) }
   .stabstr 0           : { *(.stabstr) }
index 772f95f1aecddf49ada9ceea0caa5295d22c9613..e6388dcd8cfa2cf5f7a31ee59a6728bda377f89c 100644 (file)
@@ -146,9 +146,15 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
        unsigned int shift = (irq % 4) * 8;
        unsigned int cpu = cpumask_first(mask_val);
        u32 val;
+       struct irq_desc *desc;
 
        spin_lock(&irq_controller_lock);
-       irq_desc[irq].node = cpu;
+       desc = irq_to_desc(irq);
+       if (desc == NULL) {
+               spin_unlock(&irq_controller_lock);
+               return -EINVAL;
+       }
+       desc->node = cpu;
        val = readl(reg) & ~(0xff << shift);
        val |= 1 << (cpu + shift);
        writel(val, reg);
@@ -210,7 +216,7 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
                          unsigned int irq_start)
 {
-       unsigned int max_irq, i;
+       unsigned int gic_irqs, irq_limit, i;
        u32 cpumask = 1 << smp_processor_id();
 
        if (gic_nr >= MAX_GIC_NR)
@@ -226,47 +232,49 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
 
        /*
         * Find out how many interrupts are supported.
-        */
-       max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
-       max_irq = (max_irq + 1) * 32;
-
-       /*
         * The GIC only supports up to 1020 interrupt sources.
-        * Limit this to either the architected maximum, or the
-        * platform maximum.
         */
-       if (max_irq > max(1020, NR_IRQS))
-               max_irq = max(1020, NR_IRQS);
+       gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
+       gic_irqs = (gic_irqs + 1) * 32;
+       if (gic_irqs > 1020)
+               gic_irqs = 1020;
 
        /*
         * Set all global interrupts to be level triggered, active low.
         */
-       for (i = 32; i < max_irq; i += 16)
+       for (i = 32; i < gic_irqs; i += 16)
                writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
 
        /*
         * Set all global interrupts to this CPU only.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
        /*
         * Set priority on all global interrupts.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
 
        /*
         * Disable all interrupts.  Leave the PPI and SGIs alone
         * as these enables are banked registers.
         */
-       for (i = 32; i < max_irq; i += 32)
+       for (i = 32; i < gic_irqs; i += 32)
                writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
+       /*
+        * Limit number of interrupts registered to the platform maximum
+        */
+       irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
+       if (WARN_ON(irq_limit > NR_IRQS))
+               irq_limit = NR_IRQS;
+
        /*
         * Setup the Linux IRQ subsystem.
         */
-       for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
+       for (i = irq_start; i < irq_limit; i++) {
                set_irq_chip(i, &gic_chip);
                set_irq_chip_data(i, &gic_data[gic_nr]);
                set_irq_handler(i, handle_level_irq);
diff --git a/arch/arm/configs/at91rm9200_defconfig b/arch/arm/configs/at91rm9200_defconfig
new file mode 100644 (file)
index 0000000..38cb7c9
--- /dev/null
@@ -0,0 +1,341 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_MACH_ONEARM=y
+CONFIG_ARCH_AT91RM9200DK=y
+CONFIG_MACH_AT91RM9200EK=y
+CONFIG_MACH_CSB337=y
+CONFIG_MACH_CSB637=y
+CONFIG_MACH_CARMEVA=y
+CONFIG_MACH_ATEB9200=y
+CONFIG_MACH_KB9200=y
+CONFIG_MACH_PICOTUX2XX=y
+CONFIG_MACH_KAFA=y
+CONFIG_MACH_ECBAT91=y
+CONFIG_MACH_YL9200=y
+CONFIG_MACH_CPUAT91=y
+CONFIG_MACH_ECO920=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_AT91_CF=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_EEPROM_LEGACY=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_PHYLIB=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91RM9200_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_MCT_U232=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_REISERFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
deleted file mode 100644 (file)
index 4438e64..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_ECO920=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
deleted file mode 100644 (file)
index ccd517c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_AT91RM9200EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_S1D13XXX=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
deleted file mode 100644 (file)
index 1b0e9a1..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ATEB9200=y
-CONFIG_PCCARD=m
-CONFIG_AT91_CF=m
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-# CONFIG_IPV6 is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_GL620A=y
-CONFIG_USB_NET_PLUSB=y
-CONFIG_USB_NET_RNDIS_HOST=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_USB_HID=m
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_GADGET=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-CONFIG_REISERFS_FS=m
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRC16=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig
deleted file mode 100644 (file)
index ac64dbd..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_HOTPLUG is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CARMEVA=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIO=m
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_DNOTIFY is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig
deleted file mode 100644 (file)
index 022aeb5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CPUAT91=y
-CONFIG_AT91_TIMER_HZ=100
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=y
-CONFIG_MINIX_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
deleted file mode 100644 (file)
index a24c448..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB337=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc1"
-# CONFIG_RTC_INTF_SYSFS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
deleted file mode 100644 (file)
index 98552ad..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_CSB637=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig
deleted file mode 100644 (file)
index 6bb6abd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ECBAT91=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="rootfstype=reiserfs root=/dev/mmcblk0p1 console=ttyS0,115200n8 rootdelay=1"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IPV6 is not set
-CONFIG_CFG80211=y
-CONFIG_MAC80211=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
deleted file mode 100644 (file)
index 896dbe0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KAFA=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20800000,10M root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
deleted file mode 100644 (file)
index 9f906a8..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_AUDIT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_KB9200=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x10000000
-CONFIG_ZBOOT_ROM_BSS=0x20040000
-CONFIG_CMDLINE="noinitrd root=/dev/mtdblock0 rootfstype=jffs2 mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_ATMEL_TCLIB=y
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_AT91RM9200_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_GENERIC is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
deleted file mode 100644 (file)
index 1579857..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_ONEARM=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_AT91_CF=y
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=y
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_GADGET=y
-CONFIG_MMC=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig
deleted file mode 100644 (file)
index 4c9afa4..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=m
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_MACH_PICOTUX2XX=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
-CONFIG_FW_LOADER=m
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_EEPROM_LEGACY=m
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_NETDEVICES=y
-CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_GPIO=m
-CONFIG_HWMON=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91RM9200_WATCHDOG=m
-CONFIG_HID=m
-CONFIG_USB=m
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_MMC=m
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=m
-CONFIG_RTC_DRV_AT91RM9200=m
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=m
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_NFS_FS=m
-CONFIG_SMB_FS=m
-CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_AMIGA_PARTITION=y
-CONFIG_NLS_DEFAULT="utf-8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_LL=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/yl9200_defconfig b/arch/arm/configs/yl9200_defconfig
deleted file mode 100644 (file)
index 30c537f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200DK=y
-CONFIG_MACH_YL9200=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=3
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_SPI=y
-CONFIG_SPI_DEBUG=y
-CONFIG_SPI_ATMEL=y
-CONFIG_FB=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_DISPLAY_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_M66592=y
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=y
-CONFIG_INOTIFY=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=1
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_DEBUG_KOBJECT=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
index 062b58c029ab92ceb23cf0616568a76d3ec3a6b1..749bb6622404b3aed8e9234d2c8ff67e13a731b1 100644 (file)
        @ Slightly optimised to avoid incrementing the pointer twice
        usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
        .if     \rept == 2
-       usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
+       usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
        .endif
 
        add\cond \ptr, #\rept * \inc
index 68870c7766712a4778b32278e64f82484d12f5e5..b4ffe9d5b5262bbdf01f82218144d74d0823005c 100644 (file)
@@ -13,6 +13,10 @@ typedef struct {
 
 #ifdef CONFIG_CPU_HAS_ASID
 #define ASID(mm)       ((mm)->context.id & 255)
+
+/* init_mm.context.id_lock should be initialized. */
+#define INIT_MM_CONTEXT(name)                                                 \
+       .context.id_lock    = __SPIN_LOCK_UNLOCKED(name.context.id_lock),
 #else
 #define ASID(mm)       (0)
 #endif
index b155414192daea110acf0f890a6f3d139ceef182..53d1d5deb1115b1fe11a52846e62679573534d24 100644 (file)
@@ -374,6 +374,9 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 #define pmd_page(pmd)          pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
 
+/* we don't need complex calculations here as the pmd is folded into the pgd */
+#define pmd_addr_end(addr,end) (end)
+
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
index c09e3573c5deb5795042eb1073f210472b0eadbc..bb96a7d4bbf55464a4069830657334e23fa72449 100644 (file)
@@ -911,7 +911,7 @@ __kuser_cmpxchg:                            @ 0xffff0fc0
         * A special ghost syscall is used for that (see traps.c).
         */
        stmfd   sp!, {r7, lr}
-       ldr     r7, =1f                 @ it's 20 bits
+       ldr     r7, 1f                  @ it's 20 bits
        swi     __ARM_NR_cmpxchg
        ldmfd   sp!, {r7, pc}
 1:     .word   __ARM_NR_cmpxchg
index dd6b369ac69cae5c86dca1e30edd4574b80a2052..6bd82d25683c3a81946d072825cef42f25628643 100644 (file)
@@ -85,9 +85,11 @@ ENTRY(stext)
        mrc     p15, 0, r9, c0, c0              @ get processor id
        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
        movs    r10, r5                         @ invalid processor (r5=0)?
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_p                       @ yes, error 'p'
        bl      __lookup_machine_type           @ r5=machinfo
        movs    r8, r5                          @ invalid machine (r5=0)?
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_a                       @ yes, error 'a'
        bl      __vet_atags
 #ifdef CONFIG_SMP_ON_UP
@@ -262,6 +264,7 @@ __create_page_tables:
        mov     pc, lr
 ENDPROC(__create_page_tables)
        .ltorg
+       .align
 __enable_mmu_loc:
        .long   .
        .long   __enable_mmu
@@ -282,6 +285,7 @@ ENTRY(secondary_startup)
        bl      __lookup_processor_type
        movs    r10, r5                         @ invalid processor?
        moveq   r0, #'p'                        @ yes, error 'p'
+ THUMB( it     eq )            @ force fixup-able long branch encoding
        beq     __error_p
 
        /*
@@ -308,6 +312,8 @@ ENTRY(__secondary_switched)
        b       secondary_start_kernel
 ENDPROC(__secondary_switched)
 
+       .align
+
        .type   __secondary_data, %object
 __secondary_data:
        .long   .
@@ -413,6 +419,7 @@ __fixup_smp_on_up:
        mov     pc, lr
 ENDPROC(__fixup_smp)
 
+       .align
 1:     .word   .
        .word   __smpalt_begin
        .word   __smpalt_end
index fd26f8d65151a949e6ecff394f0146258882b9d6..9cf4cbf8f95b8ca9eef1baf1d8f49054999304f8 100644 (file)
@@ -59,6 +59,8 @@ relocate_new_kernel:
        ldr r2,kexec_boot_atags
        mov pc,lr
 
+       .align
+
        .globl kexec_start_address
 kexec_start_address:
        .long   0x0
index 1e4cbd4e7be930f2515bece2a19c23f2f2a07845..64f6bc1a91326c79800bbb9205645a7d0e7e5e0c 100644 (file)
@@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be)
  */
 .L_found:
 #if __LINUX_ARM_ARCH__ >= 5
-               rsb     r1, r3, #0
-               and     r3, r3, r1
+               rsb     r0, r3, #0
+               and     r3, r3, r0
                clz     r3, r3
                rsb     r3, r3, #31
                add     r0, r2, r3
@@ -190,5 +190,7 @@ ENDPROC(_find_next_bit_be)
                addeq   r2, r2, #1
                mov     r0, r2
 #endif
+               cmp     r1, r0                  @ Clamp to maxbit
+               movlo   r0, r1
                mov     pc, lr
 
index cff4e0a996ce992953780bc1af4f11d72aff34f3..a6299e8321bd9258772cb96c80b4fddb170fa047 100644 (file)
@@ -11,6 +11,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END            0xd0000000
+#define VMALLOC_END            0xd0000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 821eb842795f137d94a2904ffe5d1db827dca4bf..62d686f0b42602e6b1f7beb096524944452b3b45 100644 (file)
@@ -24,8 +24,8 @@ obj-$(CONFIG_ARCH_AT91X40)    += at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
 obj-$(CONFIG_MACH_ONEARM)      += board-1arm.o
-obj-$(CONFIG_ARCH_AT91RM9200DK)        += board-dk.o
-obj-$(CONFIG_MACH_AT91RM9200EK)        += board-ek.o
+obj-$(CONFIG_ARCH_AT91RM9200DK)        += board-rm9200dk.o
+obj-$(CONFIG_MACH_AT91RM9200EK)        += board-rm9200ek.o
 obj-$(CONFIG_MACH_CSB337)      += board-csb337.o
 obj-$(CONFIG_MACH_CSB637)      += board-csb637.o
 obj-$(CONFIG_MACH_CARMEVA)     += board-carmeva.o
index 9338825cfcd7c1613337738ca4145e884a88a7ec..7b539228e0efb324b258d8e247c1e14c060fb30a 100644 (file)
@@ -1106,51 +1106,6 @@ static inline void configure_usart3_pins(unsigned pins)
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
 struct platform_device *atmel_default_console_device;  /* the serial console device */
 
-void __init __deprecated at91_init_serial(struct at91_uart_config *config)
-{
-       int i;
-
-       /* Fill in list of supported UARTs */
-       for (i = 0; i < config->nr_tty; i++) {
-               switch (config->tty_map[i]) {
-                       case 0:
-                               configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
-                               at91_uarts[i] = &at91rm9200_uart0_device;
-                               at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
-                               break;
-                       case 1:
-                               configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
-                               at91_uarts[i] = &at91rm9200_uart1_device;
-                               at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
-                               break;
-                       case 2:
-                               configure_usart2_pins(0);
-                               at91_uarts[i] = &at91rm9200_uart2_device;
-                               at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
-                               break;
-                       case 3:
-                               configure_usart3_pins(0);
-                               at91_uarts[i] = &at91rm9200_uart3_device;
-                               at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
-                               break;
-                       case 4:
-                               configure_dbgu_pins();
-                               at91_uarts[i] = &at91rm9200_dbgu_device;
-                               at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart");
-                               break;
-                       default:
-                               continue;
-               }
-               at91_uarts[i]->id = i;          /* update ID number to mapped ID */
-       }
-
-       /* Set serial console device */
-       if (config->console_tty < ATMEL_MAX_UART)
-               atmel_default_console_device = at91_uarts[config->console_tty];
-       if (!atmel_default_console_device)
-               printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
        struct platform_device *pdev;
index 46bdc82d3fbf9985310db451bb2cf8a6eb4b81f7..8a3fc84847c120b42980298067f74d8b3abc00fc 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata onearm_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 3,
-       .tty_map        = { 4, 0, 1, -1, -1 },          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init onearm_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91rm9200_initialize(18432000, AT91RM9200_PQFP);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&onearm_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+       at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init onearm_init_irq(void)
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
deleted file mode 100644 (file)
index e14f0e1..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-dk.c
- *
- *  Copyright (C) 2005 SAN People
- *
- *  Epson S1D framebuffer glue code is:
- *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91rm9200_mc.h>
-
-#include "generic.h"
-
-
-static void __init dk_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91rm9200_initialize(18432000, AT91RM9200_BGA);
-
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
-
-       /* DBGU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-                          | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init dk_init_irq(void)
-{
-       at91rm9200_init_interrupts(NULL);
-}
-
-static struct at91_eth_data __initdata dk_eth_data = {
-       .phy_irq_pin    = AT91_PIN_PC4,
-       .is_rmii        = 1,
-};
-
-static struct at91_usbh_data __initdata dk_usbh_data = {
-       .ports          = 2,
-};
-
-static struct at91_udc_data __initdata dk_udc_data = {
-       .vbus_pin       = AT91_PIN_PD4,
-       .pullup_pin     = AT91_PIN_PD5,
-};
-
-static struct at91_cf_data __initdata dk_cf_data = {
-       .det_pin        = AT91_PIN_PB0,
-       .rst_pin        = AT91_PIN_PC5,
-       // .irq_pin     = ... not connected
-       // .vcc_pin     = ... always powered
-};
-
-static struct at91_mmc_data __initdata dk_mmc_data = {
-       .slot_b         = 0,
-       .wire4          = 1,
-};
-
-static struct spi_board_info dk_spi_devices[] = {
-       {       /* DataFlash chip */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-       {       /* UR6HCPS2-SP40 PS2-to-SPI adapter */
-               .modalias       = "ur6hcps2",
-               .chip_select    = 1,
-               .max_speed_hz   = 250 *  1000,
-       },
-       {       /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
-               .modalias       = "tlv1504",
-               .chip_select    = 2,
-               .max_speed_hz   = 20 * 1000 * 1000,
-       },
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 3,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       }
-#endif
-};
-
-static struct i2c_board_info __initdata dk_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("ics1523", 0x26),
-       },
-       {
-               I2C_BOARD_INFO("x9429", 0x28),
-       },
-       {
-               I2C_BOARD_INFO("24c1024", 0x50),
-       }
-};
-
-static struct mtd_partition __initdata dk_nand_partition[] = {
-       {
-               .name   = "NAND Partition 1",
-               .offset = 0,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(dk_nand_partition);
-       return dk_nand_partition;
-}
-
-static struct atmel_nand_data __initdata dk_nand_data = {
-       .ale            = 22,
-       .cle            = 21,
-       .det_pin        = AT91_PIN_PB1,
-       .rdy_pin        = AT91_PIN_PC2,
-       // .enable_pin  = ... not there
-       .partition_info = nand_partitions,
-};
-
-#define DK_FLASH_BASE  AT91_CHIPSELECT_0
-#define DK_FLASH_SIZE  SZ_2M
-
-static struct physmap_flash_data dk_flash_data = {
-       .width          = 2,
-};
-
-static struct resource dk_flash_resource = {
-       .start          = DK_FLASH_BASE,
-       .end            = DK_FLASH_BASE + DK_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device dk_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-                               .platform_data  = &dk_flash_data,
-                       },
-       .resource       = &dk_flash_resource,
-       .num_resources  = 1,
-};
-
-static struct gpio_led dk_leds[] = {
-       {
-               .name                   = "led0",
-               .gpio                   = AT91_PIN_PB2,
-               .active_low             = 1,
-               .default_trigger        = "heartbeat",
-       }
-};
-
-static void __init dk_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* Ethernet */
-       at91_add_device_eth(&dk_eth_data);
-       /* USB Host */
-       at91_add_device_usbh(&dk_usbh_data);
-       /* USB Device */
-       at91_add_device_udc(&dk_udc_data);
-       at91_set_multi_drive(dk_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
-       /* Compact Flash */
-       at91_add_device_cf(&dk_cf_data);
-       /* I2C */
-       at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
-       /* SPI */
-       at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB7, 0);
-#else
-       /* MMC */
-       at91_set_gpio_output(AT91_PIN_PB7, 1);  /* this MMC card slot can optionally use SPI signaling (CS3). */
-       at91_add_device_mmc(0, &dk_mmc_data);
-#endif
-       /* NAND */
-       at91_add_device_nand(&dk_nand_data);
-       /* NOR Flash */
-       platform_device_register(&dk_flash);
-       /* LEDs */
-       at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
-       /* VGA */
-//     dk_add_device_video();
-}
-
-MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
-       /* Maintainer: SAN People/Atmel */
-       .boot_params    = AT91_SDRAM_BASE + 0x100,
-       .timer          = &at91rm9200_timer,
-       .map_io         = dk_map_io,
-       .init_irq       = dk_init_irq,
-       .init_machine   = dk_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
deleted file mode 100644 (file)
index 56e92c4..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-ek.c
- *
- *  Copyright (C) 2005 SAN People
- *
- *  Epson S1D framebuffer glue code is:
- *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91rm9200_mc.h>
-
-#include "generic.h"
-
-
-static void __init ek_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91rm9200_initialize(18432000, AT91RM9200_BGA);
-
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
-
-       /* DBGU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-                          | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init ek_init_irq(void)
-{
-       at91rm9200_init_interrupts(NULL);
-}
-
-static struct at91_eth_data __initdata ek_eth_data = {
-       .phy_irq_pin    = AT91_PIN_PC4,
-       .is_rmii        = 1,
-};
-
-static struct at91_usbh_data __initdata ek_usbh_data = {
-       .ports          = 2,
-};
-
-static struct at91_udc_data __initdata ek_udc_data = {
-       .vbus_pin       = AT91_PIN_PD4,
-       .pullup_pin     = AT91_PIN_PD5,
-};
-
-static struct at91_mmc_data __initdata ek_mmc_data = {
-       .det_pin        = AT91_PIN_PB27,
-       .slot_b         = 0,
-       .wire4          = 1,
-       .wp_pin         = AT91_PIN_PA17,
-};
-
-static struct spi_board_info ek_spi_devices[] = {
-       {       /* DataFlash chip */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 3,
-               .max_speed_hz   = 15 * 1000 * 1000,
-       },
-#endif
-};
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("ics1523", 0x26),
-       },
-       {
-               I2C_BOARD_INFO("dac3550", 0x4d),
-       }
-};
-
-#define EK_FLASH_BASE  AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE  SZ_2M
-
-static struct physmap_flash_data ek_flash_data = {
-       .width          = 2,
-};
-
-static struct resource ek_flash_resource = {
-       .start          = EK_FLASH_BASE,
-       .end            = EK_FLASH_BASE + EK_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device ek_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-                               .platform_data  = &ek_flash_data,
-                       },
-       .resource       = &ek_flash_resource,
-       .num_resources  = 1,
-};
-
-static struct gpio_led ek_leds[] = {
-       {       /* "user led 1", DS2 */
-               .name                   = "green",
-               .gpio                   = AT91_PIN_PB0,
-               .active_low             = 1,
-               .default_trigger        = "mmc0",
-       },
-       {       /* "user led 2", DS4 */
-               .name                   = "yellow",
-               .gpio                   = AT91_PIN_PB1,
-               .active_low             = 1,
-               .default_trigger        = "heartbeat",
-       },
-       {       /* "user led 3", DS6 */
-               .name                   = "red",
-               .gpio                   = AT91_PIN_PB2,
-               .active_low             = 1,
-       }
-};
-
-static void __init ek_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* Ethernet */
-       at91_add_device_eth(&ek_eth_data);
-       /* USB Host */
-       at91_add_device_usbh(&ek_usbh_data);
-       /* USB Device */
-       at91_add_device_udc(&ek_udc_data);
-       at91_set_multi_drive(ek_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
-       /* I2C */
-       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
-       /* SPI */
-       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB22, 0);
-#else
-       /* MMC */
-       at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
-       at91_add_device_mmc(0, &ek_mmc_data);
-#endif
-       /* NOR Flash */
-       platform_device_register(&ek_flash);
-       /* LEDs */
-       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-       /* VGA */
-//     ek_add_device_video();
-}
-
-MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
-       /* Maintainer: SAN People/Atmel */
-       .boot_params    = AT91_SDRAM_BASE + 0x100,
-       .timer          = &at91rm9200_timer,
-       .map_io         = ek_map_io,
-       .init_irq       = ek_init_irq,
-       .init_machine   = ek_board_init,
-MACHINE_END
index c0ce79d431a0c1f3424b232e6a746b40c9f5dc5c..d2e1f4ec1fcc87dcc6aca97d6a664af6ed637d36 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata kafa_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 2,
-       .tty_map        = { 4, 0, -1, -1, -1 }          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init kafa_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
@@ -58,8 +47,14 @@ static void __init kafa_map_io(void)
        /* Set up the LEDs */
        at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&kafa_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+       at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init kafa_init_irq(void)
index 9d833bbc592dcf3c10cfd4233140dd0ec34db8ff..55dad3a46547288cba52ed6debc5d384f55bc8e1 100644 (file)
 #include "generic.h"
 
 
-/*
- * Serial port configuration.
- *    0 .. 3 = USART0 .. USART3
- *    4      = DBGU
- */
-static struct at91_uart_config __initdata picotux200_uart_config = {
-       .console_tty    = 0,                            /* ttyS0 */
-       .nr_tty         = 2,
-       .tty_map        = { 4, 1, -1, -1, -1 }          /* ttyS0, ..., ttyS4 */
-};
-
 static void __init picotux200_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91rm9200_initialize(18432000, AT91RM9200_BGA);
 
-       /* Setup the serial ports and console */
-       at91_init_serial(&picotux200_uart_config);
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                         | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                         | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
 }
 
 static void __init picotux200_init_irq(void)
@@ -77,11 +74,6 @@ static struct at91_usbh_data __initdata picotux200_usbh_data = {
        .ports          = 1,
 };
 
-// static struct at91_udc_data __initdata picotux200_udc_data = {
-//     .vbus_pin       = AT91_PIN_PD4,
-//     .pullup_pin     = AT91_PIN_PD5,
-// };
-
 static struct at91_mmc_data __initdata picotux200_mmc_data = {
        .det_pin        = AT91_PIN_PB27,
        .slot_b         = 0,
@@ -89,21 +81,6 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = {
        .wp_pin         = AT91_PIN_PA17,
 };
 
-// static struct spi_board_info picotux200_spi_devices[] = {
-//     {       /* DataFlash chip */
-//             .modalias       = "mtd_dataflash",
-//             .chip_select    = 0,
-//             .max_speed_hz   = 15 * 1000 * 1000,
-//     },
-// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-//     {       /* DataFlash card */
-//             .modalias       = "mtd_dataflash",
-//             .chip_select    = 3,
-//             .max_speed_hz   = 15 * 1000 * 1000,
-//     },
-// #endif
-// };
-
 #define PICOTUX200_FLASH_BASE  AT91_CHIPSELECT_0
 #define PICOTUX200_FLASH_SIZE  SZ_4M
 
@@ -135,21 +112,11 @@ static void __init picotux200_board_init(void)
        at91_add_device_eth(&picotux200_eth_data);
        /* USB Host */
        at91_add_device_usbh(&picotux200_usbh_data);
-       /* USB Device */
-       // at91_add_device_udc(&picotux200_udc_data);
-       // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1);     /* pullup_pin is connected to reset */
        /* I2C */
        at91_add_device_i2c(NULL, 0);
-       /* SPI */
-       // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-       /* DataFlash card */
-       at91_set_gpio_output(AT91_PIN_PB22, 0);
-#else
        /* MMC */
        at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
        at91_add_device_mmc(0, &picotux200_mmc_data);
-#endif
        /* NOR Flash */
        platform_device_register(&picotux200_flash);
 }
diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c
new file mode 100644 (file)
index 0000000..4c1047c
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200dk.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *
+ *  Epson S1D framebuffer glue code is:
+ *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init dk_map_io(void)
+{
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+       /* Setup the LEDs */
+       at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init dk_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata dk_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PC4,
+       .is_rmii        = 1,
+};
+
+static struct at91_usbh_data __initdata dk_usbh_data = {
+       .ports          = 2,
+};
+
+static struct at91_udc_data __initdata dk_udc_data = {
+       .vbus_pin       = AT91_PIN_PD4,
+       .pullup_pin     = AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata dk_cf_data = {
+       .det_pin        = AT91_PIN_PB0,
+       .rst_pin        = AT91_PIN_PC5,
+       // .irq_pin     = ... not connected
+       // .vcc_pin     = ... always powered
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata dk_mmc_data = {
+       .slot_b         = 0,
+       .wire4          = 1,
+};
+#endif
+
+static struct spi_board_info dk_spi_devices[] = {
+       {       /* DataFlash chip */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+       {       /* UR6HCPS2-SP40 PS2-to-SPI adapter */
+               .modalias       = "ur6hcps2",
+               .chip_select    = 1,
+               .max_speed_hz   = 250 *  1000,
+       },
+       {       /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
+               .modalias       = "tlv1504",
+               .chip_select    = 2,
+               .max_speed_hz   = 20 * 1000 * 1000,
+       },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       {       /* DataFlash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 3,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       }
+#endif
+};
+
+static struct i2c_board_info __initdata dk_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("ics1523", 0x26),
+       },
+       {
+               I2C_BOARD_INFO("x9429", 0x28),
+       },
+       {
+               I2C_BOARD_INFO("24c1024", 0x50),
+       }
+};
+
+static struct mtd_partition __initdata dk_nand_partition[] = {
+       {
+               .name   = "NAND Partition 1",
+               .offset = 0,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(dk_nand_partition);
+       return dk_nand_partition;
+}
+
+static struct atmel_nand_data __initdata dk_nand_data = {
+       .ale            = 22,
+       .cle            = 21,
+       .det_pin        = AT91_PIN_PB1,
+       .rdy_pin        = AT91_PIN_PC2,
+       // .enable_pin  = ... not there
+       .partition_info = nand_partitions,
+};
+
+#define DK_FLASH_BASE  AT91_CHIPSELECT_0
+#define DK_FLASH_SIZE  SZ_2M
+
+static struct physmap_flash_data dk_flash_data = {
+       .width          = 2,
+};
+
+static struct resource dk_flash_resource = {
+       .start          = DK_FLASH_BASE,
+       .end            = DK_FLASH_BASE + DK_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device dk_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+                               .platform_data  = &dk_flash_data,
+                       },
+       .resource       = &dk_flash_resource,
+       .num_resources  = 1,
+};
+
+static struct gpio_led dk_leds[] = {
+       {
+               .name                   = "led0",
+               .gpio                   = AT91_PIN_PB2,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       }
+};
+
+static void __init dk_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* Ethernet */
+       at91_add_device_eth(&dk_eth_data);
+       /* USB Host */
+       at91_add_device_usbh(&dk_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&dk_udc_data);
+       at91_set_multi_drive(dk_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
+       /* Compact Flash */
+       at91_add_device_cf(&dk_cf_data);
+       /* I2C */
+       at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
+       /* SPI */
+       at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       /* DataFlash card */
+       at91_set_gpio_output(AT91_PIN_PB7, 0);
+#else
+       /* MMC */
+       at91_set_gpio_output(AT91_PIN_PB7, 1);  /* this MMC card slot can optionally use SPI signaling (CS3). */
+       at91_add_device_mmc(0, &dk_mmc_data);
+#endif
+       /* NAND */
+       at91_add_device_nand(&dk_nand_data);
+       /* NOR Flash */
+       platform_device_register(&dk_flash);
+       /* LEDs */
+       at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
+       /* VGA */
+//     dk_add_device_video();
+}
+
+MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
+       /* Maintainer: SAN People/Atmel */
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91rm9200_timer,
+       .map_io         = dk_map_io,
+       .init_irq       = dk_init_irq,
+       .init_machine   = dk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c
new file mode 100644 (file)
index 0000000..9df1be8
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200ek.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *
+ *  Epson S1D framebuffer glue code is:
+ *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+       /* Initialize processor: 18.432 MHz crystal */
+       at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+       /* Setup the LEDs */
+       at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
+
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata ek_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PC4,
+       .is_rmii        = 1,
+};
+
+static struct at91_usbh_data __initdata ek_usbh_data = {
+       .ports          = 2,
+};
+
+static struct at91_udc_data __initdata ek_udc_data = {
+       .vbus_pin       = AT91_PIN_PD4,
+       .pullup_pin     = AT91_PIN_PD5,
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata ek_mmc_data = {
+       .det_pin        = AT91_PIN_PB27,
+       .slot_b         = 0,
+       .wire4          = 1,
+       .wp_pin         = AT91_PIN_PA17,
+};
+#endif
+
+static struct spi_board_info ek_spi_devices[] = {
+       {       /* DataFlash chip */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       {       /* DataFlash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 3,
+               .max_speed_hz   = 15 * 1000 * 1000,
+       },
+#endif
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("ics1523", 0x26),
+       },
+       {
+               I2C_BOARD_INFO("dac3550", 0x4d),
+       }
+};
+
+#define EK_FLASH_BASE  AT91_CHIPSELECT_0
+#define EK_FLASH_SIZE  SZ_2M
+
+static struct physmap_flash_data ek_flash_data = {
+       .width          = 2,
+};
+
+static struct resource ek_flash_resource = {
+       .start          = EK_FLASH_BASE,
+       .end            = EK_FLASH_BASE + EK_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device ek_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+                               .platform_data  = &ek_flash_data,
+                       },
+       .resource       = &ek_flash_resource,
+       .num_resources  = 1,
+};
+
+static struct gpio_led ek_leds[] = {
+       {       /* "user led 1", DS2 */
+               .name                   = "green",
+               .gpio                   = AT91_PIN_PB0,
+               .active_low             = 1,
+               .default_trigger        = "mmc0",
+       },
+       {       /* "user led 2", DS4 */
+               .name                   = "yellow",
+               .gpio                   = AT91_PIN_PB1,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+       {       /* "user led 3", DS6 */
+               .name                   = "red",
+               .gpio                   = AT91_PIN_PB2,
+               .active_low             = 1,
+       }
+};
+
+static void __init ek_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* Ethernet */
+       at91_add_device_eth(&ek_eth_data);
+       /* USB Host */
+       at91_add_device_usbh(&ek_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&ek_udc_data);
+       at91_set_multi_drive(ek_udc_data.pullup_pin, 1);        /* pullup_pin is connected to reset */
+       /* I2C */
+       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+       /* SPI */
+       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+       /* DataFlash card */
+       at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
+       /* MMC */
+       at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+       at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+       /* NOR Flash */
+       platform_device_register(&ek_flash);
+       /* LEDs */
+       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+       /* VGA */
+//     ek_add_device_video();
+}
+
+MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
+       /* Maintainer: SAN People/Atmel */
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91rm9200_timer,
+       .map_io         = ek_map_io,
+       .init_irq       = ek_init_irq,
+       .init_machine   = ek_board_init,
+MACHINE_END
index 89df00a9d2f72bfd768df2986db8d792fcd3c3d2..e0f0080eb639f30137d8aca6631271ad82dc639e 100644 (file)
@@ -387,7 +387,7 @@ static struct spi_board_info yl9200_spi_devices[] = {
  * EPSON S1D13806 FB (discontinued chip)
  * EPSON S1D13506 FB
  */
-#if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
+#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE)
 #include <video/s1d13xxxfb.h>
 
 
index 58528aa9c8a86ddea8286cfb9ebdac7e26ed6942..2b499eb343a12a082ad5d0a862c0fb3fb9e722a5 100644 (file)
@@ -137,13 +137,7 @@ extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_de
 extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins);
 extern void __init at91_set_serial_console(unsigned portnr);
 
-struct at91_uart_config {
-       unsigned short  console_tty;    /* tty number of serial console */
-       unsigned short  nr_tty;         /* number of serial tty's */
-       short           tty_map[];      /* map UART to tty number */
-};
 extern struct platform_device *atmel_default_console_device;
-extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
 
 struct atmel_uart_data {
        short                   use_dma_tx;     /* use transmit DMA? */
index 3db3a09fd3986e7ee452997e75a13180a38475b1..7397bd7817d977db8283291d4544aeb2f3d9833d 100644 (file)
@@ -22,4 +22,4 @@
  * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
  * larger physical memory designs better.
  */
-#define VMALLOC_END       0xf0000000
+#define VMALLOC_END       0xf0000000UL
index 30b3a287ed8865d897adccbfb2f318cfa4212e9b..467b96137e47fabddd4cafd9463a0d0abcac1a37 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
index 38088c36936c7d97960ababadc2716050238f055..78defd71a8295423775d9316670491cb0031b2ca 100644 (file)
@@ -369,7 +369,7 @@ static int __init cns3xxx_pcie_init(void)
 {
        int i;
 
-       hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS,
+       hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
                        "imprecise external abort");
 
        for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
index 9be261beae7ddb2a72e2e9a76d9dbf2e2bf51316..2652af124acd941bcb2f7d5bcefa88fe8a0721a2 100644 (file)
@@ -359,8 +359,8 @@ static struct clk_lookup dm355_clks[] = {
        CLK(NULL, "uart1", &uart1_clk),
        CLK(NULL, "uart2", &uart2_clk),
        CLK("i2c_davinci.1", NULL, &i2c_clk),
-       CLK("davinci-asp.0", NULL, &asp0_clk),
-       CLK("davinci-asp.1", NULL, &asp1_clk),
+       CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+       CLK("davinci-mcbsp.1", NULL, &asp1_clk),
        CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
        CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
        CLK("spi_davinci.0", NULL, &spi0_clk),
@@ -664,7 +664,7 @@ static struct resource dm355_asp1_resources[] = {
 };
 
 static struct platform_device dm355_asp1_device = {
-       .name           = "davinci-asp",
+       .name           = "davinci-mcbsp",
        .id             = 1,
        .num_resources  = ARRAY_SIZE(dm355_asp1_resources),
        .resource       = dm355_asp1_resources,
index a12065e87266669a9d66f72bb21a9b4207aca4d2..c466d710d3c103cef9f64445f2e994bcdb4551ca 100644 (file)
@@ -459,7 +459,7 @@ static struct clk_lookup dm365_clks[] = {
        CLK(NULL, "usb", &usb_clk),
        CLK("davinci_emac.1", NULL, &emac_clk),
        CLK("davinci_voicecodec", NULL, &voicecodec_clk),
-       CLK("davinci-asp.0", NULL, &asp0_clk),
+       CLK("davinci-mcbsp", NULL, &asp0_clk),
        CLK(NULL, "rto", &rto_clk),
        CLK(NULL, "mjcp", &mjcp_clk),
        CLK(NULL, NULL, NULL),
@@ -922,8 +922,8 @@ static struct resource dm365_asp_resources[] = {
 };
 
 static struct platform_device dm365_asp_device = {
-       .name           = "davinci-asp",
-       .id             = 0,
+       .name           = "davinci-mcbsp",
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(dm365_asp_resources),
        .resource       = dm365_asp_resources,
 };
index 0608dd776a16ca3fd966e02b22f93804f812e618..9a2376b3137ccd57532d0d5d6c1432d3e7c23801 100644 (file)
@@ -302,7 +302,7 @@ static struct clk_lookup dm644x_clks[] = {
        CLK("davinci_emac.1", NULL, &emac_clk),
        CLK("i2c_davinci.1", NULL, &i2c_clk),
        CLK("palm_bk3710", NULL, &ide_clk),
-       CLK("davinci-asp", NULL, &asp_clk),
+       CLK("davinci-mcbsp", NULL, &asp_clk),
        CLK("davinci_mmc.0", NULL, &mmcsd_clk),
        CLK(NULL, "spi", &spi_clk),
        CLK(NULL, "gpio", &gpio_clk),
@@ -580,7 +580,7 @@ static struct resource dm644x_asp_resources[] = {
 };
 
 static struct platform_device dm644x_asp_device = {
-       .name           = "davinci-asp",
+       .name           = "davinci-mcbsp",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(dm644x_asp_resources),
        .resource       = dm644x_asp_resources,
index 60bde56fba4cf3e4ef90cea65ceb2bf8e2db3111..ea141b7a3e03369978934c837153d8da060074a2 100644 (file)
@@ -7,4 +7,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       0xdf000000
+#define VMALLOC_END       0xdf000000UL
index 0ffbb7c85e59e738ce5d1966788ae72f52252ffe..40ba78e5782bb7b236647d53a80722b36c20972c 100644 (file)
@@ -7,4 +7,4 @@
  */
 
 
-#define VMALLOC_END       0xf0000000
+#define VMALLOC_END       0xf0000000UL
index a45915b88756d4e8e786e653bba677c5e36488b0..8520b4a4d4e6f3cd642c1a4b4aa44591f17c7787 100644 (file)
@@ -5,6 +5,6 @@
 #ifndef __ARCH_ARM_VMALLOC_H
 #define __ARCH_ARM_VMALLOC_H
 
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
 
 #endif
index 026263c665cae060cfca17ca86ad2fb36c8c2cad..7e1e9dc2c8fcefed05cd1d118d6f1fd16802917c 100644 (file)
@@ -250,9 +250,6 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
 
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
-       || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-
 #define ADS7846_PENDOWN (GPIO_PORTD | 25)
 
 static void ads7846_dev_init(void)
@@ -273,9 +270,7 @@ static struct ads7846_platform_data ads7846_config __initdata = {
        .get_pendown_state      = ads7846_get_pendown_state,
        .keep_vref_on           = 1,
 };
-#endif
 
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
 static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
        [0] = {
                .modalias       = "ads7846",
@@ -294,7 +289,6 @@ static const struct spi_imx_master eukrea_mbimx27_spi0_data __initconst = {
        .chipselect     = eukrea_mbimx27_spi_cs,
        .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
 };
-#endif
 
 static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = {
        {
index e056e7cf5645f8c936f4144f8d584f2772ae9bf2..2f5a2bafb11f144340d66e7fa823e1725ef0739a 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
index 31a32ad062dcd7eee3c280aa91e63c55ea11cf64..d138448eff16dd9720502c922b47a6ba617e2d81 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef __ASM_ARCH_MSM_VMALLOC_H
 #define __ASM_ARCH_MSM_VMALLOC_H
 
-#define VMALLOC_END      0xd0000000
+#define VMALLOC_END      0xd0000000UL
 
 #endif
 
index 93afa10b13cf929de543f5f3eea3b51dead77629..d94d282fa6763c08bf09a2f0128e9de97099a92f 100644 (file)
@@ -42,9 +42,9 @@ extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst;
 #define imx25_add_mxc_nand(pdata)      \
        imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
 
-extern const struct imx_spi_imx_data imx25_spi_imx_data[] __initconst;
+extern const struct imx_spi_imx_data imx25_cspi_data[] __initconst;
 #define imx25_add_spi_imx(id, pdata)   \
-       imx_add_spi_imx(&imx25_spi_imx_data[id], pdata)
+       imx_add_spi_imx(&imx25_cspi_data[id], pdata)
 #define imx25_add_spi_imx0(pdata)      imx25_add_spi_imx(0, pdata)
 #define imx25_add_spi_imx1(pdata)      imx25_add_spi_imx(1, pdata)
 #define imx25_add_spi_imx2(pdata)      imx25_add_spi_imx(2, pdata)
index 99e0894e07db320f3e4bbd668768b24803b62f1c..fda56545d2fd0e49de9b733477efff7d936593c0 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <mach/common.h>
 #include <mach/iomux-mx3.h>
+#include <mach/spi.h>
 
 #include <asm/mach-types.h>
 
@@ -59,14 +60,12 @@ static struct spi_board_info pcm037_spi_dev[] = {
 };
 
 /* Platform Data for MXC CSPI */
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
 static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
 
 static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
        .chipselect = pcm037_spi1_cs,
        .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
 };
-#endif
 
 /* GPIO-keys input device */
 static struct gpio_keys_button pcm037_gpio_keys[] = {
@@ -171,7 +170,7 @@ static struct platform_device pcm037_gpio_keys_device = {
        },
 };
 
-static int eet_init_devices(void)
+static int __init eet_init_devices(void)
 {
        if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET)
                return 0;
index 7cca3574308f0403a07c93edf6e427e6d29f0299..871f1ef7bff58ad30be02182a1547f0d9c761624 100644 (file)
@@ -16,4 +16,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
index b001f67d695b28e3ff6f10f16fd1842d7f3742fc..22ec4a4795777a711c1e19d2ba408c36ae136146 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-#define VMALLOC_END    0xd8000000
+#define VMALLOC_END    0xd8000000UL
index 4da31e997efead8da47b602699a210f9127231b7..866319947760e179674331c6cb83f94e64670320 100644 (file)
@@ -17,4 +17,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-#define VMALLOC_END      0xf8000000
+#define VMALLOC_END      0xf8000000UL
index a40457d81927e256ec1f6af538acf038c7e11eb1..c85923e56b85e350b97b027d9a8352e9a8b6776b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
+#include <linux/console.h>
 
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
@@ -118,6 +119,10 @@ static void omap2_enter_full_retention(void)
        if (omap_irq_pending())
                goto no_sleep;
 
+       /* Block console output in case it is on one of the OMAP UARTs */
+       if (try_acquire_console_sem())
+               goto no_sleep;
+
        omap_uart_prepare_idle(0);
        omap_uart_prepare_idle(1);
        omap_uart_prepare_idle(2);
@@ -131,6 +136,8 @@ static void omap2_enter_full_retention(void)
        omap_uart_resume_idle(1);
        omap_uart_resume_idle(0);
 
+       release_console_sem();
+
 no_sleep:
        if (omap2_pm_debug) {
                unsigned long long tmp;
index 75c0cd13ad8e0e78ca9686f35d9ec18b370cb6db..0ec8a04b74730bfccc3e0d709c493e9d8ac8e256 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/console.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
@@ -385,6 +386,12 @@ void omap_sram_idle(void)
                omap3_enable_io_chain();
        }
 
+       /* Block console output in case it is on one of the OMAP UARTs */
+       if (per_next_state < PWRDM_POWER_ON ||
+           core_next_state < PWRDM_POWER_ON)
+               if (try_acquire_console_sem())
+                       goto console_still_active;
+
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
                omap_uart_prepare_idle(2);
@@ -463,6 +470,9 @@ void omap_sram_idle(void)
                omap_uart_resume_idle(3);
        }
 
+       release_console_sem();
+
+console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
        if (omap3_has_io_wakeup() &&
            (per_next_state < PWRDM_POWER_ON ||
index becf0e38ef7ed58a293588ef0b294a02c560e972..d17960a1be25814e25750270beefc4af35d1c70f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/serial_8250.h>
 #include <linux/pm_runtime.h>
+#include <linux/console.h>
 
 #ifdef CONFIG_SERIAL_OMAP
 #include <plat/omap-serial.h>
@@ -406,7 +407,7 @@ void omap_uart_resume_idle(int num)
        struct omap_uart_state *uart;
 
        list_for_each_entry(uart, &uart_list, node) {
-               if (num == uart->num) {
+               if (num == uart->num && uart->can_sleep) {
                        omap_uart_enable_clocks(uart);
 
                        /* Check for IO pad wakeup */
@@ -807,6 +808,8 @@ void __init omap_serial_init_port(int port)
 
        oh->dev_attr = uart;
 
+       acquire_console_sem(); /* in case the earlycon is on the UART */
+
        /*
         * Because of early UART probing, UART did not get idled
         * on init.  Now that omap_device is ready, ensure full idle
@@ -831,6 +834,8 @@ void __init omap_serial_init_port(int port)
        omap_uart_block_sleep(uart);
        uart->timeout = DEFAULT_TIMEOUT;
 
+       release_console_sem();
+
        if ((cpu_is_omap34xx() && uart->padconf) ||
            (uart->wk_en && uart->wk_mask)) {
                device_init_wakeup(&od->pdev.dev, true);
index 31b65ee07b0b17f498e9796c2704ff6f427f5662..184913c71141d7c448f7ebcd8f700789064390ef 100644 (file)
@@ -17,4 +17,4 @@
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  * area for the same reason. ;)
  */
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
index 4075473cf68a1b061a05860ffd4f5da35e92e1e3..b34be4554d40dd0d29809b6b256253e97ec51c56 100644 (file)
@@ -35,5 +35,6 @@ pen:  ldr     r7, [r6]
         */
        b       secondary_startup
 
+       .align
 1:     .long   .
        .long   pen_release
index 3bcd86fadb81ad994e771c27441eeb851c0b3d70..fb700228637a96dceb50a62175307049303de521 100644 (file)
@@ -7,4 +7,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       0xdc000000
+#define VMALLOC_END       0xdc000000UL
index 8aa2f1902a94092e0379d5d46fb1de734a3c0eb9..6b86a722a7db22343f4bf8226f680964c7620ff7 100644 (file)
@@ -77,13 +77,13 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
 
        /* Configures BT serial port GPIOs */
        s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
-       s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
        s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
-       s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+       s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
        s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
-       s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+       s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
        s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
-       s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
+       s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
 
 
        rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
index cef6a65637bd946c31e12691ba51d2d05f554f6a..fa2e5bffbb8eaa37c6d4db06a2213fb476115c64 100644 (file)
@@ -16,7 +16,7 @@ config CPU_S3C2412
 config CPU_S3C2412_ONLY
        bool
        depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-                  !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+                  !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
                   !CPU_S3C2443 && CPU_S3C2412
        default y if CPU_S3C2412
 
index 87b9c9f003bd503dec247cfa3f51b6a43fd97f36..27b3e7c9d61366edcdc59f234e563cec3b5b6b2b 100644 (file)
@@ -35,9 +35,12 @@ menu "S3C2416 Machines"
 config MACH_SMDK2416
        bool "SMDK2416"
        select CPU_S3C2416
+       select MACH_SMDK
        select S3C_DEV_FB
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
+       select S3C_DEV_NAND
+       select S3C_DEV_USB_HOST
        select S3C2416_PM if PM
        help
          Say Y here if you are using an SMDK2416
index 084d121f368cc87d2dfcd6bce0cf6281ab12ba51..00174daf15265024fccbf6063dc56614e827fafd 100644 (file)
@@ -168,12 +168,11 @@ static struct irq_chip s3c2416_irq_dma = {
 
 static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
 {
-       s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
+       s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
 }
 
 #define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3   (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
+#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
 
 static void s3c2416_irq_uart3_mask(unsigned int irqno)
 {
index ff024a6c0f85cd46ca45959dc7137cdb5f20693e..a0cb2581894fa9fbe322347de25781e7b9a4ba81 100644 (file)
@@ -18,6 +18,7 @@ config CPU_S3C2440
 config CPU_S3C2442
        bool
        select CPU_ARM920T
+       select S3C_GPIO_PULL_DOWN
        select S3C2410_CLOCK
        select S3C2410_GPIO
        select S3C2410_PM if PM
@@ -178,6 +179,9 @@ config MACH_MINI2440
        bool "MINI2440 development board"
        select CPU_S3C2440
        select EEPROM_AT24
+       select NEW_LEDS
+       select LEDS_CLASS
+       select LEDS_TRIGGER
        select LEDS_TRIGGER_BACKLIGHT
        select S3C_DEV_NAND
        select S3C_DEV_USB_HOST
index d50f3ae6173d72a27d71ddefc941e0d1adc6bbec..f7663f731ea0728137700c3ada958800a54296db 100644 (file)
@@ -46,9 +46,6 @@ int __init s3c2440_init(void)
 {
        printk("S3C2440: Initialising architecture\n");
 
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
-
        /* change irq for watchdog */
 
        s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
@@ -58,3 +55,11 @@ int __init s3c2440_init(void)
 
        return sysdev_register(&s3c2440_sysdev);
 }
+
+void __init s3c2440_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+}
index 188ad1e57dc0321a1f63254f1f1e2a7c04820a17..ecf813546554739e4d329114a0896c6d49a37288 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/mutex.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
+#include <plat/s3c244x.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
 
 /* S3C2442 extended clock support */
 
@@ -163,3 +169,11 @@ int __init s3c2442_init(void)
 
        return sysdev_register(&s3c2442_sysdev);
 }
+
+void __init s3c2442_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down;
+}
index 4fef723126fa3223e4c45711d80e610907208f19..31babec90cecc9b92ff4a08b00da33c8a8446833 100644 (file)
@@ -5,6 +5,7 @@
 config CPU_S3C2443
        bool
        depends on ARCH_S3C2410
+       select CPU_ARM920T
        select S3C2443_DMA if S3C2410_DMA
        select CPU_LLSERIAL_S3C2440
        select SAMSUNG_CLKSRC
index 0e0d693f397449139f8fd9e790a1f4693e3f661b..893424767ce10b68b4420ff40d3026df331639a7 100644 (file)
@@ -166,12 +166,11 @@ static struct irq_chip s3c2443_irq_dma = {
 
 static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
 {
-       s3c2443_irq_demux(IRQ_S3C2443_UART3, 3);
+       s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
 }
 
 #define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3   (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
+#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
 
 static void s3c2443_irq_uart3_mask(unsigned int irqno)
 {
index 249c62956471a04b970c082fb7eaf011373de9af..89f35e02e88367aacfe5d2a60187859c1ecd3be1 100644 (file)
@@ -45,7 +45,7 @@
 
 #include <video/platform_lcd.h>
 
-#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define UCON S3C2410_UCON_DEFAULT
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
 #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
 
index f9ef9b5c5f5a09f9aa692e3b705e14905ad4cae9..4957ab0a0d4a371effa85505fcc40b5957294485 100644 (file)
@@ -46,7 +46,7 @@
 
 #include <video/platform_lcd.h>
 
-#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define UCON S3C2410_UCON_DEFAULT
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
 #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
 
index 0ad7924fe62e8faa12c54f5aafc07c2aa81474dc..5dd1681c069e582f0f6cb7a61f26e5f6f041ca7c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/i2c.h>
+#include <linux/sysdev.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index bcd7a5d53401ae37d751cc59418f6aa74f2eab42..1fbc45b2a4326e89c3de305c9c6a33840b99351b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/sysdev.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 8e845b6a7cb57a3f74b9f00c16ba12b2bc0dd6f9..b10df988526d3d710577838a37401d11164ee13a 100644 (file)
@@ -1,4 +1,4 @@
 /*
  * arch/arm/mach-shark/include/mach/vmalloc.h
  */
-#define VMALLOC_END       0xd0000000
+#define VMALLOC_END       0xd0000000UL
index d3260542b943df9a4743b7ba5489f3a0d5733780..d440e5f456ad943979f7e5ec432cee56d91d8c77 100644 (file)
@@ -567,38 +567,127 @@ static struct platform_device *qhd_devices[] __initdata = {
 
 /* FSI */
 #define IRQ_FSI                evt2irq(0x1840)
+static int __fsi_set_rate(struct clk *clk, long rate, int enable)
+{
+       int ret = 0;
+
+       if (rate <= 0)
+               return ret;
+
+       if (enable) {
+               ret = clk_set_rate(clk, rate);
+               if (0 == ret)
+                       ret = clk_enable(clk);
+       } else {
+               clk_disable(clk);
+       }
+
+       return ret;
+}
+
+static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
+{
+       return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
+}
 
-static int fsi_set_rate(int is_porta, int rate)
+static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
+{
+       struct clk *fsia_ick;
+       struct clk *fsiack;
+       int ret = -EIO;
+
+       fsia_ick = clk_get(dev, "icka");
+       if (IS_ERR(fsia_ick))
+               return PTR_ERR(fsia_ick);
+
+       /*
+        * FSIACK is connected to AK4642,
+        * and use external clock pin from it.
+        * it is parent of fsia_ick now.
+        */
+       fsiack = clk_get_parent(fsia_ick);
+       if (!fsiack)
+               goto fsia_ick_out;
+
+       /*
+        * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
+        *
+        ** FIXME **
+        * Because the freq_table of external clk (fsiack) are all 0,
+        * the return value of clk_round_rate became 0.
+        * So, it use __fsi_set_rate here.
+        */
+       ret = __fsi_set_rate(fsiack, rate, enable);
+       if (ret < 0)
+               goto fsiack_out;
+
+       ret = __fsi_set_round_rate(fsia_ick, rate, enable);
+       if ((ret < 0) && enable)
+               __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
+
+fsiack_out:
+       clk_put(fsiack);
+
+fsia_ick_out:
+       clk_put(fsia_ick);
+
+       return 0;
+}
+
+static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
 {
        struct clk *fsib_clk;
        struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+       long fsib_rate = 0;
+       long fdiv_rate = 0;
+       int ackmd_bpfmd;
        int ret;
 
-       /* set_rate is not needed if port A */
-       if (is_porta)
-               return 0;
-
-       fsib_clk = clk_get(NULL, "fsib_clk");
-       if (IS_ERR(fsib_clk))
-               return -EINVAL;
-
        switch (rate) {
        case 44100:
-               clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000));
-               ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+               fsib_rate       = rate * 256;
+               ackmd_bpfmd     = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
                break;
        case 48000:
-               clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000));
-               clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000));
-               ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+               fsib_rate       = 85428000; /* around 48kHz x 256 x 7 */
+               fdiv_rate       = rate * 256;
+               ackmd_bpfmd     = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
                break;
        default:
                pr_err("unsupported rate in FSI2 port B\n");
-               ret = -EINVAL;
-               break;
+               return -EINVAL;
        }
 
+       /* FSI B setting */
+       fsib_clk = clk_get(dev, "ickb");
+       if (IS_ERR(fsib_clk))
+               return -EIO;
+
+       ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
        clk_put(fsib_clk);
+       if (ret < 0)
+               return ret;
+
+       /* FSI DIV setting */
+       ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
+       if (ret < 0) {
+               /* disable FSI B */
+               if (enable)
+                       __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
+               return ret;
+       }
+
+       return ackmd_bpfmd;
+}
+
+static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+{
+       int ret;
+
+       if (is_porta)
+               ret = fsi_ak4642_set_rate(dev, rate, enable);
+       else
+               ret = fsi_hdmi_set_rate(dev, rate, enable);
 
        return ret;
 }
@@ -880,6 +969,11 @@ static int __init hdmi_init_pm_clock(void)
                goto out;
        }
 
+       ret = clk_enable(&sh7372_pllc2_clk);
+       if (ret < 0) {
+               pr_err("Cannot enable pllc2 clock\n");
+               goto out;
+       }
        pr_debug("PLLC2 set frequency %lu\n", rate);
 
        ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -896,23 +990,11 @@ out:
 
 device_initcall(hdmi_init_pm_clock);
 
-#define FSIACK_DUMMY_RATE 48000
 static int __init fsi_init_pm_clock(void)
 {
        struct clk *fsia_ick;
        int ret;
 
-       /*
-        * FSIACK is connected to AK4642,
-        * and the rate is depend on playing sound rate.
-        * So, set dummy rate (= 48k) here
-        */
-       ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
-       if (ret < 0) {
-               pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
-               return ret;
-       }
-
        fsia_ick = clk_get(&fsi_device.dev, "icka");
        if (IS_ERR(fsia_ick)) {
                ret = PTR_ERR(fsia_ick);
@@ -921,16 +1003,9 @@ static int __init fsi_init_pm_clock(void)
        }
 
        ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
-       if (ret < 0) {
-               pr_err("Cannot set FSI-A parent: %d\n", ret);
-               goto out;
-       }
-
-       ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
        if (ret < 0)
-               pr_err("Cannot set FSI-A rate: %d\n", ret);
+               pr_err("Cannot set FSI-A parent: %d\n", ret);
 
-out:
        clk_put(fsia_ick);
 
        return ret;
index 7db31e6c6bf2085908cb66ce669238488c5aa444..3aa026069435a7b99ae1cbff5ccac101af016731 100644 (file)
@@ -220,8 +220,7 @@ static void pllc2_disable(struct clk *clk)
        __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
 }
 
-static int pllc2_set_rate(struct clk *clk,
-                         unsigned long rate, int algo_id)
+static int pllc2_set_rate(struct clk *clk, unsigned long rate)
 {
        unsigned long value;
        int idx;
@@ -230,21 +229,13 @@ static int pllc2_set_rate(struct clk *clk,
        if (idx < 0)
                return idx;
 
-       if (rate == clk->parent->rate) {
-               pllc2_disable(clk);
-               return 0;
-       }
+       if (rate == clk->parent->rate)
+               return -EINVAL;
 
        value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
 
-       if (value & 0x80000000)
-               pllc2_disable(clk);
-
        __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
 
-       if (value & 0x80000000)
-               return pllc2_enable(clk);
-
        return 0;
 }
 
@@ -453,32 +444,24 @@ static int fsidiv_enable(struct clk *clk)
        unsigned long value;
 
        value  = __raw_readl(clk->mapping->base) >> 16;
-       if (value < 2) {
-               fsidiv_disable(clk);
-               return -ENOENT;
-       }
+       if (value < 2)
+               return -EIO;
 
        __raw_writel((value << 16) | 0x3, clk->mapping->base);
 
        return 0;
 }
 
-static int fsidiv_set_rate(struct clk *clk,
-                          unsigned long rate, int algo_id)
+static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
 {
        int idx;
 
-       if (clk->parent->rate == rate) {
-               fsidiv_disable(clk);
-               return 0;
-       }
-
        idx = (clk->parent->rate / rate) & 0xffff;
        if (idx < 2)
-               return -ENOENT;
+               return -EINVAL;
 
        __raw_writel(idx << 16, clk->mapping->base);
-       return fsidiv_enable(clk);
+       return 0;
 }
 
 static struct clk_ops fsidiv_clk_ops = {
@@ -609,8 +592,6 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
        CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
        CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
-       CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
-       CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
        CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
        CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
@@ -647,8 +628,8 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
-       CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
-       CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
+       CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
+       CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
index 8ea3bffb4e009f39b56b2262a762b8b28131c814..a0e7c12868bdf3caf69f504924e461181858060a 100644 (file)
@@ -21,8 +21,8 @@
 #include <mach/io.h>
 
        .macro  addruart, rp, rv
-        ldreq   \rp, =IO_APB_PHYS       @ physical
-        ldrne   \rv, =IO_APB_VIRT        @ virtual
+        ldr     \rp, =IO_APB_PHYS       @ physical
+        ldr     \rv, =IO_APB_VIRT        @ virtual
 #if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
 #error "A debug UART must be selected in the kernel config to use DEBUG_LL"
 #elif defined(CONFIG_TEGRA_DEBUG_UARTA)
index 73fb1a551ec64338b136b73fb1548a9b87bd85e0..608a1372b172267170aaab6ecb2e0276fd5d49be 100644 (file)
@@ -75,14 +75,14 @@ void __init ux500_init_irq(void)
 static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
 {
        /* wait for the operation to complete */
-       while (readl(reg) & mask)
+       while (readl_relaxed(reg) & mask)
                ;
 }
 
 static inline void ux500_cache_sync(void)
 {
        void __iomem *base = __io_address(UX500_L2CC_BASE);
-       writel(0, base + L2X0_CACHE_SYNC);
+       writel_relaxed(0, base + L2X0_CACHE_SYNC);
        ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
@@ -107,7 +107,7 @@ static void ux500_l2x0_inv_all(void)
        uint32_t l2x0_way_mask = (1<<16) - 1;   /* Bitmask of active ways */
 
        /* invalidate all ways */
-       writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+       writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
        ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
        ux500_cache_sync();
 }
index ebd8a2543d3b811f5be94118e1c9c9798f134275..7d8e069ad51b98fb0ba6f8f6284276277062c1a0 100644 (file)
@@ -18,4 +18,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END            0xd8000000
+#define VMALLOC_END            0xd8000000UL
index 8a78ff68e1eea106a5730d1a32746535b6adcdf1..7a3f0632947c7f19352bb93479eae6a7b2127d92 100644 (file)
@@ -35,5 +35,6 @@ pen:  ldr     r7, [r6]
         */
        b       secondary_startup
 
+       .align
 1:     .long   .
        .long   pen_release
index 17e7b0b57e49f80e6e30c8bbe65ea9d1ebcf14a6..55c17a6fb22fba2450ebce975a467f6c33ddf0ea 100644 (file)
@@ -206,8 +206,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
         */
        if (pfn_valid(pfn)) {
                printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory.  This leads\n"
-                      KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
-                      KERN_WARNING "will fail in the next kernel release.  Please fix your driver.\n");
+                      "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
+                      "will fail in the next kernel release.  Please fix your driver.\n");
                WARN_ON(1);
        }
 
index 53cbe2225153de55cf6848394d63d1fb1ea00a18..9b9ff5d949fdd08d73d37351b0e3c580a7533b83 100644 (file)
@@ -381,7 +381,7 @@ __v7_ca9mp_proc_info:
                PMD_SECT_XN | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
-       b       __v7_ca9mp_setup
+       W(b)    __v7_ca9mp_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
@@ -413,7 +413,7 @@ __v7_proc_info:
                PMD_SECT_XN | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
-       b       __v7_setup
+       W(b)    __v7_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
index 85d3e55ca4a9c293c67d4b2557bb52d90f93d22f..558cdfaf76b6a22a4ff6ff3a5190263c662a3268 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/timex.h>
+#include <linux/sched.h>
 #include <linux/io.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
@@ -36,7 +37,7 @@
 /*
  * IOP clocksource (free-running timer 1).
  */
-static cycle_t iop_clocksource_read(struct clocksource *unused)
+static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
 {
        return 0xffffffffu - read_tcr1();
 }
index 02d989018059361c84077f1b80d49aba6d65b38b..3a705c7877dd1040121d6abd17a251c105259715 100644 (file)
 
 #include <mach/hardware.h>
 #include <mach/devices-common.h>
-#ifdef SDMA_IS_MERGED
 #include <mach/sdma.h>
-#else
-struct sdma_platform_data {
-       int sdma_version;
-       char *cpu_name;
-       int to_version;
-};
-#endif
 
 struct imx_imx_sdma_data {
        resource_size_t iobase;
index e48340ec331e4a8ca376b96c25b36faa0a7eafe0..17f724c9452d3d5520f451bfd8a198216b4fd503 100644 (file)
@@ -27,6 +27,7 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
        imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K)
        imx21_cspi_data_entry(0, 1),
        imx21_cspi_data_entry(1, 2),
+};
 #endif
 
 #ifdef CONFIG_ARCH_MX25
index aedf9c1d645e4a820c8f1f9dd884fdf5fd1cebf5..63cdc6025bd74dfaf46bc93ec49125e9f75bb49d 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2008 STMicroelectronics
  * Copyright (C) 2010 Alessandro Rubini
+ * Copyright (C) 2010 Linus Walleij for ST-Ericsson
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2, as
 #include <linux/clk.h>
 #include <linux/jiffies.h>
 #include <linux/err.h>
+#include <linux/cnt32_to_63.h>
+#include <linux/timer.h>
 #include <asm/mach/time.h>
 
 #include <plat/mtu.h>
 
-void __iomem *mtu_base; /* ssigned by machine code */
+void __iomem *mtu_base; /* Assigned by machine code */
 
 /*
  * Kernel assumes that sched_clock can be called early
@@ -48,16 +51,82 @@ static struct clocksource nmdk_clksrc = {
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
- * better resolution when scheduling the kernel. We accept that
- * this wraps around for now, since it is just a relative time
- * stamp. (Inspired by OMAP implementation.)
+ * better resolution when scheduling the kernel.
+ *
+ * Because the hardware timer period may be quite short
+ * (32.3 secs on the 133 MHz MTU timer selection on ux500)
+ * and because cnt32_to_63() needs to be called at least once per
+ * half period to work properly, a kernel keepwarm() timer is set up
+ * to ensure this requirement is always met.
+ *
+ * Also the sched_clock timer will wrap around at some point,
+ * here we set it to run continously for a year.
  */
+#define SCHED_CLOCK_MIN_WRAP 3600*24*365
+static struct timer_list cnt32_to_63_keepwarm_timer;
+static u32 sched_mult;
+static u32 sched_shift;
+
 unsigned long long notrace sched_clock(void)
 {
-       return clocksource_cyc2ns(nmdk_clksrc.read(
-                                 &nmdk_clksrc),
-                                 nmdk_clksrc.mult,
-                                 nmdk_clksrc.shift);
+       u64 cycles;
+
+       if (unlikely(!mtu_base))
+               return 0;
+
+       cycles = cnt32_to_63(-readl(mtu_base + MTU_VAL(0)));
+       /*
+        * sched_mult is guaranteed to be even so will
+        * shift out bit 63
+        */
+       return (cycles * sched_mult) >> sched_shift;
+}
+
+/* Just kick sched_clock every so often */
+static void cnt32_to_63_keepwarm(unsigned long data)
+{
+       mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
+       (void) sched_clock();
+}
+
+/*
+ * Set up a timer to keep sched_clock():s 32_to_63 algorithm warm
+ * once in half a 32bit timer wrap interval.
+ */
+static void __init nmdk_sched_clock_init(unsigned long rate)
+{
+       u32 v;
+       unsigned long delta;
+       u64 days;
+
+       /* Find the apropriate mult and shift factors */
+       clocks_calc_mult_shift(&sched_mult, &sched_shift,
+                              rate, NSEC_PER_SEC, SCHED_CLOCK_MIN_WRAP);
+       /* We need to multiply by an even number to get rid of bit 63 */
+       if (sched_mult & 1)
+               sched_mult++;
+
+       /* Let's see what we get, take max counter and scale it */
+       days = (0xFFFFFFFFFFFFFFFFLLU * sched_mult) >> sched_shift;
+       do_div(days, NSEC_PER_SEC);
+       do_div(days, (3600*24));
+
+       pr_info("sched_clock: using %d bits @ %lu Hz wrap in %lu days\n",
+               (64 - sched_shift), rate, (unsigned long) days);
+
+       /*
+        * Program a timer to kick us at half 32bit wraparound
+        * Formula: seconds per wrap = (2^32) / f
+        */
+       v = 0xFFFFFFFFUL / rate;
+       /* We want half of the wrap time to keep cnt32_to_63 warm */
+       v /= 2;
+       pr_debug("sched_clock: prescaled timer rate: %lu Hz, "
+                "initialize keepwarm timer every %d seconds\n", rate, v);
+       /* Convert seconds to jiffies */
+       delta = msecs_to_jiffies(v*1000);
+       setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, delta);
+       mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + delta));
 }
 
 /* Clockevent device: use one-shot mode */
@@ -161,13 +230,15 @@ void __init nmdk_timer_init(void)
        writel(0, mtu_base + MTU_BGLR(0));
        writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
 
-       /* Now the scheduling clock is ready */
+       /* Now the clock source is ready */
        nmdk_clksrc.read = nmdk_read_timer;
 
        if (clocksource_register(&nmdk_clksrc))
                pr_err("timer: failed to initialize clock source %s\n",
                       nmdk_clksrc.name);
 
+       nmdk_sched_clock_init(rate);
+
        /* Timer 1 is used for events */
 
        clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
index e49c5b6fc4e2efe3eb310e061d2e5d8d7ca8cd88..1ab332e37d7d578336a6d5979b6ea7f7e05ddb20 100644 (file)
@@ -17,6 +17,9 @@
 /* Require clock free running */
 #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
 
+/* Board design supports 8-bit data on SD/SDIO BUS */
+#define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2)
+
 /*
  * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
  * @max_speed: the maximum speed supported
index 76d0858c3cbba1f1cbe4482af23a43a41a8aa019..4a10c0f684b2952cdb0ebf3fe6e33914f0eca9fb 100644 (file)
@@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440000,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2440_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2440_init,
@@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440001,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2440_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2440_init,
@@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440aaa,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2442_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2442_init,
@@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = 0x32440aab,
                .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
+               .map_io         = s3c2442_map_io,
                .init_clocks    = s3c244x_init_clocks,
                .init_uarts     = s3c244x_init_uarts,
                .init           = s3c2442_init,
index 24c6f5a30596b3d8206ab16d711ab202e5d99ad8..243b6411050d5edfdd587535a65173f9b1343aa7 100644 (file)
@@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
 struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
        .set_config     = s3c_gpio_setcfg_s3c24xx,
        .get_config     = s3c_gpio_getcfg_s3c24xx,
-       .set_pull       = s3c_gpio_setpull_1up,
-       .get_pull       = s3c_gpio_getpull_1up,
 };
 
 struct s3c_gpio_chip s3c24xx_gpios[] = {
index 307248d1ccbbdd052e0b1fc34e69923ed7e104df..89e8d0a25f87454c6672429bd793557acda0fe74 100644 (file)
@@ -21,17 +21,22 @@ extern void s3c244x_init_clocks(int xtal);
 #else
 #define s3c244x_init_clocks NULL
 #define s3c244x_init_uarts NULL
-#define s3c244x_map_io NULL
 #endif
 
 #ifdef CONFIG_CPU_S3C2440
 extern  int s3c2440_init(void);
+
+extern void s3c2440_map_io(void);
 #else
 #define s3c2440_init NULL
+#define s3c2440_map_io NULL
 #endif
 
 #ifdef CONFIG_CPU_S3C2442
 extern  int s3c2442_init(void);
+
+extern void s3c2442_map_io(void);
 #else
 #define s3c2442_init NULL
+#define s3c2442_map_io NULL
 #endif
index 9793544a6aceb84bd6613fb040971a17788d41f6..704175b0573f45739d4020bddf3e4ce441604315 100644 (file)
@@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
        } else {
                s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
                s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
        }
 }
index db9e9e477ec18a1b71b8cf2c584642aa7314c841..72457afd6255119d3192f3fc8fcdd6dfc616cb37 100644 (file)
@@ -31,8 +31,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
        } else {
                s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
                s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
        }
 }
index 8ea663a438bb8cd8e6a69ee87b53ace02d36bb65..c3972b645d13c03d7e1a405d9967f1eec09fe218 100644 (file)
@@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
        } else {
                s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
                s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
+               s3c_gpio_setpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
        }
 }
index b732b773b9aff13fcc4a661b5405618aed363756..0aa32f242ee43097a477a5494f8068723a9386ad 100644 (file)
@@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
 }
 #endif
 
-#ifdef CONFIG_S3C_GPIO_PULL_UP
-int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
-                        unsigned int off, s3c_gpio_pull_t pull)
+#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
+static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull,
+                        s3c_gpio_pull_t updown)
 {
        void __iomem *reg = chip->base + 0x08;
        u32 pup = __raw_readl(reg);
 
-       pup = __raw_readl(reg);
-
-       if (pup == S3C_GPIO_PULL_UP)
+       if (pull == updown)
                pup &= ~(1 << off);
-       else if (pup == S3C_GPIO_PULL_NONE)
+       else if (pull == S3C_GPIO_PULL_NONE)
                pup |= (1 << off);
        else
                return -EINVAL;
@@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
        return 0;
 }
 
-s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
-                                    unsigned int off)
+static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
+                                    unsigned int off, s3c_gpio_pull_t updown)
 {
        void __iomem *reg = chip->base + 0x08;
        u32 pup = __raw_readl(reg);
 
        pup &= (1 << off);
-       return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+       return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
 }
 #endif /* CONFIG_S3C_GPIO_PULL_UP */
 
+#ifdef CONFIG_S3C_GPIO_PULL_DOWN
+s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
+
 #ifdef CONFIG_S5P_GPIO_DRVSTR
 s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
 {
index 8fd65d8b5863121192fa4eff36fcd33f5413a88a..0d2c5703f1eeba843726d1c3511e774d2c94e844 100644 (file)
@@ -209,6 +209,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
 extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
                                            unsigned int off);
 
+/**
+ * s3c_gpio_getpull_1down() - Get configuration for choice of down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-down resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1down.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+                                           unsigned int off);
+
 /**
  * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
  * @chip: The gpio chip that is being configured.
index d66cead97d28b3c5d63d9c22d4fdcb77b7d7bd8e..9897dcfc16d67a0e104552814adaad8ec1230e32 100644 (file)
@@ -206,6 +206,7 @@ ENTRY(vfp_save_state)
        mov     pc, lr
 ENDPROC(vfp_save_state)
 
+       .align
 last_VFP_context_address:
        .word   last_VFP_context
 
index cd0c090ebc54e1c59225144d2bf9118f7c74dca5..b407bc8ad9186f05fee0f657ffec48e7aab87efe 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/uaccess.h>
index 2b63b0191f529d187f0cde1298c637e32973fabb..efad12071c2e7b95324e9a1f0a8f7e88a6a7d645 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 97478138e361ad702308539b4d067543402df7cb..933bd388efb28c35804b482aab8014f75036afce 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 3a078ad3aa44e4a91ebfb256ca49ba674a35a3da..331de723c6767f264e8ee682fcb73aa44d4a7bf7 100644 (file)
@@ -202,7 +202,7 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
 }
 
 static int
-simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+simscsi_queuecommand_lck (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        unsigned int target_id = sc->device->id;
        char fname[MAX_ROOT_LEN+16];
@@ -326,6 +326,8 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(simscsi_queuecommand)
+
 static int
 simscsi_host_reset (struct scsi_cmnd *sc)
 {
index 18732ab232923faeedbbcd80c02a98364f285215..c2a1fc23dd758e69a49bb45d6e62247f4adf68ce 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index 6d3390590e5ba24be497b5c4a42d0327dbae6cf9..e2a63af5d517510820cfa9085d46b08bcd403f46 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
diff --git a/arch/mn10300/include/asm/syscall.h b/arch/mn10300/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..b44b0bb
--- /dev/null
@@ -0,0 +1,117 @@
+/* Access to user system call parameters and results
+ *
+ * See asm-generic/syscall.h for function descriptions.
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/sched.h>
+#include <linux/err.h>
+
+extern const unsigned long sys_call_table[];
+
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->orig_d0;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+                                   struct pt_regs *regs)
+{
+       regs->d0 = regs->orig_d0;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+                                    struct pt_regs *regs)
+{
+       unsigned long error = regs->d0;
+       return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+                                           struct pt_regs *regs)
+{
+       return regs->d0;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+                                           struct pt_regs *regs,
+                                           int error, long val)
+{
+       regs->d0 = (long) error ?: val;
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       switch (i) {
+       case 0:
+               if (!n--) break;
+               *args++ = regs->a0;
+       case 1:
+               if (!n--) break;
+               *args++ = regs->d1;
+       case 2:
+               if (!n--) break;
+               *args++ = regs->a3;
+       case 3:
+               if (!n--) break;
+               *args++ = regs->a2;
+       case 4:
+               if (!n--) break;
+               *args++ = regs->d3;
+       case 5:
+               if (!n--) break;
+               *args++ = regs->d2;
+       case 6:
+               if (!n--) break;
+       default:
+               BUG();
+               break;
+       }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        const unsigned long *args)
+{
+       switch (i) {
+       case 0:
+               if (!n--) break;
+               regs->a0 = *args++;
+       case 1:
+               if (!n--) break;
+               regs->d1 = *args++;
+       case 2:
+               if (!n--) break;
+               regs->a3 = *args++;
+       case 3:
+               if (!n--) break;
+               regs->a2 = *args++;
+       case 4:
+               if (!n--) break;
+               regs->d3 = *args++;
+       case 5:
+               if (!n--) break;
+               regs->d2 = *args++;
+       case 6:
+               if (!n--) break;
+       default:
+               BUG();
+               break;
+       }
+}
+
+#endif /* _ASM_SYSCALL_H */
index 0d5d63c91dc3ee74457d183a11d59a149022d0c5..f28dc99c6f729a23ba20cd73dd1bb39d80917cda 100644 (file)
@@ -73,7 +73,8 @@ void gdbstub_io_init(void)
        GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
 
        /* permit level 0 IRQs to take place */
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 }
 
 /*
index 97dfda23342c8d9fe8aef19d8c9d4dfaeb170a7d..abdeea153c89643184df8f7b1c13805a504b0b7a 100644 (file)
@@ -87,7 +87,8 @@ void __init gdbstub_io_init(void)
        tmp = *gdbstub_port->_control;
 
        /* permit level 0 IRQs only */
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 }
 
 /*
index a5fc3f05309b2fc26960a36fe68ef1339683c4fd..b169d99d9f20e8fd4b5da5ea353b70f02819844b 100644 (file)
@@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
 
        asm volatile("mov mdr,%0" : "=d"(mdr));
        local_save_flags(epsw);
-       local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+       arch_local_change_intr_mask_level(
+               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
 
        gdbstub_store_fpu();
 
index 0d0f8049a17b557183be48f844bb4b100f5cc87a..e1b14a6ed544675bf7929dc7861876a1a3bf2cc8 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
index ba430a03bc7a51cd99f8dd9ed3688ba531748c0e..30394081d9b6d51ab7486c70054b4bea7beaec89 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/namei.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/utsname.h>
 #include <linux/vfs.h>
index 5024f643b3b1a4c75a57a08756298c5b72e874a2..d7d94b845dc2c8bb08ece9d5e420f8cae5b7abe2 100644 (file)
@@ -75,9 +75,6 @@ static void cpu_unmask_irq(unsigned int irq)
        smp_send_all_nop();
 }
 
-void no_ack_irq(unsigned int irq) { }
-void no_end_irq(unsigned int irq) { }
-
 void cpu_ack_irq(unsigned int irq)
 {
        unsigned long mask = EIEM_MASK(irq);
@@ -241,7 +238,7 @@ int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
 
        /* for iosapic interrupts */
        if (type) {
-               set_irq_chip_and_handler(irq, type, handle_level_irq);
+               set_irq_chip_and_handler(irq, type, handle_percpu_irq);
                set_irq_chip_data(irq, data);
                cpu_unmask_irq(irq);
        }
@@ -392,7 +389,7 @@ static void claim_cpu_irqs(void)
        int i;
        for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
                set_irq_chip_and_handler(i, &cpu_interrupt_type,
-                       handle_level_irq);
+                                        handle_percpu_irq);
        }
 
        set_irq_handler(TIMER_IRQ, handle_percpu_irq);
index 35c827e94e311366af3bcaff6554688558d6dde5..609a331878e72e172fecc2e85c9695d2c36cad60 100644 (file)
@@ -98,7 +98,6 @@ void
 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 {
        struct rt_sigframe __user *frame;
-       struct siginfo si;
        sigset_t set;
        unsigned long usp = (regs->gr[30] & ~(0x01UL));
        unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
@@ -178,13 +177,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 
 give_sigsegv:
        DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
-       si.si_signo = SIGSEGV;
-       si.si_errno = 0;
-       si.si_code = SI_KERNEL;
-       si.si_pid = task_pid_vnr(current);
-       si.si_uid = current_uid();
-       si.si_addr = &frame->uc;
-       force_sig_info(SIGSEGV, &si, current);
+       force_sig(SIGSEGV, current);
        return;
 }
 
index 9779ece2b07079189884f2f17807adb85e6e5bbe..88a0ad14a9c99a466c9aaaf6ba6459868a61d1fa 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/times.h>
 #include <linux/time.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index b6447190e1a2acee2b6fddf9ef90bd5a3d0a1da9..e625e9e034ae19abe973282a3d83952493e8b709 100644 (file)
@@ -4,6 +4,10 @@ config PPC32
        bool
        default y if !PPC64
 
+config 32BIT
+       bool
+       default y if PPC32
+
 config 64BIT
        bool
        default y if PPC64
index 722f360a32a9e905b2edf6f3cdb90b9ef9e5d588..d271ab5426732ab07ec0bec73e52a195e493fe64 100644 (file)
@@ -33,9 +33,10 @@ __div64_32:
        cntlzw  r0,r5           # we are shifting the dividend right
        li      r10,-1          # to make it < 2^32, and shifting
        srw     r10,r10,r0      # the divisor right the same amount,
-       add     r9,r4,r10       # rounding up (so the estimate cannot
+       addc    r9,r4,r10       # rounding up (so the estimate cannot
        andc    r11,r6,r10      # ever be too large, only too small)
        andc    r9,r9,r10
+       addze   r9,r9
        or      r11,r5,r11
        rotlw   r9,r9,r0
        rotlw   r11,r11,r0
index 7a9db64f3f0438f8bf366b9cb2244f1ef3178004..42850ee00adabfa33f0bb5ccd69efe1388d8ec96 100644 (file)
@@ -337,7 +337,7 @@ char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
                /* FP registers 32 -> 63 */
 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
                if (current)
-                       memcpy(mem, current->thread.evr[regno-32],
+                       memcpy(mem, &current->thread.evr[regno-32],
                                        dbg_reg_def[regno].size);
 #else
                /* fp registers not used by kernel, leave zero */
@@ -362,7 +362,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
        if (regno >= 32 && regno < 64) {
                /* FP registers 32 -> 63 */
 #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
-               memcpy(current->thread.evr[regno-32], mem,
+               memcpy(&current->thread.evr[regno-32], mem,
                                dbg_reg_def[regno].size);
 #else
                /* fp registers not used by kernel, leave zero */
index 2a178b0ebcdf8ea33ed67c8a4516b7ec0f1d9f26..ce6f61c6f871022baedac98bd751de6110ff42c1 100644 (file)
@@ -497,9 +497,8 @@ static void __init emergency_stack_init(void)
 }
 
 /*
- * Called into from start_kernel, after lock_kernel has been called.
- * Initializes bootmem, which is unsed to manage page allocation until
- * mem_init is called.
+ * Called into from start_kernel this initializes bootmem, which is used
+ * to manage page allocation until mem_init is called.
  */
 void __init setup_arch(char **cmdline_p)
 {
index b1b6043a56c44f6b07537e8eb4a0aa720400e296..4e5bf1edc0f2e19690175719fcaf20bc2994237f 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index 83f534d862db2cd3934fca431e9b4d67b4ac7d38..5e9584405c4560c13c5567ba6affa81b2391e6bd 100644 (file)
@@ -1123,7 +1123,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
        else
 #endif /* CONFIG_PPC_HAS_HASH_64K */
                rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
-                                   subpage_protection(pgdir, ea));
+                                   subpage_protection(mm, ea));
 
        /* Dump some info in case of hash insertion failure, they should
         * never happen so it is really useful to know if/when they do
index 2c7e801ab20b617cc3934e9ad355af8b8734a0ec..6a3997f98dfb90a2f3d01da4b53156c2098a38f8 100644 (file)
@@ -92,7 +92,7 @@ static void pte_free_rcu_callback(struct rcu_head *head)
 
 static void pte_free_submit(struct pte_freelist_batch *batch)
 {
-       call_rcu(&batch->rcu, pte_free_rcu_callback);
+       call_rcu_sched(&batch->rcu, pte_free_rcu_callback);
 }
 
 void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
index 8b04c54e596f2a5a1bf770cb44013808eaf27246..8526bd9d2aa33603be03dbf10bc3656c7a833448 100644 (file)
        cmpldi  cr0,r15,0                       /* Check for user region */
        std     r14,EX_TLB_ESR(r12)             /* write crazy -1 to frame */
        beq     normal_tlb_miss
+
+       li      r11,_PAGE_PRESENT|_PAGE_BAP_SX  /* Base perm */
+       oris    r11,r11,_PAGE_ACCESSED@h
        /* XXX replace the RMW cycles with immediate loads + writes */
-1:     mfspr   r10,SPRN_MAS1
+       mfspr   r10,SPRN_MAS1
        cmpldi  cr0,r15,8                       /* Check for vmalloc region */
        rlwinm  r10,r10,0,16,1                  /* Clear TID */
        mtspr   SPRN_MAS1,r10
index 36c0c449a89993659c60d1b4c4b772fb5aa5f94c..2a030d89bbc6e65a847a29f6c4bf012f2e6188b0 100644 (file)
@@ -585,6 +585,6 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
        ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
 
        /* Finally limit subsequent allocations */
-       memblock_set_current_limit(ppc64_memblock_base + ppc64_rma_size);
+       memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
 }
 #endif /* CONFIG_PPC64 */
index c667f0f02c34cc44eb75138e8eae6b140a49c3e8..3139814f643985e1879ed876b651a7f1e2a370a7 100644 (file)
@@ -47,6 +47,12 @@ config LPARCFG
 config PPC_PSERIES_DEBUG
        depends on PPC_PSERIES && PPC_EARLY_DEBUG
        bool "Enable extra debug logging in platforms/pseries"
+        help
+         Say Y here if you want the pseries core to produce a bunch of
+         debug messages to the system log. Select this if you are having a
+         problem with the pseries core and want to see more of what is
+         going on. This does not enable debugging in lpar.c, which must
+         be manually done due to its verbosity.
        default y
 
 config PPC_SMLPAR
index 34b7dc12e731231e9c0110bbe7caeda20ec5c0c0..17a11c82e6f8d61676edc341783a81fc4da1cb4a 100644 (file)
@@ -21,8 +21,6 @@
  * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
  */
 
-#undef DEBUG
-
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
index 4b7a062dee15373e93b0b44c66c5ad0fbd5ee086..5fcc92a12d3e1256b1c5d648b624f4791e3b0817 100644 (file)
@@ -25,8 +25,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#undef DEBUG
-
 #include <linux/pci.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
index 45e0c6199f36d6484df7adc657527c02c7974a4e..05221b13ffb1ed746b4a276a06ad0b9bfca95364 100644 (file)
@@ -6,6 +6,18 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config STRICT_DEVMEM
+       def_bool y
+       prompt "Filter access to /dev/mem"
+       ---help---
+         This option restricts access to /dev/mem.  If this option is
+         disabled, you allow userspace access to all memory, including
+         kernel and userspace memory. Accidental memory access is likely
+         to be disastrous.
+         Memory access is required for experts who want to debug the kernel.
+
+         If you are unsure, say Y.
+
 config DEBUG_STRICT_USER_COPY_CHECKS
        bool "Strict user copy size checks"
        ---help---
index a8729ea7e9ac1d12826fb4a0e76923a19af307fa..3c987e9ec8d69e61d4eaaa5f21e409613662324c 100644 (file)
@@ -130,6 +130,11 @@ struct page;
 void arch_free_page(struct page *page, int order);
 void arch_alloc_page(struct page *page, int order);
 
+static inline int devmem_is_allowed(unsigned long pfn)
+{
+       return 0;
+}
+
 #define HAVE_ARCH_FREE_PAGE
 #define HAVE_ARCH_ALLOC_PAGE
 
index 1e6449c79ab6de6de8d7c9f1de8ed1b8bdde66d5..53acaa86dd94f353e36beb03f5c9e904c14d42d3 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index d60fc439851658761cd105d8d403be2e69fee0ad..2564793ec2b6fd0dede210f10694615606239511 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/sections.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/hardirq.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -212,7 +213,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
        /* Set the PER control regs, turns on single step for this address */
        __ctl_load(kprobe_per_regs, 9, 11);
        regs->psw.mask |= PSW_MASK_PER;
-       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
 }
 
 static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
@@ -239,7 +240,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
        __get_cpu_var(current_kprobe) = p;
        /* Save the interrupt and per flags */
        kcb->kprobe_saved_imask = regs->psw.mask &
-           (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+               (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT);
        /* Save the control regs that govern PER */
        __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
 }
@@ -316,8 +317,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                return 1;
 
 ss_probe:
-       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-               local_irq_disable();
        prepare_singlestep(p, regs);
        kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
@@ -350,6 +349,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
        struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+       kprobe_opcode_t *correct_ret_addr = NULL;
 
        INIT_HLIST_HEAD(&empty_rp);
        kretprobe_hash_lock(current, &head, &flags);
@@ -372,10 +372,32 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
                        /* another task is sharing our hash bucket */
                        continue;
 
-               if (ri->rp && ri->rp->handler)
-                       ri->rp->handler(ri, regs);
+               orig_ret_address = (unsigned long)ri->ret_addr;
+
+               if (orig_ret_address != trampoline_address)
+                       /*
+                        * This is the real return address. Any other
+                        * instances associated with this task are for
+                        * other calls deeper on the call stack
+                        */
+                       break;
+       }
+
+       kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+       correct_ret_addr = ri->ret_addr;
+       hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+               if (ri->task != current)
+                       /* another task is sharing our hash bucket */
+                       continue;
 
                orig_ret_address = (unsigned long)ri->ret_addr;
+
+               if (ri->rp && ri->rp->handler) {
+                       ri->ret_addr = correct_ret_addr;
+                       ri->rp->handler(ri, regs);
+               }
+
                recycle_rp_inst(ri, &empty_rp);
 
                if (orig_ret_address != trampoline_address) {
@@ -387,7 +409,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
                        break;
                }
        }
-       kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
        regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
 
        reset_current_kprobe();
@@ -465,8 +487,6 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
                goto out;
        }
        reset_current_kprobe();
-       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-               local_irq_enable();
 out:
        preempt_enable_no_resched();
 
@@ -482,7 +502,7 @@ out:
        return 1;
 }
 
-int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -508,8 +528,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                        restore_previous_kprobe(kcb);
                else {
                        reset_current_kprobe();
-                       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
-                               local_irq_enable();
                }
                preempt_enable_no_resched();
                break;
@@ -553,6 +571,18 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
        return 0;
 }
 
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+       int ret;
+
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_disable();
+       ret = kprobe_trap_handler(regs, trapnr);
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
+       return ret;
+}
+
 /*
  * Wrapper routine to for handling exceptions.
  */
@@ -560,8 +590,12 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       struct pt_regs *regs = args->regs;
        int ret = NOTIFY_DONE;
 
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_disable();
+
        switch (val) {
        case DIE_BPT:
                if (kprobe_handler(args->regs))
@@ -572,16 +606,17 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                        ret = NOTIFY_STOP;
                break;
        case DIE_TRAP:
-               /* kprobe_running() needs smp_processor_id() */
-               preempt_disable();
-               if (kprobe_running() &&
-                   kprobe_fault_handler(args->regs, args->trapnr))
+               if (!preemptible() && kprobe_running() &&
+                   kprobe_trap_handler(args->regs, args->trapnr))
                        ret = NOTIFY_STOP;
-               preempt_enable();
                break;
        default:
                break;
        }
+
+       if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT))
+               local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
+
        return ret;
 }
 
@@ -595,6 +630,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
        /* setup return addr to the jprobe handler routine */
        regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
+       regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
 
        /* r14 is the function return address */
        kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
index ac151399ef34153cb69da534bd52ff51fd2528fb..1995c1712fc83485193dab760623241576b0ef29 100644 (file)
@@ -95,7 +95,6 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
 static int notrace s390_revalidate_registers(struct mci *mci)
 {
        int kill_task;
-       u64 tmpclock;
        u64 zero;
        void *fpt_save_area, *fpt_creg_save_area;
 
@@ -214,11 +213,10 @@ static int notrace s390_revalidate_registers(struct mci *mci)
                        : "0", "cc");
 #endif
        /* Revalidate clock comparator register */
-       asm volatile(
-               "       stck    0(%1)\n"
-               "       sckc    0(%1)"
-               : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
+       if (S390_lowcore.clock_comparator == -1)
+               set_clock_comparator(S390_lowcore.mcck_clock);
+       else
+               set_clock_comparator(S390_lowcore.clock_comparator);
        /* Check if old PSW is valid */
        if (!mci->wp)
                /*
index 56c8687b29b3a48b9487921d2b0fdaea5767ec5b..7eff9b7347c00ff8a825624500f5713a04ccd79e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/rcupdate.h>
 #include <linux/posix-timers.h>
+#include <linux/cpu.h>
 
 #include <asm/s390_ext.h>
 #include <asm/timer.h>
@@ -566,6 +567,23 @@ void init_cpu_vtimer(void)
        __ctl_set_bit(0,10);
 }
 
+static int __cpuinit s390_nohz_notify(struct notifier_block *self,
+                                     unsigned long action, void *hcpu)
+{
+       struct s390_idle_data *idle;
+       long cpu = (long) hcpu;
+
+       idle = &per_cpu(s390_idle, cpu);
+       switch (action) {
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
+               idle->nohz_delay = 0;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
 void __init vtime_init(void)
 {
        /* request the cpu timer external interrupt */
@@ -574,5 +592,6 @@ void __init vtime_init(void)
 
        /* Enable cpu timer interrupts on the boot cpu. */
        init_cpu_vtimer();
+       cpu_notifier(s390_nohz_notify, 0);
 }
 
index 752b362bf651d7e1bdf84a3f54601ddf863e8b12..7c37ec359ec29ad40fc2cf47642316ac3cbba8bc 100644 (file)
@@ -29,17 +29,21 @@ static void __udelay_disabled(unsigned long long usecs)
 {
        unsigned long mask, cr0, cr0_saved;
        u64 clock_saved;
+       u64 end;
 
+       mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+       end = get_clock() + (usecs << 12);
        clock_saved = local_tick_disable();
-       set_clock_comparator(get_clock() + (usecs << 12));
        __ctl_store(cr0_saved, 0, 0);
        cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
        __ctl_load(cr0 , 0, 0);
-       mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
        lockdep_off();
-       trace_hardirqs_on();
-       __load_psw_mask(mask);
-       local_irq_disable();
+       do {
+               set_clock_comparator(end);
+               trace_hardirqs_on();
+               __load_psw_mask(mask);
+               local_irq_disable();
+       } while (get_clock() < end);
        lockdep_on();
        __ctl_load(cr0_saved, 0, 0);
        local_tick_enable(clock_saved);
index 38e641cdd9779ca3c96a1accf6faeb0d7148f82c..45b405ca25673a416ca33bfdd5b20a81c4876264 100644 (file)
 static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
                unsigned long end, int write, struct page **pages, int *nr)
 {
-       unsigned long mask, result;
+       unsigned long mask;
        pte_t *ptep, pte;
        struct page *page;
 
-       result = write ? 0 : _PAGE_RO;
-       mask = result | _PAGE_INVALID | _PAGE_SPECIAL;
+       mask = (write ? _PAGE_RO : 0) | _PAGE_INVALID | _PAGE_SPECIAL;
 
        ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr);
        do {
                pte = *ptep;
                barrier();
-               if ((pte_val(pte) & mask) != result)
+               if ((pte_val(pte) & mask) != 0)
                        return 0;
                VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
                page = pte_page(pte);
index 2eaeb9e5958575f59f3dd1f8d40b54ae03f5de00..f48c492a68d3824158828e820175446eb7ecc44a 100644 (file)
@@ -720,32 +720,6 @@ static struct platform_device camera_devices[] = {
 };
 
 /* FSI */
-/*
- * FSI-B use external clock which came from da7210.
- * So, we should change parent of fsi
- */
-#define FCLKBCR                0xa415000c
-static void fsimck_init(struct clk *clk)
-{
-       u32 status = __raw_readl(clk->enable_reg);
-
-       /* use external clock */
-       status &= ~0x000000ff;
-       status |= 0x00000080;
-
-       __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
-       .init = fsimck_init,
-};
-
-static struct clk fsimckb_clk = {
-       .ops            = &fsimck_clk_ops,
-       .enable_reg     = (void __iomem *)FCLKBCR,
-       .rate           = 0, /* unknown */
-};
-
 static struct sh_fsi_platform_info fsi_info = {
        .portb_flags = SH_FSI_BRS_INV |
                       SH_FSI_OUT_SLAVE_MODE |
@@ -1264,10 +1238,10 @@ static int __init arch_setup(void)
        /* change parent of FSI B */
        clk = clk_get(NULL, "fsib_clk");
        if (!IS_ERR(clk)) {
-               clk_register(&fsimckb_clk);
-               clk_set_parent(clk, &fsimckb_clk);
-               clk_set_rate(clk, 11000);
-               clk_set_rate(&fsimckb_clk, 11000);
+               /* 48kHz dummy clock was used to make sure 1/1 divide */
+               clk_set_rate(&sh7724_fsimckb_clk, 48000);
+               clk_set_parent(clk, &sh7724_fsimckb_clk);
+               clk_set_rate(clk, 48000);
                clk_put(clk);
        }
 
index c31d228fdfc6257d248c28f0fac88ba274dc52b1..527a0cd956b55e87cf785fbc885d1b39dcffac55 100644 (file)
@@ -283,31 +283,6 @@ static struct platform_device ceu1_device = {
 };
 
 /* FSI */
-/*
- * FSI-A use external clock which came from ak464x.
- * So, we should change parent of fsi
- */
-#define FCLKACR                0xa4150008
-static void fsimck_init(struct clk *clk)
-{
-       u32 status = __raw_readl(clk->enable_reg);
-
-       /* use external clock */
-       status &= ~0x000000ff;
-       status |= 0x00000080;
-       __raw_writel(status, clk->enable_reg);
-}
-
-static struct clk_ops fsimck_clk_ops = {
-       .init = fsimck_init,
-};
-
-static struct clk fsimcka_clk = {
-       .ops            = &fsimck_clk_ops,
-       .enable_reg     = (void __iomem *)FCLKACR,
-       .rate           = 0, /* unknown */
-};
-
 /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
 static struct sh_fsi_platform_info fsi_info = {
        .porta_flags = SH_FSI_BRS_INV |
@@ -852,37 +827,29 @@ static int __init devices_setup(void)
        gpio_request(GPIO_FN_KEYOUT0,     NULL);
 
        /* enable FSI */
-       gpio_request(GPIO_FN_FSIMCKB,    NULL);
        gpio_request(GPIO_FN_FSIMCKA,    NULL);
+       gpio_request(GPIO_FN_FSIIASD,    NULL);
        gpio_request(GPIO_FN_FSIOASD,    NULL);
        gpio_request(GPIO_FN_FSIIABCK,   NULL);
        gpio_request(GPIO_FN_FSIIALRCK,  NULL);
        gpio_request(GPIO_FN_FSIOABCK,   NULL);
        gpio_request(GPIO_FN_FSIOALRCK,  NULL);
        gpio_request(GPIO_FN_CLKAUDIOAO, NULL);
-       gpio_request(GPIO_FN_FSIIBSD,    NULL);
-       gpio_request(GPIO_FN_FSIOBSD,    NULL);
-       gpio_request(GPIO_FN_FSIIBBCK,   NULL);
-       gpio_request(GPIO_FN_FSIIBLRCK,  NULL);
-       gpio_request(GPIO_FN_FSIOBBCK,   NULL);
-       gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
-       gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
-       gpio_request(GPIO_FN_FSIIASD,    NULL);
 
        /* set SPU2 clock to 83.4 MHz */
        clk = clk_get(NULL, "spu_clk");
-       if (clk) {
+       if (!IS_ERR(clk)) {
                clk_set_rate(clk, clk_round_rate(clk, 83333333));
                clk_put(clk);
        }
 
        /* change parent of FSI A */
        clk = clk_get(NULL, "fsia_clk");
-       if (clk) {
-               clk_register(&fsimcka_clk);
-               clk_set_parent(clk, &fsimcka_clk);
-               clk_set_rate(clk, 11000);
-               clk_set_rate(&fsimcka_clk, 11000);
+       if (!IS_ERR(clk)) {
+               /* 48kHz dummy clock was used to make sure 1/1 divide */
+               clk_set_rate(&sh7724_fsimcka_clk, 48000);
+               clk_set_parent(clk, &sh7724_fsimcka_clk);
+               clk_set_rate(clk, 48000);
                clk_put(clk);
        }
 
index 1f4e562c5e8cc1317bd97a448e5067465bad26a9..82e1eabeac989fff1b4c2fc43aa74bcd2b23d715 100644 (file)
@@ -96,7 +96,7 @@ void kmap_coherent_init(void);
 void *kmap_coherent(struct page *page, unsigned long addr);
 void kunmap_coherent(void *kvaddr);
 
-#define PG_dcache_dirty        PG_arch_1
+#define PG_dcache_clean        PG_arch_1
 
 void cpu_cache_init(void);
 
index 46d5179c9f4902fef3b797a8772e6a65652c7aeb..e3c73cdd8c909444fa64865e24bffc5b7ed8a0d9 100644 (file)
@@ -199,10 +199,13 @@ extern unsigned long get_wchan(struct task_struct *p);
 #define ARCH_HAS_PREFETCHW
 static inline void prefetch(void *x)
 {
-       __asm__ __volatile__ ("pref @%0\n\t" : : "r" (x) : "memory");
+       __builtin_prefetch(x, 0, 3);
 }
 
-#define prefetchw(x)   prefetch(x)
+static inline void prefetchw(void *x)
+{
+       __builtin_prefetch(x, 1, 3);
+}
 #endif
 
 #endif /* __KERNEL__ */
index 4c27b68789b3fd02a89fea5c6ae42fb0a347e0d5..7eb435999426e1979a5127942a4686114626e724 100644 (file)
@@ -303,4 +303,7 @@ enum {
        SHDMA_SLAVE_SDHI1_RX,
 };
 
+extern struct clk sh7724_fsimcka_clk;
+extern struct clk sh7724_fsimckb_clk;
+
 #endif /* __ASM_SH7724_H__ */
index 4eabc68cd75325cb9952914879cb2b7235bac3a3..b601fa3978d1995f53ea466e6aed5145e6ef1f75 100644 (file)
@@ -110,7 +110,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+static int shoc_clk_set_rate(struct clk *clk, unsigned long rate)
 {
        unsigned long frqcr3;
        unsigned int tmp;
index 0fe2e9329cb25f699acd433dd4f2d9b4b945f00b..271c0b325a9a4d7f5dde40a45152546b7aa6dce0 100644 (file)
@@ -111,12 +111,21 @@ static struct clk div3_clk = {
        .parent         = &pll_clk,
 };
 
+/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+struct clk sh7724_fsimcka_clk = {
+};
+
+struct clk sh7724_fsimckb_clk = {
+};
+
 static struct clk *main_clks[] = {
        &r_clk,
        &extal_clk,
        &fll_clk,
        &pll_clk,
        &div3_clk,
+       &sh7724_fsimcka_clk,
+       &sh7724_fsimckb_clk,
 };
 
 static void div4_kick(struct clk *clk)
@@ -154,16 +163,38 @@ struct clk div4_clks[DIV4_NR] = {
        [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
-enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
 
 static struct clk div6_clks[DIV6_NR] = {
        [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
-       [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0),
-       [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0),
        [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
        [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
 };
 
+enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+
+/* Indices are important - they are the actual src selecting values */
+static struct clk *fclkacr_parent[] = {
+       [0] = &div3_clk,
+       [1] = NULL,
+       [2] = &sh7724_fsimcka_clk,
+       [3] = NULL,
+};
+
+static struct clk *fclkbcr_parent[] = {
+       [0] = &div3_clk,
+       [1] = NULL,
+       [2] = &sh7724_fsimckb_clk,
+       [3] = NULL,
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+       [DIV6_FA] = SH_CLK_DIV6_EXT(&div3_clk, FCLKACR, 0,
+                                     fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
+       [DIV6_FB] = SH_CLK_DIV6_EXT(&div3_clk, FCLKBCR, 0,
+                                     fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
+};
+
 static struct clk mstp_clks[HWBLK_NR] = {
        SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
        SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
@@ -240,8 +271,8 @@ static struct clk_lookup lookups[] = {
 
        /* DIV6 clocks */
        CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
-       CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
-       CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
+       CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
+       CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
        CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
 
@@ -375,6 +406,9 @@ int __init arch_clk_init(void)
        if (!ret)
                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
+       if (!ret)
+               ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+
        if (!ret)
                ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
 
index 81f58371613dc71c97e2cc576d91eae8266d6934..8c6a350df751a97779cfe7030054b416203f9d9a 100644 (file)
@@ -88,7 +88,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
        }
 
        if (op & CACHEFLUSH_I)
-               flush_cache_all();
+               flush_icache_range(addr, addr+len);
 
        up_read(&current->mm->mmap_sem);
        return 0;
index 3b6eb34c43fa36aac0ba0bcccd2ed0168190304e..3e70f851cdc6c1b674af7dec81bb8f19e290d4ad 100644 (file)
@@ -8,9 +8,9 @@ __kernel_vsyscall:
         * fill out .eh_frame -- PFM. */
 .LEND_vsyscall:
        .size __kernel_vsyscall,.-.LSTART_vsyscall
-       .previous
 
        .section .eh_frame,"a",@progbits
+       .previous
 .LCIE:
        .ualong .LCIE_end - .LCIE_start
 .LCIE_start:
index 2cfae81914aaac53289df444123cfb9f5f99476d..92eb98633ab05655fcdc3c4073f071798302e632 100644 (file)
@@ -114,7 +114,7 @@ static void sh4_flush_dcache_page(void *arg)
        struct address_space *mapping = page_mapping(page);
 
        if (mapping && !mapping_mapped(mapping))
-               set_bit(PG_dcache_dirty, &page->flags);
+               clear_bit(PG_dcache_clean, &page->flags);
        else
 #endif
                flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
@@ -239,7 +239,7 @@ static void sh4_flush_cache_page(void *args)
                 * another ASID than the current one.
                 */
                map_coherent = (current_cpu_data.dcache.n_aliases &&
-                       !test_bit(PG_dcache_dirty, &page->flags) &&
+                       test_bit(PG_dcache_clean, &page->flags) &&
                        page_mapped(page));
                if (map_coherent)
                        vaddr = kmap_coherent(page, address);
index f498da1cce7ac5a070e3c563f94d04a1b812f17f..7729cca727ebebb48dfd787d0dd9a601dc9d1be3 100644 (file)
@@ -139,7 +139,7 @@ static void sh7705_flush_dcache_page(void *arg)
        struct address_space *mapping = page_mapping(page);
 
        if (mapping && !mapping_mapped(mapping))
-               set_bit(PG_dcache_dirty, &page->flags);
+               clear_bit(PG_dcache_clean, &page->flags);
        else
                __flush_dcache_page(__pa(page_address(page)));
 }
index ba401d137bb9f5057b93f18afdd75da87209525e..88d3dc3d30d50aabcbdfcff04ac197cf19470bb7 100644 (file)
@@ -60,14 +60,14 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
                       unsigned long len)
 {
        if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-           !test_bit(PG_dcache_dirty, &page->flags)) {
+           test_bit(PG_dcache_clean, &page->flags)) {
                void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
                memcpy(vto, src, len);
                kunmap_coherent(vto);
        } else {
                memcpy(dst, src, len);
                if (boot_cpu_data.dcache.n_aliases)
-                       set_bit(PG_dcache_dirty, &page->flags);
+                       clear_bit(PG_dcache_clean, &page->flags);
        }
 
        if (vma->vm_flags & VM_EXEC)
@@ -79,14 +79,14 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
                         unsigned long len)
 {
        if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-           !test_bit(PG_dcache_dirty, &page->flags)) {
+           test_bit(PG_dcache_clean, &page->flags)) {
                void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
                memcpy(dst, vfrom, len);
                kunmap_coherent(vfrom);
        } else {
                memcpy(dst, src, len);
                if (boot_cpu_data.dcache.n_aliases)
-                       set_bit(PG_dcache_dirty, &page->flags);
+                       clear_bit(PG_dcache_clean, &page->flags);
        }
 }
 
@@ -98,7 +98,7 @@ void copy_user_highpage(struct page *to, struct page *from,
        vto = kmap_atomic(to, KM_USER1);
 
        if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
-           !test_bit(PG_dcache_dirty, &from->flags)) {
+           test_bit(PG_dcache_clean, &from->flags)) {
                vfrom = kmap_coherent(from, vaddr);
                copy_page(vto, vfrom);
                kunmap_coherent(vfrom);
@@ -141,7 +141,7 @@ void __update_cache(struct vm_area_struct *vma,
 
        page = pfn_to_page(pfn);
        if (pfn_valid(pfn)) {
-               int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+               int dirty = !test_and_set_bit(PG_dcache_clean, &page->flags);
                if (dirty)
                        __flush_purge_region(page_address(page), PAGE_SIZE);
        }
@@ -153,7 +153,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
 
        if (pages_do_alias(addr, vmaddr)) {
                if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
-                   !test_bit(PG_dcache_dirty, &page->flags)) {
+                   test_bit(PG_dcache_clean, &page->flags)) {
                        void *kaddr;
 
                        kaddr = kmap_coherent(page, vmaddr);
index 15d74ea4209497b8d938840a7fbf6b7cfce19666..ec29e14ec5a85643b600952b3140f013ada5d258 100644 (file)
@@ -34,7 +34,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
        enum fixed_addresses idx;
        unsigned long vaddr;
 
-       BUG_ON(test_bit(PG_dcache_dirty, &page->flags));
+       BUG_ON(!test_bit(PG_dcache_clean, &page->flags));
 
        pagefault_disable();
 
index 7524689b03d24465f78500f87e804803509b3367..16582d85368af84b891fded4406d7f0088bf3056 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/sched.h>
 #include <linux/threads.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
index e6375a750d9a641f4b253fdf2894fa989973b347..6db18c6927fbee68a20125e1eb31e486798eeac0 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index 675c9e11ada5541085e2fd6e6129272c05713df4..42b282fa6112933681082c12bb95ef04fccc4b41 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mman.h>
 #include <linux/utsname.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ipc.h>
 
 #include <asm/uaccess.h>
index 12b9f352595f44e26c3f5730d3a84e8557d8cca8..4491f4cb26953c1582e0344311b62fe82b956900 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/perf_event.h>
 
 enum direction {
index b351770cbdd6aded05ca53554b30c8716a24a4ce..3107381e576d6f78431d0ccde6c73114ae387944 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
index 07ec8a865c1d3fc122232e5aa2273814640a9e5a..e11b5fcb70ebe07d0bf7fd677a9c61943728d169 100644 (file)
@@ -329,6 +329,18 @@ endmenu  # Tilera-specific configuration
 
 menu "Bus options"
 
+config PCI
+       bool "PCI support"
+       default y
+       select PCI_DOMAINS
+       ---help---
+         Enable PCI root complex support, so PCIe endpoint devices can
+         be attached to the Tile chip.  Many, but not all, PCI devices
+         are supported under Tilera's root complex driver.
+
+config PCI_DOMAINS
+       bool
+
 config NO_IOMEM
        def_bool !PCI
 
index c5741da4eeac8dd47e45397b74be71f8890ed8ca..14a3f8556ace46362a96c80851c4e656d5d7dcee 100644 (file)
@@ -137,4 +137,56 @@ static inline void finv_buffer(void *buffer, size_t size)
        mb_incoherent();
 }
 
+/*
+ * Flush & invalidate a VA range that is homed remotely on a single core,
+ * waiting until the memory controller holds the flushed values.
+ */
+static inline void finv_buffer_remote(void *buffer, size_t size)
+{
+       char *p;
+       int i;
+
+       /*
+        * Flush and invalidate the buffer out of the local L1/L2
+        * and request the home cache to flush and invalidate as well.
+        */
+       __finv_buffer(buffer, size);
+
+       /*
+        * Wait for the home cache to acknowledge that it has processed
+        * all the flush-and-invalidate requests.  This does not mean
+        * that the flushed data has reached the memory controller yet,
+        * but it does mean the home cache is processing the flushes.
+        */
+       __insn_mf();
+
+       /*
+        * Issue a load to the last cache line, which can't complete
+        * until all the previously-issued flushes to the same memory
+        * controller have also completed.  If we weren't striping
+        * memory, that one load would be sufficient, but since we may
+        * be, we also need to back up to the last load issued to
+        * another memory controller, which would be the point where
+        * we crossed an 8KB boundary (the granularity of striping
+        * across memory controllers).  Keep backing up and doing this
+        * until we are before the beginning of the buffer, or have
+        * hit all the controllers.
+        */
+       for (i = 0, p = (char *)buffer + size - 1;
+            i < (1 << CHIP_LOG_NUM_MSHIMS()) && p >= (char *)buffer;
+            ++i) {
+               const unsigned long STRIPE_WIDTH = 8192;
+
+               /* Force a load instruction to issue. */
+               *(volatile char *)p;
+
+               /* Jump to end of previous stripe. */
+               p -= STRIPE_WIDTH;
+               p = (char *)((unsigned long)p | (STRIPE_WIDTH - 1));
+       }
+
+       /* Wait for the loads (and thus flushes) to have completed. */
+       __insn_mf();
+}
+
 #endif /* _ASM_TILE_CACHEFLUSH_H */
index ee43328713abf2ace9f76e885e9e26ce7b615b3a..d3cbb9b14cbe4b7950575c46b6f8b34312f42a78 100644 (file)
@@ -55,9 +55,6 @@ extern void iounmap(volatile void __iomem *addr);
 #define ioremap_writethrough(physaddr, size)   ioremap(physaddr, size)
 #define ioremap_fullcache(physaddr, size)      ioremap(physaddr, size)
 
-void __iomem *ioport_map(unsigned long port, unsigned int len);
-extern inline void ioport_unmap(void __iomem *addr) {}
-
 #define mmiowb()
 
 /* Conversion between virtual and physical mappings.  */
@@ -189,12 +186,22 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
  * we never run, uses them unconditionally.
  */
 
-static inline int ioport_panic(void)
+static inline long ioport_panic(void)
 {
        panic("inb/outb and friends do not exist on tile");
        return 0;
 }
 
+static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+       return (void __iomem *) ioport_panic();
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+       ioport_panic();
+}
+
 static inline u8 inb(unsigned long addr)
 {
        return ioport_panic();
diff --git a/arch/tile/include/asm/pci-bridge.h b/arch/tile/include/asm/pci-bridge.h
deleted file mode 100644 (file)
index e853b0e..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation, version 2.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- *   NON INFRINGEMENT.  See the GNU General Public License for
- *   more details.
- */
-
-#ifndef _ASM_TILE_PCI_BRIDGE_H
-#define _ASM_TILE_PCI_BRIDGE_H
-
-#include <linux/ioport.h>
-#include <linux/pci.h>
-
-struct device_node;
-struct pci_controller;
-
-/*
- * pci_io_base returns the memory address at which you can access
- * the I/O space for PCI bus number `bus' (or NULL on error).
- */
-extern void __iomem *pci_bus_io_base(unsigned int bus);
-extern unsigned long pci_bus_io_base_phys(unsigned int bus);
-extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
-
-/* Allocate a new PCI host bridge structure */
-extern struct pci_controller *pcibios_alloc_controller(void);
-
-/* Helper function for setting up resources */
-extern void pci_init_resource(struct resource *res, unsigned long start,
-                             unsigned long end, int flags, char *name);
-
-/* Get the PCI host controller for a bus */
-extern struct pci_controller *pci_bus_to_hose(int bus);
-
-/*
- * Structure of a PCI controller (host bridge)
- */
-struct pci_controller {
-       int index;              /* PCI domain number */
-       struct pci_bus *root_bus;
-
-       int first_busno;
-       int last_busno;
-
-       int hv_cfg_fd[2];       /* config{0,1} fds for this PCIe controller */
-       int hv_mem_fd;          /* fd to Hypervisor for MMIO operations */
-
-       struct pci_ops *ops;
-
-       int irq_base;           /* Base IRQ from the Hypervisor */
-       int plx_gen1;           /* flag for PLX Gen 1 configuration */
-
-       /* Address ranges that are routed to this controller/bridge. */
-       struct resource mem_resources[3];
-};
-
-static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
-{
-       return bus->sysdata;
-}
-
-extern void setup_indirect_pci_nomap(struct pci_controller *hose,
-                              void __iomem *cfg_addr, void __iomem *cfg_data);
-extern void setup_indirect_pci(struct pci_controller *hose,
-                              u32 cfg_addr, u32 cfg_data);
-extern void setup_grackle(struct pci_controller *hose);
-
-extern unsigned char common_swizzle(struct pci_dev *, unsigned char *);
-
-/*
- *   The following code swizzles for exactly one bridge.  The routine
- *   common_swizzle below handles multiple bridges.  But there are a
- *   some boards that don't follow the PCI spec's suggestion so we
- *   break this piece out separately.
- */
-static inline unsigned char bridge_swizzle(unsigned char pin,
-               unsigned char idsel)
-{
-       return (((pin-1) + idsel) % 4) + 1;
-}
-
-/*
- * The following macro is used to lookup irqs in a standard table
- * format for those PPC systems that do not already have PCI
- * interrupts properly routed.
- */
-/* FIXME - double check this */
-#define PCI_IRQ_TABLE_LOOKUP ({ \
-       long _ctl_ = -1; \
-       if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
-               _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
-       _ctl_; \
-})
-
-/*
- * Scan the buses below a given PCI host bridge and assign suitable
- * resources to all devices found.
- */
-extern int pciauto_bus_scan(struct pci_controller *, int);
-
-#ifdef CONFIG_PCI
-extern unsigned long pci_address_to_pio(phys_addr_t address);
-#else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-       return (unsigned long)-1;
-}
-#endif
-
-#endif /* _ASM_TILE_PCI_BRIDGE_H */
index b0c15da2d5d58e91dedb4fd21978a7506683c65c..c3fc458a0d323485557c1b6a97db662534fd9c3f 100644 (file)
 #ifndef _ASM_TILE_PCI_H
 #define _ASM_TILE_PCI_H
 
-#include <asm/pci-bridge.h>
+#include <linux/pci.h>
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+       int index;              /* PCI domain number */
+       struct pci_bus *root_bus;
+
+       int first_busno;
+       int last_busno;
+
+       int hv_cfg_fd[2];       /* config{0,1} fds for this PCIe controller */
+       int hv_mem_fd;          /* fd to Hypervisor for MMIO operations */
+
+       struct pci_ops *ops;
+
+       int irq_base;           /* Base IRQ from the Hypervisor */
+       int plx_gen1;           /* flag for PLX Gen 1 configuration */
+
+       /* Address ranges that are routed to this controller/bridge. */
+       struct resource mem_resources[3];
+};
 
 /*
  * The hypervisor maps the entirety of CPA-space as bus addresses, so
  */
 #define PCI_DMA_BUS_IS_PHYS     1
 
-struct pci_controller *pci_bus_to_hose(int bus);
-unsigned char __init common_swizzle(struct pci_dev *dev, unsigned char *pinp);
 int __init tile_pci_init(void);
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
-void __devinit pcibios_fixup_bus(struct pci_bus *bus);
 
-int __devinit _tile_cfg_read(struct pci_controller *hose,
-                                   int bus,
-                                   int slot,
-                                   int function,
-                                   int offset,
-                                   int size,
-                                   u32 *val);
-int __devinit _tile_cfg_write(struct pci_controller *hose,
-                                    int bus,
-                                    int slot,
-                                    int function,
-                                    int offset,
-                                    int size,
-                                    u32 val);
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
 
-/*
- * These are used to to config reads and writes in the early stages of
- * setup before the driver infrastructure has been set up enough to be
- * able to do config reads and writes.
- */
-#define early_cfg_read(where, size, value) \
-       _tile_cfg_read(controller, \
-                      current_bus, \
-                      pci_slot, \
-                      pci_fn, \
-                      where, \
-                      size, \
-                      value)
-
-#define early_cfg_write(where, size, value) \
-       _tile_cfg_write(controller, \
-                      current_bus, \
-                      pci_slot, \
-                      pci_fn, \
-                      where, \
-                      size, \
-                      value)
-
-
-
-#define PCICFG_BYTE    1
-#define PCICFG_WORD    2
-#define PCICFG_DWORD   4
+void __devinit pcibios_fixup_bus(struct pci_bus *bus);
 
 #define        TILE_NUM_PCIE   2
 
@@ -88,33 +66,33 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 
 /*
- * I/O space is currently not supported.
+ * pcibios_assign_all_busses() tells whether or not the bus numbers
+ * should be reassigned, in case the BIOS didn't do it correctly, or
+ * in case we don't have a BIOS and we want to let Linux do it.
  */
+static inline int pcibios_assign_all_busses(void)
+{
+       return 1;
+}
 
-#define TILE_PCIE_LOWER_IO             0x0
-#define TILE_PCIE_UPPER_IO             0x10000
-#define TILE_PCIE_PCIE_IO_SIZE         0x0000FFFF
-
-#define _PAGE_NO_CACHE         0
-#define _PAGE_GUARDED          0
-
-
-#define pcibios_assign_all_busses()    pci_assign_all_buses
-extern int pci_assign_all_buses;
-
+/*
+ * No special bus mastering setup handling.
+ */
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
-       /* No special bus mastering setup handling */
 }
 
 #define PCIBIOS_MIN_MEM                0
-#define PCIBIOS_MIN_IO         TILE_PCIE_LOWER_IO
+#define PCIBIOS_MIN_IO         0
 
 /*
  * This flag tells if the platform is TILEmpower that needs
  * special configuration for the PLX switch chip.
  */
-extern int blade_pci;
+extern int tile_plx_gen1;
+
+/* Use any cpu for PCI. */
+#define cpumask_of_pcibus(bus) cpu_online_mask
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
 #include <asm-generic/pci-dma-compat.h>
@@ -122,7 +100,4 @@ extern int blade_pci;
 /* generic pci stuff */
 #include <asm-generic/pci.h>
 
-/* Use any cpu for PCI. */
-#define cpumask_of_pcibus(bus) cpu_online_mask
-
 #endif /* _ASM_TILE_PCI_H */
index 1747ff3946b2ef50dea6e9591730238f3c720d08..a9e7c8760334b8430b2a8c30c5a6954d4ab4cbcd 100644 (file)
@@ -292,8 +292,18 @@ extern int kstack_hash;
 /* Are we using huge pages in the TLB for kernel data? */
 extern int kdata_huge;
 
+/* Support standard Linux prefetching. */
+#define ARCH_HAS_PREFETCH
+#define prefetch(x) __builtin_prefetch(x)
 #define PREFETCH_STRIDE CHIP_L2_LINE_SIZE()
 
+/* Bring a value into the L1D, faulting the TLB if necessary. */
+#ifdef __tilegx__
+#define prefetch_L1(x) __insn_prefetch_l1_fault((void *)(x))
+#else
+#define prefetch_L1(x) __insn_prefetch_L1((void *)(x))
+#endif
+
 #else /* __ASSEMBLY__ */
 
 /* Do some slow action (e.g. read a slow SPR). */
diff --git a/arch/tile/include/hv/drv_xgbe_impl.h b/arch/tile/include/hv/drv_xgbe_impl.h
new file mode 100644 (file)
index 0000000..3a73b2b
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+/**
+ * @file drivers/xgbe/impl.h
+ * Implementation details for the NetIO library.
+ */
+
+#ifndef __DRV_XGBE_IMPL_H__
+#define __DRV_XGBE_IMPL_H__
+
+#include <hv/netio_errors.h>
+#include <hv/netio_intf.h>
+#include <hv/drv_xgbe_intf.h>
+
+
+/** How many groups we have (log2). */
+#define LOG2_NUM_GROUPS (12)
+/** How many groups we have. */
+#define NUM_GROUPS (1 << LOG2_NUM_GROUPS)
+
+/** Number of output requests we'll buffer per tile. */
+#define EPP_REQS_PER_TILE (32)
+
+/** Words used in an eDMA command without checksum acceleration. */
+#define EDMA_WDS_NO_CSUM      8
+/** Words used in an eDMA command with checksum acceleration. */
+#define EDMA_WDS_CSUM        10
+/** Total available words in the eDMA command FIFO. */
+#define EDMA_WDS_TOTAL      128
+
+
+/*
+ * FIXME: These definitions are internal and should have underscores!
+ * NOTE: The actual numeric values here are intentional and allow us to
+ * optimize the concept "if small ... else if large ... else ...", by
+ * checking for the low bit being set, and then for non-zero.
+ * These are used as array indices, so they must have the values (0, 1, 2)
+ * in some order.
+ */
+#define SIZE_SMALL (1)       /**< Small packet queue. */
+#define SIZE_LARGE (2)       /**< Large packet queue. */
+#define SIZE_JUMBO (0)       /**< Jumbo packet queue. */
+
+/** The number of "SIZE_xxx" values. */
+#define NETIO_NUM_SIZES 3
+
+
+/*
+ * Default numbers of packets for IPP drivers.  These values are chosen
+ * such that CIPP1 will not overflow its L2 cache.
+ */
+
+/** The default number of small packets. */
+#define NETIO_DEFAULT_SMALL_PACKETS 2750
+/** The default number of large packets. */
+#define NETIO_DEFAULT_LARGE_PACKETS 2500
+/** The default number of jumbo packets. */
+#define NETIO_DEFAULT_JUMBO_PACKETS 250
+
+
+/** Log2 of the size of a memory arena. */
+#define NETIO_ARENA_SHIFT      24      /* 16 MB */
+/** Size of a memory arena. */
+#define NETIO_ARENA_SIZE       (1 << NETIO_ARENA_SHIFT)
+
+
+/** A queue of packets.
+ *
+ * This structure partially defines a queue of packets waiting to be
+ * processed.  The queue as a whole is written to by an interrupt handler and
+ * read by non-interrupt code; this data structure is what's touched by the
+ * interrupt handler.  The other part of the queue state, the read offset, is
+ * kept in user space, not in hypervisor space, so it is in a separate data
+ * structure.
+ *
+ * The read offset (__packet_receive_read in the user part of the queue
+ * structure) points to the next packet to be read. When the read offset is
+ * equal to the write offset, the queue is empty; therefore the queue must
+ * contain one more slot than the required maximum queue size.
+ *
+ * Here's an example of all 3 state variables and what they mean.  All
+ * pointers move left to right.
+ *
+ * @code
+ *   I   I   V   V   V   V   I   I   I   I
+ *   0   1   2   3   4   5   6   7   8   9  10
+ *           ^       ^       ^               ^
+ *           |               |               |
+ *           |               |               __last_packet_plus_one
+ *           |               __buffer_write
+ *           __packet_receive_read
+ * @endcode
+ *
+ * This queue has 10 slots, and thus can hold 9 packets (_last_packet_plus_one
+ * = 10).  The read pointer is at 2, and the write pointer is at 6; thus,
+ * there are valid, unread packets in slots 2, 3, 4, and 5.  The remaining
+ * slots are invalid (do not contain a packet).
+ */
+typedef struct {
+  /** Byte offset of the next notify packet to be written: zero for the first
+   *  packet on the queue, sizeof (netio_pkt_t) for the second packet on the
+   *  queue, etc. */
+  volatile uint32_t __packet_write;
+
+  /** Offset of the packet after the last valid packet (i.e., when any
+   *  pointer is incremented to this value, it wraps back to zero). */
+  uint32_t __last_packet_plus_one;
+}
+__netio_packet_queue_t;
+
+
+/** A queue of buffers.
+ *
+ * This structure partially defines a queue of empty buffers which have been
+ * obtained via requests to the IPP.  (The elements of the queue are packet
+ * handles, which are transformed into a full netio_pkt_t when the buffer is
+ * retrieved.)  The queue as a whole is written to by an interrupt handler and
+ * read by non-interrupt code; this data structure is what's touched by the
+ * interrupt handler.  The other parts of the queue state, the read offset and
+ * requested write offset, are kept in user space, not in hypervisor space, so
+ * they are in a separate data structure.
+ *
+ * The read offset (__buffer_read in the user part of the queue structure)
+ * points to the next buffer to be read. When the read offset is equal to the
+ * write offset, the queue is empty; therefore the queue must contain one more
+ * slot than the required maximum queue size.
+ *
+ * The requested write offset (__buffer_requested_write in the user part of
+ * the queue structure) points to the slot which will hold the next buffer we
+ * request from the IPP, once we get around to sending such a request.  When
+ * the requested write offset is equal to the write offset, no requests for
+ * new buffers are outstanding; when the requested write offset is one greater
+ * than the read offset, no more requests may be sent.
+ *
+ * Note that, unlike the packet_queue, the buffer_queue places incoming
+ * buffers at decreasing addresses.  This makes the check for "is it time to
+ * wrap the buffer pointer" cheaper in the assembly code which receives new
+ * buffers, and means that the value which defines the queue size,
+ * __last_buffer, is different than in the packet queue.  Also, the offset
+ * used in the packet_queue is already scaled by the size of a packet; here we
+ * use unscaled slot indices for the offsets.  (These differences are
+ * historical, and in the future it's possible that the packet_queue will look
+ * more like this queue.)
+ *
+ * @code
+ * Here's an example of all 4 state variables and what they mean.  Remember:
+ * all pointers move right to left.
+ *
+ *   V   V   V   I   I   R   R   V   V   V
+ *   0   1   2   3   4   5   6   7   8   9
+ *           ^       ^       ^           ^
+ *           |       |       |           |
+ *           |       |       |           __last_buffer
+ *           |       |       __buffer_write
+ *           |       __buffer_requested_write
+ *           __buffer_read
+ * @endcode
+ *
+ * This queue has 10 slots, and thus can hold 9 buffers (_last_buffer = 9).
+ * The read pointer is at 2, and the write pointer is at 6; thus, there are
+ * valid, unread buffers in slots 2, 1, 0, 9, 8, and 7.  The requested write
+ * pointer is at 4; thus, requests have been made to the IPP for buffers which
+ * will be placed in slots 6 and 5 when they arrive.  Finally, the remaining
+ * slots are invalid (do not contain a buffer).
+ */
+typedef struct
+{
+  /** Ordinal number of the next buffer to be written: 0 for the first slot in
+   *  the queue, 1 for the second slot in the queue, etc. */
+  volatile uint32_t __buffer_write;
+
+  /** Ordinal number of the last buffer (i.e., when any pointer is decremented
+   *  below zero, it is reloaded with this value). */
+  uint32_t __last_buffer;
+}
+__netio_buffer_queue_t;
+
+
+/**
+ * An object for providing Ethernet packets to a process.
+ */
+typedef struct __netio_queue_impl_t
+{
+  /** The queue of packets waiting to be received. */
+  __netio_packet_queue_t __packet_receive_queue;
+  /** The intr bit mask that IDs this device. */
+  unsigned int __intr_id;
+  /** Offset to queues of empty buffers, one per size. */
+  uint32_t __buffer_queue[NETIO_NUM_SIZES];
+  /** The address of the first EPP tile, or -1 if no EPP. */
+  /* ISSUE: Actually this is always "0" or "~0". */
+  uint32_t __epp_location;
+  /** The queue ID that this queue represents. */
+  unsigned int __queue_id;
+  /** Number of acknowledgements received. */
+  volatile uint32_t __acks_received;
+  /** Last completion number received for packet_sendv. */
+  volatile uint32_t __last_completion_rcv;
+  /** Number of packets allowed to be outstanding. */
+  uint32_t __max_outstanding;
+  /** First VA available for packets. */
+  void* __va_0;
+  /** First VA in second range available for packets. */
+  void* __va_1;
+  /** Padding to align the "__packets" field to the size of a netio_pkt_t. */
+  uint32_t __padding[3];
+  /** The packets themselves. */
+  netio_pkt_t __packets[0];
+}
+netio_queue_impl_t;
+
+
+/**
+ * An object for managing the user end of a NetIO queue.
+ */
+typedef struct __netio_queue_user_impl_t
+{
+  /** The next incoming packet to be read. */
+  uint32_t __packet_receive_read;
+  /** The next empty buffers to be read, one index per size. */
+  uint8_t __buffer_read[NETIO_NUM_SIZES];
+  /** Where the empty buffer we next request from the IPP will go, one index
+   * per size. */
+  uint8_t __buffer_requested_write[NETIO_NUM_SIZES];
+  /** PCIe interface flag. */
+  uint8_t __pcie;
+  /** Number of packets left to be received before we send a credit update. */
+  uint32_t __receive_credit_remaining;
+  /** Value placed in __receive_credit_remaining when it reaches zero. */
+  uint32_t __receive_credit_interval;
+  /** First fast I/O routine index. */
+  uint32_t __fastio_index;
+  /** Number of acknowledgements expected. */
+  uint32_t __acks_outstanding;
+  /** Last completion number requested. */
+  uint32_t __last_completion_req;
+  /** File descriptor for driver. */
+  int __fd;
+}
+netio_queue_user_impl_t;
+
+
+#define NETIO_GROUP_CHUNK_SIZE   64   /**< Max # groups in one IPP request */
+#define NETIO_BUCKET_CHUNK_SIZE  64   /**< Max # buckets in one IPP request */
+
+
+/** Internal structure used to convey packet send information to the
+ * hypervisor.  FIXME: Actually, it's not used for that anymore, but
+ * netio_packet_send() still uses it internally.
+ */
+typedef struct
+{
+  uint16_t flags;              /**< Packet flags (__NETIO_SEND_FLG_xxx) */
+  uint16_t transfer_size;      /**< Size of packet */
+  uint32_t va;                 /**< VA of start of packet */
+  __netio_pkt_handle_t handle; /**< Packet handle */
+  uint32_t csum0;              /**< First checksum word */
+  uint32_t csum1;              /**< Second checksum word */
+}
+__netio_send_cmd_t;
+
+
+/** Flags used in two contexts:
+ *  - As the "flags" member in the __netio_send_cmd_t, above; used only
+ *    for netio_pkt_send_{prepare,commit}.
+ *  - As part of the flags passed to the various send packet fast I/O calls.
+ */
+
+/** Need acknowledgement on this packet.  Note that some code in the
+ *  normal send_pkt fast I/O handler assumes that this is equal to 1. */
+#define __NETIO_SEND_FLG_ACK    0x1
+
+/** Do checksum on this packet.  (Only used with the __netio_send_cmd_t;
+ *  normal packet sends use a special fast I/O index to denote checksumming,
+ *  and multi-segment sends test the checksum descriptor.) */
+#define __NETIO_SEND_FLG_CSUM   0x2
+
+/** Get a completion on this packet.  Only used with multi-segment sends.  */
+#define __NETIO_SEND_FLG_COMPLETION 0x4
+
+/** Position of the number-of-extra-segments value in the flags word.
+    Only used with multi-segment sends. */
+#define __NETIO_SEND_FLG_XSEG_SHIFT 3
+
+/** Width of the number-of-extra-segments value in the flags word. */
+#define __NETIO_SEND_FLG_XSEG_WIDTH 2
+
+#endif /* __DRV_XGBE_IMPL_H__ */
diff --git a/arch/tile/include/hv/drv_xgbe_intf.h b/arch/tile/include/hv/drv_xgbe_intf.h
new file mode 100644 (file)
index 0000000..146e47d
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+/**
+ * @file drv_xgbe_intf.h
+ * Interface to the hypervisor XGBE driver.
+ */
+
+#ifndef __DRV_XGBE_INTF_H__
+#define __DRV_XGBE_INTF_H__
+
+/**
+ * An object for forwarding VAs and PAs to the hypervisor.
+ * @ingroup types
+ *
+ * This allows the supervisor to specify a number of areas of memory to
+ * store packet buffers.
+ */
+typedef struct
+{
+  /** The physical address of the memory. */
+  HV_PhysAddr pa;
+  /** Page table entry for the memory.  This is only used to derive the
+   *  memory's caching mode; the PA bits are ignored. */
+  HV_PTE pte;
+  /** The virtual address of the memory. */
+  HV_VirtAddr va;
+  /** Size (in bytes) of the memory area. */
+  int size;
+
+}
+netio_ipp_address_t;
+
+/** The various pread/pwrite offsets into the hypervisor-level driver.
+ * @ingroup types
+ */
+typedef enum
+{
+  /** Inform the Linux driver of the address of the NetIO arena memory.
+   *  This offset is actually only used to convey information from netio
+   *  to the Linux driver; it never makes it from there to the hypervisor.
+   *  Write-only; takes a uint32_t specifying the VA address. */
+  NETIO_FIXED_ADDR               = 0x5000000000000000ULL,
+
+  /** Inform the Linux driver of the size of the NetIO arena memory.
+   *  This offset is actually only used to convey information from netio
+   *  to the Linux driver; it never makes it from there to the hypervisor.
+   *  Write-only; takes a uint32_t specifying the VA size. */
+  NETIO_FIXED_SIZE               = 0x5100000000000000ULL,
+
+  /** Register current tile with IPP.  Write then read: write, takes a
+   *  netio_input_config_t, read returns a pointer to a netio_queue_impl_t. */
+  NETIO_IPP_INPUT_REGISTER_OFF   = 0x6000000000000000ULL,
+
+  /** Unregister current tile from IPP.  Write-only, takes a dummy argument. */
+  NETIO_IPP_INPUT_UNREGISTER_OFF = 0x6100000000000000ULL,
+
+  /** Start packets flowing.  Write-only, takes a dummy argument. */
+  NETIO_IPP_INPUT_INIT_OFF       = 0x6200000000000000ULL,
+
+  /** Stop packets flowing.  Write-only, takes a dummy argument. */
+  NETIO_IPP_INPUT_UNINIT_OFF     = 0x6300000000000000ULL,
+
+  /** Configure group (typically we group on VLAN).  Write-only: takes an
+   *  array of netio_group_t's, low 24 bits of the offset is the base group
+   *  number times the size of a netio_group_t. */
+  NETIO_IPP_INPUT_GROUP_CFG_OFF  = 0x6400000000000000ULL,
+
+  /** Configure bucket.  Write-only: takes an array of netio_bucket_t's, low
+   *  24 bits of the offset is the base bucket number times the size of a
+   *  netio_bucket_t. */
+  NETIO_IPP_INPUT_BUCKET_CFG_OFF = 0x6500000000000000ULL,
+
+  /** Get/set a parameter.  Read or write: read or write data is the parameter
+   *  value, low 32 bits of the offset is a __netio_getset_offset_t. */
+  NETIO_IPP_PARAM_OFF            = 0x6600000000000000ULL,
+
+  /** Get fast I/O index.  Read-only; returns a 4-byte base index value. */
+  NETIO_IPP_GET_FASTIO_OFF       = 0x6700000000000000ULL,
+
+  /** Configure hijack IP address.  Packets with this IPv4 dest address
+   *  go to bucket NETIO_NUM_BUCKETS - 1.  Write-only: takes an IP address
+   *  in some standard form.  FIXME: Define the form! */
+  NETIO_IPP_INPUT_HIJACK_CFG_OFF  = 0x6800000000000000ULL,
+
+  /**
+   * Offsets beyond this point are reserved for the supervisor (although that
+   * enforcement must be done by the supervisor driver itself).
+   */
+  NETIO_IPP_USER_MAX_OFF         = 0x6FFFFFFFFFFFFFFFULL,
+
+  /** Register I/O memory.  Write-only, takes a netio_ipp_address_t. */
+  NETIO_IPP_IOMEM_REGISTER_OFF   = 0x7000000000000000ULL,
+
+  /** Unregister I/O memory.  Write-only, takes a netio_ipp_address_t. */
+  NETIO_IPP_IOMEM_UNREGISTER_OFF = 0x7100000000000000ULL,
+
+  /* Offsets greater than 0x7FFFFFFF can't be used directly from Linux
+   * userspace code due to limitations in the pread/pwrite syscalls. */
+
+  /** Drain LIPP buffers. */
+  NETIO_IPP_DRAIN_OFF              = 0xFA00000000000000ULL,
+
+  /** Supply a netio_ipp_address_t to be used as shared memory for the
+   *  LEPP command queue. */
+  NETIO_EPP_SHM_OFF              = 0xFB00000000000000ULL,
+
+  /* 0xFC... is currently unused. */
+
+  /** Stop IPP/EPP tiles.  Write-only, takes a dummy argument.  */
+  NETIO_IPP_STOP_SHIM_OFF        = 0xFD00000000000000ULL,
+
+  /** Start IPP/EPP tiles.  Write-only, takes a dummy argument.  */
+  NETIO_IPP_START_SHIM_OFF       = 0xFE00000000000000ULL,
+
+  /** Supply packet arena.  Write-only, takes an array of
+    * netio_ipp_address_t values. */
+  NETIO_IPP_ADDRESS_OFF          = 0xFF00000000000000ULL,
+} netio_hv_offset_t;
+
+/** Extract the base offset from an offset */
+#define NETIO_BASE_OFFSET(off)    ((off) & 0xFF00000000000000ULL)
+/** Extract the local offset from an offset */
+#define NETIO_LOCAL_OFFSET(off)   ((off) & 0x00FFFFFFFFFFFFFFULL)
+
+
+/**
+ * Get/set offset.
+ */
+typedef union
+{
+  struct
+  {
+    uint64_t addr:48;        /**< Class-specific address */
+    unsigned int class:8;    /**< Class (e.g., NETIO_PARAM) */
+    unsigned int opcode:8;   /**< High 8 bits of NETIO_IPP_PARAM_OFF */
+  }
+  bits;                      /**< Bitfields */
+  uint64_t word;             /**< Aggregated value to use as the offset */
+}
+__netio_getset_offset_t;
+
+/**
+ * Fast I/O index offsets (must be contiguous).
+ */
+typedef enum
+{
+  NETIO_FASTIO_ALLOCATE         = 0, /**< Get empty packet buffer */
+  NETIO_FASTIO_FREE_BUFFER      = 1, /**< Give buffer back to IPP */
+  NETIO_FASTIO_RETURN_CREDITS   = 2, /**< Give credits to IPP */
+  NETIO_FASTIO_SEND_PKT_NOCK    = 3, /**< Send a packet, no checksum */
+  NETIO_FASTIO_SEND_PKT_CK      = 4, /**< Send a packet, with checksum */
+  NETIO_FASTIO_SEND_PKT_VEC     = 5, /**< Send a vector of packets */
+  NETIO_FASTIO_SENDV_PKT        = 6, /**< Sendv one packet */
+  NETIO_FASTIO_NUM_INDEX        = 7, /**< Total number of fast I/O indices */
+} netio_fastio_index_t;
+
+/** 3-word return type for Fast I/O call. */
+typedef struct
+{
+  int err;            /**< Error code. */
+  uint32_t val0;      /**< Value.  Meaning depends upon the specific call. */
+  uint32_t val1;      /**< Value.  Meaning depends upon the specific call. */
+} netio_fastio_rv3_t;
+
+/** 0-argument fast I/O call */
+int __netio_fastio0(uint32_t fastio_index);
+/** 1-argument fast I/O call */
+int __netio_fastio1(uint32_t fastio_index, uint32_t arg0);
+/** 3-argument fast I/O call, 2-word return value */
+netio_fastio_rv3_t __netio_fastio3_rv3(uint32_t fastio_index, uint32_t arg0,
+                                       uint32_t arg1, uint32_t arg2);
+/** 4-argument fast I/O call */
+int __netio_fastio4(uint32_t fastio_index, uint32_t arg0, uint32_t arg1,
+                    uint32_t arg2, uint32_t arg3);
+/** 6-argument fast I/O call */
+int __netio_fastio6(uint32_t fastio_index, uint32_t arg0, uint32_t arg1,
+                    uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5);
+/** 9-argument fast I/O call */
+int __netio_fastio9(uint32_t fastio_index, uint32_t arg0, uint32_t arg1,
+                    uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5,
+                    uint32_t arg6, uint32_t arg7, uint32_t arg8);
+
+/** Allocate an empty packet.
+ * @param fastio_index Fast I/O index.
+ * @param size Size of the packet to allocate.
+ */
+#define __netio_fastio_allocate(fastio_index, size) \
+  __netio_fastio1((fastio_index) + NETIO_FASTIO_ALLOCATE, size)
+
+/** Free a buffer.
+ * @param fastio_index Fast I/O index.
+ * @param handle Handle for the packet to free.
+ */
+#define __netio_fastio_free_buffer(fastio_index, handle) \
+  __netio_fastio1((fastio_index) + NETIO_FASTIO_FREE_BUFFER, handle)
+
+/** Increment our receive credits.
+ * @param fastio_index Fast I/O index.
+ * @param credits Number of credits to add.
+ */
+#define __netio_fastio_return_credits(fastio_index, credits) \
+  __netio_fastio1((fastio_index) + NETIO_FASTIO_RETURN_CREDITS, credits)
+
+/** Send packet, no checksum.
+ * @param fastio_index Fast I/O index.
+ * @param ackflag Nonzero if we want an ack.
+ * @param size Size of the packet.
+ * @param va Virtual address of start of packet.
+ * @param handle Packet handle.
+ */
+#define __netio_fastio_send_pkt_nock(fastio_index, ackflag, size, va, handle) \
+  __netio_fastio4((fastio_index) + NETIO_FASTIO_SEND_PKT_NOCK, ackflag, \
+                  size, va, handle)
+
+/** Send packet, calculate checksum.
+ * @param fastio_index Fast I/O index.
+ * @param ackflag Nonzero if we want an ack.
+ * @param size Size of the packet.
+ * @param va Virtual address of start of packet.
+ * @param handle Packet handle.
+ * @param csum0 Shim checksum header.
+ * @param csum1 Checksum seed.
+ */
+#define __netio_fastio_send_pkt_ck(fastio_index, ackflag, size, va, handle, \
+                                   csum0, csum1) \
+  __netio_fastio6((fastio_index) + NETIO_FASTIO_SEND_PKT_CK, ackflag, \
+                  size, va, handle, csum0, csum1)
+
+
+/** Format for the "csum0" argument to the __netio_fastio_send routines
+ * and LEPP.  Note that this is currently exactly identical to the
+ * ShimProtocolOffloadHeader.
+ */
+typedef union
+{
+  struct
+  {
+    unsigned int start_byte:7;       /**< The first byte to be checksummed */
+    unsigned int count:14;           /**< Number of bytes to be checksummed. */
+    unsigned int destination_byte:7; /**< The byte to write the checksum to. */
+    unsigned int reserved:4;         /**< Reserved. */
+  } bits;                            /**< Decomposed method of access. */
+  unsigned int word;                 /**< To send out the IDN. */
+} __netio_checksum_header_t;
+
+
+/** Sendv packet with 1 or 2 segments.
+ * @param fastio_index Fast I/O index.
+ * @param flags Ack/csum/notify flags in low 3 bits; number of segments minus
+ *        1 in next 2 bits; expected checksum in high 16 bits.
+ * @param confno Confirmation number to request, if notify flag set.
+ * @param csum0 Checksum descriptor; if zero, no checksum.
+ * @param va_F Virtual address of first segment.
+ * @param va_L Virtual address of last segment, if 2 segments.
+ * @param len_F_L Length of first segment in low 16 bits; length of last
+ *        segment, if 2 segments, in high 16 bits.
+ */
+#define __netio_fastio_sendv_pkt_1_2(fastio_index, flags, confno, csum0, \
+                                     va_F, va_L, len_F_L) \
+  __netio_fastio6((fastio_index) + NETIO_FASTIO_SENDV_PKT, flags, confno, \
+                  csum0, va_F, va_L, len_F_L)
+
+/** Send packet on PCIe interface.
+ * @param fastio_index Fast I/O index.
+ * @param flags Ack/csum/notify flags in low 3 bits.
+ * @param confno Confirmation number to request, if notify flag set.
+ * @param csum0 Checksum descriptor; Hard wired 0, not needed for PCIe.
+ * @param va_F Virtual address of the packet buffer.
+ * @param va_L Virtual address of last segment, if 2 segments. Hard wired 0.
+ * @param len_F_L Length of the packet buffer in low 16 bits.
+ */
+#define __netio_fastio_send_pcie_pkt(fastio_index, flags, confno, csum0, \
+                                     va_F, va_L, len_F_L) \
+  __netio_fastio6((fastio_index) + PCIE_FASTIO_SENDV_PKT, flags, confno, \
+                  csum0, va_F, va_L, len_F_L)
+
+/** Sendv packet with 3 or 4 segments.
+ * @param fastio_index Fast I/O index.
+ * @param flags Ack/csum/notify flags in low 3 bits; number of segments minus
+ *        1 in next 2 bits; expected checksum in high 16 bits.
+ * @param confno Confirmation number to request, if notify flag set.
+ * @param csum0 Checksum descriptor; if zero, no checksum.
+ * @param va_F Virtual address of first segment.
+ * @param va_L Virtual address of last segment (third segment if 3 segments,
+ *        fourth segment if 4 segments).
+ * @param len_F_L Length of first segment in low 16 bits; length of last
+ *        segment in high 16 bits.
+ * @param va_M0 Virtual address of "middle 0" segment; this segment is sent
+ *        second when there are three segments, and third if there are four.
+ * @param va_M1 Virtual address of "middle 1" segment; this segment is sent
+ *        second when there are four segments.
+ * @param len_M0_M1 Length of middle 0 segment in low 16 bits; length of middle
+ *        1 segment, if 4 segments, in high 16 bits.
+ */
+#define __netio_fastio_sendv_pkt_3_4(fastio_index, flags, confno, csum0, va_F, \
+                                     va_L, len_F_L, va_M0, va_M1, len_M0_M1) \
+  __netio_fastio9((fastio_index) + NETIO_FASTIO_SENDV_PKT, flags, confno, \
+                  csum0, va_F, va_L, len_F_L, va_M0, va_M1, len_M0_M1)
+
+/** Send vector of packets.
+ * @param fastio_index Fast I/O index.
+ * @param seqno Number of packets transmitted so far on this interface;
+ *        used to decide which packets should be acknowledged.
+ * @param nentries Number of entries in vector.
+ * @param va Virtual address of start of vector entry array.
+ * @return 3-word netio_fastio_rv3_t structure.  The structure's err member
+ *         is an error code, or zero if no error.  The val0 member is the
+ *         updated value of seqno; it has been incremented by 1 for each
+ *         packet sent.  That increment may be less than nentries if an
+ *         error occured, or if some of the entries in the vector contain
+ *         handles equal to NETIO_PKT_HANDLE_NONE.  The val1 member is the
+ *         updated value of nentries; it has been decremented by 1 for each
+ *         vector entry processed.  Again, that decrement may be less than
+ *         nentries (leaving the returned value positive) if an error
+ *         occurred.
+ */
+#define __netio_fastio_send_pkt_vec(fastio_index, seqno, nentries, va) \
+  __netio_fastio3_rv3((fastio_index) + NETIO_FASTIO_SEND_PKT_VEC, seqno, \
+                      nentries, va)
+
+
+/** An egress DMA command for LEPP. */
+typedef struct
+{
+  /** Is this a TSO transfer?
+   *
+   * NOTE: This field is always 0, to distinguish it from
+   * lepp_tso_cmd_t.  It must come first!
+   */
+  uint8_t tso               : 1;
+
+  /** Unused padding bits. */
+  uint8_t _unused           : 3;
+
+  /** Should this packet be sent directly from caches instead of DRAM,
+   * using hash-for-home to locate the packet data?
+   */
+  uint8_t hash_for_home     : 1;
+
+  /** Should we compute a checksum? */
+  uint8_t compute_checksum  : 1;
+
+  /** Is this the final buffer for this packet?
+   *
+   * A single packet can be split over several input buffers (a "gather"
+   * operation).  This flag indicates that this is the last buffer
+   * in a packet.
+   */
+  uint8_t end_of_packet     : 1;
+
+  /** Should LEPP advance 'comp_busy' when this DMA is fully finished? */
+  uint8_t send_completion   : 1;
+
+  /** High bits of Client Physical Address of the start of the buffer
+   *  to be egressed.
+   *
+   *  NOTE: Only 6 bits are actually needed here, as CPAs are
+   *  currently 38 bits.  So two bits could be scavenged from this.
+   */
+  uint8_t cpa_hi;
+
+  /** The number of bytes to be egressed. */
+  uint16_t length;
+
+  /** Low 32 bits of Client Physical Address of the start of the buffer
+   *  to be egressed.
+   */
+  uint32_t cpa_lo;
+
+  /** Checksum information (only used if 'compute_checksum'). */
+  __netio_checksum_header_t checksum_data;
+
+} lepp_cmd_t;
+
+
+/** A chunk of physical memory for a TSO egress. */
+typedef struct
+{
+  /** The low bits of the CPA. */
+  uint32_t cpa_lo;
+  /** The high bits of the CPA. */
+  uint16_t cpa_hi              : 15;
+  /** Should this packet be sent directly from caches instead of DRAM,
+   *  using hash-for-home to locate the packet data?
+   */
+  uint16_t hash_for_home       : 1;
+  /** The length in bytes. */
+  uint16_t length;
+} lepp_frag_t;
+
+
+/** An LEPP command that handles TSO. */
+typedef struct
+{
+  /** Is this a TSO transfer?
+   *
+   *  NOTE: This field is always 1, to distinguish it from
+   *  lepp_cmd_t.  It must come first!
+   */
+  uint8_t tso             : 1;
+
+  /** Unused padding bits. */
+  uint8_t _unused         : 7;
+
+  /** Size of the header[] array in bytes.  It must be in the range
+   *  [40, 127], which are the smallest header for a TCP packet over
+   *  Ethernet and the maximum possible prepend size supported by
+   *  hardware, respectively.  Note that the array storage must be
+   *  padded out to a multiple of four bytes so that the following
+   *  LEPP command is aligned properly.
+   */
+  uint8_t header_size;
+
+  /** Byte offset of the IP header in header[]. */
+  uint8_t ip_offset;
+
+  /** Byte offset of the TCP header in header[]. */
+  uint8_t tcp_offset;
+
+  /** The number of bytes to use for the payload of each packet,
+   *  except of course the last one, which may not have enough bytes.
+   *  This means that each Ethernet packet except the last will have a
+   *  size of header_size + payload_size.
+   */
+  uint16_t payload_size;
+
+  /** The length of the 'frags' array that follows this struct. */
+  uint16_t num_frags;
+
+  /** The actual frags. */
+  lepp_frag_t frags[0 /* Variable-sized; num_frags entries. */];
+
+  /*
+   * The packet header template logically follows frags[],
+   * but you can't declare that in C.
+   *
+   * uint32_t header[header_size_in_words_rounded_up];
+   */
+
+} lepp_tso_cmd_t;
+
+
+/** An LEPP completion ring entry. */
+typedef void* lepp_comp_t;
+
+
+/** Maximum number of frags for one TSO command.  This is adapted from
+ *  linux's "MAX_SKB_FRAGS", and presumably over-estimates by one, for
+ *  our page size of exactly 65536.  We add one for a "body" fragment.
+ */
+#define LEPP_MAX_FRAGS (65536 / HV_PAGE_SIZE_SMALL + 2 + 1)
+
+/** Total number of bytes needed for an lepp_tso_cmd_t. */
+#define LEPP_TSO_CMD_SIZE(num_frags, header_size) \
+  (sizeof(lepp_tso_cmd_t) + \
+   (num_frags) * sizeof(lepp_frag_t) + \
+   (((header_size) + 3) & -4))
+
+/** The size of the lepp "cmd" queue. */
+#define LEPP_CMD_QUEUE_BYTES \
+ (((CHIP_L2_CACHE_SIZE() - 2 * CHIP_L2_LINE_SIZE()) / \
+  (sizeof(lepp_cmd_t) + sizeof(lepp_comp_t))) * sizeof(lepp_cmd_t))
+
+/** The largest possible command that can go in lepp_queue_t::cmds[]. */
+#define LEPP_MAX_CMD_SIZE LEPP_TSO_CMD_SIZE(LEPP_MAX_FRAGS, 128)
+
+/** The largest possible value of lepp_queue_t::cmd_{head, tail} (inclusive).
+ */
+#define LEPP_CMD_LIMIT \
+  (LEPP_CMD_QUEUE_BYTES - LEPP_MAX_CMD_SIZE)
+
+/** The maximum number of completions in an LEPP queue. */
+#define LEPP_COMP_QUEUE_SIZE \
+  ((LEPP_CMD_LIMIT + sizeof(lepp_cmd_t) - 1) / sizeof(lepp_cmd_t))
+
+/** Increment an index modulo the queue size. */
+#define LEPP_QINC(var) \
+  (var = __insn_mnz(var - (LEPP_COMP_QUEUE_SIZE - 1), var + 1))
+
+/** A queue used to convey egress commands from the client to LEPP. */
+typedef struct
+{
+  /** Index of first completion not yet processed by user code.
+   *  If this is equal to comp_busy, there are no such completions.
+   *
+   *  NOTE: This is only read/written by the user.
+   */
+  unsigned int comp_head;
+
+  /** Index of first completion record not yet completed.
+   *  If this is equal to comp_tail, there are no such completions.
+   *  This index gets advanced (modulo LEPP_QUEUE_SIZE) whenever
+   *  a command with the 'completion' bit set is finished.
+   *
+   *  NOTE: This is only written by LEPP, only read by the user.
+   */
+  volatile unsigned int comp_busy;
+
+  /** Index of the first empty slot in the completion ring.
+   *  Entries from this up to but not including comp_head (in ring order)
+   *  can be filled in with completion data.
+   *
+   *  NOTE: This is only read/written by the user.
+   */
+  unsigned int comp_tail;
+
+  /** Byte index of first command enqueued for LEPP but not yet processed.
+   *
+   *  This is always divisible by sizeof(void*) and always <= LEPP_CMD_LIMIT.
+   *
+   *  NOTE: LEPP advances this counter as soon as it no longer needs
+   *  the cmds[] storage for this entry, but the transfer is not actually
+   *  complete (i.e. the buffer pointed to by the command is no longer
+   *  needed) until comp_busy advances.
+   *
+   *  If this is equal to cmd_tail, the ring is empty.
+   *
+   *  NOTE: This is only written by LEPP, only read by the user.
+   */
+  volatile unsigned int cmd_head;
+
+  /** Byte index of first empty slot in the command ring.  This field can
+   *  be incremented up to but not equal to cmd_head (because that would
+   *  mean the ring is empty).
+   *
+   *  This is always divisible by sizeof(void*) and always <= LEPP_CMD_LIMIT.
+   *
+   *  NOTE: This is read/written by the user, only read by LEPP.
+   */
+  volatile unsigned int cmd_tail;
+
+  /** A ring of variable-sized egress DMA commands.
+   *
+   *  NOTE: Only written by the user, only read by LEPP.
+   */
+  char cmds[LEPP_CMD_QUEUE_BYTES]
+    __attribute__((aligned(CHIP_L2_LINE_SIZE())));
+
+  /** A ring of user completion data.
+   *  NOTE: Only read/written by the user.
+   */
+  lepp_comp_t comps[LEPP_COMP_QUEUE_SIZE]
+    __attribute__((aligned(CHIP_L2_LINE_SIZE())));
+} lepp_queue_t;
+
+
+/** An internal helper function for determining the number of entries
+ *  available in a ring buffer, given that there is one sentinel.
+ */
+static inline unsigned int
+_lepp_num_free_slots(unsigned int head, unsigned int tail)
+{
+  /*
+   * One entry is reserved for use as a sentinel, to distinguish
+   * "empty" from "full".  So we compute
+   * (head - tail - 1) % LEPP_QUEUE_SIZE, but without using a slow % operation.
+   */
+  return (head - tail - 1) + ((head <= tail) ? LEPP_COMP_QUEUE_SIZE : 0);
+}
+
+
+/** Returns how many new comp entries can be enqueued. */
+static inline unsigned int
+lepp_num_free_comp_slots(const lepp_queue_t* q)
+{
+  return _lepp_num_free_slots(q->comp_head, q->comp_tail);
+}
+
+static inline int
+lepp_qsub(int v1, int v2)
+{
+  int delta = v1 - v2;
+  return delta + ((delta >> 31) & LEPP_COMP_QUEUE_SIZE);
+}
+
+
+/** FIXME: Check this from linux, via a new "pwrite()" call. */
+#define LIPP_VERSION 1
+
+
+/** We use exactly two bytes of alignment padding. */
+#define LIPP_PACKET_PADDING 2
+
+/** The minimum size of a "small" buffer (including the padding). */
+#define LIPP_SMALL_PACKET_SIZE 128
+
+/*
+ * NOTE: The following two values should total to less than around
+ * 13582, to keep the total size used for "lipp_state_t" below 64K.
+ */
+
+/** The maximum number of "small" buffers.
+ *  This is enough for 53 network cpus with 128 credits.  Note that
+ *  if these are exhausted, we will fall back to using large buffers.
+ */
+#define LIPP_SMALL_BUFFERS 6785
+
+/** The maximum number of "large" buffers.
+ *  This is enough for 53 network cpus with 128 credits.
+ */
+#define LIPP_LARGE_BUFFERS 6785
+
+#endif /* __DRV_XGBE_INTF_H__ */
diff --git a/arch/tile/include/hv/netio_errors.h b/arch/tile/include/hv/netio_errors.h
new file mode 100644 (file)
index 0000000..e1591bf
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+/**
+ * Error codes returned from NetIO routines.
+ */
+
+#ifndef __NETIO_ERRORS_H__
+#define __NETIO_ERRORS_H__
+
+/**
+ * @addtogroup error
+ *
+ * @brief The error codes returned by NetIO functions.
+ *
+ * NetIO functions return 0 (defined as ::NETIO_NO_ERROR) on success, and
+ * a negative value if an error occurs.
+ *
+ * In cases where a NetIO function failed due to a error reported by
+ * system libraries, the error code will be the negation of the
+ * system errno at the time of failure.  The @ref netio_strerror()
+ * function will deliver error strings for both NetIO and system error
+ * codes.
+ *
+ * @{
+ */
+
+/** The set of all NetIO errors. */
+typedef enum
+{
+  /** Operation successfully completed. */
+  NETIO_NO_ERROR        = 0,
+
+  /** A packet was successfully retrieved from an input queue. */
+  NETIO_PKT             = 0,
+
+  /** Largest NetIO error number. */
+  NETIO_ERR_MAX         = -701,
+
+  /** The tile is not registered with the IPP. */
+  NETIO_NOT_REGISTERED  = -701,
+
+  /** No packet was available to retrieve from the input queue. */
+  NETIO_NOPKT           = -702,
+
+  /** The requested function is not implemented. */
+  NETIO_NOT_IMPLEMENTED = -703,
+
+  /** On a registration operation, the target queue already has the maximum
+   *  number of tiles registered for it, and no more may be added.  On a
+   *  packet send operation, the output queue is full and nothing more can
+   *  be queued until some of the queued packets are actually transmitted. */
+  NETIO_QUEUE_FULL      = -704,
+
+  /** The calling process or thread is not bound to exactly one CPU. */
+  NETIO_BAD_AFFINITY    = -705,
+
+  /** Cannot allocate memory on requested controllers. */
+  NETIO_CANNOT_HOME     = -706,
+
+  /** On a registration operation, the IPP specified is not configured
+   *  to support the options requested; for instance, the application
+   *  wants a specific type of tagged headers which the configured IPP
+   *  doesn't support.  Or, the supplied configuration information is
+   *  not self-consistent, or is out of range; for instance, specifying
+   *  both NETIO_RECV and NETIO_NO_RECV, or asking for more than
+   *  NETIO_MAX_SEND_BUFFERS to be preallocated.  On a VLAN or bucket
+   *  configure operation, the number of items, or the base item, was
+   *  out of range.
+   */
+  NETIO_BAD_CONFIG      = -707,
+
+  /** Too many tiles have registered to transmit packets. */
+  NETIO_TOOMANY_XMIT    = -708,
+
+  /** Packet transmission was attempted on a queue which was registered
+      with transmit disabled. */
+  NETIO_UNREG_XMIT      = -709,
+
+  /** This tile is already registered with the IPP. */
+  NETIO_ALREADY_REGISTERED = -710,
+
+  /** The Ethernet link is down. The application should try again later. */
+  NETIO_LINK_DOWN       = -711,
+
+  /** An invalid memory buffer has been specified.  This may be an unmapped
+   * virtual address, or one which does not meet alignment requirements.
+   * For netio_input_register(), this error may be returned when multiple
+   * processes specify different memory regions to be used for NetIO
+   * buffers.  That can happen if these processes specify explicit memory
+   * regions with the ::NETIO_FIXED_BUFFER_VA flag, or if tmc_cmem_init()
+   * has not been called by a common ancestor of the processes.
+   */
+  NETIO_FAULT           = -712,
+
+  /** Cannot combine user-managed shared memory and cache coherence. */
+  NETIO_BAD_CACHE_CONFIG = -713,
+
+  /** Smallest NetIO error number. */
+  NETIO_ERR_MIN         = -713,
+
+#ifndef __DOXYGEN__
+  /** Used internally to mean that no response is needed; never returned to
+   *  an application. */
+  NETIO_NO_RESPONSE     = 1
+#endif
+} netio_error_t;
+
+/** @} */
+
+#endif /* __NETIO_ERRORS_H__ */
diff --git a/arch/tile/include/hv/netio_intf.h b/arch/tile/include/hv/netio_intf.h
new file mode 100644 (file)
index 0000000..8d20972
--- /dev/null
@@ -0,0 +1,2975 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+/**
+ * NetIO interface structures and macros.
+ */
+
+#ifndef __NETIO_INTF_H__
+#define __NETIO_INTF_H__
+
+#include <hv/netio_errors.h>
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__)
+#include <assert.h>
+#define netio_assert assert  /**< Enable assertions from macros */
+#else
+#define netio_assert(...) ((void)(0))  /**< Disable assertions from macros */
+#endif
+
+/*
+ * If none of these symbols are defined, we're building libnetio in an
+ * environment where we have pthreads, so we'll enable locking.
+ */
+#if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__) && \
+    !defined(__NEWLIB__)
+#define _NETIO_PTHREAD       /**< Include a mutex in netio_queue_t below */
+
+/*
+ * If NETIO_UNLOCKED is defined, we don't do use per-cpu locks on
+ * per-packet NetIO operations.  We still do pthread locking on things
+ * like netio_input_register, though.  This is used for building
+ * libnetio_unlocked.
+ */
+#ifndef NETIO_UNLOCKED
+
+/* Avoid PLT overhead by using our own inlined per-cpu lock. */
+#include <sched.h>
+typedef int _netio_percpu_mutex_t;
+
+static __inline int
+_netio_percpu_mutex_init(_netio_percpu_mutex_t* lock)
+{
+  *lock = 0;
+  return 0;
+}
+
+static __inline int
+_netio_percpu_mutex_lock(_netio_percpu_mutex_t* lock)
+{
+  while (__builtin_expect(__insn_tns(lock), 0))
+    sched_yield();
+  return 0;
+}
+
+static __inline int
+_netio_percpu_mutex_unlock(_netio_percpu_mutex_t* lock)
+{
+  *lock = 0;
+  return 0;
+}
+
+#else /* NETIO_UNLOCKED */
+
+/* Don't do any locking for per-packet NetIO operations. */
+typedef int _netio_percpu_mutex_t;
+#define _netio_percpu_mutex_init(L)
+#define _netio_percpu_mutex_lock(L)
+#define _netio_percpu_mutex_unlock(L)
+
+#endif /* NETIO_UNLOCKED */
+#endif /* !__HV__, !__BOGUX, !__KERNEL__, !__NEWLIB__ */
+
+/** How many tiles can register for a given queue.
+ *  @ingroup setup */
+#define NETIO_MAX_TILES_PER_QUEUE  64
+
+
+/** Largest permissible queue identifier.
+ *  @ingroup setup  */
+#define NETIO_MAX_QUEUE_ID        255
+
+
+#ifndef __DOXYGEN__
+
+/* Metadata packet checksum/ethertype flags. */
+
+/** The L4 checksum has not been calculated. */
+#define _NETIO_PKT_NO_L4_CSUM_SHIFT           0
+#define _NETIO_PKT_NO_L4_CSUM_RMASK           1
+#define _NETIO_PKT_NO_L4_CSUM_MASK \
+         (_NETIO_PKT_NO_L4_CSUM_RMASK << _NETIO_PKT_NO_L4_CSUM_SHIFT)
+
+/** The L3 checksum has not been calculated. */
+#define _NETIO_PKT_NO_L3_CSUM_SHIFT           1
+#define _NETIO_PKT_NO_L3_CSUM_RMASK           1
+#define _NETIO_PKT_NO_L3_CSUM_MASK \
+         (_NETIO_PKT_NO_L3_CSUM_RMASK << _NETIO_PKT_NO_L3_CSUM_SHIFT)
+
+/** The L3 checksum is incorrect (or perhaps has not been calculated). */
+#define _NETIO_PKT_BAD_L3_CSUM_SHIFT          2
+#define _NETIO_PKT_BAD_L3_CSUM_RMASK          1
+#define _NETIO_PKT_BAD_L3_CSUM_MASK \
+         (_NETIO_PKT_BAD_L3_CSUM_RMASK << _NETIO_PKT_BAD_L3_CSUM_SHIFT)
+
+/** The Ethernet packet type is unrecognized. */
+#define _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT    3
+#define _NETIO_PKT_TYPE_UNRECOGNIZED_RMASK    1
+#define _NETIO_PKT_TYPE_UNRECOGNIZED_MASK \
+         (_NETIO_PKT_TYPE_UNRECOGNIZED_RMASK << \
+          _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT)
+
+/* Metadata packet type flags. */
+
+/** Where the packet type bits are; this field is the index into
+ *  _netio_pkt_info. */
+#define _NETIO_PKT_TYPE_SHIFT        4
+#define _NETIO_PKT_TYPE_RMASK        0x3F
+
+/** How many VLAN tags the packet has, and, if we have two, which one we
+ *  actually grouped on.  A VLAN within a proprietary (Marvell or Broadcom)
+ *  tag is counted here. */
+#define _NETIO_PKT_VLAN_SHIFT        4
+#define _NETIO_PKT_VLAN_RMASK        0x3
+#define _NETIO_PKT_VLAN_MASK \
+         (_NETIO_PKT_VLAN_RMASK << _NETIO_PKT_VLAN_SHIFT)
+#define _NETIO_PKT_VLAN_NONE         0   /* No VLAN tag. */
+#define _NETIO_PKT_VLAN_ONE          1   /* One VLAN tag. */
+#define _NETIO_PKT_VLAN_TWO_OUTER    2   /* Two VLAN tags, outer one used. */
+#define _NETIO_PKT_VLAN_TWO_INNER    3   /* Two VLAN tags, inner one used. */
+
+/** Which proprietary tags the packet has. */
+#define _NETIO_PKT_TAG_SHIFT         6
+#define _NETIO_PKT_TAG_RMASK         0x3
+#define _NETIO_PKT_TAG_MASK \
+          (_NETIO_PKT_TAG_RMASK << _NETIO_PKT_TAG_SHIFT)
+#define _NETIO_PKT_TAG_NONE          0   /* No proprietary tags. */
+#define _NETIO_PKT_TAG_MRVL          1   /* Marvell HyperG.Stack tags. */
+#define _NETIO_PKT_TAG_MRVL_EXT      2   /* HyperG.Stack extended tags. */
+#define _NETIO_PKT_TAG_BRCM          3   /* Broadcom HiGig tags. */
+
+/** Whether a packet has an LLC + SNAP header. */
+#define _NETIO_PKT_SNAP_SHIFT        8
+#define _NETIO_PKT_SNAP_RMASK        0x1
+#define _NETIO_PKT_SNAP_MASK \
+          (_NETIO_PKT_SNAP_RMASK << _NETIO_PKT_SNAP_SHIFT)
+
+/* NOTE: Bits 9 and 10 are unused. */
+
+/** Length of any custom data before the L2 header, in words. */
+#define _NETIO_PKT_CUSTOM_LEN_SHIFT  11
+#define _NETIO_PKT_CUSTOM_LEN_RMASK  0x1F
+#define _NETIO_PKT_CUSTOM_LEN_MASK \
+          (_NETIO_PKT_CUSTOM_LEN_RMASK << _NETIO_PKT_CUSTOM_LEN_SHIFT)
+
+/** The L4 checksum is incorrect (or perhaps has not been calculated). */
+#define _NETIO_PKT_BAD_L4_CSUM_SHIFT 16
+#define _NETIO_PKT_BAD_L4_CSUM_RMASK 0x1
+#define _NETIO_PKT_BAD_L4_CSUM_MASK \
+          (_NETIO_PKT_BAD_L4_CSUM_RMASK << _NETIO_PKT_BAD_L4_CSUM_SHIFT)
+
+/** Length of the L2 header, in words. */
+#define _NETIO_PKT_L2_LEN_SHIFT  17
+#define _NETIO_PKT_L2_LEN_RMASK  0x1F
+#define _NETIO_PKT_L2_LEN_MASK \
+          (_NETIO_PKT_L2_LEN_RMASK << _NETIO_PKT_L2_LEN_SHIFT)
+
+
+/* Flags in minimal packet metadata. */
+
+/** We need an eDMA checksum on this packet. */
+#define _NETIO_PKT_NEED_EDMA_CSUM_SHIFT            0
+#define _NETIO_PKT_NEED_EDMA_CSUM_RMASK            1
+#define _NETIO_PKT_NEED_EDMA_CSUM_MASK \
+         (_NETIO_PKT_NEED_EDMA_CSUM_RMASK << _NETIO_PKT_NEED_EDMA_CSUM_SHIFT)
+
+/* Data within the packet information table. */
+
+/* Note that, for efficiency, code which uses these fields assumes that none
+ * of the shift values below are zero.  See uses below for an explanation. */
+
+/** Offset within the L2 header of the innermost ethertype (in halfwords). */
+#define _NETIO_PKT_INFO_ETYPE_SHIFT       6
+#define _NETIO_PKT_INFO_ETYPE_RMASK    0x1F
+
+/** Offset within the L2 header of the VLAN tag (in halfwords). */
+#define _NETIO_PKT_INFO_VLAN_SHIFT       11
+#define _NETIO_PKT_INFO_VLAN_RMASK     0x1F
+
+#endif
+
+
+/** The size of a memory buffer representing a small packet.
+ *  @ingroup egress */
+#define SMALL_PACKET_SIZE 256
+
+/** The size of a memory buffer representing a large packet.
+ *  @ingroup egress */
+#define LARGE_PACKET_SIZE 2048
+
+/** The size of a memory buffer representing a jumbo packet.
+ *  @ingroup egress */
+#define JUMBO_PACKET_SIZE (12 * 1024)
+
+
+/* Common ethertypes.
+ * @ingroup ingress */
+/** @{ */
+/** The ethertype of IPv4. */
+#define ETHERTYPE_IPv4 (0x0800)
+/** The ethertype of ARP. */
+#define ETHERTYPE_ARP (0x0806)
+/** The ethertype of VLANs. */
+#define ETHERTYPE_VLAN (0x8100)
+/** The ethertype of a Q-in-Q header. */
+#define ETHERTYPE_Q_IN_Q (0x9100)
+/** The ethertype of IPv6. */
+#define ETHERTYPE_IPv6 (0x86DD)
+/** The ethertype of MPLS. */
+#define ETHERTYPE_MPLS (0x8847)
+/** @} */
+
+
+/** The possible return values of NETIO_PKT_STATUS.
+ * @ingroup ingress
+ */
+typedef enum
+{
+  /** No problems were detected with this packet. */
+  NETIO_PKT_STATUS_OK,
+  /** The packet is undersized; this is expected behavior if the packet's
+    * ethertype is unrecognized, but otherwise the packet is likely corrupt. */
+  NETIO_PKT_STATUS_UNDERSIZE,
+  /** The packet is oversized and some trailing bytes have been discarded.
+      This is expected behavior for short packets, since it's impossible to
+      precisely determine the amount of padding which may have been added to
+      them to make them meet the minimum Ethernet packet size. */
+  NETIO_PKT_STATUS_OVERSIZE,
+  /** The packet was judged to be corrupt by hardware (for instance, it had
+      a bad CRC, or part of it was discarded due to lack of buffer space in
+      the I/O shim) and should be discarded. */
+  NETIO_PKT_STATUS_BAD
+} netio_pkt_status_t;
+
+
+/** Log2 of how many buckets we have. */
+#define NETIO_LOG2_NUM_BUCKETS (10)
+
+/** How many buckets we have.
+ * @ingroup ingress */
+#define NETIO_NUM_BUCKETS (1 << NETIO_LOG2_NUM_BUCKETS)
+
+
+/**
+ * @brief A group-to-bucket identifier.
+ *
+ * @ingroup setup
+ *
+ * This tells us what to do with a given group.
+ */
+typedef union {
+  /** The header broken down into bits. */
+  struct {
+    /** Whether we should balance on L4, if available */
+    unsigned int __balance_on_l4:1;
+    /** Whether we should balance on L3, if available */
+    unsigned int __balance_on_l3:1;
+    /** Whether we should balance on L2, if available */
+    unsigned int __balance_on_l2:1;
+    /** Reserved for future use */
+    unsigned int __reserved:1;
+    /** The base bucket to use to send traffic */
+    unsigned int __bucket_base:NETIO_LOG2_NUM_BUCKETS;
+    /** The mask to apply to the balancing value. This must be one less
+     * than a power of two, e.g. 0x3 or 0xFF.
+     */
+    unsigned int __bucket_mask:NETIO_LOG2_NUM_BUCKETS;
+    /** Pad to 32 bits */
+    unsigned int __padding:(32 - 4 - 2 * NETIO_LOG2_NUM_BUCKETS);
+  } bits;
+  /** To send out the IDN. */
+  unsigned int word;
+}
+netio_group_t;
+
+
+/**
+ * @brief A VLAN-to-bucket identifier.
+ *
+ * @ingroup setup
+ *
+ * This tells us what to do with a given VLAN.
+ */
+typedef netio_group_t netio_vlan_t;
+
+
+/**
+ * A bucket-to-queue mapping.
+ * @ingroup setup
+ */
+typedef unsigned char netio_bucket_t;
+
+
+/**
+ * A packet size can always fit in a netio_size_t.
+ * @ingroup setup
+ */
+typedef unsigned int netio_size_t;
+
+
+/**
+ * @brief Ethernet standard (ingress) packet metadata.
+ *
+ * @ingroup ingress
+ *
+ * This is additional data associated with each packet.
+ * This structure is opaque and accessed through the @ref ingress.
+ *
+ * Also, the buffer population operation currently assumes that standard
+ * metadata is at least as large as minimal metadata, and will need to be
+ * modified if that is no longer the case.
+ */
+typedef struct
+{
+#ifdef __DOXYGEN__
+  /** This structure is opaque. */
+  unsigned char opaque[24];
+#else
+  /** The overall ordinal of the packet */
+  unsigned int __packet_ordinal;
+  /** The ordinal of the packet within the group */
+  unsigned int __group_ordinal;
+  /** The best flow hash IPP could compute. */
+  unsigned int __flow_hash;
+  /** Flags pertaining to checksum calculation, packet type, etc. */
+  unsigned int __flags;
+  /** The first word of "user data". */
+  unsigned int __user_data_0;
+  /** The second word of "user data". */
+  unsigned int __user_data_1;
+#endif
+}
+netio_pkt_metadata_t;
+
+
+/** To ensure that the L3 header is aligned mod 4, the L2 header should be
+ * aligned mod 4 plus 2, since every supported L2 header is 4n + 2 bytes
+ * long.  The standard way to do this is to simply add 2 bytes of padding
+ * before the L2 header.
+ */
+#define NETIO_PACKET_PADDING 2
+
+
+
+/**
+ * @brief Ethernet minimal (egress) packet metadata.
+ *
+ * @ingroup egress
+ *
+ * This structure represents information about packets which have
+ * been processed by @ref netio_populate_buffer() or
+ * @ref netio_populate_prepend_buffer().  This structure is opaque
+ * and accessed through the @ref egress.
+ *
+ * @internal This structure is actually copied into the memory used by
+ * standard metadata, which is assumed to be large enough.
+ */
+typedef struct
+{
+#ifdef __DOXYGEN__
+  /** This structure is opaque. */
+  unsigned char opaque[14];
+#else
+  /** The offset of the L2 header from the start of the packet data. */
+  unsigned short l2_offset;
+  /** The offset of the L3 header from the start of the packet data. */
+  unsigned short l3_offset;
+  /** Where to write the checksum. */
+  unsigned char csum_location;
+  /** Where to start checksumming from. */
+  unsigned char csum_start;
+  /** Flags pertaining to checksum calculation etc. */
+  unsigned short flags;
+  /** The L2 length of the packet. */
+  unsigned short l2_length;
+  /** The checksum with which to seed the checksum generator. */
+  unsigned short csum_seed;
+  /** How much to checksum. */
+  unsigned short csum_length;
+#endif
+}
+netio_pkt_minimal_metadata_t;
+
+
+#ifndef __DOXYGEN__
+
+/**
+ * @brief An I/O notification header.
+ *
+ * This is the first word of data received from an I/O shim in a notification
+ * packet. It contains framing and status information.
+ */
+typedef union
+{
+  unsigned int word; /**< The whole word. */
+  /** The various fields. */
+  struct
+  {
+    unsigned int __channel:7;    /**< Resource channel. */
+    unsigned int __type:4;       /**< Type. */
+    unsigned int __ack:1;        /**< Whether an acknowledgement is needed. */
+    unsigned int __reserved:1;   /**< Reserved. */
+    unsigned int __protocol:1;   /**< A protocol-specific word is added. */
+    unsigned int __status:2;     /**< Status of the transfer. */
+    unsigned int __framing:2;    /**< Framing of the transfer. */
+    unsigned int __transfer_size:14; /**< Transfer size in bytes (total). */
+  } bits;
+}
+__netio_pkt_notif_t;
+
+
+/**
+ * Returns the base address of the packet.
+ */
+#define _NETIO_PKT_HANDLE_BASE(p) \
+  ((unsigned char*)((p).word & 0xFFFFFFC0))
+
+/**
+ * Returns the base address of the packet.
+ */
+#define _NETIO_PKT_BASE(p) \
+  _NETIO_PKT_HANDLE_BASE(p->__packet)
+
+/**
+ * @brief An I/O notification packet (second word)
+ *
+ * This is the second word of data received from an I/O shim in a notification
+ * packet.  This is the virtual address of the packet buffer, plus some flag
+ * bits.  (The virtual address of the packet is always 256-byte aligned so we
+ * have room for 8 bits' worth of flags in the low 8 bits.)
+ *
+ * @internal
+ * NOTE: The low two bits must contain "__queue", so the "packet size"
+ * (SIZE_SMALL, SIZE_LARGE, or SIZE_JUMBO) can be determined quickly.
+ *
+ * If __addr or __offset are moved, _NETIO_PKT_BASE
+ * (defined right below this) must be changed.
+ */
+typedef union
+{
+  unsigned int word; /**< The whole word. */
+  /** The various fields. */
+  struct
+  {
+    /** Which queue the packet will be returned to once it is sent back to
+        the IPP.  This is one of the SIZE_xxx values. */
+    unsigned int __queue:2;
+
+    /** The IPP handle of the sending IPP. */
+    unsigned int __ipp_handle:2;
+
+    /** Reserved for future use. */
+    unsigned int __reserved:1;
+
+    /** If 1, this packet has minimal (egress) metadata; otherwise, it
+        has standard (ingress) metadata. */
+    unsigned int __minimal:1;
+
+    /** Offset of the metadata within the packet.  This value is multiplied
+     *  by 64 and added to the base packet address to get the metadata
+     *  address.  Note that this field is aligned within the word such that
+     *  you can easily extract the metadata address with a 26-bit mask. */
+    unsigned int __offset:2;
+
+    /** The top 24 bits of the packet's virtual address. */
+    unsigned int __addr:24;
+  } bits;
+}
+__netio_pkt_handle_t;
+
+#endif /* !__DOXYGEN__ */
+
+
+/**
+ * @brief A handle for an I/O packet's storage.
+ * @ingroup ingress
+ *
+ * netio_pkt_handle_t encodes the concept of a ::netio_pkt_t with its
+ * packet metadata removed.  It is a much smaller type that exists to
+ * facilitate applications where the full ::netio_pkt_t type is too
+ * large, such as those that cache enormous numbers of packets or wish
+ * to transmit packet descriptors over the UDN.
+ *
+ * Because there is no metadata, most ::netio_pkt_t operations cannot be
+ * performed on a netio_pkt_handle_t.  It supports only
+ * netio_free_handle() (to free the buffer) and
+ * NETIO_PKT_CUSTOM_DATA_H() (to access a pointer to its contents).
+ * The application must acquire any additional metadata it wants from the
+ * original ::netio_pkt_t and record it separately.
+ *
+ * A netio_pkt_handle_t can be extracted from a ::netio_pkt_t by calling
+ * NETIO_PKT_HANDLE().  An invalid handle (analogous to NULL) can be
+ * created by assigning the value ::NETIO_PKT_HANDLE_NONE. A handle can
+ * be tested for validity with NETIO_PKT_HANDLE_IS_VALID().
+ */
+typedef struct
+{
+  unsigned int word; /**< Opaque bits. */
+} netio_pkt_handle_t;
+
+/**
+ * @brief A packet descriptor.
+ *
+ * @ingroup ingress
+ * @ingroup egress
+ *
+ * This data structure represents a packet.  The structure is manipulated
+ * through the @ref ingress and the @ref egress.
+ *
+ * While the contents of a netio_pkt_t are opaque, the structure itself is
+ * portable.  This means that it may be shared between all tiles which have
+ * done a netio_input_register() call for the interface on which the pkt_t
+ * was initially received (via netio_get_packet()) or retrieved (via
+ * netio_get_buffer()).  The contents of a netio_pkt_t can be transmitted to
+ * another tile via shared memory, or via a UDN message, or by other means.
+ * The destination tile may then use the pkt_t as if it had originally been
+ * received locally; it may read or write the packet's data, read its
+ * metadata, free the packet, send the packet, transfer the netio_pkt_t to
+ * yet another tile, and so forth.
+ *
+ * Once a netio_pkt_t has been transferred to a second tile, the first tile
+ * should not reference the original copy; in particular, if more than one
+ * tile frees or sends the same netio_pkt_t, the IPP's packet free lists will
+ * become corrupted.  Note also that each tile which reads or modifies
+ * packet data must obey the memory coherency rules outlined in @ref input.
+ */
+typedef struct
+{
+#ifdef __DOXYGEN__
+  /** This structure is opaque. */
+  unsigned char opaque[32];
+#else
+  /** For an ingress packet (one with standard metadata), this is the
+   *  notification header we got from the I/O shim.  For an egress packet
+   *  (one with minimal metadata), this word is zero if the packet has not
+   *  been populated, and nonzero if it has. */
+  __netio_pkt_notif_t __notif_header;
+
+  /** Virtual address of the packet buffer, plus state flags. */
+  __netio_pkt_handle_t __packet;
+
+  /** Metadata associated with the packet. */
+  netio_pkt_metadata_t __metadata;
+#endif
+}
+netio_pkt_t;
+
+
+#ifndef __DOXYGEN__
+
+#define __NETIO_PKT_NOTIF_HEADER(pkt) ((pkt)->__notif_header)
+#define __NETIO_PKT_IPP_HANDLE(pkt) ((pkt)->__packet.bits.__ipp_handle)
+#define __NETIO_PKT_QUEUE(pkt) ((pkt)->__packet.bits.__queue)
+#define __NETIO_PKT_NOTIF_HEADER_M(mda, pkt) ((pkt)->__notif_header)
+#define __NETIO_PKT_IPP_HANDLE_M(mda, pkt) ((pkt)->__packet.bits.__ipp_handle)
+#define __NETIO_PKT_MINIMAL(pkt) ((pkt)->__packet.bits.__minimal)
+#define __NETIO_PKT_QUEUE_M(mda, pkt) ((pkt)->__packet.bits.__queue)
+#define __NETIO_PKT_FLAGS_M(mda, pkt) ((mda)->__flags)
+
+/* Packet information table, used by the attribute access functions below. */
+extern const uint16_t _netio_pkt_info[];
+
+#endif /* __DOXYGEN__ */
+
+
+#ifndef __DOXYGEN__
+/* These macros are deprecated and will disappear in a future MDE release. */
+#define NETIO_PKT_GOOD_CHECKSUM(pkt) \
+  NETIO_PKT_L4_CSUM_CORRECT(pkt)
+#define NETIO_PKT_GOOD_CHECKSUM_M(mda, pkt) \
+  NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt)
+#endif /* __DOXYGEN__ */
+
+
+/* Packet attribute access functions. */
+
+/** Return a pointer to the metadata for a packet.
+ * @ingroup ingress
+ *
+ * Calling this function once and passing the result to other retrieval
+ * functions with a "_M" suffix usually improves performance.  This
+ * function must be called on an 'ingress' packet (i.e. one retrieved
+ * by @ref netio_get_packet(), on which @ref netio_populate_buffer() or
+ * @ref netio_populate_prepend_buffer have not been called). Use of this
+ * function on an 'egress' packet will cause an assertion failure.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to the packet's standard metadata.
+ */
+static __inline netio_pkt_metadata_t*
+NETIO_PKT_METADATA(netio_pkt_t* pkt)
+{
+  netio_assert(!pkt->__packet.bits.__minimal);
+  return &pkt->__metadata;
+}
+
+
+/** Return a pointer to the minimal metadata for a packet.
+ * @ingroup egress
+ *
+ * Calling this function once and passing the result to other retrieval
+ * functions with a "_MM" suffix usually improves performance.  This
+ * function must be called on an 'egress' packet (i.e. one on which
+ * @ref netio_populate_buffer() or @ref netio_populate_prepend_buffer()
+ * have been called, or one retrieved by @ref netio_get_buffer()). Use of
+ * this function on an 'ingress' packet will cause an assertion failure.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to the packet's standard metadata.
+ */
+static __inline netio_pkt_minimal_metadata_t*
+NETIO_PKT_MINIMAL_METADATA(netio_pkt_t* pkt)
+{
+  netio_assert(pkt->__packet.bits.__minimal);
+  return (netio_pkt_minimal_metadata_t*) &pkt->__metadata;
+}
+
+
+/** Determine whether a packet has 'minimal' metadata.
+ * @ingroup pktfuncs
+ *
+ * This function will return nonzero if the packet is an 'egress'
+ * packet (i.e. one on which @ref netio_populate_buffer() or
+ * @ref netio_populate_prepend_buffer() have been called, or one
+ * retrieved by @ref netio_get_buffer()), and zero if the packet
+ * is an 'ingress' packet (i.e. one retrieved by @ref netio_get_packet(),
+ * which has not been converted into an 'egress' packet).
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the packet has minimal metadata.
+ */
+static __inline unsigned int
+NETIO_PKT_IS_MINIMAL(netio_pkt_t* pkt)
+{
+  return pkt->__packet.bits.__minimal;
+}
+
+
+/** Return a handle for a packet's storage.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A handle for the packet's storage.
+ */
+static __inline netio_pkt_handle_t
+NETIO_PKT_HANDLE(netio_pkt_t* pkt)
+{
+  netio_pkt_handle_t h;
+  h.word = pkt->__packet.word;
+  return h;
+}
+
+
+/** A special reserved value indicating the absence of a packet handle.
+ *
+ * @ingroup pktfuncs
+ */
+#define NETIO_PKT_HANDLE_NONE ((netio_pkt_handle_t) { 0 })
+
+
+/** Test whether a packet handle is valid.
+ *
+ * Applications may wish to use the reserved value NETIO_PKT_HANDLE_NONE
+ * to indicate no packet at all.  This function tests to see if a packet
+ * handle is a real handle, not this special reserved value.
+ *
+ * @ingroup pktfuncs
+ *
+ * @param[in] handle Handle on which to operate.
+ * @return One if the packet handle is valid, else zero.
+ */
+static __inline unsigned int
+NETIO_PKT_HANDLE_IS_VALID(netio_pkt_handle_t handle)
+{
+  return handle.word != 0;
+}
+
+
+
+/** Return a pointer to the start of the packet's custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup ingress
+ *
+ * @param[in] handle Handle on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_CUSTOM_DATA_H(netio_pkt_handle_t handle)
+{
+  return _NETIO_PKT_HANDLE_BASE(handle) + NETIO_PACKET_PADDING;
+}
+
+
+/** Return the length of the packet's custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ *
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet's custom header, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_CUSTOM_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  /*
+   * Note that we effectively need to extract a quantity from the flags word
+   * which is measured in words, and then turn it into bytes by shifting
+   * it left by 2.  We do this all at once by just shifting right two less
+   * bits, and shifting the mask up two bits.
+   */
+  return ((mda->__flags >> (_NETIO_PKT_CUSTOM_LEN_SHIFT - 2)) &
+          (_NETIO_PKT_CUSTOM_LEN_RMASK << 2));
+}
+
+
+/** Return the length of the packet, starting with the custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_CUSTOM_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (__NETIO_PKT_NOTIF_HEADER(pkt).bits.__transfer_size -
+          NETIO_PACKET_PADDING);
+}
+
+
+/** Return a pointer to the start of the packet's custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_CUSTOM_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return NETIO_PKT_CUSTOM_DATA_H(NETIO_PKT_HANDLE(pkt));
+}
+
+
+/** Return the length of the packet's L2 (Ethernet plus VLAN or SNAP) header.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet's L2 header, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  /*
+   * Note that we effectively need to extract a quantity from the flags word
+   * which is measured in words, and then turn it into bytes by shifting
+   * it left by 2.  We do this all at once by just shifting right two less
+   * bits, and shifting the mask up two bits.  We then add two bytes.
+   */
+  return ((mda->__flags >> (_NETIO_PKT_L2_LEN_SHIFT - 2)) &
+          (_NETIO_PKT_L2_LEN_RMASK << 2)) + 2;
+}
+
+
+/** Return the length of the packet, starting with the L2 (Ethernet) header.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt) -
+          NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda,pkt));
+}
+
+
+/** Return a pointer to the start of the packet's L2 (Ethernet) header.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_L2_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (NETIO_PKT_CUSTOM_DATA_M(mda, pkt) +
+          NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt));
+}
+
+
+/** Retrieve the length of the packet, starting with the L3 (generally,
+ *  the IP) header.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Length of the packet's L3 header and data, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L3_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (NETIO_PKT_L2_LENGTH_M(mda, pkt) -
+          NETIO_PKT_L2_HEADER_LENGTH_M(mda,pkt));
+}
+
+
+/** Return a pointer to the packet's L3 (generally, the IP) header.
+ * @ingroup ingress
+ *
+ * Note that we guarantee word alignment of the L3 header.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to the packet's L3 header.
+ */
+static __inline unsigned char*
+NETIO_PKT_L3_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (NETIO_PKT_L2_DATA_M(mda, pkt) +
+          NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt));
+}
+
+
+/** Return the ordinal of the packet.
+ * @ingroup ingress
+ *
+ * Each packet is given an ordinal number when it is delivered by the IPP.
+ * In the medium term, the ordinal is unique and monotonically increasing,
+ * being incremented by 1 for each packet; the ordinal of the first packet
+ * delivered after the IPP starts is zero.  (Since the ordinal is of finite
+ * size, given enough input packets, it will eventually wrap around to zero;
+ * in the long term, therefore, ordinals are not unique.)  The ordinals
+ * handed out by different IPPs are not disjoint, so two packets from
+ * different IPPs may have identical ordinals.  Packets dropped by the
+ * IPP or by the I/O shim are not assigned ordinals.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's per-IPP packet ordinal.
+ */
+static __inline unsigned int
+NETIO_PKT_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return mda->__packet_ordinal;
+}
+
+
+/** Return the per-group ordinal of the packet.
+ * @ingroup ingress
+ *
+ * Each packet is given a per-group ordinal number when it is
+ * delivered by the IPP. By default, the group is the packet's VLAN,
+ * although IPP can be recompiled to use different values.  In
+ * the medium term, the ordinal is unique and monotonically
+ * increasing, being incremented by 1 for each packet; the ordinal of
+ * the first packet distributed to a particular group is zero.
+ * (Since the ordinal is of finite size, given enough input packets,
+ * it will eventually wrap around to zero; in the long term,
+ * therefore, ordinals are not unique.)  The ordinals handed out by
+ * different IPPs are not disjoint, so two packets from different IPPs
+ * may have identical ordinals; similarly, packets distributed to
+ * different groups may have identical ordinals.  Packets dropped by
+ * the IPP or by the I/O shim are not assigned ordinals.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's per-IPP, per-group ordinal.
+ */
+static __inline unsigned int
+NETIO_PKT_GROUP_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return mda->__group_ordinal;
+}
+
+
+/** Return the VLAN ID assigned to the packet.
+ * @ingroup ingress
+ *
+ * This value is usually contained within the packet header.
+ *
+ * This value will be zero if the packet does not have a VLAN tag, or if
+ * this value was not extracted from the packet.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's VLAN ID.
+ */
+static __inline unsigned short
+NETIO_PKT_VLAN_ID_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  int vl = (mda->__flags >> _NETIO_PKT_VLAN_SHIFT) & _NETIO_PKT_VLAN_RMASK;
+  unsigned short* pkt_p;
+  int index;
+  unsigned short val;
+
+  if (vl == _NETIO_PKT_VLAN_NONE)
+    return 0;
+
+  pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt);
+  index = (mda->__flags >> _NETIO_PKT_TYPE_SHIFT) & _NETIO_PKT_TYPE_RMASK;
+
+  val = pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_VLAN_SHIFT) &
+              _NETIO_PKT_INFO_VLAN_RMASK];
+
+#ifdef __TILECC__
+  return (__insn_bytex(val) >> 16) & 0xFFF;
+#else
+  return (__builtin_bswap32(val) >> 16) & 0xFFF;
+#endif
+}
+
+
+/** Return the ethertype of the packet.
+ * @ingroup ingress
+ *
+ * This value is usually contained within the packet header.
+ *
+ * This value is reliable if @ref NETIO_PKT_ETHERTYPE_RECOGNIZED_M()
+ * returns true, and otherwise, may not be well defined.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's ethertype.
+ */
+static __inline unsigned short
+NETIO_PKT_ETHERTYPE_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  unsigned short* pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt);
+  int index = (mda->__flags >> _NETIO_PKT_TYPE_SHIFT) & _NETIO_PKT_TYPE_RMASK;
+
+  unsigned short val =
+    pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_ETYPE_SHIFT) &
+          _NETIO_PKT_INFO_ETYPE_RMASK];
+
+  return __builtin_bswap32(val) >> 16;
+}
+
+
+/** Return the flow hash computed on the packet.
+ * @ingroup ingress
+ *
+ * For TCP and UDP packets, this hash is calculated by hashing together
+ * the "5-tuple" values, specifically the source IP address, destination
+ * IP address, protocol type, source port and destination port.
+ * The hash value is intended to be helpful for millions of distinct
+ * flows.
+ *
+ * For IPv4 or IPv6 packets which are neither TCP nor UDP, the flow hash is
+ * derived by hashing together the source and destination IP addresses.
+ *
+ * For MPLS-encapsulated packets, the flow hash is derived by hashing
+ * the first MPLS label.
+ *
+ * For all other packets the flow hash is computed from the source
+ * and destination Ethernet addresses.
+ *
+ * The hash is symmetric, meaning it produces the same value if the
+ * source and destination are swapped. The only exceptions are
+ * tunneling protocols 0x04 (IP in IP Encapsulation), 0x29 (Simple
+ * Internet Protocol), 0x2F (General Routing Encapsulation) and 0x32
+ * (Encap Security Payload), which use only the destination address
+ * since the source address is not meaningful.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's 32-bit flow hash.
+ */
+static __inline unsigned int
+NETIO_PKT_FLOW_HASH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return mda->__flow_hash;
+}
+
+
+/** Return the first word of "user data" for the packet.
+ *
+ * The contents of the user data words depend on the IPP.
+ *
+ * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the first
+ * word of user data contains the least significant bits of the 64-bit
+ * arrival cycle count (see @c get_cycle_count_low()).
+ *
+ * See the <em>System Programmer's Guide</em> for details.
+ *
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's first word of "user data".
+ */
+static __inline unsigned int
+NETIO_PKT_USER_DATA_0_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return mda->__user_data_0;
+}
+
+
+/** Return the second word of "user data" for the packet.
+ *
+ * The contents of the user data words depend on the IPP.
+ *
+ * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the second
+ * word of user data contains the most significant bits of the 64-bit
+ * arrival cycle count (see @c get_cycle_count_high()).
+ *
+ * See the <em>System Programmer's Guide</em> for details.
+ *
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's second word of "user data".
+ */
+static __inline unsigned int
+NETIO_PKT_USER_DATA_1_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return mda->__user_data_1;
+}
+
+
+/** Determine whether the L4 (TCP/UDP) checksum was calculated.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the L4 checksum was calculated.
+ */
+static __inline unsigned int
+NETIO_PKT_L4_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return !(mda->__flags & _NETIO_PKT_NO_L4_CSUM_MASK);
+}
+
+
+/** Determine whether the L4 (TCP/UDP) checksum was calculated and found to
+ *  be correct.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the checksum was calculated and is correct.
+ */
+static __inline unsigned int
+NETIO_PKT_L4_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return !(mda->__flags &
+           (_NETIO_PKT_BAD_L4_CSUM_MASK | _NETIO_PKT_NO_L4_CSUM_MASK));
+}
+
+
+/** Determine whether the L3 (IP) checksum was calculated.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the L3 (IP) checksum was calculated.
+*/
+static __inline unsigned int
+NETIO_PKT_L3_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return !(mda->__flags & _NETIO_PKT_NO_L3_CSUM_MASK);
+}
+
+
+/** Determine whether the L3 (IP) checksum was calculated and found to be
+ *  correct.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the checksum was calculated and is correct.
+ */
+static __inline unsigned int
+NETIO_PKT_L3_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return !(mda->__flags &
+           (_NETIO_PKT_BAD_L3_CSUM_MASK | _NETIO_PKT_NO_L3_CSUM_MASK));
+}
+
+
+/** Determine whether the ethertype was recognized and L3 packet data was
+ *  processed.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the ethertype was recognized and L3 packet data was
+ *   processed.
+ */
+static __inline unsigned int
+NETIO_PKT_ETHERTYPE_RECOGNIZED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return !(mda->__flags & _NETIO_PKT_TYPE_UNRECOGNIZED_MASK);
+}
+
+
+/** Retrieve the status of a packet and any errors that may have occurred
+ * during ingress processing (length mismatches, CRC errors, etc.).
+ * @ingroup ingress
+ *
+ * Note that packets for which @ref NETIO_PKT_ETHERTYPE_RECOGNIZED()
+ * returns zero are always reported as underlength, as there is no a priori
+ * means to determine their length.  Normally, applications should use
+ * @ref NETIO_PKT_BAD_M() instead of explicitly checking status with this
+ * function.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's status.
+ */
+static __inline netio_pkt_status_t
+NETIO_PKT_STATUS_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status;
+}
+
+
+/** Report whether a packet is bad (i.e., was shorter than expected based on
+ *  its headers, or had a bad CRC).
+ * @ingroup ingress
+ *
+ * Note that this function does not verify L3 or L4 checksums.
+ *
+ * @param[in] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the packet is bad and should be discarded.
+ */
+static __inline unsigned int
+NETIO_PKT_BAD_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return ((NETIO_PKT_STATUS_M(mda, pkt) & 1) &&
+          (NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt) ||
+           NETIO_PKT_STATUS_M(mda, pkt) == NETIO_PKT_STATUS_BAD));
+}
+
+
+/** Return the length of the packet, starting with the L2 (Ethernet) header.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
+{
+  return mmd->l2_length;
+}
+
+
+/** Return the length of the L2 (Ethernet) header.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet's L2 header, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd,
+                              netio_pkt_t* pkt)
+{
+  return mmd->l3_offset - mmd->l2_offset;
+}
+
+
+/** Return the length of the packet, starting with the L3 (IP) header.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return Length of the packet's L3 header and data, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L3_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
+{
+  return (NETIO_PKT_L2_LENGTH_MM(mmd, pkt) -
+          NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt));
+}
+
+
+/** Return a pointer to the packet's L3 (generally, the IP) header.
+ * @ingroup egress
+ *
+ * Note that we guarantee word alignment of the L3 header.
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to the packet's L3 header.
+ */
+static __inline unsigned char*
+NETIO_PKT_L3_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
+{
+  return _NETIO_PKT_BASE(pkt) + mmd->l3_offset;
+}
+
+
+/** Return a pointer to the packet's L2 (Ethernet) header.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_L2_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
+{
+  return _NETIO_PKT_BASE(pkt) + mmd->l2_offset;
+}
+
+
+/** Retrieve the status of a packet and any errors that may have occurred
+ * during ingress processing (length mismatches, CRC errors, etc.).
+ * @ingroup ingress
+ *
+ * Note that packets for which @ref NETIO_PKT_ETHERTYPE_RECOGNIZED()
+ * returns zero are always reported as underlength, as there is no a priori
+ * means to determine their length.  Normally, applications should use
+ * @ref NETIO_PKT_BAD() instead of explicitly checking status with this
+ * function.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's status.
+ */
+static __inline netio_pkt_status_t
+NETIO_PKT_STATUS(netio_pkt_t* pkt)
+{
+  netio_assert(!pkt->__packet.bits.__minimal);
+
+  return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status;
+}
+
+
+/** Report whether a packet is bad (i.e., was shorter than expected based on
+ *  its headers, or had a bad CRC).
+ * @ingroup ingress
+ *
+ * Note that this function does not verify L3 or L4 checksums.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the packet is bad and should be discarded.
+ */
+static __inline unsigned int
+NETIO_PKT_BAD(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_BAD_M(mda, pkt);
+}
+
+
+/** Return the length of the packet's custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet's custom header, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_CUSTOM_HEADER_LENGTH(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt);
+}
+
+
+/** Return the length of the packet, starting with the custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return  The length of the packet, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_CUSTOM_LENGTH(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt);
+}
+
+
+/** Return a pointer to the packet's custom header.
+ *  A custom header may or may not be present, depending upon the IPP; its
+ *  contents and alignment are also IPP-dependent.  Currently, none of the
+ *  standard IPPs supplied by Tilera produce a custom header.  If present,
+ *  the custom header precedes the L2 header in the packet buffer.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_CUSTOM_DATA(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_CUSTOM_DATA_M(mda, pkt);
+}
+
+
+/** Return the length of the packet's L2 (Ethernet plus VLAN or SNAP) header.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The length of the packet's L2 header, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_HEADER_LENGTH(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt);
+  }
+}
+
+
+/** Return the length of the packet, starting with the L2 (Ethernet) header.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return  The length of the packet, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L2_LENGTH(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_L2_LENGTH_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_L2_LENGTH_M(mda, pkt);
+  }
+}
+
+
+/** Return a pointer to the packet's L2 (Ethernet) header.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to start of the packet.
+ */
+static __inline unsigned char*
+NETIO_PKT_L2_DATA(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_L2_DATA_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_L2_DATA_M(mda, pkt);
+  }
+}
+
+
+/** Retrieve the length of the packet, starting with the L3 (generally, the IP)
+ * header.
+ * @ingroup pktfuncs
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Length of the packet's L3 header and data, in bytes.
+ */
+static __inline netio_size_t
+NETIO_PKT_L3_LENGTH(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_L3_LENGTH_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_L3_LENGTH_M(mda, pkt);
+  }
+}
+
+
+/** Return a pointer to the packet's L3 (generally, the IP) header.
+ * @ingroup pktfuncs
+ *
+ * Note that we guarantee word alignment of the L3 header.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return A pointer to the packet's L3 header.
+ */
+static __inline unsigned char*
+NETIO_PKT_L3_DATA(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_L3_DATA_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_L3_DATA_M(mda, pkt);
+  }
+}
+
+
+/** Return the ordinal of the packet.
+ * @ingroup ingress
+ *
+ * Each packet is given an ordinal number when it is delivered by the IPP.
+ * In the medium term, the ordinal is unique and monotonically increasing,
+ * being incremented by 1 for each packet; the ordinal of the first packet
+ * delivered after the IPP starts is zero.  (Since the ordinal is of finite
+ * size, given enough input packets, it will eventually wrap around to zero;
+ * in the long term, therefore, ordinals are not unique.)  The ordinals
+ * handed out by different IPPs are not disjoint, so two packets from
+ * different IPPs may have identical ordinals.  Packets dropped by the
+ * IPP or by the I/O shim are not assigned ordinals.
+ *
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's per-IPP packet ordinal.
+ */
+static __inline unsigned int
+NETIO_PKT_ORDINAL(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_ORDINAL_M(mda, pkt);
+}
+
+
+/** Return the per-group ordinal of the packet.
+ * @ingroup ingress
+ *
+ * Each packet is given a per-group ordinal number when it is
+ * delivered by the IPP. By default, the group is the packet's VLAN,
+ * although IPP can be recompiled to use different values.  In
+ * the medium term, the ordinal is unique and monotonically
+ * increasing, being incremented by 1 for each packet; the ordinal of
+ * the first packet distributed to a particular group is zero.
+ * (Since the ordinal is of finite size, given enough input packets,
+ * it will eventually wrap around to zero; in the long term,
+ * therefore, ordinals are not unique.)  The ordinals handed out by
+ * different IPPs are not disjoint, so two packets from different IPPs
+ * may have identical ordinals; similarly, packets distributed to
+ * different groups may have identical ordinals.  Packets dropped by
+ * the IPP or by the I/O shim are not assigned ordinals.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's per-IPP, per-group ordinal.
+ */
+static __inline unsigned int
+NETIO_PKT_GROUP_ORDINAL(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_GROUP_ORDINAL_M(mda, pkt);
+}
+
+
+/** Return the VLAN ID assigned to the packet.
+ * @ingroup ingress
+ *
+ * This is usually also contained within the packet header.  If the packet
+ * does not have a VLAN tag, the VLAN ID returned by this function is zero.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's VLAN ID.
+ */
+static __inline unsigned short
+NETIO_PKT_VLAN_ID(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_VLAN_ID_M(mda, pkt);
+}
+
+
+/** Return the ethertype of the packet.
+ * @ingroup ingress
+ *
+ * This value is reliable if @ref NETIO_PKT_ETHERTYPE_RECOGNIZED()
+ * returns true, and otherwise, may not be well defined.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's ethertype.
+ */
+static __inline unsigned short
+NETIO_PKT_ETHERTYPE(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_ETHERTYPE_M(mda, pkt);
+}
+
+
+/** Return the flow hash computed on the packet.
+ * @ingroup ingress
+ *
+ * For TCP and UDP packets, this hash is calculated by hashing together
+ * the "5-tuple" values, specifically the source IP address, destination
+ * IP address, protocol type, source port and destination port.
+ * The hash value is intended to be helpful for millions of distinct
+ * flows.
+ *
+ * For IPv4 or IPv6 packets which are neither TCP nor UDP, the flow hash is
+ * derived by hashing together the source and destination IP addresses.
+ *
+ * For MPLS-encapsulated packets, the flow hash is derived by hashing
+ * the first MPLS label.
+ *
+ * For all other packets the flow hash is computed from the source
+ * and destination Ethernet addresses.
+ *
+ * The hash is symmetric, meaning it produces the same value if the
+ * source and destination are swapped. The only exceptions are
+ * tunneling protocols 0x04 (IP in IP Encapsulation), 0x29 (Simple
+ * Internet Protocol), 0x2F (General Routing Encapsulation) and 0x32
+ * (Encap Security Payload), which use only the destination address
+ * since the source address is not meaningful.
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's 32-bit flow hash.
+ */
+static __inline unsigned int
+NETIO_PKT_FLOW_HASH(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_FLOW_HASH_M(mda, pkt);
+}
+
+
+/** Return the first word of "user data" for the packet.
+ *
+ * The contents of the user data words depend on the IPP.
+ *
+ * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the first
+ * word of user data contains the least significant bits of the 64-bit
+ * arrival cycle count (see @c get_cycle_count_low()).
+ *
+ * See the <em>System Programmer's Guide</em> for details.
+ *
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's first word of "user data".
+ */
+static __inline unsigned int
+NETIO_PKT_USER_DATA_0(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_USER_DATA_0_M(mda, pkt);
+}
+
+
+/** Return the second word of "user data" for the packet.
+ *
+ * The contents of the user data words depend on the IPP.
+ *
+ * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the second
+ * word of user data contains the most significant bits of the 64-bit
+ * arrival cycle count (see @c get_cycle_count_high()).
+ *
+ * See the <em>System Programmer's Guide</em> for details.
+ *
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return The packet's second word of "user data".
+ */
+static __inline unsigned int
+NETIO_PKT_USER_DATA_1(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_USER_DATA_1_M(mda, pkt);
+}
+
+
+/** Determine whether the L4 (TCP/UDP) checksum was calculated.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the L4 checksum was calculated.
+ */
+static __inline unsigned int
+NETIO_PKT_L4_CSUM_CALCULATED(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_L4_CSUM_CALCULATED_M(mda, pkt);
+}
+
+
+/** Determine whether the L4 (TCP/UDP) checksum was calculated and found to
+ *  be correct.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the checksum was calculated and is correct.
+ */
+static __inline unsigned int
+NETIO_PKT_L4_CSUM_CORRECT(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt);
+}
+
+
+/** Determine whether the L3 (IP) checksum was calculated.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the L3 (IP) checksum was calculated.
+*/
+static __inline unsigned int
+NETIO_PKT_L3_CSUM_CALCULATED(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_L3_CSUM_CALCULATED_M(mda, pkt);
+}
+
+
+/** Determine whether the L3 (IP) checksum was calculated and found to be
+ *  correct.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the checksum was calculated and is correct.
+ */
+static __inline unsigned int
+NETIO_PKT_L3_CSUM_CORRECT(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_L3_CSUM_CORRECT_M(mda, pkt);
+}
+
+
+/** Determine whether the Ethertype was recognized and L3 packet data was
+ *  processed.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ * @return Nonzero if the Ethertype was recognized and L3 packet data was
+ *   processed.
+ */
+static __inline unsigned int
+NETIO_PKT_ETHERTYPE_RECOGNIZED(netio_pkt_t* pkt)
+{
+  netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+  return NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt);
+}
+
+
+/** Set an egress packet's L2 length, using a metadata pointer to speed the
+ * computation.
+ * @ingroup egress
+ *
+ * @param[in,out] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @param[in] len Packet L2 length, in bytes.
+ */
+static __inline void
+NETIO_PKT_SET_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt,
+                           int len)
+{
+  mmd->l2_length = len;
+}
+
+
+/** Set an egress packet's L2 length.
+ * @ingroup egress
+ *
+ * @param[in,out] pkt Packet on which to operate.
+ * @param[in] len Packet L2 length, in bytes.
+ */
+static __inline void
+NETIO_PKT_SET_L2_LENGTH(netio_pkt_t* pkt, int len)
+{
+  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+  NETIO_PKT_SET_L2_LENGTH_MM(mmd, pkt, len);
+}
+
+
+/** Set an egress packet's L2 header length, using a metadata pointer to
+ *  speed the computation.
+ * @ingroup egress
+ *
+ * It is not normally necessary to call this routine; only the L2 length,
+ * not the header length, is needed to transmit a packet.  It may be useful if
+ * the egress packet will later be processed by code which expects to use
+ * functions like @ref NETIO_PKT_L3_DATA() to get a pointer to the L3 payload.
+ *
+ * @param[in,out] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @param[in] len Packet L2 header length, in bytes.
+ */
+static __inline void
+NETIO_PKT_SET_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd,
+                                  netio_pkt_t* pkt, int len)
+{
+  mmd->l3_offset = mmd->l2_offset + len;
+}
+
+
+/** Set an egress packet's L2 header length.
+ * @ingroup egress
+ *
+ * It is not normally necessary to call this routine; only the L2 length,
+ * not the header length, is needed to transmit a packet.  It may be useful if
+ * the egress packet will later be processed by code which expects to use
+ * functions like @ref NETIO_PKT_L3_DATA() to get a pointer to the L3 payload.
+ *
+ * @param[in,out] pkt Packet on which to operate.
+ * @param[in] len Packet L2 header length, in bytes.
+ */
+static __inline void
+NETIO_PKT_SET_L2_HEADER_LENGTH(netio_pkt_t* pkt, int len)
+{
+  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+  NETIO_PKT_SET_L2_HEADER_LENGTH_MM(mmd, pkt, len);
+}
+
+
+/** Set up an egress packet for hardware checksum computation, using a
+ *  metadata pointer to speed the operation.
+ * @ingroup egress
+ *
+ *  NetIO provides the ability to automatically calculate a standard
+ *  16-bit Internet checksum on transmitted packets.  The application
+ *  may specify the point in the packet where the checksum starts, the
+ *  number of bytes to be checksummed, and the two bytes in the packet
+ *  which will be replaced with the completed checksum.  (If the range
+ *  of bytes to be checksummed includes the bytes to be replaced, the
+ *  initial values of those bytes will be included in the checksum.)
+ *
+ *  For some protocols, the packet checksum covers data which is not present
+ *  in the packet, or is at least not contiguous to the main data payload.
+ *  For instance, the TCP checksum includes a "pseudo-header" which includes
+ *  the source and destination IP addresses of the packet.  To accommodate
+ *  this, the checksum engine may be "seeded" with an initial value, which
+ *  the application would need to compute based on the specific protocol's
+ *  requirements.  Note that the seed is given in host byte order (little-
+ *  endian), not network byte order (big-endian); code written to compute a
+ *  pseudo-header checksum in network byte order will need to byte-swap it
+ *  before use as the seed.
+ *
+ *  Note that the checksum is computed as part of the transmission process,
+ *  so it will not be present in the packet upon completion of this routine.
+ *
+ * @param[in,out] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ * @param[in] start Offset within L2 packet of the first byte to include in
+ *   the checksum.
+ * @param[in] length Number of bytes to include in the checksum.
+ *   the checksum.
+ * @param[in] location Offset within L2 packet of the first of the two bytes
+ *   to be replaced with the calculated checksum.
+ * @param[in] seed Initial value of the running checksum before any of the
+ *   packet data is added.
+ */
+static __inline void
+NETIO_PKT_DO_EGRESS_CSUM_MM(netio_pkt_minimal_metadata_t* mmd,
+                            netio_pkt_t* pkt, int start, int length,
+                            int location, uint16_t seed)
+{
+  mmd->csum_start = start;
+  mmd->csum_length = length;
+  mmd->csum_location = location;
+  mmd->csum_seed = seed;
+  mmd->flags |= _NETIO_PKT_NEED_EDMA_CSUM_MASK;
+}
+
+
+/** Set up an egress packet for hardware checksum computation.
+ * @ingroup egress
+ *
+ *  NetIO provides the ability to automatically calculate a standard
+ *  16-bit Internet checksum on transmitted packets.  The application
+ *  may specify the point in the packet where the checksum starts, the
+ *  number of bytes to be checksummed, and the two bytes in the packet
+ *  which will be replaced with the completed checksum.  (If the range
+ *  of bytes to be checksummed includes the bytes to be replaced, the
+ *  initial values of those bytes will be included in the checksum.)
+ *
+ *  For some protocols, the packet checksum covers data which is not present
+ *  in the packet, or is at least not contiguous to the main data payload.
+ *  For instance, the TCP checksum includes a "pseudo-header" which includes
+ *  the source and destination IP addresses of the packet.  To accommodate
+ *  this, the checksum engine may be "seeded" with an initial value, which
+ *  the application would need to compute based on the specific protocol's
+ *  requirements.  Note that the seed is given in host byte order (little-
+ *  endian), not network byte order (big-endian); code written to compute a
+ *  pseudo-header checksum in network byte order will need to byte-swap it
+ *  before use as the seed.
+ *
+ *  Note that the checksum is computed as part of the transmission process,
+ *  so it will not be present in the packet upon completion of this routine.
+ *
+ * @param[in,out] pkt Packet on which to operate.
+ * @param[in] start Offset within L2 packet of the first byte to include in
+ *   the checksum.
+ * @param[in] length Number of bytes to include in the checksum.
+ *   the checksum.
+ * @param[in] location Offset within L2 packet of the first of the two bytes
+ *   to be replaced with the calculated checksum.
+ * @param[in] seed Initial value of the running checksum before any of the
+ *   packet data is added.
+ */
+static __inline void
+NETIO_PKT_DO_EGRESS_CSUM(netio_pkt_t* pkt, int start, int length,
+                         int location, uint16_t seed)
+{
+  netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+  NETIO_PKT_DO_EGRESS_CSUM_MM(mmd, pkt, start, length, location, seed);
+}
+
+
+/** Return the number of bytes which could be prepended to a packet, using a
+ *  metadata pointer to speed the operation.
+ *  See @ref netio_populate_prepend_buffer() to get a full description of
+ *  prepending.
+ *
+ * @param[in,out] mda Pointer to packet's standard metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline int
+NETIO_PKT_PREPEND_AVAIL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+  return (pkt->__packet.bits.__offset << 6) +
+         NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt);
+}
+
+
+/** Return the number of bytes which could be prepended to a packet, using a
+ *  metadata pointer to speed the operation.
+ *  See @ref netio_populate_prepend_buffer() to get a full description of
+ *  prepending.
+ * @ingroup egress
+ *
+ * @param[in,out] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline int
+NETIO_PKT_PREPEND_AVAIL_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt)
+{
+  return (pkt->__packet.bits.__offset << 6) + mmd->l2_offset;
+}
+
+
+/** Return the number of bytes which could be prepended to a packet.
+ *  See @ref netio_populate_prepend_buffer() to get a full description of
+ *  prepending.
+ * @ingroup egress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline int
+NETIO_PKT_PREPEND_AVAIL(netio_pkt_t* pkt)
+{
+  if (NETIO_PKT_IS_MINIMAL(pkt))
+  {
+    netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt);
+
+    return NETIO_PKT_PREPEND_AVAIL_MM(mmd, pkt);
+  }
+  else
+  {
+    netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt);
+
+    return NETIO_PKT_PREPEND_AVAIL_M(mda, pkt);
+  }
+}
+
+
+/** Flush a packet's minimal metadata from the cache, using a metadata pointer
+ *  to speed the operation.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
+                                    netio_pkt_t* pkt)
+{
+}
+
+
+/** Invalidate a packet's minimal metadata from the cache, using a metadata
+ *  pointer to speed the operation.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
+                                  netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush and then invalidate a packet's minimal metadata from the cache,
+ *  using a metadata pointer to speed the operation.
+ * @ingroup egress
+ *
+ * @param[in] mmd Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd,
+                                        netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush a packet's metadata from the cache, using a metadata pointer
+ *  to speed the operation.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's minimal metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+}
+
+
+/** Invalidate a packet's metadata from the cache, using a metadata
+ *  pointer to speed the operation.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush and then invalidate a packet's metadata from the cache,
+ *  using a metadata pointer to speed the operation.
+ * @ingroup ingress
+ *
+ * @param[in] mda Pointer to packet's metadata.
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush a packet's minimal metadata from the cache.
+ * @ingroup egress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_MINIMAL_METADATA(netio_pkt_t* pkt)
+{
+}
+
+
+/** Invalidate a packet's minimal metadata from the cache.
+ * @ingroup egress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_INV_MINIMAL_METADATA(netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush and then invalidate a packet's minimal metadata from the cache.
+ * @ingroup egress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_INV_MINIMAL_METADATA(netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush a packet's metadata from the cache.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_METADATA(netio_pkt_t* pkt)
+{
+}
+
+
+/** Invalidate a packet's metadata from the cache.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_INV_METADATA(netio_pkt_t* pkt)
+{
+}
+
+
+/** Flush and then invalidate a packet's metadata from the cache.
+ * @ingroup ingress
+ *
+ * @param[in] pkt Packet on which to operate.
+ */
+static __inline void
+NETIO_PKT_FLUSH_INV_METADATA(netio_pkt_t* pkt)
+{
+}
+
+/** Number of NUMA nodes we can distribute buffers to.
+ * @ingroup setup */
+#define NETIO_NUM_NODE_WEIGHTS  16
+
+/**
+ * @brief An object for specifying the characteristics of NetIO communication
+ * endpoint.
+ *
+ * @ingroup setup
+ *
+ * The @ref netio_input_register() function uses this structure to define
+ * how an application tile will communicate with an IPP.
+ *
+ *
+ * Future updates to NetIO may add new members to this structure,
+ * which can affect the success of the registration operation.  Thus,
+ * if dynamically initializing the structure, applications are urged to
+ * zero it out first, for example:
+ *
+ * @code
+ * netio_input_config_t config;
+ * memset(&config, 0, sizeof (config));
+ * config.flags = NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE;
+ * config.num_receive_packets = NETIO_MAX_RECEIVE_PKTS;
+ * config.queue_id = 0;
+ *     .
+ *     .
+ *     .
+ * @endcode
+ *
+ * since that guarantees that any unused structure members, including
+ * members which did not exist when the application was first developed,
+ * will not have unexpected values.
+ *
+ * If statically initializing the structure, we strongly recommend use of
+ * C99-style named initializers, for example:
+ *
+ * @code
+ * netio_input_config_t config = {
+ *    .flags = NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE,
+ *    .num_receive_packets = NETIO_MAX_RECEIVE_PKTS,
+ *    .queue_id = 0,
+ * },
+ * @endcode
+ *
+ * instead of the old-style structure initialization:
+ *
+ * @code
+ * // Bad example! Currently equivalent to the above, but don't do this.
+ * netio_input_config_t config = {
+ *    NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE, NETIO_MAX_RECEIVE_PKTS, 0
+ * },
+ * @endcode
+ *
+ * since the C99 style requires no changes to the code if elements of the
+ * config structure are rearranged.  (It also makes the initialization much
+ * easier to understand.)
+ *
+ * Except for items which address a particular tile's transmit or receive
+ * characteristics, such as the ::NETIO_RECV flag, applications are advised
+ * to specify the same set of configuration data on all registrations.
+ * This prevents differing results if multiple tiles happen to do their
+ * registration operations in a different order on different invocations of
+ * the application.  This is particularly important for things like link
+ * management flags, and buffer size and homing specifications.
+ *
+ * Unless the ::NETIO_FIXED_BUFFER_VA flag is specified in flags, the NetIO
+ * buffer pool is automatically created and mapped into the application's
+ * virtual address space at an address chosen by the operating system,
+ * using the common memory (cmem) facility in the Tilera Multicore
+ * Components library.  The cmem facility allows multiple processes to gain
+ * access to shared memory which is mapped into each process at an
+ * identical virtual address.  In order for this to work, the processes
+ * must have a common ancestor, which must create the common memory using
+ * tmc_cmem_init().
+ *
+ * In programs using the iLib process creation API, or in programs which use
+ * only one process (which include programs using the pthreads library),
+ * tmc_cmem_init() is called automatically.  All other applications
+ * must call it explicitly, before any child processes which might call
+ * netio_input_register() are created.
+ */
+typedef struct
+{
+  /** Registration characteristics.
+
+      This value determines several characteristics of the registration;
+      flags for different types of behavior are ORed together to make the
+      final flag value.  Generally applications should specify exactly
+      one flag from each of the following categories:
+
+      - Whether the application will be receiving packets on this queue
+        (::NETIO_RECV or ::NETIO_NO_RECV).
+
+      - Whether the application will be transmitting packets on this queue,
+        and if so, whether it will request egress checksum calculation
+        (::NETIO_XMIT, ::NETIO_XMIT_CSUM, or ::NETIO_NO_XMIT).  It is
+        legal to call netio_get_buffer() without one of the XMIT flags,
+        as long as ::NETIO_RECV is specified; in this case, the retrieved
+        buffers must be passed to another tile for transmission.
+
+      - Whether the application expects any vendor-specific tags in
+        its packets' L2 headers (::NETIO_TAG_NONE, ::NETIO_TAG_BRCM,
+        or ::NETIO_TAG_MRVL).  This must match the configuration of the
+        target IPP.
+
+      To accommodate applications written to previous versions of the NetIO
+      interface, none of the flags above are currently required; if omitted,
+      NetIO behaves more or less as if ::NETIO_RECV | ::NETIO_XMIT_CSUM |
+      ::NETIO_TAG_NONE were used.  However, explicit specification of
+      the relevant flags allows NetIO to do a better job of resource
+      allocation, allows earlier detection of certain configuration errors,
+      and may enable advanced features or higher performance in the future,
+      so their use is strongly recommended.
+
+      Note that specifying ::NETIO_NO_RECV along with ::NETIO_NO_XMIT
+      is a special case, intended primarily for use by programs which
+      retrieve network statistics or do link management operations.
+      When these flags are both specified, the resulting queue may not
+      be used with NetIO routines other than netio_get(), netio_set(),
+      and netio_input_unregister().  See @ref link for more information
+      on link management.
+
+      Other flags are optional; their use is described below.
+  */
+  int flags;
+
+  /** Interface name.  This is a string which identifies the specific
+      Ethernet controller hardware to be used.  The format of the string
+      is a device type and a device index, separated by a slash; so,
+      the first 10 Gigabit Ethernet controller is named "xgbe/0", while
+      the second 10/100/1000 Megabit Ethernet controller is named "gbe/1".
+   */
+  const char* interface;
+
+  /** Receive packet queue size.  This specifies the maximum number
+      of ingress packets that can be received on this queue without
+      being retrieved by @ref netio_get_packet().  If the IPP's distribution
+      algorithm calls for a packet to be sent to this queue, and this
+      number of packets are already pending there, the new packet
+      will either be discarded, or sent to another tile registered
+      for the same queue_id (see @ref drops).  This value must
+      be at least ::NETIO_MIN_RECEIVE_PKTS, can always be at least
+      ::NETIO_MAX_RECEIVE_PKTS, and may be larger than that on certain
+      interfaces.
+   */
+  int num_receive_packets;
+
+  /** The queue ID being requested.  Legal values for this range from 0
+      to ::NETIO_MAX_QUEUE_ID, inclusive.  ::NETIO_MAX_QUEUE_ID is always
+      greater than or equal to the number of tiles; this allows one queue
+      for each tile, plus at least one additional queue.  Some applications
+      may wish to use the additional queue as a destination for unwanted
+      packets, since packets delivered to queues for which no tiles have
+      registered are discarded.
+   */
+  unsigned int queue_id;
+
+  /** Maximum number of small send buffers to be held in the local empty
+      buffer cache.  This specifies the size of the area which holds
+      empty small egress buffers requested from the IPP but not yet
+      retrieved via @ref netio_get_buffer().  This value must be greater
+      than zero if the application will ever use @ref netio_get_buffer()
+      to allocate empty small egress buffers; it may be no larger than
+      ::NETIO_MAX_SEND_BUFFERS.  See @ref epp for more details on empty
+      buffer caching.
+   */
+  int num_send_buffers_small_total;
+
+  /** Number of small send buffers to be preallocated at registration.
+      If this value is nonzero, the specified number of empty small egress
+      buffers will be requested from the IPP during the netio_input_register
+      operation; this may speed the execution of @ref netio_get_buffer().
+      This may be no larger than @ref num_send_buffers_small_total.  See @ref
+      epp for more details on empty buffer caching.
+   */
+  int num_send_buffers_small_prealloc;
+
+  /** Maximum number of large send buffers to be held in the local empty
+      buffer cache.  This specifies the size of the area which holds empty
+      large egress buffers requested from the IPP but not yet retrieved via
+      @ref netio_get_buffer().  This value must be greater than zero if the
+      application will ever use @ref netio_get_buffer() to allocate empty
+      large egress buffers; it may be no larger than ::NETIO_MAX_SEND_BUFFERS.
+      See @ref epp for more details on empty buffer caching.
+   */
+  int num_send_buffers_large_total;
+
+  /** Number of large send buffers to be preallocated at registration.
+      If this value is nonzero, the specified number of empty large egress
+      buffers will be requested from the IPP during the netio_input_register
+      operation; this may speed the execution of @ref netio_get_buffer().
+      This may be no larger than @ref num_send_buffers_large_total.  See @ref
+      epp for more details on empty buffer caching.
+   */
+  int num_send_buffers_large_prealloc;
+
+  /** Maximum number of jumbo send buffers to be held in the local empty
+      buffer cache.  This specifies the size of the area which holds empty
+      jumbo egress buffers requested from the IPP but not yet retrieved via
+      @ref netio_get_buffer().  This value must be greater than zero if the
+      application will ever use @ref netio_get_buffer() to allocate empty
+      jumbo egress buffers; it may be no larger than ::NETIO_MAX_SEND_BUFFERS.
+      See @ref epp for more details on empty buffer caching.
+   */
+  int num_send_buffers_jumbo_total;
+
+  /** Number of jumbo send buffers to be preallocated at registration.
+      If this value is nonzero, the specified number of empty jumbo egress
+      buffers will be requested from the IPP during the netio_input_register
+      operation; this may speed the execution of @ref netio_get_buffer().
+      This may be no larger than @ref num_send_buffers_jumbo_total.  See @ref
+      epp for more details on empty buffer caching.
+   */
+  int num_send_buffers_jumbo_prealloc;
+
+  /** Total packet buffer size.  This determines the total size, in bytes,
+      of the NetIO buffer pool.  Note that the maximum number of available
+      buffers of each size is determined during hypervisor configuration
+      (see the <em>System Programmer's Guide</em> for details); this just
+      influences how much host memory is allocated for those buffers.
+
+      The buffer pool is allocated from common memory, which will be
+      automatically initialized if needed.  If your buffer pool is larger
+      than 240 MB, you might need to explicitly call @c tmc_cmem_init(),
+      as described in the Application Libraries Reference Manual (UG227).
+
+      Packet buffers are currently allocated in chunks of 16 MB; this
+      value will be rounded up to the next larger multiple of 16 MB.
+      If this value is zero, a default of 32 MB will be used; this was
+      the value used by previous versions of NetIO.  Note that taking this
+      default also affects the placement of buffers on Linux NUMA nodes.
+      See @ref buffer_node_weights for an explanation of buffer placement.
+
+      In order to successfully allocate packet buffers, Linux must have
+      available huge pages on the relevant Linux NUMA nodes.  See the
+      <em>System Programmer's Guide</em> for information on configuring
+      huge page support in Linux.
+   */
+  uint64_t total_buffer_size;
+
+  /** Buffer placement weighting factors.
+
+      This array specifies the relative amount of buffering to place
+      on each of the available Linux NUMA nodes.  This array is
+      indexed by the NUMA node, and the values in the array are
+      proportional to the amount of buffer space to allocate on that
+      node.
+
+      If memory striping is enabled in the Hypervisor, then there is
+      only one logical NUMA node (node 0). In that case, NetIO will by
+      default ignore the suggested buffer node weights, and buffers
+      will be striped across the physical memory controllers. See
+      UG209 System Programmer's Guide for a description of the
+      hypervisor option that controls memory striping.
+
+      If memory striping is disabled, then there are up to four NUMA
+      nodes, corresponding to the four DDRAM controllers in the TILE
+      processor architecture.  See UG100 Tile Processor Architecture
+      Overview for a diagram showing the location of each of the DDRAM
+      controllers relative to the tile array.
+
+      For instance, if memory striping is disabled, the following
+      configuration strucure:
+
+      @code
+      netio_input_config_t config = {
+            .
+            .
+            .
+        .total_buffer_size = 4 * 16 * 1024 * 1024;
+        .buffer_node_weights = { 1, 0, 1, 0 },
+      },
+      @endcode
+
+      would result in 32 MB of buffers being placed on controller 0, and
+      32 MB on controller 2.  (Since buffers are allocated in units of
+      16 MB, some sets of weights will not be able to be matched exactly.)
+
+      For the weights to be effective, @ref total_buffer_size must be
+      nonzero.  If @ref total_buffer_size is zero, causing the default
+      32 MB of buffer space to be used, then any specified weights will
+      be ignored, and buffers will positioned as they were in previous
+      versions of NetIO:
+
+      - For xgbe/0 and gbe/0, 16 MB of buffers will be placed on controller 1,
+        and the other 16 MB will be placed on controller 2.
+
+      - For xgbe/1 and gbe/1, 16 MB of buffers will be placed on controller 2,
+        and the other 16 MB will be placed on controller 3.
+
+      If @ref total_buffer_size is nonzero, but all weights are zero,
+      then all buffer space will be allocated on Linux NUMA node zero.
+
+      By default, the specified buffer placement is treated as a hint;
+      if sufficient free memory is not available on the specified
+      controllers, the buffers will be allocated elsewhere.  However,
+      if the ::NETIO_STRICT_HOMING flag is specified in @ref flags, then a
+      failure to allocate buffer space exactly as requested will cause the
+      registration operation to fail with an error of ::NETIO_CANNOT_HOME.
+
+      Note that maximal network performance cannot be achieved with
+      only one memory controller.
+   */
+  uint8_t buffer_node_weights[NETIO_NUM_NODE_WEIGHTS];
+
+  /** Fixed virtual address for packet buffers.  Only valid when
+      ::NETIO_FIXED_BUFFER_VA is specified in @ref flags; see the
+      description of that flag for details.
+   */
+  void* fixed_buffer_va;
+
+  /**
+      Maximum number of outstanding send packet requests.  This value is
+      only relevant when an EPP is in use; it determines the number of
+      slots in the EPP's outgoing packet queue which this tile is allowed
+      to consume, and thus the number of packets which may be sent before
+      the sending tile must wait for an acknowledgment from the EPP.
+      Modifying this value is generally only helpful when using @ref
+      netio_send_packet_vector(), where it can help improve performance by
+      allowing a single vector send operation to process more packets.
+      Typically it is not specified, and the default, which divides the
+      outgoing packet slots evenly between all tiles on the chip, is used.
+
+      If a registration asks for more outgoing packet queue slots than are
+      available, ::NETIO_TOOMANY_XMIT will be returned.  The total number
+      of packet queue slots which are available for all tiles for each EPP
+      is subject to change, but is currently ::NETIO_TOTAL_SENDS_OUTSTANDING.
+
+
+      This value is ignored if ::NETIO_XMIT is not specified in flags.
+      If you want to specify a large value here for a specific tile, you are
+      advised to specify NETIO_NO_XMIT on other, non-transmitting tiles so
+      that they do not consume a default number of packet slots.  Any tile
+      transmitting is required to have at least ::NETIO_MIN_SENDS_OUTSTANDING
+      slots allocated to it; values less than that will be silently
+      increased by the NetIO library.
+   */
+  int num_sends_outstanding;
+}
+netio_input_config_t;
+
+
+/** Registration flags; used in the @ref netio_input_config_t structure.
+ * @addtogroup setup
+ */
+/** @{ */
+
+/** Fail a registration request if we can't put packet buffers
+    on the specified memory controllers. */
+#define NETIO_STRICT_HOMING   0x00000002
+
+/** This application expects no tags on its L2 headers. */
+#define NETIO_TAG_NONE        0x00000004
+
+/** This application expects Marvell extended tags on its L2 headers. */
+#define NETIO_TAG_MRVL        0x00000008
+
+/** This application expects Broadcom tags on its L2 headers. */
+#define NETIO_TAG_BRCM        0x00000010
+
+/** This registration may call routines which receive packets. */
+#define NETIO_RECV            0x00000020
+
+/** This registration may not call routines which receive packets. */
+#define NETIO_NO_RECV         0x00000040
+
+/** This registration may call routines which transmit packets. */
+#define NETIO_XMIT            0x00000080
+
+/** This registration may call routines which transmit packets with
+    checksum acceleration. */
+#define NETIO_XMIT_CSUM       0x00000100
+
+/** This registration may not call routines which transmit packets. */
+#define NETIO_NO_XMIT         0x00000200
+
+/** This registration wants NetIO buffers mapped at an application-specified
+    virtual address.
+
+    NetIO buffers are by default created by the TMC common memory facility,
+    which must be configured by a common ancestor of all processes sharing
+    a network interface.  When this flag is specified, NetIO buffers are
+    instead mapped at an address chosen by the application (and specified
+    in @ref netio_input_config_t::fixed_buffer_va).  This allows multiple
+    unrelated but cooperating processes to share a NetIO interface.
+    All processes sharing the same interface must specify this flag,
+    and all must specify the same fixed virtual address.
+
+    @ref netio_input_config_t::fixed_buffer_va must be a
+    multiple of 16 MB, and the packet buffers will occupy @ref
+    netio_input_config_t::total_buffer_size bytes of virtual address
+    space, beginning at that address.  If any of those virtual addresses
+    are currently occupied by other memory objects, like application or
+    shared library code or data, @ref netio_input_register() will return
+    ::NETIO_FAULT.  While it is impossible to provide a fixed_buffer_va
+    which will work for all applications, a good first guess might be to
+    use 0xb0000000 minus @ref netio_input_config_t::total_buffer_size.
+    If that fails, it might be helpful to consult the running application's
+    virtual address description file (/proc/<em>pid</em>/maps) to see
+    which regions of virtual address space are available.
+ */
+#define NETIO_FIXED_BUFFER_VA 0x00000400
+
+/** This registration call will not complete unless the network link
+    is up.  The process will wait several seconds for this to happen (the
+    precise interval is link-dependent), but if the link does not come up,
+    ::NETIO_LINK_DOWN will be returned.  This flag is the default if
+    ::NETIO_NOREQUIRE_LINK_UP is not specified.  Note that this flag by
+    itself does not request that the link be brought up; that can be done
+    with the ::NETIO_AUTO_LINK_UPDN or ::NETIO_AUTO_LINK_UP flags (the
+    latter is the default if no NETIO_AUTO_LINK_xxx flags are specified),
+    or by explicitly setting the link's desired state via netio_set().
+    If the link is not brought up by one of those methods, and this flag
+    is specified, the registration operation will return ::NETIO_LINK_DOWN.
+    This flag is ignored if it is specified along with ::NETIO_NO_XMIT and
+    ::NETIO_NO_RECV.  See @ref link for more information on link
+    management.
+ */
+#define NETIO_REQUIRE_LINK_UP    0x00000800
+
+/** This registration call will complete even if the network link is not up.
+    Whenever the link is not up, packets will not be sent or received:
+    netio_get_packet() will return ::NETIO_NOPKT once all queued packets
+    have been drained, and netio_send_packet() and similar routines will
+    return NETIO_QUEUE_FULL once the outgoing packet queue in the EPP
+    or the I/O shim is full.  See @ref link for more information on link
+    management.
+ */
+#define NETIO_NOREQUIRE_LINK_UP  0x00001000
+
+#ifndef __DOXYGEN__
+/*
+ * These are part of the implementation of the NETIO_AUTO_LINK_xxx flags,
+ * but should not be used directly by applications, and are thus not
+ * documented.
+ */
+#define _NETIO_AUTO_UP        0x00002000
+#define _NETIO_AUTO_DN        0x00004000
+#define _NETIO_AUTO_PRESENT   0x00008000
+#endif
+
+/** Set the desired state of the link to up, allowing any speeds which are
+    supported by the link hardware, as part of this registration operation.
+    Do not take down the link automatically.  This is the default if
+    no other NETIO_AUTO_LINK_xxx flags are specified.  This flag is ignored
+    if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV.
+    See @ref link for more information on link management.
+ */
+#define NETIO_AUTO_LINK_UP     (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP)
+
+/** Set the desired state of the link to up, allowing any speeds which are
+    supported by the link hardware, as part of this registration operation.
+    Set the desired state of the link to down the next time no tiles are
+    registered for packet reception or transmission.  This flag is ignored
+    if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV.
+    See @ref link for more information on link management.
+ */
+#define NETIO_AUTO_LINK_UPDN   (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP | \
+                                _NETIO_AUTO_DN)
+
+/** Set the desired state of the link to down the next time no tiles are
+    registered for packet reception or transmission.  This flag is ignored
+    if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV.
+    See @ref link for more information on link management.
+ */
+#define NETIO_AUTO_LINK_DN     (_NETIO_AUTO_PRESENT | _NETIO_AUTO_DN)
+
+/** Do not bring up the link automatically as part of this registration
+    operation.  Do not take down the link automatically.  This flag
+    is ignored if it is specified along with ::NETIO_NO_XMIT and
+    ::NETIO_NO_RECV.  See @ref link for more information on link management.
+  */
+#define NETIO_AUTO_LINK_NONE   _NETIO_AUTO_PRESENT
+
+
+/** Minimum number of receive packets. */
+#define NETIO_MIN_RECEIVE_PKTS            16
+
+/** Lower bound on the maximum number of receive packets; may be higher
+    than this on some interfaces. */
+#define NETIO_MAX_RECEIVE_PKTS           128
+
+/** Maximum number of send buffers, per packet size. */
+#define NETIO_MAX_SEND_BUFFERS            16
+
+/** Number of EPP queue slots, and thus outstanding sends, per EPP. */
+#define NETIO_TOTAL_SENDS_OUTSTANDING   2015
+
+/** Minimum number of EPP queue slots, and thus outstanding sends, per
+ *  transmitting tile. */
+#define NETIO_MIN_SENDS_OUTSTANDING       16
+
+
+/**@}*/
+
+#ifndef __DOXYGEN__
+
+/**
+ * An object for providing Ethernet packets to a process.
+ */
+struct __netio_queue_impl_t;
+
+/**
+ * An object for managing the user end of a NetIO queue.
+ */
+struct __netio_queue_user_impl_t;
+
+#endif /* !__DOXYGEN__ */
+
+
+/** A netio_queue_t describes a NetIO communications endpoint.
+ * @ingroup setup
+ */
+typedef struct
+{
+#ifdef __DOXYGEN__
+  uint8_t opaque[8];                 /**< This is an opaque structure. */
+#else
+  struct __netio_queue_impl_t* __system_part;    /**< The system part. */
+  struct __netio_queue_user_impl_t* __user_part; /**< The user part. */
+#ifdef _NETIO_PTHREAD
+  _netio_percpu_mutex_t lock;                    /**< Queue lock. */
+#endif
+#endif
+}
+netio_queue_t;
+
+
+/**
+ * @brief Packet send context.
+ *
+ * @ingroup egress
+ *
+ * Packet send context for use with netio_send_packet_prepare and _commit.
+ */
+typedef struct
+{
+#ifdef __DOXYGEN__
+  uint8_t opaque[44];   /**< This is an opaque structure. */
+#else
+  uint8_t flags;        /**< Defined below */
+  uint8_t datalen;      /**< Number of valid words pointed to by data. */
+  uint32_t request[9];  /**< Request to be sent to the EPP or shim.  Note
+                             that this is smaller than the 11-word maximum
+                             request size, since some constant values are
+                             not saved in the context. */
+  uint32_t *data;       /**< Data to be sent to the EPP or shim via IDN. */
+#endif
+}
+netio_send_pkt_context_t;
+
+
+#ifndef __DOXYGEN__
+#define SEND_PKT_CTX_USE_EPP   1  /**< We're sending to an EPP. */
+#define SEND_PKT_CTX_SEND_CSUM 2  /**< Request includes a checksum. */
+#endif
+
+/**
+ * @brief Packet vector entry.
+ *
+ * @ingroup egress
+ *
+ * This data structure is used with netio_send_packet_vector() to send multiple
+ * packets with one NetIO call.  The structure should be initialized by
+ * calling netio_pkt_vector_set(), rather than by setting the fields
+ * directly.
+ *
+ * This structure is guaranteed to be a power of two in size, no
+ * bigger than one L2 cache line, and to be aligned modulo its size.
+ */
+typedef struct
+#ifndef __DOXYGEN__
+__attribute__((aligned(8)))
+#endif
+{
+  /** Reserved for use by the user application.  When initialized with
+   *  the netio_set_pkt_vector_entry() function, this field is guaranteed
+   *  to be visible to readers only after all other fields are already
+   *  visible.  This way it can be used as a valid flag or generation
+   *  counter. */
+  uint8_t user_data;
+
+  /* Structure members below this point should not be accessed directly by
+   * applications, as they may change in the future. */
+
+  /** Low 8 bits of the packet address to send.  The high bits are
+   *  acquired from the 'handle' field. */
+  uint8_t buffer_address_low;
+
+  /** Number of bytes to transmit. */
+  uint16_t size;
+
+  /** The raw handle from a netio_pkt_t.  If this is NETIO_PKT_HANDLE_NONE,
+   *  this vector entry will be skipped and no packet will be transmitted. */
+  netio_pkt_handle_t handle;
+}
+netio_pkt_vector_entry_t;
+
+
+/**
+ * @brief Initialize fields in a packet vector entry.
+ *
+ * @ingroup egress
+ *
+ * @param[out] v Pointer to the vector entry to be initialized.
+ * @param[in] pkt Packet to be transmitted when the vector entry is passed to
+ *        netio_send_packet_vector().  Note that the packet's attributes
+ *        (e.g., its L2 offset and length) are captured at the time this
+ *        routine is called; subsequent changes in those attributes will not
+ *        be reflected in the packet which is actually transmitted.
+ *        Changes in the packet's contents, however, will be so reflected.
+ *        If this is NULL, no packet will be transmitted.
+ * @param[in] user_data User data to be set in the vector entry.
+ *        This function guarantees that the "user_data" field will become
+ *        visible to a reader only after all other fields have become visible.
+ *        This allows a structure in a ring buffer to be written and read
+ *        by a polling reader without any locks or other synchronization.
+ */
+static __inline void
+netio_pkt_vector_set(volatile netio_pkt_vector_entry_t* v, netio_pkt_t* pkt,
+                     uint8_t user_data)
+{
+  if (pkt)
+  {
+    if (NETIO_PKT_IS_MINIMAL(pkt))
+    {
+      netio_pkt_minimal_metadata_t* mmd =
+        (netio_pkt_minimal_metadata_t*) &pkt->__metadata;
+      v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_MM(mmd, pkt) & 0xFF;
+      v->size = NETIO_PKT_L2_LENGTH_MM(mmd, pkt);
+    }
+    else
+    {
+      netio_pkt_metadata_t* mda = &pkt->__metadata;
+      v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_M(mda, pkt) & 0xFF;
+      v->size = NETIO_PKT_L2_LENGTH_M(mda, pkt);
+    }
+    v->handle.word = pkt->__packet.word;
+  }
+  else
+  {
+    v->handle.word = 0;   /* Set handle to NETIO_PKT_HANDLE_NONE. */
+  }
+
+  __asm__("" : : : "memory");
+
+  v->user_data = user_data;
+}
+
+
+/**
+ * Flags and structures for @ref netio_get() and @ref netio_set().
+ * @ingroup config
+ */
+
+/** @{ */
+/** Parameter class; addr is a NETIO_PARAM_xxx value. */
+#define NETIO_PARAM       0
+/** Interface MAC address. This address is only valid with @ref netio_get().
+ *  The value is a 6-byte MAC address.  Depending upon the overall system
+ *  design, a MAC address may or may not be available for each interface. */
+#define NETIO_PARAM_MAC        0
+
+/** Determine whether to suspend output on the receipt of pause frames.
+ *  If the value is nonzero, the I/O shim will suspend output when a pause
+ *  frame is received.  If the value is zero, pause frames will be ignored. */
+#define NETIO_PARAM_PAUSE_IN   1
+
+/** Determine whether to send pause frames if the I/O shim packet FIFOs are
+ *  nearly full.  If the value is zero, pause frames are not sent.  If
+ *  the value is nonzero, it is the delay value which will be sent in any
+ *  pause frames which are output, in units of 512 bit times. */
+#define NETIO_PARAM_PAUSE_OUT  2
+
+/** Jumbo frame support.  The value is a 4-byte integer.  If the value is
+ *  nonzero, the MAC will accept frames of up to 10240 bytes.  If the value
+ *  is zero, the MAC will only accept frames of up to 1544 bytes. */
+#define NETIO_PARAM_JUMBO      3
+
+/** I/O shim's overflow statistics register.  The value is two 16-bit integers.
+ *  The first 16-bit value (or the low 16 bits, if the value is treated as a
+ *  32-bit number) is the count of packets which were completely dropped and
+ *  not delivered by the shim.  The second 16-bit value (or the high 16 bits,
+ *  if the value is treated as a 32-bit number) is the count of packets
+ *  which were truncated and thus only partially delivered by the shim.  This
+ *  register is automatically reset to zero after it has been read.
+ */
+#define NETIO_PARAM_OVERFLOW   4
+
+/** IPP statistics.  This address is only valid with @ref netio_get().  The
+ *  value is a netio_stat_t structure.  Unlike the I/O shim statistics, the
+ *  IPP statistics are not all reset to zero on read; see the description
+ *  of the netio_stat_t for details. */
+#define NETIO_PARAM_STAT 5
+
+/** Possible link state.  The value is a combination of "NETIO_LINK_xxx"
+ *  flags.  With @ref netio_get(), this will indicate which flags are
+ *  actually supported by the hardware.
+ *
+ *  For historical reasons, specifying this value to netio_set() will have
+ *  the same behavior as using ::NETIO_PARAM_LINK_CONFIG, but this usage is
+ *  discouraged.
+ */
+#define NETIO_PARAM_LINK_POSSIBLE_STATE 6
+
+/** Link configuration. The value is a combination of "NETIO_LINK_xxx" flags.
+ *  With @ref netio_set(), this will attempt to immediately bring up the
+ *  link using whichever of the requested flags are supported by the
+ *  hardware, or take down the link if the flags are zero; if this is
+ *  not possible, an error will be returned.  Many programs will want
+ *  to use ::NETIO_PARAM_LINK_DESIRED_STATE instead.
+ *
+ *  For historical reasons, specifying this value to netio_get() will
+ *  have the same behavior as using ::NETIO_PARAM_LINK_POSSIBLE_STATE,
+ *  but this usage is discouraged.
+ */
+#define NETIO_PARAM_LINK_CONFIG NETIO_PARAM_LINK_POSSIBLE_STATE
+
+/** Current link state. This address is only valid with @ref netio_get().
+ *  The value is zero or more of the "NETIO_LINK_xxx" flags, ORed together.
+ *  If the link is down, the value ANDed with NETIO_LINK_SPEED will be
+ *  zero; if the link is up, the value ANDed with NETIO_LINK_SPEED will
+ *  result in exactly one of the NETIO_LINK_xxx values, indicating the
+ *  current speed. */
+#define NETIO_PARAM_LINK_CURRENT_STATE 7
+
+/** Variant symbol for current state, retained for compatibility with
+ *  pre-MDE-2.1 programs. */
+#define NETIO_PARAM_LINK_STATUS NETIO_PARAM_LINK_CURRENT_STATE
+
+/** Packet Coherence protocol. This address is only valid with @ref netio_get().
+ *  The value is nonzero if the interface is configured for cache-coherent DMA.
+ */
+#define NETIO_PARAM_COHERENT 8
+
+/** Desired link state. The value is a conbination of "NETIO_LINK_xxx"
+ *  flags, which specify the desired state for the link.  With @ref
+ *  netio_set(), this will, in the background, attempt to bring up the link
+ *  using whichever of the requested flags are reasonable, or take down the
+ *  link if the flags are zero.  The actual link up or down operation may
+ *  happen after this call completes.  If the link state changes in the
+ *  future, the system will continue to try to get back to the desired link
+ *  state; for instance, if the link is brought up successfully, and then
+ *  the network cable is disconnected, the link will go down.  However, the
+ *  desired state of the link is still up, so if the cable is reconnected,
+ *  the link will be brought up again.
+ *
+ *  With @ref netio_get(), this will indicate the desired state for the
+ *  link, as set with a previous netio_set() call, or implicitly by a
+ *  netio_input_register() or netio_input_unregister() operation.  This may
+ *  not reflect the current state of the link; to get that, use
+ *  ::NETIO_PARAM_LINK_CURRENT_STATE. */
+#define NETIO_PARAM_LINK_DESIRED_STATE 9
+
+/** NetIO statistics structure.  Retrieved using the ::NETIO_PARAM_STAT
+ *  address passed to @ref netio_get(). */
+typedef struct
+{
+  /** Number of packets which have been received by the IPP and forwarded
+   *  to a tile's receive queue for processing.  This value wraps at its
+   *  maximum, and is not cleared upon read. */
+  uint32_t packets_received;
+
+  /** Number of packets which have been dropped by the IPP, because they could
+   *  not be received, or could not be forwarded to a tile.  The former happens
+   *  when the IPP does not have a free packet buffer of suitable size for an
+   *  incoming frame.  The latter happens when all potential destination tiles
+   *  for a packet, as defined by the group, bucket, and queue configuration,
+   *  have full receive queues.   This value wraps at its maximum, and is not
+   *  cleared upon read. */
+  uint32_t packets_dropped;
+
+  /*
+   * Note: the #defines after each of the following four one-byte values
+   * denote their location within the third word of the netio_stat_t.  They
+   * are intended for use only by the IPP implementation and are thus omitted
+   * from the Doxygen output.
+   */
+
+  /** Number of packets dropped because no worker was able to accept a new
+   *  packet.  This value saturates at its maximum, and is cleared upon
+   *  read. */
+  uint8_t drops_no_worker;
+#ifndef __DOXYGEN__
+#define NETIO_STAT_DROPS_NO_WORKER   0
+#endif
+
+  /** Number of packets dropped because no small buffers were available.
+   *  This value saturates at its maximum, and is cleared upon read. */
+  uint8_t drops_no_smallbuf;
+#ifndef __DOXYGEN__
+#define NETIO_STAT_DROPS_NO_SMALLBUF 1
+#endif
+
+  /** Number of packets dropped because no large buffers were available.
+   *  This value saturates at its maximum, and is cleared upon read. */
+  uint8_t drops_no_largebuf;
+#ifndef __DOXYGEN__
+#define NETIO_STAT_DROPS_NO_LARGEBUF 2
+#endif
+
+  /** Number of packets dropped because no jumbo buffers were available.
+   *  This value saturates at its maximum, and is cleared upon read. */
+  uint8_t drops_no_jumbobuf;
+#ifndef __DOXYGEN__
+#define NETIO_STAT_DROPS_NO_JUMBOBUF 3
+#endif
+}
+netio_stat_t;
+
+
+/** Link can run, should run, or is running at 10 Mbps. */
+#define NETIO_LINK_10M         0x01
+
+/** Link can run, should run, or is running at 100 Mbps. */
+#define NETIO_LINK_100M        0x02
+
+/** Link can run, should run, or is running at 1 Gbps. */
+#define NETIO_LINK_1G          0x04
+
+/** Link can run, should run, or is running at 10 Gbps. */
+#define NETIO_LINK_10G         0x08
+
+/** Link should run at the highest speed supported by the link and by
+ *  the device connected to the link.  Only usable as a value for
+ *  the link's desired state; never returned as a value for the current
+ *  or possible states. */
+#define NETIO_LINK_ANYSPEED    0x10
+
+/** All legal link speeds. */
+#define NETIO_LINK_SPEED  (NETIO_LINK_10M  | \
+                           NETIO_LINK_100M | \
+                           NETIO_LINK_1G   | \
+                           NETIO_LINK_10G  | \
+                           NETIO_LINK_ANYSPEED)
+
+
+/** MAC register class.  Addr is a register offset within the MAC.
+ *  Registers within the XGbE and GbE MACs are documented in the Tile
+ *  Processor I/O Device Guide (UG104). MAC registers start at address
+ *  0x4000, and do not include the MAC_INTERFACE registers. */
+#define NETIO_MAC             1
+
+/** MDIO register class (IEEE 802.3 clause 22 format).  Addr is the "addr"
+ *  member of a netio_mdio_addr_t structure. */
+#define NETIO_MDIO            2
+
+/** MDIO register class (IEEE 802.3 clause 45 format).  Addr is the "addr"
+ *  member of a netio_mdio_addr_t structure. */
+#define NETIO_MDIO_CLAUSE45   3
+
+/** NetIO MDIO address type.  Retrieved or provided using the ::NETIO_MDIO
+ *  address passed to @ref netio_get() or @ref netio_set(). */
+typedef union
+{
+  struct
+  {
+    unsigned int reg:16;  /**< MDIO register offset.  For clause 22 access,
+                               must be less than 32. */
+    unsigned int phy:5;   /**< Which MDIO PHY to access. */
+    unsigned int dev:5;   /**< Which MDIO device to access within that PHY.
+                               Applicable for clause 45 access only; ignored
+                               for clause 22 access. */
+  }
+  bits;                   /**< Container for bitfields. */
+  uint64_t addr;          /**< Value to pass to @ref netio_get() or
+                           *   @ref netio_set(). */
+}
+netio_mdio_addr_t;
+
+/** @} */
+
+#endif /* __NETIO_INTF_H__ */
index 112b1e248f0555985109e921616265c926dd16a7..b4c8e8ec45dc7fa041befe4d12e56c4d94236f8f 100644 (file)
@@ -15,3 +15,4 @@ obj-$(CONFIG_SMP)             += smpboot.o smp.o tlb.o
 obj-$(CONFIG_MODULES)          += module.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_PCI)              += pci.o
index 67617a05e602380a7d1fba86dadba25db17a13ef..dbc213adf5e1dac8557e38647266c730ecb7e6eb 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kdev_t.h>
 #include <linux/fs.h>
 #include <linux/fcntl.h>
-#include <linux/smp_lock.h>
 #include <linux/uaccess.h>
 #include <linux/signal.h>
 #include <asm/syscalls.h>
index fb64b99959d42dd796c6d16c4b471cc8d9769a50..543d6a33aa26f6c02f7f41f59fcdceea1729bcd8 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
new file mode 100644 (file)
index 0000000..a1ee25b
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/byteorder.h>
+#include <asm/hv_driver.h>
+#include <hv/drv_pcie_rc_intf.h>
+
+
+/*
+ * Initialization flow and process
+ * -------------------------------
+ *
+ * This files containes the routines to search for PCI buses,
+ * enumerate the buses, and configure any attached devices.
+ *
+ * There are two entry points here:
+ * 1) tile_pci_init
+ *    This sets up the pci_controller structs, and opens the
+ *    FDs to the hypervisor.  This is called from setup_arch() early
+ *    in the boot process.
+ * 2) pcibios_init
+ *    This probes the PCI bus(es) for any attached hardware.  It's
+ *    called by subsys_initcall.  All of the real work is done by the
+ *    generic Linux PCI layer.
+ *
+ */
+
+/*
+ * This flag tells if the platform is TILEmpower that needs
+ * special configuration for the PLX switch chip.
+ */
+int __write_once tile_plx_gen1;
+
+static struct pci_controller controllers[TILE_NUM_PCIE];
+static int num_controllers;
+
+static struct pci_ops tile_cfg_ops;
+
+
+/*
+ * We don't need to worry about the alignment of resources.
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+                           resource_size_t size, resource_size_t align)
+{
+       return res->start;
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+/*
+ * Open a FD to the hypervisor PCI device.
+ *
+ * controller_id is the controller number, config type is 0 or 1 for
+ * config0 or config1 operations.
+ */
+static int __init tile_pcie_open(int controller_id, int config_type)
+{
+       char filename[32];
+       int fd;
+
+       sprintf(filename, "pcie/%d/config%d", controller_id, config_type);
+
+       fd = hv_dev_open((HV_VirtAddr)filename, 0);
+
+       return fd;
+}
+
+
+/*
+ * Get the IRQ numbers from the HV and set up the handlers for them.
+ */
+static int __init tile_init_irqs(int controller_id,
+                                struct pci_controller *controller)
+{
+       char filename[32];
+       int fd;
+       int ret;
+       int x;
+       struct pcie_rc_config rc_config;
+
+       sprintf(filename, "pcie/%d/ctl", controller_id);
+       fd = hv_dev_open((HV_VirtAddr)filename, 0);
+       if (fd < 0) {
+               pr_err("PCI: hv_dev_open(%s) failed\n", filename);
+               return -1;
+       }
+       ret = hv_dev_pread(fd, 0, (HV_VirtAddr)(&rc_config),
+                          sizeof(rc_config), PCIE_RC_CONFIG_MASK_OFF);
+       hv_dev_close(fd);
+       if (ret != sizeof(rc_config)) {
+               pr_err("PCI: wanted %zd bytes, got %d\n",
+                      sizeof(rc_config), ret);
+               return -1;
+       }
+       /* Record irq_base so that we can map INTx to IRQ # later. */
+       controller->irq_base = rc_config.intr;
+
+       for (x = 0; x < 4; x++)
+               tile_irq_activate(rc_config.intr + x,
+                                 TILE_IRQ_HW_CLEAR);
+
+       if (rc_config.plx_gen1)
+               controller->plx_gen1 = 1;
+
+       return 0;
+}
+
+/*
+ * First initialization entry point, called from setup_arch().
+ *
+ * Find valid controllers and fill in pci_controller structs for each
+ * of them.
+ *
+ * Returns the number of controllers discovered.
+ */
+int __init tile_pci_init(void)
+{
+       int i;
+
+       pr_info("PCI: Searching for controllers...\n");
+
+       /* Do any configuration we need before using the PCIe */
+
+       for (i = 0; i < TILE_NUM_PCIE; i++) {
+               int hv_cfg_fd0 = -1;
+               int hv_cfg_fd1 = -1;
+               int hv_mem_fd = -1;
+               char name[32];
+               struct pci_controller *controller;
+
+               /*
+                * Open the fd to the HV.  If it fails then this
+                * device doesn't exist.
+                */
+               hv_cfg_fd0 = tile_pcie_open(i, 0);
+               if (hv_cfg_fd0 < 0)
+                       continue;
+               hv_cfg_fd1 = tile_pcie_open(i, 1);
+               if (hv_cfg_fd1 < 0) {
+                       pr_err("PCI: Couldn't open config fd to HV "
+                           "for controller %d\n", i);
+                       goto err_cont;
+               }
+
+               sprintf(name, "pcie/%d/mem", i);
+               hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
+               if (hv_mem_fd < 0) {
+                       pr_err("PCI: Could not open mem fd to HV!\n");
+                       goto err_cont;
+               }
+
+               pr_info("PCI: Found PCI controller #%d\n", i);
+
+               controller = &controllers[num_controllers];
+
+               if (tile_init_irqs(i, controller)) {
+                       pr_err("PCI: Could not initialize "
+                              "IRQs, aborting.\n");
+                       goto err_cont;
+               }
+
+               controller->index = num_controllers;
+               controller->hv_cfg_fd[0] = hv_cfg_fd0;
+               controller->hv_cfg_fd[1] = hv_cfg_fd1;
+               controller->hv_mem_fd = hv_mem_fd;
+               controller->first_busno = 0;
+               controller->last_busno = 0xff;
+               controller->ops = &tile_cfg_ops;
+
+               num_controllers++;
+               continue;
+
+err_cont:
+               if (hv_cfg_fd0 >= 0)
+                       hv_dev_close(hv_cfg_fd0);
+               if (hv_cfg_fd1 >= 0)
+                       hv_dev_close(hv_cfg_fd1);
+               if (hv_mem_fd >= 0)
+                       hv_dev_close(hv_mem_fd);
+               continue;
+       }
+
+       /*
+        * Before using the PCIe, see if we need to do any platform-specific
+        * configuration, such as the PLX switch Gen 1 issue on TILEmpower.
+        */
+       for (i = 0; i < num_controllers; i++) {
+               struct pci_controller *controller = &controllers[i];
+
+               if (controller->plx_gen1)
+                       tile_plx_gen1 = 1;
+       }
+
+       return num_controllers;
+}
+
+/*
+ * (pin - 1) converts from the PCI standard's [1:4] convention to
+ * a normal [0:3] range.
+ */
+static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       struct pci_controller *controller =
+               (struct pci_controller *)dev->sysdata;
+       return (pin - 1) + controller->irq_base;
+}
+
+
+static void __init fixup_read_and_payload_sizes(void)
+{
+       struct pci_dev *dev = NULL;
+       int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
+       int max_read_size = 0x2; /* Limit to 512 byte reads. */
+       u16 new_values;
+
+       /* Scan for the smallest maximum payload size. */
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               int pcie_caps_offset;
+               u32 devcap;
+               int max_payload;
+
+               pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
+               if (pcie_caps_offset == 0)
+                       continue;
+
+               pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP,
+                                     &devcap);
+               max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD;
+               if (max_payload < smallest_max_payload)
+                       smallest_max_payload = max_payload;
+       }
+
+       /* Now, set the max_payload_size for all devices to that value. */
+       new_values = (max_read_size << 12) | (smallest_max_payload << 5);
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               int pcie_caps_offset;
+               u16 devctl;
+
+               pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP);
+               if (pcie_caps_offset == 0)
+                       continue;
+
+               pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
+                                    &devctl);
+               devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
+               devctl |= new_values;
+               pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL,
+                                     devctl);
+       }
+}
+
+
+/*
+ * Second PCI initialization entry point, called by subsys_initcall.
+ *
+ * The controllers have been set up by the time we get here, by a call to
+ * tile_pci_init.
+ */
+static int __init pcibios_init(void)
+{
+       int i;
+
+       pr_info("PCI: Probing PCI hardware\n");
+
+       /*
+        * Delay a bit in case devices aren't ready.  Some devices are
+        * known to require at least 20ms here, but we use a more
+        * conservative value.
+        */
+       mdelay(250);
+
+       /* Scan all of the recorded PCI controllers.  */
+       for (i = 0; i < num_controllers; i++) {
+               struct pci_controller *controller = &controllers[i];
+               struct pci_bus *bus;
+
+               pr_info("PCI: initializing controller #%d\n", i);
+
+               /*
+                * This comes from the generic Linux PCI driver.
+                *
+                * It reads the PCI tree for this bus into the Linux
+                * data structures.
+                *
+                * This is inlined in linux/pci.h and calls into
+                * pci_scan_bus_parented() in probe.c.
+                */
+               bus = pci_scan_bus(0, controller->ops, controller);
+               controller->root_bus = bus;
+               controller->last_busno = bus->subordinate;
+
+       }
+
+       /* Do machine dependent PCI interrupt routing */
+       pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
+
+       /*
+        * This comes from the generic Linux PCI driver.
+        *
+        * It allocates all of the resources (I/O memory, etc)
+        * associated with the devices read in above.
+        */
+
+       pci_assign_unassigned_resources();
+
+       /* Configure the max_read_size and max_payload_size values. */
+       fixup_read_and_payload_sizes();
+
+       /* Record the I/O resources in the PCI controller structure. */
+       for (i = 0; i < num_controllers; i++) {
+               struct pci_bus *root_bus = controllers[i].root_bus;
+               struct pci_bus *next_bus;
+               struct pci_dev *dev;
+
+               list_for_each_entry(dev, &root_bus->devices, bus_list) {
+                       /* Find the PCI host controller, ie. the 1st bridge. */
+                       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+                               (PCI_SLOT(dev->devfn) == 0)) {
+                               next_bus = dev->subordinate;
+                               controllers[i].mem_resources[0] =
+                                       *next_bus->resource[0];
+                               controllers[i].mem_resources[1] =
+                                        *next_bus->resource[1];
+                               controllers[i].mem_resources[2] =
+                                        *next_bus->resource[2];
+
+                               break;
+                       }
+               }
+
+       }
+
+       return 0;
+}
+subsys_initcall(pcibios_init);
+
+/*
+ * No bus fixups needed.
+ */
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+       /* Nothing needs to be done. */
+}
+
+/*
+ * This can be called from the generic PCI layer, but doesn't need to
+ * do anything.
+ */
+char __devinit *pcibios_setup(char *str)
+{
+       /* Nothing needs to be done. */
+       return str;
+}
+
+/*
+ * This is called from the generic Linux layer.
+ */
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ * Enable memory and/or address decoding, as appropriate, for the
+ * device described by the 'dev' struct.
+ *
+ * This is called from the generic PCI layer, and can be called
+ * for bridges or endpoints.
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+       u16 cmd, old_cmd;
+       u8 header_type;
+       int i;
+       struct resource *r;
+
+       pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       old_cmd = cmd;
+       if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+               /*
+                * For bridges, we enable both memory and I/O decoding
+                * in call cases.
+                */
+               cmd |= PCI_COMMAND_IO;
+               cmd |= PCI_COMMAND_MEMORY;
+       } else {
+               /*
+                * For endpoints, we enable memory and/or I/O decoding
+                * only if they have a memory resource of that type.
+                */
+               for (i = 0; i < 6; i++) {
+                       r = &dev->resource[i];
+                       if (r->flags & IORESOURCE_UNSET) {
+                               pr_err("PCI: Device %s not available "
+                                      "because of resource collisions\n",
+                                      pci_name(dev));
+                               return -EINVAL;
+                       }
+                       if (r->flags & IORESOURCE_IO)
+                               cmd |= PCI_COMMAND_IO;
+                       if (r->flags & IORESOURCE_MEM)
+                               cmd |= PCI_COMMAND_MEMORY;
+               }
+       }
+
+       /*
+        * We only write the command if it changed.
+        */
+       if (cmd != old_cmd)
+               pci_write_config_word(dev, PCI_COMMAND, cmd);
+       return 0;
+}
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+       unsigned long start = pci_resource_start(dev, bar);
+       unsigned long len = pci_resource_len(dev, bar);
+       unsigned long flags = pci_resource_flags(dev, bar);
+
+       if (!len)
+               return NULL;
+       if (max && len > max)
+               len = max;
+
+       if (!(flags & IORESOURCE_MEM)) {
+               pr_info("PCI: Trying to map invalid resource %#lx\n", flags);
+               start = 0;
+       }
+
+       return (void __iomem *)start;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+
+/****************************************************************
+ *
+ * Tile PCI config space read/write routines
+ *
+ ****************************************************************/
+
+/*
+ * These are the normal read and write ops
+ * These are expanded with macros from  pci_bus_read_config_byte() etc.
+ *
+ * devfn is the combined PCI slot & function.
+ *
+ * offset is in bytes, from the start of config space for the
+ * specified bus & slot.
+ */
+
+static int __devinit tile_cfg_read(struct pci_bus *bus,
+                                  unsigned int devfn,
+                                  int offset,
+                                  int size,
+                                  u32 *val)
+{
+       struct pci_controller *controller = bus->sysdata;
+       int busnum = bus->number & 0xff;
+       int slot = (devfn >> 3) & 0x1f;
+       int function = devfn & 0x7;
+       u32 addr;
+       int config_mode = 1;
+
+       /*
+        * There is no bridge between the Tile and bus 0, so we
+        * use config0 to talk to bus 0.
+        *
+        * If we're talking to a bus other than zero then we
+        * must have found a bridge.
+        */
+       if (busnum == 0) {
+               /*
+                * We fake an empty slot for (busnum == 0) && (slot > 0),
+                * since there is only one slot on bus 0.
+                */
+               if (slot) {
+                       *val = 0xFFFFFFFF;
+                       return 0;
+               }
+               config_mode = 0;
+       }
+
+       addr = busnum << 20;            /* Bus in 27:20 */
+       addr |= slot << 15;             /* Slot (device) in 19:15 */
+       addr |= function << 12;         /* Function is in 14:12 */
+       addr |= (offset & 0xFFF);       /* byte address in 0:11 */
+
+       return hv_dev_pread(controller->hv_cfg_fd[config_mode], 0,
+                           (HV_VirtAddr)(val), size, addr);
+}
+
+
+/*
+ * See tile_cfg_read() for relevent comments.
+ * Note that "val" is the value to write, not a pointer to that value.
+ */
+static int __devinit tile_cfg_write(struct pci_bus *bus,
+                                   unsigned int devfn,
+                                   int offset,
+                                   int size,
+                                   u32 val)
+{
+       struct pci_controller *controller = bus->sysdata;
+       int busnum = bus->number & 0xff;
+       int slot = (devfn >> 3) & 0x1f;
+       int function = devfn & 0x7;
+       u32 addr;
+       int config_mode = 1;
+       HV_VirtAddr valp = (HV_VirtAddr)&val;
+
+       /*
+        * For bus 0 slot 0 we use config 0 accesses.
+        */
+       if (busnum == 0) {
+               /*
+                * We fake an empty slot for (busnum == 0) && (slot > 0),
+                * since there is only one slot on bus 0.
+                */
+               if (slot)
+                       return 0;
+               config_mode = 0;
+       }
+
+       addr = busnum << 20;            /* Bus in 27:20 */
+       addr |= slot << 15;             /* Slot (device) in 19:15 */
+       addr |= function << 12;         /* Function is in 14:12 */
+       addr |= (offset & 0xFFF);       /* byte address in 0:11 */
+
+#ifdef __BIG_ENDIAN
+       /* Point to the correct part of the 32-bit "val". */
+       valp += 4 - size;
+#endif
+
+       return hv_dev_pwrite(controller->hv_cfg_fd[config_mode], 0,
+                            valp, size, addr);
+}
+
+
+static struct pci_ops tile_cfg_ops = {
+       .read =         tile_cfg_read,
+       .write =        tile_cfg_write,
+};
+
+
+/*
+ * In the following, each PCI controller's mem_resources[1]
+ * represents its (non-prefetchable) PCI memory resource.
+ * mem_resources[0] and mem_resources[2] refer to its PCI I/O and
+ * prefetchable PCI memory resources, respectively.
+ * For more details, see pci_setup_bridge() in setup-bus.c.
+ * By comparing the target PCI memory address against the
+ * end address of controller 0, we can determine the controller
+ * that should accept the PCI memory access.
+ */
+#define TILE_READ(size, type)                                          \
+type _tile_read##size(unsigned long addr)                              \
+{                                                                      \
+       type val;                                                       \
+       int idx = 0;                                                    \
+       if (addr > controllers[0].mem_resources[1].end &&               \
+           addr > controllers[0].mem_resources[2].end)                 \
+               idx = 1;                                                \
+       if (hv_dev_pread(controllers[idx].hv_mem_fd, 0,                 \
+                        (HV_VirtAddr)(&val), sizeof(type), addr))      \
+               pr_err("PCI: read %zd bytes at 0x%lX failed\n",         \
+                      sizeof(type), addr);                             \
+       return val;                                                     \
+}                                                                      \
+EXPORT_SYMBOL(_tile_read##size)
+
+TILE_READ(b, u8);
+TILE_READ(w, u16);
+TILE_READ(l, u32);
+TILE_READ(q, u64);
+
+#define TILE_WRITE(size, type)                                         \
+void _tile_write##size(type val, unsigned long addr)                   \
+{                                                                      \
+       int idx = 0;                                                    \
+       if (addr > controllers[0].mem_resources[1].end &&               \
+           addr > controllers[0].mem_resources[2].end)                 \
+               idx = 1;                                                \
+       if (hv_dev_pwrite(controllers[idx].hv_mem_fd, 0,                \
+                         (HV_VirtAddr)(&val), sizeof(type), addr))     \
+               pr_err("PCI: write %zd bytes at 0x%lX failed\n",        \
+                      sizeof(type), addr);                             \
+}                                                                      \
+EXPORT_SYMBOL(_tile_write##size)
+
+TILE_WRITE(b, u8);
+TILE_WRITE(w, u16);
+TILE_WRITE(l, u32);
+TILE_WRITE(q, u64);
index fb0b3cbeae149081a5b3011f0230fbd48f4d56dd..f18573643ed1e940c34af318e2ecf81a949be92e 100644 (file)
@@ -840,7 +840,7 @@ static int __init topology_init(void)
        for_each_online_node(i)
                register_one_node(i);
 
-       for_each_present_cpu(i)
+       for (i = 0; i < smp_height * smp_width; ++i)
                register_cpu(&cpu_devices[i], i);
 
        return 0;
index 687719d4abd1eba56fbd591852c8fab51950bc52..757407e36696688d59810453b1ffca8da8522a62 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index 74d62d098edf455bddb73852535b69e733d442a0..b949edcec200b60018c7ecf6a9aef049771e0260 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
index 7e764669a0222755db93373089539e18ade539d8..e2187d24a9b41d8ad765f1a383347525dc728a5f 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/mman.h>
 #include <linux/file.h>
index 6235283b4859e031b22d5a168ef611fc0b4368c8..cc3d9badf03057d2a2ec38d74b6b6bf57c24d592 100644 (file)
 
 void *memchr(const void *s, int c, size_t n)
 {
+       const uint32_t *last_word_ptr;
+       const uint32_t *p;
+       const char *last_byte_ptr;
+       uintptr_t s_int;
+       uint32_t goal, before_mask, v, bits;
+       char *ret;
+
+       if (__builtin_expect(n == 0, 0)) {
+               /* Don't dereference any memory if the array is empty. */
+               return NULL;
+       }
+
        /* Get an aligned pointer. */
-       const uintptr_t s_int = (uintptr_t) s;
-       const uint32_t *p = (const uint32_t *)(s_int & -4);
+       s_int = (uintptr_t) s;
+       p = (const uint32_t *)(s_int & -4);
 
        /* Create four copies of the byte for which we are looking. */
-       const uint32_t goal = 0x01010101 * (uint8_t) c;
+       goal = 0x01010101 * (uint8_t) c;
 
        /* Read the first word, but munge it so that bytes before the array
         * will not match goal.
@@ -31,23 +43,14 @@ void *memchr(const void *s, int c, size_t n)
         * Note that this shift count expression works because we know
         * shift counts are taken mod 32.
         */
-       const uint32_t before_mask = (1 << (s_int << 3)) - 1;
-       uint32_t v = (*p | before_mask) ^ (goal & before_mask);
+       before_mask = (1 << (s_int << 3)) - 1;
+       v = (*p | before_mask) ^ (goal & before_mask);
 
        /* Compute the address of the last byte. */
-       const char *const last_byte_ptr = (const char *)s + n - 1;
+       last_byte_ptr = (const char *)s + n - 1;
 
        /* Compute the address of the word containing the last byte. */
-       const uint32_t *const last_word_ptr =
-           (const uint32_t *)((uintptr_t) last_byte_ptr & -4);
-
-       uint32_t bits;
-       char *ret;
-
-       if (__builtin_expect(n == 0, 0)) {
-               /* Don't dereference any memory if the array is empty. */
-               return NULL;
-       }
+       last_word_ptr = (const uint32_t *)((uintptr_t) last_byte_ptr & -4);
 
        while ((bits = __insn_seqb(v, goal)) == 0) {
                if (__builtin_expect(p == last_word_ptr, 0)) {
index 485e24d62c6bfd5658727d3873ab488e27732d8d..5cd1c4004ecaee49ce19cd55782b8161cf2c5ffc 100644 (file)
@@ -167,23 +167,30 @@ void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val)
         * when we compare them.
         */
        u32 my_ticket_;
+       u32 iterations = 0;
 
-       /* Take out the next ticket; this will also stop would-be readers. */
-       if (val & 1)
-               val = get_rwlock(rwlock);
-       rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
+       /*
+        * Wait until there are no readers, then bump up the next
+        * field and capture the ticket value.
+        */
+       for (;;) {
+               if (!(val & 1)) {
+                       if ((val >> RD_COUNT_SHIFT) == 0)
+                               break;
+                       rwlock->lock = val;
+               }
+               delay_backoff(iterations++);
+               val = __insn_tns((int *)&rwlock->lock);
+       }
 
-       /* Extract my ticket value from the original word. */
+       /* Take out the next ticket and extract my ticket value. */
+       rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
        my_ticket_ = val >> WR_NEXT_SHIFT;
 
-       /*
-        * Wait until the "current" field matches our ticket, and
-        * there are no remaining readers.
-        */
+       /* Wait until the "current" field matches our ticket. */
        for (;;) {
                u32 curr_ = val >> WR_CURR_SHIFT;
-               u32 readers = val >> RD_COUNT_SHIFT;
-               u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers;
+               u32 delta = ((my_ticket_ - curr_) & WR_MASK);
                if (likely(delta == 0))
                        break;
 
index f295b4ac941de22b760651f5ac019361e00802d2..dcebfc831cd6e94a23571681cd341db358d8d807 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/tty.h>
index 24688b697a8d92e48284daff0643b61cfd11c281..201a582c413752c40ec6fc87bfc87ca3e73bb8d2 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
index 7f7338c90784e01489be21b91e269ce85d757d21..1664cce7b0ac5774313ed2805b58f6cac8058279 100644 (file)
@@ -727,6 +727,9 @@ struct winch {
 
 static void free_winch(struct winch *winch, int free_irq_ok)
 {
+       if (free_irq_ok)
+               free_irq(WINCH_IRQ, winch);
+
        list_del(&winch->list);
 
        if (winch->pid != -1)
@@ -735,8 +738,6 @@ static void free_winch(struct winch *winch, int free_irq_ok)
                os_close_file(winch->fd);
        if (winch->stack != 0)
                free_stack(winch->stack, 0);
-       if (free_irq_ok)
-               free_irq(WINCH_IRQ, winch);
        kfree(winch);
 }
 
index 340268be00b5a934f6fc3ac632c26e53b58623ec..09bd7b585726cdcd2109a5a70250a8871bbdcaf7 100644 (file)
@@ -5,7 +5,6 @@
 
 #include "linux/stddef.h"
 #include "linux/fs.h"
-#include "linux/smp_lock.h"
 #include "linux/ptrace.h"
 #include "linux/sched.h"
 #include "linux/slab.h"
index 849813f398e75e8f699b5a5e999efad7df1a76a8..5852519b2d0f94005d688159c045b52b69c8766b 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/syscalls.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
-#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/uio.h>
 #include <linux/poll.h>
index 4d293dced62f4c178cd19e6cb2eae882678afb33..9479a037419fe1358a96cece0d877a269c71e365 100644 (file)
@@ -216,8 +216,8 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
 }
 
 /* Return an pointer with offset calculated */
-static inline unsigned long __set_fixmap_offset(enum fixed_addresses idx,
-                               phys_addr_t phys, pgprot_t flags)
+static __always_inline unsigned long
+__set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
 {
        __set_fixmap(idx, phys, flags);
        return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1));
index 3ea3dc4870474bdbbb7d0a14e1c43e52c428ddd4..6b89f5e860214266d7270160f739e9a9be290802 100644 (file)
 #define FAM10H_MMIO_CONF_ENABLE                (1<<0)
 #define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf
 #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
-#define FAM10H_MMIO_CONF_BASE_MASK     0xfffffff
+#define FAM10H_MMIO_CONF_BASE_MASK     0xfffffffULL
 #define FAM10H_MMIO_CONF_BASE_SHIFT    20
 #define MSR_FAM10H_NODE_ID             0xc001100c
 
index 7f7e577a0e39cfca111c5a0b4718480b01c86170..31d84acc15125646018914b51a758821ec796590 100644 (file)
@@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
                            struct pvclock_vcpu_time_info *vcpu,
                            struct timespec *ts);
+void pvclock_resume(void);
 
 /*
  * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
index e969f691cbfde23c6ffd53a540d0e3841084255d..a501741c2335a854fa43d14f73761d8bf8f9c82e 100644 (file)
@@ -199,6 +199,8 @@ union uvh_apicid {
 #define UVH_APICID             0x002D0E00L
 #define UV_APIC_PNODE_SHIFT    6
 
+#define UV_APICID_HIBIT_MASK   0xffff0000
+
 /* Local Bus from cpu's perspective */
 #define LOCAL_BUS_BASE         0x1c00000
 #define LOCAL_BUS_SIZE         (4 * 1024 * 1024)
@@ -491,8 +493,10 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
        }
 }
 
+extern unsigned int uv_apicid_hibits;
 static unsigned long uv_hub_ipi_value(int apicid, int vector, int mode)
 {
+       apicid |= uv_apicid_hibits;
        return (1UL << UVH_IPI_INT_SEND_SHFT) |
                        ((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
                        (mode << UVH_IPI_INT_DELIVERY_MODE_SHFT) |
index 6d90adf4428a03d90d183dcd1a77cb2b630fc8e2..20cafeac7455594d73a3bc6837da0a34fcdee3eb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI UV MMR definitions
  *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_X86_UV_UV_MMRS_H
@@ -753,6 +753,23 @@ union uvh_lb_bau_sb_descriptor_base_u {
     } s;
 };
 
+/* ========================================================================= */
+/*                   UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK                     */
+/* ========================================================================= */
+#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL
+#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x009f0
+
+#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0
+#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL
+
+union uvh_lb_target_physical_apic_id_mask_u {
+       unsigned long v;
+       struct uvh_lb_target_physical_apic_id_mask_s {
+               unsigned long bit_enables : 32;  /* RW */
+               unsigned long rsvd_32_63  : 32;  /*    */
+       } s;
+};
+
 /* ========================================================================= */
 /*                               UVH_NODE_ID                                 */
 /* ========================================================================= */
index e8506c1f0c55115e8282ef5b8177b824f88df282..1c10c88ee4e1a5154168b4b35a6ba34857687fc9 100644 (file)
@@ -61,9 +61,9 @@ DEFINE_GUEST_HANDLE(void);
 #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
 #endif
 
-#ifndef machine_to_phys_mapping
-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
-#endif
+#define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
+#define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
+#define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT)
 
 /* Maximum number of virtual CPUs in multi-processor guests. */
 #define MAX_VIRT_CPUS 32
index 42a7e004ae5ca5372553fec8a9059378ab6a55c4..8413688b2571d760f77d918713b758345bdece0a 100644 (file)
 /* And the trap vector is... */
 #define TRAP_INSTR "int $0x82"
 
+#define __MACH2PHYS_VIRT_START 0xF5800000
+#define __MACH2PHYS_VIRT_END   0xF6800000
+
+#define __MACH2PHYS_SHIFT      2
+
 /*
  * Virtual addresses beyond this are not modifiable by guest OSes. The
  * machine->physical mapping table starts at this address, read-only.
index 100d2662b97c3c8a821fc6039e93a06b7a2924c7..839a4811cf983630faa5b724277aafacfefe36cb 100644 (file)
 #define __HYPERVISOR_VIRT_END   0xFFFF880000000000
 #define __MACH2PHYS_VIRT_START  0xFFFF800000000000
 #define __MACH2PHYS_VIRT_END    0xFFFF804000000000
-
-#ifndef HYPERVISOR_VIRT_START
-#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-#define HYPERVISOR_VIRT_END   mk_unsigned_long(__HYPERVISOR_VIRT_END)
-#endif
-
-#define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
-#define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
-#define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
-#ifndef machine_to_phys_mapping
-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
-#endif
+#define __MACH2PHYS_SHIFT       3
 
 /*
  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
index dd8c1414b3d57540d374fee9d923947aaa57ceb1..8760cc60a21c8af5bcc7be1993bdf0b67c0eeb06 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/pfn.h>
+#include <linux/mm.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -35,6 +36,8 @@ typedef struct xpaddr {
 #define MAX_DOMAIN_PAGES                                               \
     ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
 
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int   machine_to_phys_order;
 
 extern unsigned long get_phys_to_machine(unsigned long pfn);
 extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
@@ -69,10 +72,8 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
-#if 0
        if (unlikely((mfn >> machine_to_phys_order) != 0))
-               return max_mapnr;
-#endif
+               return ~0;
 
        pfn = 0;
        /*
index 194539aea1757d79058e3ec17acbeaa68ae6432f..c1c52c341f40a607be5b252746db31f36b8dc561 100644 (file)
@@ -44,6 +44,8 @@ static u64 gru_start_paddr, gru_end_paddr;
 static union uvh_apicid uvh_apicid;
 int uv_min_hub_revision_id;
 EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
+unsigned int uv_apicid_hibits;
+EXPORT_SYMBOL_GPL(uv_apicid_hibits);
 static DEFINE_SPINLOCK(uv_nmi_lock);
 
 static inline bool is_GRU_range(u64 start, u64 end)
@@ -85,6 +87,23 @@ static void __init early_get_apic_pnode_shift(void)
                uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
 }
 
+/*
+ * Add an extra bit as dictated by bios to the destination apicid of
+ * interrupts potentially passing through the UV HUB.  This prevents
+ * a deadlock between interrupts and IO port operations.
+ */
+static void __init uv_set_apicid_hibit(void)
+{
+       union uvh_lb_target_physical_apic_id_mask_u apicid_mask;
+       unsigned long *mmr;
+
+       mmr = early_ioremap(UV_LOCAL_MMR_BASE |
+               UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK, sizeof(*mmr));
+       apicid_mask.v = *mmr;
+       early_iounmap(mmr, sizeof(*mmr));
+       uv_apicid_hibits = apicid_mask.s.bit_enables & UV_APICID_HIBIT_MASK;
+}
+
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        int nodeid;
@@ -102,6 +121,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
                        __get_cpu_var(x2apic_extra_bits) =
                                nodeid << (uvh_apicid.s.pnode_shift - 1);
                        uv_system_type = UV_NON_UNIQUE_APIC;
+                       uv_set_apicid_hibit();
                        return 1;
                }
        }
@@ -155,6 +175,7 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri
        int pnode;
 
        pnode = uv_apicid_to_pnode(phys_apicid);
+       phys_apicid |= uv_apicid_hibits;
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
            (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
            ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
@@ -236,7 +257,7 @@ static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask)
        int cpu = cpumask_first(cpumask);
 
        if ((unsigned)cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
+               return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits;
        else
                return BAD_APICID;
 }
@@ -255,7 +276,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       return per_cpu(x86_cpu_to_apicid, cpu);
+       return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits;
 }
 
 static unsigned int x2apic_get_apic_id(unsigned long x)
index 1b7b31ab7d86536ecde1d68034cf882216ac32a6..212a6a42527c5fcbd0a79f05e4ed7d1cff077cf7 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
index 59e175e89599c96462707f8fe368a86405e9bce4..591e60104278e41445fd7069e5f05d8cc5680a07 100644 (file)
@@ -395,7 +395,7 @@ sysenter_past_esp:
         * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
         * pushed above; +8 corresponds to copy_thread's esp0 setting.
         */
-       pushl_cfi (TI_sysenter_return-THREAD_SIZE_asm+8+4*4)(%esp)
+       pushl_cfi ((TI_sysenter_return)-THREAD_SIZE_asm+8+4*4)(%esp)
        CFI_REL_OFFSET eip, 0
 
        pushl_cfi %eax
index ec592caac4b4e11b5d7ac0bc2986d6617ac4b90b..cd21b654dec6c70382b68ab29f4364ab60ff4e88 100644 (file)
@@ -315,14 +315,18 @@ static void kgdb_remove_all_hw_break(void)
                if (!breakinfo[i].enabled)
                        continue;
                bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
-               if (bp->attr.disabled == 1)
+               if (!bp->attr.disabled) {
+                       arch_uninstall_hw_breakpoint(bp);
+                       bp->attr.disabled = 1;
                        continue;
+               }
                if (dbg_is_early)
                        early_dr7 &= ~encode_dr7(i, breakinfo[i].len,
                                                 breakinfo[i].type);
-               else
-                       arch_uninstall_hw_breakpoint(bp);
-               bp->attr.disabled = 1;
+               else if (hw_break_release_slot(i))
+                       printk(KERN_ERR "KGDB: hw bpt remove failed %lx\n",
+                              breakinfo[i].addr);
+               breakinfo[i].enabled = 0;
        }
 }
 
index 6da143c2a6b8b27f03a611bad88047879c80f3bf..ac861b8348e2d9dd3f863dece898a2974d7bff51 100644 (file)
@@ -25,7 +25,6 @@ struct pci_hostbridge_probe {
 };
 
 static u64 __cpuinitdata fam10h_pci_mmconf_base;
-static int __cpuinitdata fam10h_pci_mmconf_base_status;
 
 static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
        { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
@@ -44,10 +43,12 @@ static int __cpuinit cmp_range(const void *x1, const void *x2)
        return start1 - start2;
 }
 
-/*[47:0] */
-/* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */
+#define MMCONF_UNIT (1ULL << FAM10H_MMIO_CONF_BASE_SHIFT)
+#define MMCONF_MASK (~(MMCONF_UNIT - 1))
+#define MMCONF_SIZE (MMCONF_UNIT << 8)
+/* need to avoid (0xfd<<32), (0xfe<<32), and (0xff<<32), ht used space */
 #define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32)
-#define BASE_VALID(b) ((b != (0xfdULL << 32)) && (b != (0xfeULL << 32)))
+#define BASE_VALID(b) ((b) + MMCONF_SIZE <= (0xfdULL<<32) || (b) >= (1ULL<<40))
 static void __cpuinit get_fam10h_pci_mmconf_base(void)
 {
        int i;
@@ -64,12 +65,11 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
        struct range range[8];
 
        /* only try to get setting from BSP */
-       /* -1 or 1 */
-       if (fam10h_pci_mmconf_base_status)
+       if (fam10h_pci_mmconf_base)
                return;
 
        if (!early_pci_allowed())
-               goto fail;
+               return;
 
        found = 0;
        for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
@@ -91,7 +91,7 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
        }
 
        if (!found)
-               goto fail;
+               return;
 
        /* SYS_CFG */
        address = MSR_K8_SYSCFG;
@@ -99,16 +99,16 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 
        /* TOP_MEM2 is not enabled? */
        if (!(val & (1<<21))) {
-               tom2 = 0;
+               tom2 = 1ULL << 32;
        } else {
                /* TOP_MEM2 */
                address = MSR_K8_TOP_MEM2;
                rdmsrl(address, val);
-               tom2 = val & (0xffffULL<<32);
+               tom2 = max(val & 0xffffff800000ULL, 1ULL << 32);
        }
 
        if (base <= tom2)
-               base = tom2 + (1ULL<<32);
+               base = (tom2 + 2 * MMCONF_UNIT - 1) & MMCONF_MASK;
 
        /*
         * need to check if the range is in the high mmio range that is
@@ -123,11 +123,11 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
                if (!(reg & 3))
                        continue;
 
-               start = (((u64)reg) << 8) & (0xffULL << 32); /* 39:16 on 31:8*/
+               start = (u64)(reg & 0xffffff00) << 8; /* 39:16 on 31:8*/
                reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
-               end = (((u64)reg) << 8) & (0xffULL << 32); /* 39:16 on 31:8*/
+               end = ((u64)(reg & 0xffffff00) << 8) | 0xffff; /* 39:16 on 31:8*/
 
-               if (!end)
+               if (end < tom2)
                        continue;
 
                range[hi_mmio_num].start = start;
@@ -143,32 +143,27 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void)
 
        if (range[hi_mmio_num - 1].end < base)
                goto out;
-       if (range[0].start > base)
+       if (range[0].start > base + MMCONF_SIZE)
                goto out;
 
        /* need to find one window */
-       base = range[0].start - (1ULL << 32);
+       base = (range[0].start & MMCONF_MASK) - MMCONF_UNIT;
        if ((base > tom2) && BASE_VALID(base))
                goto out;
-       base = range[hi_mmio_num - 1].end + (1ULL << 32);
-       if ((base > tom2) && BASE_VALID(base))
+       base = (range[hi_mmio_num - 1].end + MMCONF_UNIT) & MMCONF_MASK;
+       if (BASE_VALID(base))
                goto out;
        /* need to find window between ranges */
-       if (hi_mmio_num > 1)
-       for (i = 0; i < hi_mmio_num - 1; i++) {
-               if (range[i + 1].start > (range[i].end + (1ULL << 32))) {
-                       base = range[i].end + (1ULL << 32);
-                       if ((base > tom2) && BASE_VALID(base))
-                               goto out;
-               }
+       for (i = 1; i < hi_mmio_num; i++) {
+               base = (range[i - 1].end + MMCONF_UNIT) & MMCONF_MASK;
+               val = range[i].start & MMCONF_MASK;
+               if (val >= base + MMCONF_SIZE && BASE_VALID(base))
+                       goto out;
        }
-
-fail:
-       fam10h_pci_mmconf_base_status = -1;
        return;
+
 out:
        fam10h_pci_mmconf_base = base;
-       fam10h_pci_mmconf_base_status = 1;
 }
 
 void __cpuinit fam10h_check_enable_mmcfg(void)
@@ -190,11 +185,10 @@ void __cpuinit fam10h_check_enable_mmcfg(void)
 
                /* only trust the one handle 256 buses, if acpi=off */
                if (!acpi_pci_disabled || busnbits >= 8) {
-                       u64 base;
-                       base = val & (0xffffULL << 32);
-                       if (fam10h_pci_mmconf_base_status <= 0) {
+                       u64 base = val & MMCONF_MASK;
+
+                       if (!fam10h_pci_mmconf_base) {
                                fam10h_pci_mmconf_base = base;
-                               fam10h_pci_mmconf_base_status = 1;
                                return;
                        } else if (fam10h_pci_mmconf_base ==  base)
                                return;
@@ -206,8 +200,10 @@ void __cpuinit fam10h_check_enable_mmcfg(void)
         * with 256 buses
         */
        get_fam10h_pci_mmconf_base();
-       if (fam10h_pci_mmconf_base_status <= 0)
+       if (!fam10h_pci_mmconf_base) {
+               pci_probe &= ~PCI_CHECK_ENABLE_AMD_MMCONF;
                return;
+       }
 
        printk(KERN_INFO "Enable MMCONFIG on AMD Family 10h\n");
        val &= ~((FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT) |
index 7bf2dc4c8f701de8965fc1e124126863c7384552..12fcbe2c143e5e3c7a9e62f58981a78f5355bd64 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
index 008b91eefa188139f57f7b77de6c7aef6240ef08..42eb3300dfc6c35630aab267e051678f1a677e59 100644 (file)
@@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
 
 static atomic64_t last_value = ATOMIC64_INIT(0);
 
+void pvclock_resume(void)
+{
+       atomic64_set(&last_value, 0);
+}
+
 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
 {
        struct pvclock_shadow_time shadow;
index 82e144a4e514249c140f5c28a8bd0df00869b5ca..1ca12298ffc74f2d783effb35da0953163bbb314 100644 (file)
@@ -3395,6 +3395,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
        load_host_msrs(vcpu);
+       kvm_load_ldt(ldt_selector);
        loadsegment(fs, fs_selector);
 #ifdef CONFIG_X86_64
        load_gs_index(gs_selector);
@@ -3402,7 +3403,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 #else
        loadsegment(gs, gs_selector);
 #endif
-       kvm_load_ldt(ldt_selector);
 
        reload_tss(vcpu);
 
index 8da0e45ff7c9cde22d424583adbb2786cf78a72a..ff21fdda0c53b6dbf2ca84b1e4e2300e2a659b90 100644 (file)
@@ -821,10 +821,9 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
 #endif
 
 #ifdef CONFIG_X86_64
-       if (is_long_mode(&vmx->vcpu)) {
-               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+       rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+       if (is_long_mode(&vmx->vcpu))
                wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-       }
 #endif
        for (i = 0; i < vmx->save_nmsrs; ++i)
                kvm_set_shared_msr(vmx->guest_msrs[i].index,
@@ -839,23 +838,23 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 
        ++vmx->vcpu.stat.host_state_reload;
        vmx->host_state.loaded = 0;
-       if (vmx->host_state.fs_reload_needed)
-               loadsegment(fs, vmx->host_state.fs_sel);
+#ifdef CONFIG_X86_64
+       if (is_long_mode(&vmx->vcpu))
+               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+#endif
        if (vmx->host_state.gs_ldt_reload_needed) {
                kvm_load_ldt(vmx->host_state.ldt_sel);
 #ifdef CONFIG_X86_64
                load_gs_index(vmx->host_state.gs_sel);
-               wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
 #else
                loadsegment(gs, vmx->host_state.gs_sel);
 #endif
        }
+       if (vmx->host_state.fs_reload_needed)
+               loadsegment(fs, vmx->host_state.fs_sel);
        reload_tss();
 #ifdef CONFIG_X86_64
-       if (is_long_mode(&vmx->vcpu)) {
-               rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-               wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
-       }
+       wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
        if (current_thread_info()->status & TS_USEDFPU)
                clts();
index 12cdbb17ad181dfac805d60f4991ee1eacfb935c..6acc724d5d8ff759f93290a2591c84945f9e6bd2 100644 (file)
@@ -223,7 +223,7 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
 
 static void __cpuinit calculate_tlb_offset(void)
 {
-       int cpu, node, nr_node_vecs;
+       int cpu, node, nr_node_vecs, idx = 0;
        /*
         * we are changing tlb_vector_offset for each CPU in runtime, but this
         * will not cause inconsistency, as the write is atomic under X86. we
@@ -239,7 +239,7 @@ static void __cpuinit calculate_tlb_offset(void)
                nr_node_vecs = NUM_INVALIDATE_TLB_VECTORS/nr_online_nodes;
 
        for_each_online_node(node) {
-               int node_offset = (node % NUM_INVALIDATE_TLB_VECTORS) *
+               int node_offset = (idx % NUM_INVALIDATE_TLB_VECTORS) *
                        nr_node_vecs;
                int cpu_offset = 0;
                for_each_cpu(cpu, cpumask_of_node(node)) {
@@ -248,6 +248,7 @@ static void __cpuinit calculate_tlb_offset(void)
                        cpu_offset++;
                        cpu_offset = cpu_offset % nr_node_vecs;
                }
+               idx++;
        }
 }
 
index d7b5109f7a9c28b05e120da3eec295b1716f543e..25cd4a07d09f78cbe850733f0d2d36d98fe5d176 100644 (file)
@@ -70,6 +70,9 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
 struct xen_pci_frontend_ops *xen_pci_frontend;
 EXPORT_SYMBOL_GPL(xen_pci_frontend);
 
+#define XEN_PIRQ_MSI_DATA  (MSI_DATA_TRIGGER_EDGE | \
+               MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0))
+
 static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
                struct msi_msg *msg)
 {
@@ -83,12 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
                MSI_ADDR_REDIRECTION_CPU |
                MSI_ADDR_DEST_ID(pirq);
 
-       msg->data =
-               MSI_DATA_TRIGGER_EDGE |
-               MSI_DATA_LEVEL_ASSERT |
-               /* delivery mode reserved */
-               (3 << 8) |
-               MSI_DATA_VECTOR(0);
+       msg->data = XEN_PIRQ_MSI_DATA;
 }
 
 static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
@@ -98,8 +96,23 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
        struct msi_msg msg;
 
        list_for_each_entry(msidesc, &dev->msi_list, list) {
+               __read_msi_msg(msidesc, &msg);
+               pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
+                       ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
+               if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) {
+                       xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
+                                       "msi-x" : "msi", &irq, &pirq, XEN_ALLOC_IRQ);
+                       if (irq < 0)
+                               goto error;
+                       ret = set_irq_msi(irq, msidesc);
+                       if (ret < 0)
+                               goto error_while;
+                       printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d"
+                                       " pirq=%d\n", irq, pirq);
+                       return 0;
+               }
                xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
-                               "msi-x" : "msi", &irq, &pirq);
+                               "msi-x" : "msi", &irq, &pirq, (XEN_ALLOC_IRQ | XEN_ALLOC_PIRQ));
                if (irq < 0 || pirq < 0)
                        goto error;
                printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
index a318194002b56c3a953df57a9664c5f02745d2ba..ba9caa808a9c1b42c6a616968c57e96769039314 100644 (file)
@@ -1455,7 +1455,7 @@ static void __init uv_init_uvhub(int uvhub, int vector)
         * the below initialization can't be in firmware because the
         * messaging IRQ will be determined by the OS
         */
-       apicid = uvhub_to_first_apicid(uvhub);
+       apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits;
        uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
                                      ((apicid << 32) | vector));
 }
index 56e421bc379b19931d4db718b35e3b92e71c3d5e..9daf5d1af9f190015b8b9be646aac14cbe6c2c44 100644 (file)
@@ -89,6 +89,7 @@ static void uv_rtc_send_IPI(int cpu)
 
        apicid = cpu_physical_id(cpu);
        pnode = uv_apicid_to_pnode(apicid);
+       apicid |= uv_apicid_hibits;
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
              (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
              (X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);
@@ -107,6 +108,7 @@ static int uv_intr_pending(int pnode)
 static int uv_setup_intr(int cpu, u64 expires)
 {
        u64 val;
+       unsigned long apicid = cpu_physical_id(cpu) | uv_apicid_hibits;
        int pnode = uv_cpu_to_pnode(cpu);
 
        uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
@@ -117,7 +119,7 @@ static int uv_setup_intr(int cpu, u64 expires)
                UVH_EVENT_OCCURRED0_RTC1_MASK);
 
        val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
-               ((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
+               ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
 
        /* Set configuration */
        uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val);
index 235c0f4d3861da6f1c9d64ded710c7c2176cf895..44dcad43989dc983af51863fac28677e2cfdaaee 100644 (file)
@@ -75,6 +75,11 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 enum xen_domain_type xen_domain_type = XEN_NATIVE;
 EXPORT_SYMBOL_GPL(xen_domain_type);
 
+unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
+EXPORT_SYMBOL(machine_to_phys_mapping);
+unsigned int   machine_to_phys_order;
+EXPORT_SYMBOL(machine_to_phys_order);
+
 struct start_info *xen_start_info;
 EXPORT_SYMBOL_GPL(xen_start_info);
 
@@ -1016,10 +1021,6 @@ static void xen_reboot(int reason)
 {
        struct sched_shutdown r = { .reason = reason };
 
-#ifdef CONFIG_SMP
-       stop_other_cpus();
-#endif
-
        if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
                BUG();
 }
@@ -1090,6 +1091,8 @@ static void __init xen_setup_stackprotector(void)
 /* First C function to be called on Xen boot */
 asmlinkage void __init xen_start_kernel(void)
 {
+       struct physdev_set_iopl set_iopl;
+       int rc;
        pgd_t *pgd;
 
        if (!xen_start_info)
@@ -1097,6 +1100,8 @@ asmlinkage void __init xen_start_kernel(void)
 
        xen_domain_type = XEN_PV_DOMAIN;
 
+       xen_setup_machphys_mapping();
+
        /* Install Xen paravirt ops */
        pv_info = xen_info;
        pv_init_ops = xen_init_ops;
@@ -1191,8 +1196,6 @@ asmlinkage void __init xen_start_kernel(void)
        /* Allocate and initialize top and mid mfn levels for p2m structure */
        xen_build_mfn_list_list();
 
-       init_mm.pgd = pgd;
-
        /* keep using Xen gdt for now; no urgent need to change it */
 
 #ifdef CONFIG_X86_32
@@ -1202,10 +1205,18 @@ asmlinkage void __init xen_start_kernel(void)
 #else
        pv_info.kernel_rpl = 0;
 #endif
-
        /* set the limit of our address space */
        xen_reserve_top();
 
+       /* We used to do this in xen_arch_setup, but that is too late on AMD
+        * were early_cpu_init (run before ->arch_setup()) calls early_amd_init
+        * which pokes 0xcf8 port.
+        */
+       set_iopl.iopl = 1;
+       rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
+       if (rc != 0)
+               xen_raw_printk("physdev_op failed %d\n", rc);
+
 #ifdef CONFIG_X86_32
        /* set up basic CPUID stuff */
        cpu_detect(&new_cpu_data);
index 21ed8d7f75a5aa6fa85970d177979457d6b94d5c..44924e551fde2566989ce6aa6cc886447686b977 100644 (file)
@@ -2034,6 +2034,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
        set_page_prot(pmd, PAGE_KERNEL_RO);
 }
 
+void __init xen_setup_machphys_mapping(void)
+{
+       struct xen_machphys_mapping mapping;
+       unsigned long machine_to_phys_nr_ents;
+
+       if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
+               machine_to_phys_mapping = (unsigned long *)mapping.v_start;
+               machine_to_phys_nr_ents = mapping.max_mfn + 1;
+       } else {
+               machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
+       }
+       machine_to_phys_order = fls(machine_to_phys_nr_ents - 1);
+}
+
 #ifdef CONFIG_X86_64
 static void convert_pfn_mfn(void *v)
 {
@@ -2119,44 +2133,83 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
        return pgd;
 }
 #else  /* !CONFIG_X86_64 */
-static RESERVE_BRK_ARRAY(pmd_t, level2_kernel_pgt, PTRS_PER_PMD);
+static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
+static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD);
+
+static __init void xen_write_cr3_init(unsigned long cr3)
+{
+       unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir));
+
+       BUG_ON(read_cr3() != __pa(initial_page_table));
+       BUG_ON(cr3 != __pa(swapper_pg_dir));
+
+       /*
+        * We are switching to swapper_pg_dir for the first time (from
+        * initial_page_table) and therefore need to mark that page
+        * read-only and then pin it.
+        *
+        * Xen disallows sharing of kernel PMDs for PAE
+        * guests. Therefore we must copy the kernel PMD from
+        * initial_page_table into a new kernel PMD to be used in
+        * swapper_pg_dir.
+        */
+       swapper_kernel_pmd =
+               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
+       memcpy(swapper_kernel_pmd, initial_kernel_pmd,
+              sizeof(pmd_t) * PTRS_PER_PMD);
+       swapper_pg_dir[KERNEL_PGD_BOUNDARY] =
+               __pgd(__pa(swapper_kernel_pmd) | _PAGE_PRESENT);
+       set_page_prot(swapper_kernel_pmd, PAGE_KERNEL_RO);
+
+       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+       xen_write_cr3(cr3);
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, pfn);
+
+       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE,
+                         PFN_DOWN(__pa(initial_page_table)));
+       set_page_prot(initial_page_table, PAGE_KERNEL);
+       set_page_prot(initial_kernel_pmd, PAGE_KERNEL);
+
+       pv_mmu_ops.write_cr3 = &xen_write_cr3;
+}
 
 __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
                                         unsigned long max_pfn)
 {
        pmd_t *kernel_pmd;
 
-       level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
+       initial_kernel_pmd =
+               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
 
        max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
                                  xen_start_info->nr_pt_frames * PAGE_SIZE +
                                  512*1024);
 
        kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
-       memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+       memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
 
-       xen_map_identity_early(level2_kernel_pgt, max_pfn);
+       xen_map_identity_early(initial_kernel_pmd, max_pfn);
 
-       memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
-       set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
-                       __pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
+       memcpy(initial_page_table, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
+       initial_page_table[KERNEL_PGD_BOUNDARY] =
+               __pgd(__pa(initial_kernel_pmd) | _PAGE_PRESENT);
 
-       set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
-       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+       set_page_prot(initial_kernel_pmd, PAGE_KERNEL_RO);
+       set_page_prot(initial_page_table, PAGE_KERNEL_RO);
        set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
 
        pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
 
-       xen_write_cr3(__pa(swapper_pg_dir));
-
-       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE,
+                         PFN_DOWN(__pa(initial_page_table)));
+       xen_write_cr3(__pa(initial_page_table));
 
        memblock_x86_reserve_range(__pa(xen_start_info->pt_base),
                      __pa(xen_start_info->pt_base +
                           xen_start_info->nr_pt_frames * PAGE_SIZE),
                      "XEN PAGETABLES");
 
-       return swapper_pg_dir;
+       return initial_page_table;
 }
 #endif /* CONFIG_X86_64 */
 
@@ -2290,7 +2343,11 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .write_cr2 = xen_write_cr2,
 
        .read_cr3 = xen_read_cr3,
+#ifdef CONFIG_X86_32
+       .write_cr3 = xen_write_cr3_init,
+#else
        .write_cr3 = xen_write_cr3,
+#endif
 
        .flush_tlb_user = xen_flush_tlb,
        .flush_tlb_kernel = xen_flush_tlb,
@@ -2358,8 +2415,6 @@ void __init xen_init_mmu_ops(void)
        x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
        pv_mmu_ops = xen_mmu_ops;
 
-       vmap_lazy_unmap = false;
-
        memset(dummy_mapping, 0xff, PAGE_SIZE);
 }
 
@@ -2627,7 +2682,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
 
        prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
 
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
+                               (VM_PFNMAP | VM_RESERVED | VM_IO)));
 
        rmd.mfn = mfn;
        rmd.prot = prot;
index 0f456386cce5dc3a0c08ed45bfaf0a268be25819..25c52f94a27c788232ec7b6582c4ba776d1dbfb5 100644 (file)
@@ -68,7 +68,7 @@ static int __init check_platform_magic(void)
        return 0;
 }
 
-void __init xen_unplug_emulated_devices(void)
+void xen_unplug_emulated_devices(void)
 {
        int r;
 
index 769c4b01fa32e11f01e3a77a37d42f4c8ab13207..b5a7f928234b064b34a0b9d2c8d2f9d869e7c635 100644 (file)
@@ -23,7 +23,6 @@
 #include <xen/interface/callback.h>
 #include <xen/interface/memory.h>
 #include <xen/interface/physdev.h>
-#include <xen/interface/memory.h>
 #include <xen/features.h>
 
 #include "xen-ops.h"
@@ -182,24 +181,21 @@ char * __init xen_memory_setup(void)
        for (i = 0; i < memmap.nr_entries; i++) {
                unsigned long long end = map[i].addr + map[i].size;
 
-               if (map[i].type == E820_RAM) {
-                       if (map[i].addr < mem_end && end > mem_end) {
-                               /* Truncate region to max_mem. */
-                               u64 delta = end - mem_end;
+               if (map[i].type == E820_RAM && end > mem_end) {
+                       /* RAM off the end - may be partially included */
+                       u64 delta = min(map[i].size, end - mem_end);
 
-                               map[i].size -= delta;
-                               extra_pages += PFN_DOWN(delta);
+                       map[i].size -= delta;
+                       end -= delta;
 
-                               end = mem_end;
-                       }
+                       extra_pages += PFN_DOWN(delta);
                }
 
-               if (end > xen_extra_mem_start)
+               if (map[i].size > 0 && end > xen_extra_mem_start)
                        xen_extra_mem_start = end;
 
-               /* If region is non-RAM or below mem_end, add what remains */
-               if ((map[i].type != E820_RAM || map[i].addr < mem_end) &&
-                   map[i].size > 0)
+               /* Add region if any remains */
+               if (map[i].size > 0)
                        e820_add_region(map[i].addr, map[i].size, map[i].type);
        }
 
@@ -248,26 +244,11 @@ char * __init xen_memory_setup(void)
        else
                extra_pages = 0;
 
-       if (!xen_initial_domain())
-               xen_add_extra_mem(extra_pages);
+       xen_add_extra_mem(extra_pages);
 
        return "Xen";
 }
 
-static void xen_idle(void)
-{
-       local_irq_disable();
-
-       if (need_resched())
-               local_irq_enable();
-       else {
-               current_thread_info()->status &= ~TS_POLLING;
-               smp_mb__after_clear_bit();
-               safe_halt();
-               current_thread_info()->status |= TS_POLLING;
-       }
-}
-
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
@@ -337,9 +318,6 @@ void __cpuinit xen_enable_syscall(void)
 
 void __init xen_arch_setup(void)
 {
-       struct physdev_set_iopl set_iopl;
-       int rc;
-
        xen_panic_handler_init();
 
        HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
@@ -356,11 +334,6 @@ void __init xen_arch_setup(void)
        xen_enable_sysenter();
        xen_enable_syscall();
 
-       set_iopl.iopl = 1;
-       rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
-       if (rc != 0)
-               printk(KERN_INFO "physdev_op failed %d\n", rc);
-
 #ifdef CONFIG_ACPI
        if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
                printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
@@ -372,7 +345,11 @@ void __init xen_arch_setup(void)
               MAX_GUEST_CMDLINE > COMMAND_LINE_SIZE ?
               COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
 
-       pm_idle = xen_idle;
+       /* Set up idle, making sure it calls safe_halt() pvop */
+#ifdef CONFIG_X86_32
+       boot_cpu_data.hlt_works_ok = 1;
+#endif
+       pm_idle = default_idle;
 
        fiddle_vdso();
 }
index 1d789d56877cd509a11a4aff08f38952b892c79f..9bbd63a129b5869a4842238423217d620b26d79b 100644 (file)
@@ -31,6 +31,7 @@ void xen_hvm_post_suspend(int suspend_cancelled)
        int cpu;
        xen_hvm_init_shared_info();
        xen_callback_vector();
+       xen_unplug_emulated_devices();
        if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
                for_each_online_cpu(cpu) {
                        xen_setup_runstate_info(cpu);
index b2bb5aa3b0540e42847a7664aa529cf5d2c0fb83..5da5e53fb94c20bf6c244dce734e515c92d10b34 100644 (file)
@@ -426,6 +426,8 @@ void xen_timer_resume(void)
 {
        int cpu;
 
+       pvclock_resume();
+
        if (xen_clockevent != &xen_vcpuop_clockevent)
                return;
 
index 64044747348efb3535461a67610621d9067767e3..9d41bf985757973ece1288bd27b84d6c7af6622c 100644 (file)
@@ -43,7 +43,7 @@ void xen_vcpu_restore(void);
 
 void xen_callback_vector(void);
 void xen_hvm_init_shared_info(void);
-void __init xen_unplug_emulated_devices(void);
+void xen_unplug_emulated_devices(void);
 
 void __init xen_build_dynamic_phys_to_machine(void);
 
index 56ad4531b41234f87485e4f4bca5ca84d4d10dc1..004be80fd89402efbdc3f4a89a894570b7f27e59 100644 (file)
@@ -645,7 +645,7 @@ static int throtl_dispatch_tg(struct throtl_data *td, struct throtl_grp *tg,
 {
        unsigned int nr_reads = 0, nr_writes = 0;
        unsigned int max_nr_reads = throtl_grp_quantum*3/4;
-       unsigned int max_nr_writes = throtl_grp_quantum - nr_reads;
+       unsigned int max_nr_writes = throtl_grp_quantum - max_nr_reads;
        struct bio *bio;
 
        /* Try to dispatch 75% READS and 25% WRITES */
index 58c6ee5b010c4fd4a22206e9c88c5cadedc1a1a2..cc3eb78e333acaf14eb27a4ae8e54737d816f255 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/hdreg.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
 
index 3d866d0037f240c8d636f8b8523df962e72ab123..a9a302eba01e6a78b46e3af154c4f1b2a1c2c510 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/hdreg.h>
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include <linux/blktrace_api.h>
 #include <asm/uaccess.h>
 
index 3f91c01c217fe8179a58da9dd00c59465b700aba..66aa4bee80a659712b75e8b3949678d56e8bd5a3 100644 (file)
@@ -3166,8 +3166,8 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
 
 /**
  *     ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
+ *     @shost: SCSI host of command to be sent
  *     @cmd: SCSI command to be sent
- *     @done: Completion function, called when command is complete
  *
  *     In some cases, this function translates SCSI commands into
  *     ATA taskfiles, and queues the taskfiles to be sent to
@@ -3177,37 +3177,36 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
  *     ATA and ATAPI devices appearing as SCSI devices.
  *
  *     LOCKING:
- *     Releases scsi-layer-held lock, and obtains host lock.
+ *     ATA host lock
  *
  *     RETURNS:
  *     Return value from __ata_scsi_queuecmd() if @cmd can be queued,
  *     0 otherwise.
  */
-int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
 {
        struct ata_port *ap;
        struct ata_device *dev;
        struct scsi_device *scsidev = cmd->device;
-       struct Scsi_Host *shost = scsidev->host;
        int rc = 0;
+       unsigned long irq_flags;
 
        ap = ata_shost_to_port(shost);
 
-       spin_unlock(shost->host_lock);
-       spin_lock(ap->lock);
+       spin_lock_irqsave(ap->lock, irq_flags);
 
        ata_scsi_dump_cdb(ap, cmd);
 
        dev = ata_scsi_find_dev(ap, scsidev);
        if (likely(dev))
-               rc = __ata_scsi_queuecmd(cmd, done, dev);
+               rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev);
        else {
                cmd->result = (DID_BAD_TARGET << 16);
-               done(cmd);
+               cmd->scsi_done(cmd);
        }
 
-       spin_unlock(ap->lock);
-       spin_lock(shost->host_lock);
+       spin_unlock_irqrestore(ap->lock, irq_flags);
+
        return rc;
 }
 
index c21589986c695f38756d1ced8a13422acfa3cac9..8b677bbf2d37be97d37e89c57441e26807a55e87 100644 (file)
@@ -538,7 +538,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        return 0;
 }
 
-static void svia_configure(struct pci_dev *pdev)
+static void svia_configure(struct pci_dev *pdev, int board_id)
 {
        u8 tmp8;
 
@@ -577,7 +577,7 @@ static void svia_configure(struct pci_dev *pdev)
        }
 
        /*
-        * vt6421 has problems talking to some drives.  The following
+        * vt6420/1 has problems talking to some drives.  The following
         * is the fix from Joseph Chan <JosephChan@via.com.tw>.
         *
         * When host issues HOLD, device may send up to 20DW of data
@@ -596,8 +596,9 @@ static void svia_configure(struct pci_dev *pdev)
         *
         * https://bugzilla.kernel.org/show_bug.cgi?id=15173
         * http://article.gmane.org/gmane.linux.ide/46352
+        * http://thread.gmane.org/gmane.linux.kernel/1062139
         */
-       if (pdev->device == 0x3249) {
+       if (board_id == vt6420 || board_id == vt6421) {
                pci_read_config_byte(pdev, 0x52, &tmp8);
                tmp8 |= 1 << 2;
                pci_write_config_byte(pdev, 0x52, tmp8);
@@ -652,7 +653,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       svia_configure(pdev);
+       svia_configure(pdev, board_id);
 
        pci_set_master(pdev);
        return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
index 31b526661ec4d78346c3b6edd04b733705285797..ead3e79d6fcf10f684f8d8f55a30d7254356ff42 100644 (file)
@@ -475,20 +475,33 @@ End:
  */
 void dpm_resume_noirq(pm_message_t state)
 {
-       struct device *dev;
+       struct list_head list;
        ktime_t starttime = ktime_get();
 
+       INIT_LIST_HEAD(&list);
        mutex_lock(&dpm_list_mtx);
        transition_started = false;
-       list_for_each_entry(dev, &dpm_list, power.entry)
+       while (!list_empty(&dpm_list)) {
+               struct device *dev = to_device(dpm_list.next);
+
+               get_device(dev);
                if (dev->power.status > DPM_OFF) {
                        int error;
 
                        dev->power.status = DPM_OFF;
+                       mutex_unlock(&dpm_list_mtx);
+
                        error = device_resume_noirq(dev, state);
+
+                       mutex_lock(&dpm_list_mtx);
                        if (error)
                                pm_dev_err(dev, state, " early", error);
                }
+               if (!list_empty(&dev->power.entry))
+                       list_move_tail(&dev->power.entry, &list);
+               put_device(dev);
+       }
+       list_splice(&list, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
        dpm_show_time(starttime, state, "early");
        resume_device_irqs();
@@ -789,20 +802,33 @@ End:
  */
 int dpm_suspend_noirq(pm_message_t state)
 {
-       struct device *dev;
+       struct list_head list;
        ktime_t starttime = ktime_get();
        int error = 0;
 
+       INIT_LIST_HEAD(&list);
        suspend_device_irqs();
        mutex_lock(&dpm_list_mtx);
-       list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
+       while (!list_empty(&dpm_list)) {
+               struct device *dev = to_device(dpm_list.prev);
+
+               get_device(dev);
+               mutex_unlock(&dpm_list_mtx);
+
                error = device_suspend_noirq(dev, state);
+
+               mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, " late", error);
+                       put_device(dev);
                        break;
                }
                dev->power.status = DPM_OFF_IRQ;
+               if (!list_empty(&dev->power.entry))
+                       list_move(&dev->power.entry, &list);
+               put_device(dev);
        }
+       list_splice_tail(&list, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
        if (error)
                dpm_resume_noirq(resume_event(state));
index a1725e6488d3081628aa2923e1da77195c4d914a..7888501ad9ee1af078b47695a00c8074011797c3 100644 (file)
@@ -1341,7 +1341,7 @@ static struct request *set_next_request(void)
 {
        struct request_queue *q;
        int cnt = FD_MAX_UNITS;
-       struct request *rq;
+       struct request *rq = NULL;
 
        /* Find next queue we can dispatch from */
        fdc_queue = fdc_queue + 1;
index 4e4cc6c828cb71359ebb6f8aa5ab06335444c6bf..605a67e40bbfc902609233ebc52d22f8bc008e23 100644 (file)
@@ -1399,7 +1399,7 @@ static struct request *set_next_request(void)
 {
        struct request_queue *q;
        int old_pos = fdc_queue;
-       struct request *rq;
+       struct request *rq = NULL;
 
        do {
                q = unit[fdc_queue].disk->queue;
index a67d0a611a8ac1d53ee16a00963ef19ade3487c8..f291587d753e1b49ceb6138af1b925801b47a4db 100644 (file)
@@ -66,6 +66,7 @@ MODULE_VERSION("3.6.26");
 MODULE_LICENSE("GPL");
 
 static DEFINE_MUTEX(cciss_mutex);
+static struct proc_dir_entry *proc_cciss;
 
 #include "cciss_cmd.h"
 #include "cciss.h"
@@ -363,8 +364,6 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
 #define ENG_GIG_FACTOR (ENG_GIG/512)
 #define ENGAGE_SCSI    "engage scsi"
 
-static struct proc_dir_entry *proc_cciss;
-
 static void cciss_seq_show_header(struct seq_file *seq)
 {
        ctlr_info_t *h = seq->private;
index 575495f3c4b870d2085347f5015f72efc32adb2b..727d0225b7d049e9f529655c081c513267d248bc 100644 (file)
@@ -62,8 +62,8 @@ static int cciss_scsi_proc_info(
                int length,        /* length of data in buffer */
                int func);         /* 0 == read, 1 == write */
 
-static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
-               void (* done)(struct scsi_cmnd *));
+static int cciss_scsi_queue_command (struct Scsi_Host *h,
+                                    struct scsi_cmnd *cmd);
 static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
 static int cciss_eh_abort_handler(struct scsi_cmnd *);
 
@@ -1406,7 +1406,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
 
 
 static int
-cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+cciss_scsi_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        ctlr_info_t *h;
        int rc;
@@ -1504,6 +1504,8 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(cciss_scsi_queue_command)
+
 static void cciss_unregister_scsi(ctlr_info_t *h)
 {
        struct cciss_scsi_adapter_data_t *sa;
index d299fe9e78c8acc80b3a3f2fb370675bf7b299be..89d8a7cc4054ba627b670a8786e05b1824f5a8b3 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/memcontrol.h>
 #include <linux/mm_inline.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pkt_sched.h>
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
index b0551ba7ad0c9355a36621d3a6405ba76a8ab9d0..47d223c2409c8cebbd233103d8ff1790dfae833c 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/drbd.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/memcontrol.h>
index 6ec9d53806c5e791b5d56fa0ae27dae0e903db02..008d4a00b50df57f529528b1b2eefec9b379a544 100644 (file)
 
 
 
-   Instructions for use
-   --------------------
+   For usage instructions, please refer to:
 
-   1) Map a Linux block device to an existing rbd image.
-
-      Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
-
-      $ echo "192.168.0.1 name=admin rbd foo" > /sys/class/rbd/add
-
-      The snapshot name can be "-" or omitted to map the image read/write.
-
-   2) List all active blkdev<->object mappings.
-
-      In this example, we have performed step #1 twice, creating two blkdevs,
-      mapped to two separate rados objects in the rados rbd pool
-
-      $ cat /sys/class/rbd/list
-      #id     major   client_name     pool    name    snap    KB
-      0       254     client4143      rbd     foo     -      1024000
-
-      The columns, in order, are:
-      - blkdev unique id
-      - blkdev assigned major
-      - rados client id
-      - rados pool name
-      - rados block device name
-      - mapped snapshot ("-" if none)
-      - device size in KB
-
-
-   3) Create a snapshot.
-
-      Usage: <blkdev id> <snapname>
-
-      $ echo "0 mysnap" > /sys/class/rbd/snap_create
-
-
-   4) Listing a snapshot.
-
-      $ cat /sys/class/rbd/snaps_list
-      #id     snap    KB
-      0       -       1024000 (*)
-      0       foo     1024000
-
-      The columns, in order, are:
-      - blkdev unique id
-      - snapshot name, '-' means none (active read/write version)
-      - size of device at time of snapshot
-      - the (*) indicates this is the active version
-
-   5) Rollback to snapshot.
-
-      Usage: <blkdev id> <snapname>
-
-      $ echo "0 mysnap" > /sys/class/rbd/snap_rollback
-
-
-   6) Mapping an image using snapshot.
-
-      A snapshot mapping is read-only. This is being done by passing
-      snap=<snapname> to the options when adding a device.
-
-      $ echo "192.168.0.1 name=admin,snap=mysnap rbd foo" > /sys/class/rbd/add
-
-
-   7) Remove an active blkdev<->rbd image mapping.
-
-      In this example, we remove the mapping with blkdev unique id 1.
-
-      $ echo 1 > /sys/class/rbd/remove
-
-
-   NOTE:  The actual creation and deletion of rados objects is outside the scope
-   of this driver.
+                 Documentation/ABI/testing/sysfs-bus-rbd
 
  */
 
@@ -163,6 +92,14 @@ struct rbd_request {
        u64                     len;
 };
 
+struct rbd_snap {
+       struct  device          dev;
+       const char              *name;
+       size_t                  size;
+       struct list_head        node;
+       u64                     id;
+};
+
 /*
  * a single device
  */
@@ -193,21 +130,60 @@ struct rbd_device {
        int read_only;
 
        struct list_head        node;
+
+       /* list of snapshots */
+       struct list_head        snaps;
+
+       /* sysfs related */
+       struct device           dev;
+};
+
+static struct bus_type rbd_bus_type = {
+       .name           = "rbd",
 };
 
 static spinlock_t node_lock;      /* protects client get/put */
 
-static struct class *class_rbd;          /* /sys/class/rbd */
 static DEFINE_MUTEX(ctl_mutex);          /* Serialize open/close/setup/teardown */
 static LIST_HEAD(rbd_dev_list);    /* devices */
 static LIST_HEAD(rbd_client_list);      /* clients */
 
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static void rbd_dev_release(struct device *dev);
+static ssize_t rbd_snap_rollback(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t size);
+static ssize_t rbd_snap_add(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf,
+                           size_t count);
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap);;
+
+
+static struct rbd_device *dev_to_rbd(struct device *dev)
+{
+       return container_of(dev, struct rbd_device, dev);
+}
+
+static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
+{
+       return get_device(&rbd_dev->dev);
+}
+
+static void rbd_put_dev(struct rbd_device *rbd_dev)
+{
+       put_device(&rbd_dev->dev);
+}
 
 static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
        struct gendisk *disk = bdev->bd_disk;
        struct rbd_device *rbd_dev = disk->private_data;
 
+       rbd_get_dev(rbd_dev);
+
        set_device_ro(bdev, rbd_dev->read_only);
 
        if ((mode & FMODE_WRITE) && rbd_dev->read_only)
@@ -216,9 +192,19 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
        return 0;
 }
 
+static int rbd_release(struct gendisk *disk, fmode_t mode)
+{
+       struct rbd_device *rbd_dev = disk->private_data;
+
+       rbd_put_dev(rbd_dev);
+
+       return 0;
+}
+
 static const struct block_device_operations rbd_bd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = rbd_open,
+       .release                = rbd_release,
 };
 
 /*
@@ -361,7 +347,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
        int ret = -ENOMEM;
 
        init_rwsem(&header->snap_rwsem);
-
        header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
        header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
                                snap_count *
@@ -1256,10 +1241,20 @@ bad:
        return -ERANGE;
 }
 
+static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
+{
+       struct rbd_snap *snap;
+
+       while (!list_empty(&rbd_dev->snaps)) {
+               snap = list_first_entry(&rbd_dev->snaps, struct rbd_snap, node);
+               __rbd_remove_snap_dev(rbd_dev, snap);
+       }
+}
+
 /*
  * only read the first part of the ondisk header, without the snaps info
  */
-static int rbd_update_snaps(struct rbd_device *rbd_dev)
+static int __rbd_update_snaps(struct rbd_device *rbd_dev)
 {
        int ret;
        struct rbd_image_header h;
@@ -1280,12 +1275,15 @@ static int rbd_update_snaps(struct rbd_device *rbd_dev)
        rbd_dev->header.total_snaps = h.total_snaps;
        rbd_dev->header.snapc = h.snapc;
        rbd_dev->header.snap_names = h.snap_names;
+       rbd_dev->header.snap_names_len = h.snap_names_len;
        rbd_dev->header.snap_sizes = h.snap_sizes;
        rbd_dev->header.snapc->seq = snap_seq;
 
+       ret = __rbd_init_snaps_header(rbd_dev);
+
        up_write(&rbd_dev->header.snap_rwsem);
 
-       return 0;
+       return ret;
 }
 
 static int rbd_init_disk(struct rbd_device *rbd_dev)
@@ -1300,6 +1298,11 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        if (rc)
                return rc;
 
+       /* no need to lock here, as rbd_dev is not registered yet */
+       rc = __rbd_init_snaps_header(rbd_dev);
+       if (rc)
+               return rc;
+
        rc = rbd_header_set_snap(rbd_dev, rbd_dev->snap_name, &total_size);
        if (rc)
                return rc;
@@ -1343,54 +1346,360 @@ out:
        return rc;
 }
 
-/********************************************************************
- * /sys/class/rbd/
- *                   add       map rados objects to blkdev
- *                   remove    unmap rados objects
- *                   list      show mappings
- *******************************************************************/
+/*
+  sysfs
+*/
+
+static ssize_t rbd_size_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%llu\n", (unsigned long long)rbd_dev->header.image_size);
+}
+
+static ssize_t rbd_major_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
 
-static void class_rbd_release(struct class *cls)
+       return sprintf(buf, "%d\n", rbd_dev->major);
+}
+
+static ssize_t rbd_client_id_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
 {
-       kfree(cls);
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "client%lld\n", ceph_client_id(rbd_dev->client));
 }
 
-static ssize_t class_rbd_list(struct class *c,
-                             struct class_attribute *attr,
-                             char *data)
+static ssize_t rbd_pool_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
 {
-       int n = 0;
-       struct list_head *tmp;
-       int max = PAGE_SIZE;
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->pool_name);
+}
+
+static ssize_t rbd_name_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->obj);
+}
+
+static ssize_t rbd_snap_show(struct device *dev,
+                            struct device_attribute *attr,
+                            char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->snap_name);
+}
+
+static ssize_t rbd_image_refresh(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t size)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int rc;
+       int ret = size;
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       n += snprintf(data, max,
-                     "#id\tmajor\tclient_name\tpool\tname\tsnap\tKB\n");
+       rc = __rbd_update_snaps(rbd_dev);
+       if (rc < 0)
+               ret = rc;
 
-       list_for_each(tmp, &rbd_dev_list) {
-               struct rbd_device *rbd_dev;
+       mutex_unlock(&ctl_mutex);
+       return ret;
+}
 
-               rbd_dev = list_entry(tmp, struct rbd_device, node);
-               n += snprintf(data+n, max-n,
-                             "%d\t%d\tclient%lld\t%s\t%s\t%s\t%lld\n",
-                             rbd_dev->id,
-                             rbd_dev->major,
-                             ceph_client_id(rbd_dev->client),
-                             rbd_dev->pool_name,
-                             rbd_dev->obj, rbd_dev->snap_name,
-                             rbd_dev->header.image_size >> 10);
-               if (n == max)
+static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
+static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
+static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
+static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
+static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
+static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);
+
+static struct attribute *rbd_attrs[] = {
+       &dev_attr_size.attr,
+       &dev_attr_major.attr,
+       &dev_attr_client_id.attr,
+       &dev_attr_pool.attr,
+       &dev_attr_name.attr,
+       &dev_attr_current_snap.attr,
+       &dev_attr_refresh.attr,
+       &dev_attr_create_snap.attr,
+       &dev_attr_rollback_snap.attr,
+       NULL
+};
+
+static struct attribute_group rbd_attr_group = {
+       .attrs = rbd_attrs,
+};
+
+static const struct attribute_group *rbd_attr_groups[] = {
+       &rbd_attr_group,
+       NULL
+};
+
+static void rbd_sysfs_dev_release(struct device *dev)
+{
+}
+
+static struct device_type rbd_device_type = {
+       .name           = "rbd",
+       .groups         = rbd_attr_groups,
+       .release        = rbd_sysfs_dev_release,
+};
+
+
+/*
+  sysfs - snapshots
+*/
+
+static ssize_t rbd_snap_size_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+       return sprintf(buf, "%lld\n", (long long)snap->size);
+}
+
+static ssize_t rbd_snap_id_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+       return sprintf(buf, "%lld\n", (long long)snap->id);
+}
+
+static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
+static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+
+static struct attribute *rbd_snap_attrs[] = {
+       &dev_attr_snap_size.attr,
+       &dev_attr_snap_id.attr,
+       NULL,
+};
+
+static struct attribute_group rbd_snap_attr_group = {
+       .attrs = rbd_snap_attrs,
+};
+
+static void rbd_snap_dev_release(struct device *dev)
+{
+       struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+       kfree(snap->name);
+       kfree(snap);
+}
+
+static const struct attribute_group *rbd_snap_attr_groups[] = {
+       &rbd_snap_attr_group,
+       NULL
+};
+
+static struct device_type rbd_snap_device_type = {
+       .groups         = rbd_snap_attr_groups,
+       .release        = rbd_snap_dev_release,
+};
+
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap)
+{
+       list_del(&snap->node);
+       device_unregister(&snap->dev);
+}
+
+static int rbd_register_snap_dev(struct rbd_device *rbd_dev,
+                                 struct rbd_snap *snap,
+                                 struct device *parent)
+{
+       struct device *dev = &snap->dev;
+       int ret;
+
+       dev->type = &rbd_snap_device_type;
+       dev->parent = parent;
+       dev->release = rbd_snap_dev_release;
+       dev_set_name(dev, "snap_%s", snap->name);
+       ret = device_register(dev);
+
+       return ret;
+}
+
+static int __rbd_add_snap_dev(struct rbd_device *rbd_dev,
+                             int i, const char *name,
+                             struct rbd_snap **snapp)
+{
+       int ret;
+       struct rbd_snap *snap = kzalloc(sizeof(*snap), GFP_KERNEL);
+       if (!snap)
+               return -ENOMEM;
+       snap->name = kstrdup(name, GFP_KERNEL);
+       snap->size = rbd_dev->header.snap_sizes[i];
+       snap->id = rbd_dev->header.snapc->snaps[i];
+       if (device_is_registered(&rbd_dev->dev)) {
+               ret = rbd_register_snap_dev(rbd_dev, snap,
+                                            &rbd_dev->dev);
+               if (ret < 0)
+                       goto err;
+       }
+       *snapp = snap;
+       return 0;
+err:
+       kfree(snap->name);
+       kfree(snap);
+       return ret;
+}
+
+/*
+ * search for the previous snap in a null delimited string list
+ */
+const char *rbd_prev_snap_name(const char *name, const char *start)
+{
+       if (name < start + 2)
+               return NULL;
+
+       name -= 2;
+       while (*name) {
+               if (name == start)
+                       return start;
+               name--;
+       }
+       return name + 1;
+}
+
+/*
+ * compare the old list of snapshots that we have to what's in the header
+ * and update it accordingly. Note that the header holds the snapshots
+ * in a reverse order (from newest to oldest) and we need to go from
+ * older to new so that we don't get a duplicate snap name when
+ * doing the process (e.g., removed snapshot and recreated a new
+ * one with the same name.
+ */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+{
+       const char *name, *first_name;
+       int i = rbd_dev->header.total_snaps;
+       struct rbd_snap *snap, *old_snap = NULL;
+       int ret;
+       struct list_head *p, *n;
+
+       first_name = rbd_dev->header.snap_names;
+       name = first_name + rbd_dev->header.snap_names_len;
+
+       list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
+               u64 cur_id;
+
+               old_snap = list_entry(p, struct rbd_snap, node);
+
+               if (i)
+                       cur_id = rbd_dev->header.snapc->snaps[i - 1];
+
+               if (!i || old_snap->id < cur_id) {
+                       /* old_snap->id was skipped, thus was removed */
+                       __rbd_remove_snap_dev(rbd_dev, old_snap);
+                       continue;
+               }
+               if (old_snap->id == cur_id) {
+                       /* we have this snapshot already */
+                       i--;
+                       name = rbd_prev_snap_name(name, first_name);
+                       continue;
+               }
+               for (; i > 0;
+                    i--, name = rbd_prev_snap_name(name, first_name)) {
+                       if (!name) {
+                               WARN_ON(1);
+                               return -EINVAL;
+                       }
+                       cur_id = rbd_dev->header.snapc->snaps[i];
+                       /* snapshot removal? handle it above */
+                       if (cur_id >= old_snap->id)
+                               break;
+                       /* a new snapshot */
+                       ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+                       if (ret < 0)
+                               return ret;
+
+                       /* note that we add it backward so using n and not p */
+                       list_add(&snap->node, n);
+                       p = &snap->node;
+               }
+       }
+       /* we're done going over the old snap list, just add what's left */
+       for (; i > 0; i--) {
+               name = rbd_prev_snap_name(name, first_name);
+               if (!name) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+               ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+               if (ret < 0)
+                       return ret;
+               list_add(&snap->node, &rbd_dev->snaps);
+       }
+
+       return 0;
+}
+
+
+static void rbd_root_dev_release(struct device *dev)
+{
+}
+
+static struct device rbd_root_dev = {
+       .init_name =    "rbd",
+       .release =      rbd_root_dev_release,
+};
+
+static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
+{
+       int ret = -ENOMEM;
+       struct device *dev;
+       struct rbd_snap *snap;
+
+       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+       dev = &rbd_dev->dev;
+
+       dev->bus = &rbd_bus_type;
+       dev->type = &rbd_device_type;
+       dev->parent = &rbd_root_dev;
+       dev->release = rbd_dev_release;
+       dev_set_name(dev, "%d", rbd_dev->id);
+       ret = device_register(dev);
+       if (ret < 0)
+               goto done_free;
+
+       list_for_each_entry(snap, &rbd_dev->snaps, node) {
+               ret = rbd_register_snap_dev(rbd_dev, snap,
+                                            &rbd_dev->dev);
+               if (ret < 0)
                        break;
        }
 
        mutex_unlock(&ctl_mutex);
-       return n;
+       return 0;
+done_free:
+       mutex_unlock(&ctl_mutex);
+       return ret;
 }
 
-static ssize_t class_rbd_add(struct class *c,
-                            struct class_attribute *attr,
-                            const char *buf, size_t count)
+static void rbd_bus_del_dev(struct rbd_device *rbd_dev)
+{
+       device_unregister(&rbd_dev->dev);
+}
+
+static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count)
 {
        struct ceph_osd_client *osdc;
        struct rbd_device *rbd_dev;
@@ -1419,6 +1728,7 @@ static ssize_t class_rbd_add(struct class *c,
        /* static rbd_device initialization */
        spin_lock_init(&rbd_dev->lock);
        INIT_LIST_HEAD(&rbd_dev->node);
+       INIT_LIST_HEAD(&rbd_dev->snaps);
 
        /* generate unique id: find highest unique id, add one */
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1478,6 +1788,9 @@ static ssize_t class_rbd_add(struct class *c,
        }
        rbd_dev->major = irc;
 
+       rc = rbd_bus_add_dev(rbd_dev);
+       if (rc)
+               goto err_out_disk;
        /* set up and announce blkdev mapping */
        rc = rbd_init_disk(rbd_dev);
        if (rc)
@@ -1487,6 +1800,8 @@ static ssize_t class_rbd_add(struct class *c,
 
 err_out_blkdev:
        unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_disk:
+       rbd_free_disk(rbd_dev);
 err_out_client:
        rbd_put_client(rbd_dev);
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1518,35 +1833,10 @@ static struct rbd_device *__rbd_get_dev(unsigned long id)
        return NULL;
 }
 
-static ssize_t class_rbd_remove(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static void rbd_dev_release(struct device *dev)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, rc;
-       unsigned long ul;
-
-       rc = strict_strtoul(buf, 10, &ul);
-       if (rc)
-               return rc;
-
-       /* convert to int; abort if we lost anything in the conversion */
-       target_id = (int) ul;
-       if (target_id != ul)
-               return -EINVAL;
-
-       /* remove object from list immediately */
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-       rbd_dev = __rbd_get_dev(target_id);
-       if (rbd_dev)
-               list_del_init(&rbd_dev->node);
-
-       mutex_unlock(&ctl_mutex);
-
-       if (!rbd_dev)
-               return -ENOENT;
+       struct rbd_device *rbd_dev =
+                       container_of(dev, struct rbd_device, dev);
 
        rbd_put_client(rbd_dev);
 
@@ -1557,67 +1847,11 @@ static ssize_t class_rbd_remove(struct class *c,
 
        /* release module ref */
        module_put(THIS_MODULE);
-
-       return count;
 }
 
-static ssize_t class_rbd_snaps_list(struct class *c,
-                             struct class_attribute *attr,
-                             char *data)
-{
-       struct rbd_device *rbd_dev = NULL;
-       struct list_head *tmp;
-       struct rbd_image_header *header;
-       int i, n = 0, max = PAGE_SIZE;
-       int ret;
-
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-       n += snprintf(data, max, "#id\tsnap\tKB\n");
-
-       list_for_each(tmp, &rbd_dev_list) {
-               char *names, *p;
-               struct ceph_snap_context *snapc;
-
-               rbd_dev = list_entry(tmp, struct rbd_device, node);
-               header = &rbd_dev->header;
-
-               down_read(&header->snap_rwsem);
-
-               names = header->snap_names;
-               snapc = header->snapc;
-
-               n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
-                             rbd_dev->id, RBD_SNAP_HEAD_NAME,
-                             header->image_size >> 10,
-                             (!rbd_dev->cur_snap ? " (*)" : ""));
-               if (n == max)
-                       break;
-
-               p = names;
-               for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) {
-                       n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
-                             rbd_dev->id, p, header->snap_sizes[i] >> 10,
-                             (rbd_dev->cur_snap &&
-                              (snap_index(header, i) == rbd_dev->cur_snap) ?
-                              " (*)" : ""));
-                       if (n == max)
-                               break;
-               }
-
-               up_read(&header->snap_rwsem);
-       }
-
-
-       ret = n;
-       mutex_unlock(&ctl_mutex);
-       return ret;
-}
-
-static ssize_t class_rbd_snaps_refresh(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_remove(struct bus_type *bus,
+                         const char *buf,
+                         size_t count)
 {
        struct rbd_device *rbd_dev = NULL;
        int target_id, rc;
@@ -1641,95 +1875,70 @@ static ssize_t class_rbd_snaps_refresh(struct class *c,
                goto done;
        }
 
-       rc = rbd_update_snaps(rbd_dev);
-       if (rc < 0)
-               ret = rc;
+       list_del_init(&rbd_dev->node);
+
+       __rbd_remove_all_snaps(rbd_dev);
+       rbd_bus_del_dev(rbd_dev);
 
 done:
        mutex_unlock(&ctl_mutex);
        return ret;
 }
 
-static ssize_t class_rbd_snap_create(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_snap_add(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf,
+                           size_t count)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, ret;
-       char *name;
-
-       name = kmalloc(RBD_MAX_SNAP_NAME_LEN + 1, GFP_KERNEL);
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int ret;
+       char *name = kmalloc(count + 1, GFP_KERNEL);
        if (!name)
                return -ENOMEM;
 
-       /* parse snaps add command */
-       if (sscanf(buf, "%d "
-                  "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
-                  &target_id,
-                  name) != 2) {
-               ret = -EINVAL;
-               goto done;
-       }
+       snprintf(name, count, "%s", buf);
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       rbd_dev = __rbd_get_dev(target_id);
-       if (!rbd_dev) {
-               ret = -ENOENT;
-               goto done_unlock;
-       }
-
        ret = rbd_header_add_snap(rbd_dev,
                                  name, GFP_KERNEL);
        if (ret < 0)
                goto done_unlock;
 
-       ret = rbd_update_snaps(rbd_dev);
+       ret = __rbd_update_snaps(rbd_dev);
        if (ret < 0)
                goto done_unlock;
 
        ret = count;
 done_unlock:
        mutex_unlock(&ctl_mutex);
-done:
        kfree(name);
        return ret;
 }
 
-static ssize_t class_rbd_rollback(struct class *c,
-                               struct class_attribute *attr,
-                               const char *buf,
-                               size_t count)
+static ssize_t rbd_snap_rollback(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf,
+                                size_t count)
 {
-       struct rbd_device *rbd_dev = NULL;
-       int target_id, ret;
+       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       int ret;
        u64 snapid;
-       char snap_name[RBD_MAX_SNAP_NAME_LEN];
        u64 cur_ofs;
-       char *seg_name;
+       char *seg_name = NULL;
+       char *snap_name = kmalloc(count + 1, GFP_KERNEL);
+       ret = -ENOMEM;
+       if (!snap_name)
+               return ret;
 
        /* parse snaps add command */
-       if (sscanf(buf, "%d "
-                  "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
-                  &target_id,
-                  snap_name) != 2) {
-               return -EINVAL;
-       }
-
-       ret = -ENOMEM;
+       snprintf(snap_name, count, "%s", buf);
        seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
        if (!seg_name)
-               return ret;
+               goto done;
 
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
-       rbd_dev = __rbd_get_dev(target_id);
-       if (!rbd_dev) {
-               ret = -ENOENT;
-               goto done_unlock;
-       }
-
        ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL);
        if (ret < 0)
                goto done_unlock;
@@ -1750,7 +1959,7 @@ static ssize_t class_rbd_rollback(struct class *c,
                                   seg_name, ret);
        }
 
-       ret = rbd_update_snaps(rbd_dev);
+       ret = __rbd_update_snaps(rbd_dev);
        if (ret < 0)
                goto done_unlock;
 
@@ -1758,57 +1967,42 @@ static ssize_t class_rbd_rollback(struct class *c,
 
 done_unlock:
        mutex_unlock(&ctl_mutex);
+done:
        kfree(seg_name);
+       kfree(snap_name);
 
        return ret;
 }
 
-static struct class_attribute class_rbd_attrs[] = {
-       __ATTR(add,             0200, NULL, class_rbd_add),
-       __ATTR(remove,          0200, NULL, class_rbd_remove),
-       __ATTR(list,            0444, class_rbd_list, NULL),
-       __ATTR(snaps_refresh,   0200, NULL, class_rbd_snaps_refresh),
-       __ATTR(snap_create,     0200, NULL, class_rbd_snap_create),
-       __ATTR(snaps_list,      0444, class_rbd_snaps_list, NULL),
-       __ATTR(snap_rollback,   0200, NULL, class_rbd_rollback),
+static struct bus_attribute rbd_bus_attrs[] = {
+       __ATTR(add, S_IWUSR, NULL, rbd_add),
+       __ATTR(remove, S_IWUSR, NULL, rbd_remove),
        __ATTR_NULL
 };
 
 /*
  * create control files in sysfs
- * /sys/class/rbd/...
+ * /sys/bus/rbd/...
  */
 static int rbd_sysfs_init(void)
 {
-       int ret = -ENOMEM;
+       int ret;
 
-       class_rbd = kzalloc(sizeof(*class_rbd), GFP_KERNEL);
-       if (!class_rbd)
-               goto out;
+       rbd_bus_type.bus_attrs = rbd_bus_attrs;
 
-       class_rbd->name = DRV_NAME;
-       class_rbd->owner = THIS_MODULE;
-       class_rbd->class_release = class_rbd_release;
-       class_rbd->class_attrs = class_rbd_attrs;
+       ret = bus_register(&rbd_bus_type);
+        if (ret < 0)
+               return ret;
 
-       ret = class_register(class_rbd);
-       if (ret)
-               goto out_class;
-       return 0;
+       ret = device_register(&rbd_root_dev);
 
-out_class:
-       kfree(class_rbd);
-       class_rbd = NULL;
-       pr_err(DRV_NAME ": failed to create class rbd\n");
-out:
        return ret;
 }
 
 static void rbd_sysfs_cleanup(void)
 {
-       if (class_rbd)
-               class_destroy(class_rbd);
-       class_rbd = NULL;
+       device_unregister(&rbd_root_dev);
+       bus_unregister(&rbd_bus_type);
 }
 
 int __init rbd_init(void)
index 255035cfc88ab8ff3a279578487facd6d17a113f..4f9e22f29138f1001dfca566ab3b04e176b6ae2e 100644 (file)
@@ -65,7 +65,7 @@ enum blkif_state {
 
 struct blk_shadow {
        struct blkif_request req;
-       unsigned long request;
+       struct request *request;
        unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 };
 
@@ -136,7 +136,7 @@ static void add_id_to_freelist(struct blkfront_info *info,
                               unsigned long id)
 {
        info->shadow[id].req.id  = info->shadow_free;
-       info->shadow[id].request = 0;
+       info->shadow[id].request = NULL;
        info->shadow_free = id;
 }
 
@@ -245,14 +245,11 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
 }
 
 /*
- * blkif_queue_request
+ * Generate a Xen blkfront IO request from a blk layer request.  Reads
+ * and writes are handled as expected.  Since we lack a loose flush
+ * request, we map flushes into a full ordered barrier.
  *
- * request block io
- *
- * id: for guest use only.
- * operation: BLKIF_OP_{READ,WRITE,PROBE}
- * buffer: buffer to read/write into. this should be a
- *   virtual address in the guest os.
+ * @req: a request struct
  */
 static int blkif_queue_request(struct request *req)
 {
@@ -281,7 +278,7 @@ static int blkif_queue_request(struct request *req)
        /* Fill out a communications ring structure. */
        ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
        id = get_id_from_freelist(info);
-       info->shadow[id].request = (unsigned long)req;
+       info->shadow[id].request = req;
 
        ring_req->id = id;
        ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req);
@@ -290,6 +287,18 @@ static int blkif_queue_request(struct request *req)
        ring_req->operation = rq_data_dir(req) ?
                BLKIF_OP_WRITE : BLKIF_OP_READ;
 
+       if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
+               /*
+                * Ideally we could just do an unordered
+                * flush-to-disk, but all we have is a full write
+                * barrier at the moment.  However, a barrier write is
+                * a superset of FUA, so we can implement it the same
+                * way.  (It's also a FLUSH+FUA, since it is
+                * guaranteed ordered WRT previous writes.)
+                */
+               ring_req->operation = BLKIF_OP_WRITE_BARRIER;
+       }
+
        ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
        BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
 
@@ -634,7 +643,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
 
                bret = RING_GET_RESPONSE(&info->ring, i);
                id   = bret->id;
-               req  = (struct request *)info->shadow[id].request;
+               req  = info->shadow[id].request;
 
                blkif_completion(&info->shadow[id]);
 
@@ -647,6 +656,16 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                                printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
                                       info->gd->disk_name);
                                error = -EOPNOTSUPP;
+                       }
+                       if (unlikely(bret->status == BLKIF_RSP_ERROR &&
+                                    info->shadow[id].req.nr_segments == 0)) {
+                               printk(KERN_WARNING "blkfront: %s: empty write barrier op failed\n",
+                                      info->gd->disk_name);
+                               error = -EOPNOTSUPP;
+                       }
+                       if (unlikely(error)) {
+                               if (error == -EOPNOTSUPP)
+                                       error = 0;
                                info->feature_flush = 0;
                                xlvbd_flush(info);
                        }
@@ -899,7 +918,7 @@ static int blkif_recover(struct blkfront_info *info)
        /* Stage 3: Find pending requests and requeue them. */
        for (i = 0; i < BLK_RING_SIZE; i++) {
                /* Not in use? */
-               if (copy[i].request == 0)
+               if (!copy[i].request)
                        continue;
 
                /* Grab a request slot and copy shadow state into it. */
@@ -916,9 +935,7 @@ static int blkif_recover(struct blkfront_info *info)
                                req->seg[j].gref,
                                info->xbdev->otherend_id,
                                pfn_to_mfn(info->shadow[req->id].frame[j]),
-                               rq_data_dir(
-                                       (struct request *)
-                                       info->shadow[req->id].request));
+                               rq_data_dir(info->shadow[req->id].request));
                info->shadow[req->id].req = *req;
 
                info->ring.req_prod_pvt++;
@@ -1067,14 +1084,8 @@ static void blkfront_connect(struct blkfront_info *info)
         */
        info->feature_flush = 0;
 
-       /*
-        * The driver doesn't properly handled empty flushes, so
-        * lets disable barrier support for now.
-        */
-#if 0
        if (!err && barrier)
-               info->feature_flush = REQ_FLUSH;
-#endif
+               info->feature_flush = REQ_FLUSH | REQ_FUA;
 
        err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
        if (err) {
index 43412c03969e14d0d0b92f1323109128bdb22a35..3cb4539a98b2f56d3a32509cd2ae951160a2d3d4 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include "agp.h"
index 9272c38dd3c6ce8a66e9e0d2b0a5085ddd2973a7..16a2847b7cdbfeee43c9dcd212915a2f6b500711 100644 (file)
@@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void)
 
 static void i830_cleanup(void)
 {
-       kunmap(intel_private.i8xx_page);
-       intel_private.i8xx_flush_page = NULL;
+       if (intel_private.i8xx_flush_page) {
+               kunmap(intel_private.i8xx_flush_page);
+               intel_private.i8xx_flush_page = NULL;
+       }
 
        __free_page(intel_private.i8xx_page);
        intel_private.i8xx_page = NULL;
index c0bd6f472c523a377f4d6efef8d90f8f6fbfe373..6ee3348bc3e4c922c3f9733830905c199ef85c29 100644 (file)
@@ -81,7 +81,6 @@ static char *serial_version = "4.30";
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
index f6718f05dad4a4ca16465967dd8779984637238e..095ab90535cea7519cce26cdc948a48c38dec02f 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
index 55b8667f739f64a82731ab926738601825cbb00c..7066e801b9d348e9506651e11bf51197b24d2847 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
 #include <linux/major.h>
index 788da05190ccf865ab47f0e53848c70faa8f5d33..2016aad85203ac2e868d5be0df20b267ab9e5ecf 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
index 667abd23ad6ab91b81fa957f3c80260e9c7735a6..7c6de4c92458ded21561df8d75e6f92e5c6f6945 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
index f646725bd567ec279541dd968e9a1653746035fe..748c3b0ecd89413f4bbe918e783bb042fcb02d1a 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/interrupt.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
index 9f8495b4fc8f5d648529d9c57950718bf11e8fd0..a7616d226a491bb0c295441f5db66c8e2cd98cc8 100644 (file)
@@ -87,7 +87,6 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/serial.h>
-#include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
index 4bef6ab83622f5e0e71ed6532a7f4cca12397a1c..461a5a0455170b63807b1945451d69c9f1abd1fd 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/stallion.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
index e53f16865397c491fa4afac65988c49b0f391ff9..a786326cea2f38163c343ff77997d2c2322c5e5b 100644 (file)
 #include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/bitops.h>
index 1030f8420137adb8ff7363eb259f9578026fe178..c17a305ecb2806256c2f7c4f1e9e0e4c3f878734 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
+#include <linux/acpi.h>
 #include "tpm.h"
 
 #define TPM_HEADER_SIZE 10
@@ -78,6 +79,26 @@ enum tis_defaults {
 static LIST_HEAD(tis_chips);
 static DEFINE_SPINLOCK(tis_lock);
 
+#ifdef CONFIG_ACPI
+static int is_itpm(struct pnp_dev *dev)
+{
+       struct acpi_device *acpi = pnp_acpi_device(dev);
+       struct acpi_hardware_id *id;
+
+       list_for_each_entry(id, &acpi->pnp.ids, list) {
+               if (!strcmp("INTC0102", id->id))
+                       return 1;
+       }
+
+       return 0;
+}
+#else
+static int is_itpm(struct pnp_dev *dev)
+{
+       return 0;
+}
+#endif
+
 static int check_locality(struct tpm_chip *chip, int l)
 {
        if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
@@ -472,6 +493,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
                 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
                 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
+       if (is_itpm(to_pnp_dev(dev)))
+               itpm = 1;
+
        if (itpm)
                dev_info(dev, "Intel iTPM workaround enabled\n");
 
index 493b47a0d511bd1a01dcd8985b76666f66a03971..956ebe2080a584d4a8e7843a9e4110edbc15f7b6 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/math64.h>
-#include <linux/smp_lock.h>
 
 #include <asm/genapic.h>
 #include <asm/uv/uv_hub.h>
index 6c1b676643a9ef43fe3984bb8495996960cf4337..896a2ced1d27952d9288a48911ee406ccabe1ee7 100644 (file)
@@ -1547,31 +1547,16 @@ static int init_vqs(struct ports_device *portdev)
        nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
 
        vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
-       if (!vqs) {
-               err = -ENOMEM;
-               goto fail;
-       }
        io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
-       if (!io_callbacks) {
-               err = -ENOMEM;
-               goto free_vqs;
-       }
        io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
-       if (!io_names) {
-               err = -ENOMEM;
-               goto free_callbacks;
-       }
        portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
                                  GFP_KERNEL);
-       if (!portdev->in_vqs) {
-               err = -ENOMEM;
-               goto free_names;
-       }
        portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
                                   GFP_KERNEL);
-       if (!portdev->out_vqs) {
+       if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs ||
+                       !portdev->out_vqs) {
                err = -ENOMEM;
-               goto free_invqs;
+               goto free;
        }
 
        /*
@@ -1605,7 +1590,7 @@ static int init_vqs(struct ports_device *portdev)
                                              io_callbacks,
                                              (const char **)io_names);
        if (err)
-               goto free_outvqs;
+               goto free;
 
        j = 0;
        portdev->in_vqs[0] = vqs[0];
@@ -1621,23 +1606,19 @@ static int init_vqs(struct ports_device *portdev)
                        portdev->out_vqs[i] = vqs[j + 1];
                }
        }
-       kfree(io_callbacks);
        kfree(io_names);
+       kfree(io_callbacks);
        kfree(vqs);
 
        return 0;
 
-free_names:
-       kfree(io_names);
-free_callbacks:
-       kfree(io_callbacks);
-free_outvqs:
+free:
        kfree(portdev->out_vqs);
-free_invqs:
        kfree(portdev->in_vqs);
-free_vqs:
+       kfree(io_names);
+       kfree(io_callbacks);
        kfree(vqs);
-fail:
+
        return err;
 }
 
index eb6b54dbb8064a9a5d2e71eb3261132195ff6f8d..85ffd5e38c5031690ea125cf5341fa70591bfa58 100644 (file)
@@ -1213,3 +1213,4 @@ module_exit(sh_dmae_exit);
 MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>");
 MODULE_DESCRIPTION("Renesas SH DMA Engine driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-dma-engine");
index b3781399b38abf7997d00ae6ee7da7b023d9cd26..ba2898b3639bd0d26c489c3ac1ee228193ca51ab 100644 (file)
@@ -10,16 +10,16 @@ obj-$(CONFIG_EDAC)                  := edac_stub.o
 obj-$(CONFIG_EDAC_MM_EDAC)             += edac_core.o
 obj-$(CONFIG_EDAC_MCE)                 += edac_mce.o
 
-edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
-edac_core-objs += edac_module.o edac_device_sysfs.o
+edac_core-y    := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
+edac_core-y    += edac_module.o edac_device_sysfs.o
 
 ifdef CONFIG_PCI
-edac_core-objs += edac_pci.o edac_pci_sysfs.o
+edac_core-y    += edac_pci.o edac_pci_sysfs.o
 endif
 
 obj-$(CONFIG_EDAC_MCE_INJ)             += mce_amd_inj.o
 
-edac_mce_amd-objs                      := mce_amd.o
+edac_mce_amd-y                         := mce_amd.o
 obj-$(CONFIG_EDAC_DECODE_MCE)          += edac_mce_amd.o
 
 obj-$(CONFIG_EDAC_AMD76X)              += amd76x_edac.o
index 8d0688f36d4cee2331c84fddb2848325badd849e..39faded3cadd6c753a9aecd5d4257a2bf12fa1c7 100644 (file)
@@ -139,7 +139,7 @@ static int __init edac_init_mce_inject(void)
        return 0;
 
 err_sysfs_create:
-       while (i-- >= 0)
+       while (--i >= 0)
                sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr);
 
        kobject_del(mce_kobj);
index 18fdd9703b483fbdaadbaec83cbbb956ffa669dd..1a467a91fb0b2c8ee4c7ac577f02c497d249e1dc 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bug.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
 #include <asm/unaligned.h>
 #include <net/arp.h>
 
-#define FWNET_MAX_FRAGMENTS    25      /* arbitrary limit */
-#define FWNET_ISO_PAGE_COUNT   (PAGE_SIZE < 16 * 1024 ? 4 : 2)
+/* rx limits */
+#define FWNET_MAX_FRAGMENTS            30 /* arbitrary, > TX queue depth */
+#define FWNET_ISO_PAGE_COUNT           (PAGE_SIZE < 16*1024 ? 4 : 2)
+
+/* tx limits */
+#define FWNET_MAX_QUEUED_DATAGRAMS     20 /* < 64 = number of tlabels */
+#define FWNET_MIN_QUEUED_DATAGRAMS     10 /* should keep AT DMA busy enough */
+#define FWNET_TX_QUEUE_LEN             FWNET_MAX_QUEUED_DATAGRAMS /* ? */
 
 #define IEEE1394_BROADCAST_CHANNEL     31
 #define IEEE1394_ALL_NODES             (0xffc0 | 0x003f)
@@ -169,15 +176,8 @@ struct fwnet_device {
        struct fw_address_handler handler;
        u64 local_fifo;
 
-       /* List of packets to be sent */
-       struct list_head packet_list;
-       /*
-        * List of packets that were broadcasted.  When we get an ISO interrupt
-        * one of them has been sent
-        */
-       struct list_head broadcasted_list;
-       /* List of packets that have been sent but not yet acked */
-       struct list_head sent_list;
+       /* Number of tx datagrams that have been queued but not yet acked */
+       int queued_datagrams;
 
        struct list_head peer_list;
        struct fw_card *card;
@@ -195,7 +195,7 @@ struct fwnet_peer {
        unsigned pdg_size;        /* pd_list size */
 
        u16 datagram_label;       /* outgoing datagram label */
-       unsigned max_payload;     /* includes RFC2374_FRAG_HDR_SIZE overhead */
+       u16 max_payload;          /* includes RFC2374_FRAG_HDR_SIZE overhead */
        int node_id;
        int generation;
        unsigned speed;
@@ -203,22 +203,18 @@ struct fwnet_peer {
 
 /* This is our task struct. It's used for the packet complete callback.  */
 struct fwnet_packet_task {
-       /*
-        * ptask can actually be on dev->packet_list, dev->broadcasted_list,
-        * or dev->sent_list depending on its current state.
-        */
-       struct list_head pt_link;
        struct fw_transaction transaction;
        struct rfc2734_header hdr;
        struct sk_buff *skb;
        struct fwnet_device *dev;
 
        int outstanding_pkts;
-       unsigned max_payload;
        u64 fifo_addr;
        u16 dest_node;
+       u16 max_payload;
        u8 generation;
        u8 speed;
+       u8 enqueued;
 };
 
 /*
@@ -650,8 +646,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
                net->stats.rx_packets++;
                net->stats.rx_bytes += skb->len;
        }
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
 
        return 0;
 
@@ -660,8 +654,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
        net->stats.rx_dropped++;
 
        dev_kfree_skb_any(skb);
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
 
        return -ENOENT;
 }
@@ -793,15 +785,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
         * Datagram is not complete, we're done for the
         * moment.
         */
-       spin_unlock_irqrestore(&dev->lock, flags);
-
-       return 0;
+       retval = 0;
  fail:
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       if (netif_queue_stopped(net))
-               netif_wake_queue(net);
-
        return retval;
 }
 
@@ -901,11 +888,19 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask)
        kmem_cache_free(fwnet_packet_task_cache, ptask);
 }
 
+/* Caller must hold dev->lock. */
+static void dec_queued_datagrams(struct fwnet_device *dev)
+{
+       if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS)
+               netif_wake_queue(dev->netdev);
+}
+
 static int fwnet_send_packet(struct fwnet_packet_task *ptask);
 
 static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
 {
        struct fwnet_device *dev = ptask->dev;
+       struct sk_buff *skb = ptask->skb;
        unsigned long flags;
        bool free;
 
@@ -914,10 +909,14 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
        ptask->outstanding_pkts--;
 
        /* Check whether we or the networking TX soft-IRQ is last user. */
-       free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link));
+       free = (ptask->outstanding_pkts == 0 && ptask->enqueued);
+       if (free)
+               dec_queued_datagrams(dev);
 
-       if (ptask->outstanding_pkts == 0)
-               list_del(&ptask->pt_link);
+       if (ptask->outstanding_pkts == 0) {
+               dev->netdev->stats.tx_packets++;
+               dev->netdev->stats.tx_bytes += skb->len;
+       }
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -926,7 +925,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                u16 fg_off;
                u16 datagram_label;
                u16 lf;
-               struct sk_buff *skb;
 
                /* Update the ptask to point to the next fragment and send it */
                lf = fwnet_get_hdr_lf(&ptask->hdr);
@@ -953,7 +951,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                        datagram_label = fwnet_get_hdr_dgl(&ptask->hdr);
                        break;
                }
-               skb = ptask->skb;
+
                skb_pull(skb, ptask->max_payload);
                if (ptask->outstanding_pkts > 1) {
                        fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
@@ -970,6 +968,31 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
                fwnet_free_ptask(ptask);
 }
 
+static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask)
+{
+       struct fwnet_device *dev = ptask->dev;
+       unsigned long flags;
+       bool free;
+
+       spin_lock_irqsave(&dev->lock, flags);
+
+       /* One fragment failed; don't try to send remaining fragments. */
+       ptask->outstanding_pkts = 0;
+
+       /* Check whether we or the networking TX soft-IRQ is last user. */
+       free = ptask->enqueued;
+       if (free)
+               dec_queued_datagrams(dev);
+
+       dev->netdev->stats.tx_dropped++;
+       dev->netdev->stats.tx_errors++;
+
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       if (free)
+               fwnet_free_ptask(ptask);
+}
+
 static void fwnet_write_complete(struct fw_card *card, int rcode,
                                 void *payload, size_t length, void *data)
 {
@@ -977,11 +1000,12 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,
 
        ptask = data;
 
-       if (rcode == RCODE_COMPLETE)
+       if (rcode == RCODE_COMPLETE) {
                fwnet_transmit_packet_done(ptask);
-       else
+       } else {
                fw_error("fwnet_write_complete: failed: %x\n", rcode);
-               /* ??? error recovery */
+               fwnet_transmit_packet_failed(ptask);
+       }
 }
 
 static int fwnet_send_packet(struct fwnet_packet_task *ptask)
@@ -1039,9 +1063,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
                spin_lock_irqsave(&dev->lock, flags);
 
                /* If the AT tasklet already ran, we may be last user. */
-               free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+               free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
                if (!free)
-                       list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
+                       ptask->enqueued = true;
+               else
+                       dec_queued_datagrams(dev);
 
                spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -1056,9 +1082,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
        spin_lock_irqsave(&dev->lock, flags);
 
        /* If the AT tasklet already ran, we may be last user. */
-       free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+       free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
        if (!free)
-               list_add_tail(&ptask->pt_link, &dev->sent_list);
+               ptask->enqueued = true;
+       else
+               dec_queued_datagrams(dev);
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -1224,6 +1252,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
        struct fwnet_peer *peer;
        unsigned long flags;
 
+       spin_lock_irqsave(&dev->lock, flags);
+
+       /* Can this happen? */
+       if (netif_queue_stopped(dev->netdev)) {
+               spin_unlock_irqrestore(&dev->lock, flags);
+
+               return NETDEV_TX_BUSY;
+       }
+
        ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC);
        if (ptask == NULL)
                goto fail;
@@ -1242,9 +1279,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
        proto = hdr_buf.h_proto;
        dg_size = skb->len;
 
-       /* serialize access to peer, including peer->datagram_label */
-       spin_lock_irqsave(&dev->lock, flags);
-
        /*
         * Set the transmission type for the packet.  ARP packets and IP
         * broadcast packets are sent via GASP.
@@ -1266,7 +1300,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
 
                peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid));
                if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR)
-                       goto fail_unlock;
+                       goto fail;
 
                generation         = peer->generation;
                dest_node          = peer->node_id;
@@ -1320,18 +1354,21 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
                max_payload += RFC2374_FRAG_HDR_SIZE;
        }
 
+       if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS)
+               netif_stop_queue(dev->netdev);
+
        spin_unlock_irqrestore(&dev->lock, flags);
 
        ptask->max_payload = max_payload;
-       INIT_LIST_HEAD(&ptask->pt_link);
+       ptask->enqueued    = 0;
 
        fwnet_send_packet(ptask);
 
        return NETDEV_TX_OK;
 
- fail_unlock:
-       spin_unlock_irqrestore(&dev->lock, flags);
  fail:
+       spin_unlock_irqrestore(&dev->lock, flags);
+
        if (ptask)
                kmem_cache_free(fwnet_packet_task_cache, ptask);
 
@@ -1377,7 +1414,7 @@ static void fwnet_init_dev(struct net_device *net)
        net->addr_len           = FWNET_ALEN;
        net->hard_header_len    = FWNET_HLEN;
        net->type               = ARPHRD_IEEE1394;
-       net->tx_queue_len       = 10;
+       net->tx_queue_len       = FWNET_TX_QUEUE_LEN;
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1457,14 +1494,9 @@ static int fwnet_probe(struct device *_dev)
        dev->broadcast_rcv_context = NULL;
        dev->broadcast_xmt_max_payload = 0;
        dev->broadcast_xmt_datagramlabel = 0;
-
        dev->local_fifo = FWNET_NO_FIFO_ADDR;
-
-       INIT_LIST_HEAD(&dev->packet_list);
-       INIT_LIST_HEAD(&dev->broadcasted_list);
-       INIT_LIST_HEAD(&dev->sent_list);
+       dev->queued_datagrams = 0;
        INIT_LIST_HEAD(&dev->peer_list);
-
        dev->card = card;
        dev->netdev = net;
 
@@ -1522,7 +1554,7 @@ static int fwnet_remove(struct device *_dev)
        struct fwnet_peer *peer = dev_get_drvdata(_dev);
        struct fwnet_device *dev = peer->dev;
        struct net_device *net;
-       struct fwnet_packet_task *ptask, *pt_next;
+       int i;
 
        mutex_lock(&fwnet_device_mutex);
 
@@ -1540,21 +1572,9 @@ static int fwnet_remove(struct device *_dev)
                                              dev->card);
                        fw_iso_context_destroy(dev->broadcast_rcv_context);
                }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->packet_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->broadcasted_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
-               list_for_each_entry_safe(ptask, pt_next,
-                                        &dev->sent_list, pt_link) {
-                       dev_kfree_skb_any(ptask->skb);
-                       kmem_cache_free(fwnet_packet_task_cache, ptask);
-               }
+               for (i = 0; dev->queued_datagrams && i < 5; i++)
+                       ssleep(1);
+               WARN_ON(dev->queued_datagrams);
                list_del(&dev->dev_link);
 
                free_netdev(net);
index bfae4b309791103e48b2bb704300d1cd84da9750..afa576a75a8ed443273d4722c03edc2bb8c31720 100644 (file)
@@ -1468,7 +1468,7 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
 
 /* SCSI stack integration */
 
-static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+static int sbp2_scsi_queuecommand_lck(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 {
        struct sbp2_logical_unit *lu = cmd->device->hostdata;
        struct fw_device *device = target_device(lu->tgt);
@@ -1534,6 +1534,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        return retval;
 }
 
+static DEF_SCSI_QCMD(sbp2_scsi_queuecommand)
+
 static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct sbp2_logical_unit *lu = sdev->hostdata;
index e23c06893d19f62195247220075aafce1cfa75c0..599f6c9e0fbf18661d7607407d11b73cd3cda7ff 100644 (file)
@@ -56,6 +56,18 @@ static struct cs5535_gpio_chip {
  * registers, see include/linux/cs5535.h.
  */
 
+static void errata_outl(u32 val, unsigned long addr)
+{
+       /*
+        * According to the CS5536 errata (#36), after suspend
+        * a write to the high bank GPIO register will clear all
+        * non-selected bits; the recommended workaround is a
+        * read-modify-write operation.
+        */
+       val |= inl(addr);
+       outl(val, addr);
+}
+
 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
                unsigned int reg)
 {
@@ -64,7 +76,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << offset, chip->base + reg);
        else
                /* high bank register */
-               outl(1 << (offset - 16), chip->base + 0x80 + reg);
+               errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
 }
 
 void cs5535_gpio_set(unsigned offset, unsigned int reg)
@@ -86,7 +98,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << (offset + 16), chip->base + reg);
        else
                /* high bank register */
-               outl(1 << offset, chip->base + 0x80 + reg);
+               errata_outl(1 << offset, chip->base + 0x80 + reg);
 }
 
 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
index f7af91cb273d58232d41c68b712b2d6d4404671c..bede10a0340700b69717caf1da8e81ee0546ab00 100644 (file)
@@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (!drm_helper_encoder_in_use(encoder)) {
+               if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) {
                        drm_encoder_disable(encoder);
                        /* disconnector encoder from any connector */
                        encoder->crtc = NULL;
@@ -471,6 +471,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        int count = 0, ro, fail = 0;
        struct drm_crtc_helper_funcs *crtc_funcs;
        int ret = 0;
+       int i;
 
        DRM_DEBUG_KMS("\n");
 
@@ -666,6 +667,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                if (ret != 0)
                        goto fail;
        }
+       DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
+       for (i = 0; i < set->num_connectors; i++) {
+               DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
+                             drm_get_connector_name(set->connectors[i]));
+               set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+       }
 
        kfree(save_connectors);
        kfree(save_encoders);
@@ -841,7 +848,7 @@ static void output_poll_execute(struct work_struct *work)
        struct delayed_work *delayed_work = to_delayed_work(work);
        struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
        struct drm_connector *connector;
-       enum drm_connector_status old_status, status;
+       enum drm_connector_status old_status;
        bool repoll = false, changed = false;
 
        if (!drm_kms_helper_poll)
@@ -866,8 +873,9 @@ static void output_poll_execute(struct work_struct *work)
                    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
                        continue;
 
-               status = connector->funcs->detect(connector, false);
-               if (old_status != status)
+               connector->status = connector->funcs->detect(connector, false);
+               DRM_DEBUG_KMS("connector status updated to %d\n", connector->status);
+               if (old_status != connector->status)
                        changed = true;
        }
 
index b744dad5c237f5371d571d13dc35d46a2fc95e2c..a39794bac04b4a57a8531c5ed38cccf081aa8ef9 100644 (file)
@@ -37,7 +37,6 @@
 #include "drmP.h"
 #include <linux/poll.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 /* from BKL pushdown: note that nothing else serializes idr_find() */
 DEFINE_MUTEX(drm_global_mutex);
index 9d3a5030b6e1dfcfbf522a783d24f14816c7b813..722700d5d73ee69a6ac49d4fbd96d307f704c2bb 100644 (file)
@@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        struct timeval now;
        unsigned long flags;
        unsigned int seq;
+       int ret;
 
        e = kzalloc(sizeof *e, GFP_KERNEL);
-       if (e == NULL)
-               return -ENOMEM;
+       if (e == NULL) {
+               ret = -ENOMEM;
+               goto err_put;
+       }
 
        e->pipe = pipe;
        e->base.pid = current->pid;
@@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        spin_lock_irqsave(&dev->event_lock, flags);
 
        if (file_priv->event_space < sizeof e->event) {
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               kfree(e);
-               return -ENOMEM;
+               ret = -EBUSY;
+               goto err_unlock;
        }
 
        file_priv->event_space -= sizeof e->event;
@@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        return 0;
+
+err_unlock:
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+       kfree(e);
+err_put:
+       drm_vblank_put(dev, e->pipe);
+       return ret;
 }
 
 /**
index 7a26f4dd21ae0a055036f78ce588ea4def08d73a..e6800819bca846f6a3fd102ef37e2632858247f8 100644 (file)
@@ -767,6 +767,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_HAS_BLT:
                value = HAS_BLT(dev);
                break;
+       case I915_PARAM_HAS_COHERENT_RINGS:
+               value = 1;
+               break;
        default:
                DRM_DEBUG_DRIVER("Unknown parameter %d\n",
                                 param->param);
index 80745f85902cf73fe17bf2ec41863dcb36a38550..f737960712e607c448eabc83d57e6d0557269f16 100644 (file)
@@ -150,7 +150,8 @@ static const struct intel_device_info intel_ironlake_d_info = {
 
 static const struct intel_device_info intel_ironlake_m_info = {
        .gen = 5, .is_mobile = 1,
-       .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .has_fbc = 0, /* disabled due to buggy hardware */
        .has_bsd_ring = 1,
 };
 
index 90414ae86afcd0758d49b2c70dfb39f613ab22f5..409826da3099dcb594473685bdf4b5f2e78183c9 100644 (file)
@@ -1045,6 +1045,8 @@ void i915_gem_clflush_object(struct drm_gem_object *obj);
 int i915_gem_object_set_domain(struct drm_gem_object *obj,
                               uint32_t read_domains,
                               uint32_t write_domain);
+int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+                             bool interruptible);
 int i915_gem_init_ringbuffer(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
index ef188e391406a1b3a2763e92d578c8f9e03b28b3..275ec6ed43ae7dcc4f396322909296e00305c617 100644 (file)
@@ -38,8 +38,7 @@
 
 static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
 
-static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
-                                                 bool pipelined);
+static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
 static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
 static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
@@ -547,6 +546,19 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_object *obj_priv;
        int ret = 0;
 
+       if (args->size == 0)
+               return 0;
+
+       if (!access_ok(VERIFY_WRITE,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size))
+               return -EFAULT;
+
+       ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
+                                      args->size);
+       if (ret)
+               return -EFAULT;
+
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
                return ret;
@@ -564,23 +576,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
                goto out;
        }
 
-       if (args->size == 0)
-               goto out;
-
-       if (!access_ok(VERIFY_WRITE,
-                      (char __user *)(uintptr_t)args->data_ptr,
-                      args->size)) {
-               ret = -EFAULT;
-               goto out;
-       }
-
-       ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
-                                      args->size);
-       if (ret) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        ret = i915_gem_object_get_pages_or_evict(obj);
        if (ret)
                goto out;
@@ -981,7 +976,20 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        struct drm_i915_gem_pwrite *args = data;
        struct drm_gem_object *obj;
        struct drm_i915_gem_object *obj_priv;
-       int ret = 0;
+       int ret;
+
+       if (args->size == 0)
+               return 0;
+
+       if (!access_ok(VERIFY_READ,
+                      (char __user *)(uintptr_t)args->data_ptr,
+                      args->size))
+               return -EFAULT;
+
+       ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
+                                     args->size);
+       if (ret)
+               return -EFAULT;
 
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
@@ -994,30 +1002,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        }
        obj_priv = to_intel_bo(obj);
 
-
        /* Bounds check destination. */
        if (args->offset > obj->size || args->size > obj->size - args->offset) {
                ret = -EINVAL;
                goto out;
        }
 
-       if (args->size == 0)
-               goto out;
-
-       if (!access_ok(VERIFY_READ,
-                      (char __user *)(uintptr_t)args->data_ptr,
-                      args->size)) {
-               ret = -EFAULT;
-               goto out;
-       }
-
-       ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
-                                     args->size);
-       if (ret) {
-               ret = -EFAULT;
-               goto out;
-       }
-
        /* We can only do the GTT pwrite on untiled buffers, as otherwise
         * it would end up going through the fenced access, and we'll get
         * different detiling behavior between reading and writing.
@@ -2603,7 +2593,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
        if (reg->gpu) {
                int ret;
 
-               ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+               ret = i915_gem_object_flush_gpu_write_domain(obj);
                if (ret)
                        return ret;
 
@@ -2751,8 +2741,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
 
 /** Flushes any GPU write domain for the object if it's dirty. */
 static int
-i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
-                                      bool pipelined)
+i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        uint32_t old_write_domain;
@@ -2771,10 +2760,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
                                            obj->read_domains,
                                            old_write_domain);
 
-       if (pipelined)
-               return 0;
-
-       return i915_gem_object_wait_rendering(obj, true);
+       return 0;
 }
 
 /** Flushes the GTT write domain for the object if it's dirty. */
@@ -2835,18 +2821,15 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
 
        i915_gem_object_flush_cpu_write_domain(obj);
 
-       if (write) {
-               ret = i915_gem_object_wait_rendering(obj, true);
-               if (ret)
-                       return ret;
-       }
-
        old_write_domain = obj->write_domain;
        old_read_domains = obj->read_domains;
 
@@ -2884,7 +2867,7 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
        if (obj_priv->gtt_space == NULL)
                return -EINVAL;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret)
                return ret;
 
@@ -2907,6 +2890,20 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
        return 0;
 }
 
+int
+i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+                         bool interruptible)
+{
+       if (!obj->active)
+               return 0;
+
+       if (obj->base.write_domain & I915_GEM_GPU_DOMAINS)
+               i915_gem_flush_ring(obj->base.dev, NULL, obj->ring,
+                                   0, obj->base.write_domain);
+
+       return i915_gem_object_wait_rendering(&obj->base, interruptible);
+}
+
 /**
  * Moves a single object to the CPU read, and possibly write domain.
  *
@@ -2919,9 +2916,12 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
 
        i915_gem_object_flush_gtt_write_domain(obj);
 
@@ -2930,12 +2930,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
         */
        i915_gem_object_set_to_full_cpu_read_domain(obj);
 
-       if (write) {
-               ret = i915_gem_object_wait_rendering(obj, true);
-               if (ret)
-                       return ret;
-       }
-
        old_write_domain = obj->write_domain;
        old_read_domains = obj->read_domains;
 
@@ -3200,9 +3194,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
        if (offset == 0 && size == obj->size)
                return i915_gem_object_set_to_cpu_domain(obj, 0);
 
-       ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
        if (ret != 0)
                return ret;
+       ret = i915_gem_object_wait_rendering(obj, true);
+       if (ret)
+               return ret;
+
        i915_gem_object_flush_gtt_write_domain(obj);
 
        /* If we're already fully in the CPU read domain, we're done. */
@@ -3249,192 +3247,230 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
        return 0;
 }
 
-/**
- * Pin an object to the GTT and evaluate the relocations landing in it.
- */
 static int
-i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj,
-                            struct drm_file *file_priv,
-                            struct drm_i915_gem_exec_object2 *entry)
+i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+                                  struct drm_file *file_priv,
+                                  struct drm_i915_gem_exec_object2 *entry,
+                                  struct drm_i915_gem_relocation_entry *reloc)
 {
        struct drm_device *dev = obj->base.dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_relocation_entry __user *user_relocs;
-       struct drm_gem_object *target_obj = NULL;
-       uint32_t target_handle = 0;
-       int i, ret = 0;
+       struct drm_gem_object *target_obj;
+       uint32_t target_offset;
+       int ret = -EINVAL;
 
-       user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
-       for (i = 0; i < entry->relocation_count; i++) {
-               struct drm_i915_gem_relocation_entry reloc;
-               uint32_t target_offset;
+       target_obj = drm_gem_object_lookup(dev, file_priv,
+                                          reloc->target_handle);
+       if (target_obj == NULL)
+               return -ENOENT;
 
-               if (__copy_from_user_inatomic(&reloc,
-                                             user_relocs+i,
-                                             sizeof(reloc))) {
-                       ret = -EFAULT;
-                       break;
-               }
+       target_offset = to_intel_bo(target_obj)->gtt_offset;
 
-               if (reloc.target_handle != target_handle) {
-                       drm_gem_object_unreference(target_obj);
+#if WATCH_RELOC
+       DRM_INFO("%s: obj %p offset %08x target %d "
+                "read %08x write %08x gtt %08x "
+                "presumed %08x delta %08x\n",
+                __func__,
+                obj,
+                (int) reloc->offset,
+                (int) reloc->target_handle,
+                (int) reloc->read_domains,
+                (int) reloc->write_domain,
+                (int) target_offset,
+                (int) reloc->presumed_offset,
+                reloc->delta);
+#endif
 
-                       target_obj = drm_gem_object_lookup(dev, file_priv,
-                                                          reloc.target_handle);
-                       if (target_obj == NULL) {
-                               ret = -ENOENT;
-                               break;
-                       }
+       /* The target buffer should have appeared before us in the
+        * exec_object list, so it should have a GTT space bound by now.
+        */
+       if (target_offset == 0) {
+               DRM_ERROR("No GTT space found for object %d\n",
+                         reloc->target_handle);
+               goto err;
+       }
 
-                       target_handle = reloc.target_handle;
-               }
-               target_offset = to_intel_bo(target_obj)->gtt_offset;
+       /* Validate that the target is in a valid r/w GPU domain */
+       if (reloc->write_domain & (reloc->write_domain - 1)) {
+               DRM_ERROR("reloc with multiple write domains: "
+                         "obj %p target %d offset %d "
+                         "read %08x write %08x",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->read_domains,
+                         reloc->write_domain);
+               goto err;
+       }
+       if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+           reloc->read_domains & I915_GEM_DOMAIN_CPU) {
+               DRM_ERROR("reloc with read/write CPU domains: "
+                         "obj %p target %d offset %d "
+                         "read %08x write %08x",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->read_domains,
+                         reloc->write_domain);
+               goto err;
+       }
+       if (reloc->write_domain && target_obj->pending_write_domain &&
+           reloc->write_domain != target_obj->pending_write_domain) {
+               DRM_ERROR("Write domain conflict: "
+                         "obj %p target %d offset %d "
+                         "new %08x old %08x\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         reloc->write_domain,
+                         target_obj->pending_write_domain);
+               goto err;
+       }
 
-#if WATCH_RELOC
-               DRM_INFO("%s: obj %p offset %08x target %d "
-                        "read %08x write %08x gtt %08x "
-                        "presumed %08x delta %08x\n",
-                        __func__,
-                        obj,
-                        (int) reloc.offset,
-                        (int) reloc.target_handle,
-                        (int) reloc.read_domains,
-                        (int) reloc.write_domain,
-                        (int) target_offset,
-                        (int) reloc.presumed_offset,
-                        reloc.delta);
-#endif
+       target_obj->pending_read_domains |= reloc->read_domains;
+       target_obj->pending_write_domain |= reloc->write_domain;
 
-               /* The target buffer should have appeared before us in the
-                * exec_object list, so it should have a GTT space bound by now.
-                */
-               if (target_offset == 0) {
-                       DRM_ERROR("No GTT space found for object %d\n",
-                                 reloc.target_handle);
-                       ret = -EINVAL;
-                       break;
-               }
+       /* If the relocation already has the right value in it, no
+        * more work needs to be done.
+        */
+       if (target_offset == reloc->presumed_offset)
+               goto out;
 
-               /* Validate that the target is in a valid r/w GPU domain */
-               if (reloc.write_domain & (reloc.write_domain - 1)) {
-                       DRM_ERROR("reloc with multiple write domains: "
-                                 "obj %p target %d offset %d "
-                                 "read %08x write %08x",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.read_domains,
-                                 reloc.write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
-                   reloc.read_domains & I915_GEM_DOMAIN_CPU) {
-                       DRM_ERROR("reloc with read/write CPU domains: "
-                                 "obj %p target %d offset %d "
-                                 "read %08x write %08x",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.read_domains,
-                                 reloc.write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.write_domain && target_obj->pending_write_domain &&
-                   reloc.write_domain != target_obj->pending_write_domain) {
-                       DRM_ERROR("Write domain conflict: "
-                                 "obj %p target %d offset %d "
-                                 "new %08x old %08x\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset,
-                                 reloc.write_domain,
-                                 target_obj->pending_write_domain);
-                       ret = -EINVAL;
-                       break;
-               }
+       /* Check that the relocation address is valid... */
+       if (reloc->offset > obj->base.size - 4) {
+               DRM_ERROR("Relocation beyond object bounds: "
+                         "obj %p target %d offset %d size %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset,
+                         (int) obj->base.size);
+               goto err;
+       }
+       if (reloc->offset & 3) {
+               DRM_ERROR("Relocation not 4-byte aligned: "
+                         "obj %p target %d offset %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->offset);
+               goto err;
+       }
 
-               target_obj->pending_read_domains |= reloc.read_domains;
-               target_obj->pending_write_domain |= reloc.write_domain;
+       /* and points to somewhere within the target object. */
+       if (reloc->delta >= target_obj->size) {
+               DRM_ERROR("Relocation beyond target object bounds: "
+                         "obj %p target %d delta %d size %d.\n",
+                         obj, reloc->target_handle,
+                         (int) reloc->delta,
+                         (int) target_obj->size);
+               goto err;
+       }
 
-               /* If the relocation already has the right value in it, no
-                * more work needs to be done.
-                */
-               if (target_offset == reloc.presumed_offset)
-                       continue;
+       reloc->delta += target_offset;
+       if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
+               uint32_t page_offset = reloc->offset & ~PAGE_MASK;
+               char *vaddr;
 
-               /* Check that the relocation address is valid... */
-               if (reloc.offset > obj->base.size - 4) {
-                       DRM_ERROR("Relocation beyond object bounds: "
-                                 "obj %p target %d offset %d size %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset, (int) obj->base.size);
-                       ret = -EINVAL;
-                       break;
-               }
-               if (reloc.offset & 3) {
-                       DRM_ERROR("Relocation not 4-byte aligned: "
-                                 "obj %p target %d offset %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.offset);
-                       ret = -EINVAL;
-                       break;
-               }
+               vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
+               *(uint32_t *)(vaddr + page_offset) = reloc->delta;
+               kunmap_atomic(vaddr);
+       } else {
+               struct drm_i915_private *dev_priv = dev->dev_private;
+               uint32_t __iomem *reloc_entry;
+               void __iomem *reloc_page;
 
-               /* and points to somewhere within the target object. */
-               if (reloc.delta >= target_obj->size) {
-                       DRM_ERROR("Relocation beyond target object bounds: "
-                                 "obj %p target %d delta %d size %d.\n",
-                                 obj, reloc.target_handle,
-                                 (int) reloc.delta, (int) target_obj->size);
-                       ret = -EINVAL;
-                       break;
-               }
+               ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
+               if (ret)
+                       goto err;
 
-               reloc.delta += target_offset;
-               if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
-                       uint32_t page_offset = reloc.offset & ~PAGE_MASK;
-                       char *vaddr;
+               /* Map the page containing the relocation we're going to perform.  */
+               reloc->offset += obj->gtt_offset;
+               reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+                                                     reloc->offset & PAGE_MASK);
+               reloc_entry = (uint32_t __iomem *)
+                       (reloc_page + (reloc->offset & ~PAGE_MASK));
+               iowrite32(reloc->delta, reloc_entry);
+               io_mapping_unmap_atomic(reloc_page);
+       }
 
-                       vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]);
-                       *(uint32_t *)(vaddr + page_offset) = reloc.delta;
-                       kunmap_atomic(vaddr);
-               } else {
-                       uint32_t __iomem *reloc_entry;
-                       void __iomem *reloc_page;
+       /* and update the user's relocation entry */
+       reloc->presumed_offset = target_offset;
 
-                       ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
-                       if (ret)
-                               break;
+out:
+       ret = 0;
+err:
+       drm_gem_object_unreference(target_obj);
+       return ret;
+}
 
-                       /* Map the page containing the relocation we're going to perform.  */
-                       reloc.offset += obj->gtt_offset;
-                       reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
-                                                             reloc.offset & PAGE_MASK);
-                       reloc_entry = (uint32_t __iomem *)
-                               (reloc_page + (reloc.offset & ~PAGE_MASK));
-                       iowrite32(reloc.delta, reloc_entry);
-                       io_mapping_unmap_atomic(reloc_page);
-               }
+static int
+i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
+                                   struct drm_file *file_priv,
+                                   struct drm_i915_gem_exec_object2 *entry)
+{
+       struct drm_i915_gem_relocation_entry __user *user_relocs;
+       int i, ret;
+
+       user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
+       for (i = 0; i < entry->relocation_count; i++) {
+               struct drm_i915_gem_relocation_entry reloc;
+
+               if (__copy_from_user_inatomic(&reloc,
+                                             user_relocs+i,
+                                             sizeof(reloc)))
+                       return -EFAULT;
+
+               ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc);
+               if (ret)
+                       return ret;
 
-               /* and update the user's relocation entry */
-               reloc.presumed_offset = target_offset;
                if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
-                                             &reloc.presumed_offset,
-                                             sizeof(reloc.presumed_offset))) {
-                   ret = -EFAULT;
-                   break;
-               }
+                                           &reloc.presumed_offset,
+                                           sizeof(reloc.presumed_offset)))
+                       return -EFAULT;
        }
 
-       drm_gem_object_unreference(target_obj);
-       return ret;
+       return 0;
 }
 
 static int
-i915_gem_execbuffer_pin(struct drm_device *dev,
-                       struct drm_file *file,
-                       struct drm_gem_object **object_list,
-                       struct drm_i915_gem_exec_object2 *exec_list,
-                       int count)
+i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
+                                        struct drm_file *file_priv,
+                                        struct drm_i915_gem_exec_object2 *entry,
+                                        struct drm_i915_gem_relocation_entry *relocs)
+{
+       int i, ret;
+
+       for (i = 0; i < entry->relocation_count; i++) {
+               ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate(struct drm_device *dev,
+                            struct drm_file *file,
+                            struct drm_gem_object **object_list,
+                            struct drm_i915_gem_exec_object2 *exec_list,
+                            int count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->base.pending_read_domains = 0;
+               obj->base.pending_write_domain = 0;
+               ret = i915_gem_execbuffer_relocate_object(obj, file,
+                                                         &exec_list[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int
+i915_gem_execbuffer_reserve(struct drm_device *dev,
+                           struct drm_file *file,
+                           struct drm_gem_object **object_list,
+                           struct drm_i915_gem_exec_object2 *exec_list,
+                           int count)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret, i, retry;
@@ -3496,6 +3532,87 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
        return 0;
 }
 
+static int
+i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
+                                 struct drm_file *file,
+                                 struct drm_gem_object **object_list,
+                                 struct drm_i915_gem_exec_object2 *exec_list,
+                                 int count)
+{
+       struct drm_i915_gem_relocation_entry *reloc;
+       int i, total, ret;
+
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->in_execbuffer = false;
+       }
+
+       mutex_unlock(&dev->struct_mutex);
+
+       total = 0;
+       for (i = 0; i < count; i++)
+               total += exec_list[i].relocation_count;
+
+       reloc = drm_malloc_ab(total, sizeof(*reloc));
+       if (reloc == NULL) {
+               mutex_lock(&dev->struct_mutex);
+               return -ENOMEM;
+       }
+
+       total = 0;
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+               user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+               if (copy_from_user(reloc+total, user_relocs,
+                                  exec_list[i].relocation_count *
+                                  sizeof(*reloc))) {
+                       ret = -EFAULT;
+                       mutex_lock(&dev->struct_mutex);
+                       goto err;
+               }
+
+               total += exec_list[i].relocation_count;
+       }
+
+       ret = i915_mutex_lock_interruptible(dev);
+       if (ret) {
+               mutex_lock(&dev->struct_mutex);
+               goto err;
+       }
+
+       ret = i915_gem_execbuffer_reserve(dev, file,
+                                         object_list, exec_list,
+                                         count);
+       if (ret)
+               goto err;
+
+       total = 0;
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+               obj->base.pending_read_domains = 0;
+               obj->base.pending_write_domain = 0;
+               ret = i915_gem_execbuffer_relocate_object_slow(obj, file,
+                                                              &exec_list[i],
+                                                              reloc + total);
+               if (ret)
+                       goto err;
+
+               total += exec_list[i].relocation_count;
+       }
+
+       /* Leave the user relocations as are, this is the painfully slow path,
+        * and we want to avoid the complication of dropping the lock whilst
+        * having buffers reserved in the aperture and so causing spurious
+        * ENOSPC for random operations.
+        */
+
+err:
+       drm_free_large(reloc);
+       return ret;
+}
+
 static int
 i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
                                struct drm_file *file,
@@ -3625,8 +3742,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
 
        for (i = 0; i < count; i++) {
                char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
-               size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry);
+               int length; /* limited by fault_in_pages_readable() */
+
+               /* First check for malicious input causing overflow */
+               if (exec[i].relocation_count >
+                   INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+                       return -EINVAL;
 
+               length = exec[i].relocation_count *
+                       sizeof(struct drm_i915_gem_relocation_entry);
                if (!access_ok(VERIFY_READ, ptr, length))
                        return -EFAULT;
 
@@ -3769,18 +3893,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        }
 
        /* Move the objects en-masse into the GTT, evicting if necessary. */
-       ret = i915_gem_execbuffer_pin(dev, file,
-                                     object_list, exec_list,
-                                     args->buffer_count);
+       ret = i915_gem_execbuffer_reserve(dev, file,
+                                         object_list, exec_list,
+                                         args->buffer_count);
        if (ret)
                goto err;
 
        /* The objects are in their final locations, apply the relocations. */
-       for (i = 0; i < args->buffer_count; i++) {
-               struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
-               obj->base.pending_read_domains = 0;
-               obj->base.pending_write_domain = 0;
-               ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]);
+       ret = i915_gem_execbuffer_relocate(dev, file,
+                                          object_list, exec_list,
+                                          args->buffer_count);
+       if (ret) {
+               if (ret == -EFAULT) {
+                       ret = i915_gem_execbuffer_relocate_slow(dev, file,
+                                                               object_list,
+                                                               exec_list,
+                                                               args->buffer_count);
+                       BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+               }
                if (ret)
                        goto err;
        }
@@ -4244,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                 * use this buffer rather sooner than later, so issuing the required
                 * flush earlier is beneficial.
                 */
-               if (obj->write_domain & I915_GEM_GPU_DOMAINS)
+               if (obj->write_domain & I915_GEM_GPU_DOMAINS) {
                        i915_gem_flush_ring(dev, file_priv,
                                            obj_priv->ring,
                                            0, obj->write_domain);
+               } else if (obj_priv->ring->outstanding_lazy_request) {
+                       /* This ring is not being cleared by active usage,
+                        * so emit a request to do so.
+                        */
+                       u32 seqno = i915_add_request(dev,
+                                                    NULL, NULL,
+                                                    obj_priv->ring);
+                       if (seqno == 0)
+                               ret = -ENOMEM;
+               }
 
                /* Update the active list for the hardware's current position.
                 * Otherwise this only updates on a delayed timer or when irqs
index 25ed911a31127256b753970d2b2fca22d67f755d..878fc766a12cc05f6b30c90d53d65a52c6023727 100644 (file)
 #define  TRANS_DP_10BPC                (1<<9)
 #define  TRANS_DP_6BPC         (2<<9)
 #define  TRANS_DP_12BPC                (3<<9)
+#define  TRANS_DP_BPC_MASK     (3<<9)
 #define  TRANS_DP_VSYNC_ACTIVE_HIGH    (1<<4)
 #define  TRANS_DP_VSYNC_ACTIVE_LOW     0
 #define  TRANS_DP_HSYNC_ACTIVE_HIGH    (1<<3)
index 454c064f8ef7f8d0daffe0ed40394354b152ee55..42729d25da58a5ecfb98317330ed1a62dcd3a745 100644 (file)
@@ -239,6 +239,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return;
 
+       /* Cursor state */
+       dev_priv->saveCURACNTR = I915_READ(CURACNTR);
+       dev_priv->saveCURAPOS = I915_READ(CURAPOS);
+       dev_priv->saveCURABASE = I915_READ(CURABASE);
+       dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
+       dev_priv->saveCURBPOS = I915_READ(CURBPOS);
+       dev_priv->saveCURBBASE = I915_READ(CURBBASE);
+       if (IS_GEN2(dev))
+               dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
        if (HAS_PCH_SPLIT(dev)) {
                dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
                dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
@@ -529,6 +539,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
        I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
 
+       /* Cursor state */
+       I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
+       I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
+       I915_WRITE(CURABASE, dev_priv->saveCURABASE);
+       I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
+       I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
+       I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
+       if (IS_GEN2(dev))
+               I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
        return;
 }
 
@@ -543,16 +563,6 @@ void i915_save_display(struct drm_device *dev)
        /* Don't save them in KMS mode */
        i915_save_modeset_reg(dev);
 
-       /* Cursor state */
-       dev_priv->saveCURACNTR = I915_READ(CURACNTR);
-       dev_priv->saveCURAPOS = I915_READ(CURAPOS);
-       dev_priv->saveCURABASE = I915_READ(CURABASE);
-       dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
-       dev_priv->saveCURBPOS = I915_READ(CURBPOS);
-       dev_priv->saveCURBBASE = I915_READ(CURBBASE);
-       if (IS_GEN2(dev))
-               dev_priv->saveCURSIZE = I915_READ(CURSIZE);
-
        /* CRT state */
        if (HAS_PCH_SPLIT(dev)) {
                dev_priv->saveADPA = I915_READ(PCH_ADPA);
@@ -657,16 +667,6 @@ void i915_restore_display(struct drm_device *dev)
        /* Don't restore them in KMS mode */
        i915_restore_modeset_reg(dev);
 
-       /* Cursor state */
-       I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
-       I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
-       I915_WRITE(CURABASE, dev_priv->saveCURABASE);
-       I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
-       I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
-       I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
-       if (IS_GEN2(dev))
-               I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
-
        /* CRT state */
        if (HAS_PCH_SPLIT(dev))
                I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
index 65c88f9ba12c825cad46592938f390e0eabf4ee6..2cb8e0b9f1ee4f9975fd3b8e863673d359bafdfe 100644 (file)
@@ -190,37 +190,6 @@ out:
        kfree(output.pointer);
 }
 
-static int intel_dsm_switchto(enum vga_switcheroo_client_id id)
-{
-       return 0;
-}
-
-static int intel_dsm_power_state(enum vga_switcheroo_client_id id,
-                                enum vga_switcheroo_state state)
-{
-       return 0;
-}
-
-static int intel_dsm_init(void)
-{
-       return 0;
-}
-
-static int intel_dsm_get_client_id(struct pci_dev *pdev)
-{
-       if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
-               return VGA_SWITCHEROO_IGD;
-       else
-               return VGA_SWITCHEROO_DIS;
-}
-
-static struct vga_switcheroo_handler intel_dsm_handler = {
-       .switchto = intel_dsm_switchto,
-       .power_state = intel_dsm_power_state,
-       .init = intel_dsm_init,
-       .get_client_id = intel_dsm_get_client_id,
-};
-
 static bool intel_dsm_pci_probe(struct pci_dev *pdev)
 {
        acpi_handle dhandle, intel_handle;
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void)
 {
        if (!intel_dsm_detect())
                return;
-
-       vga_switcheroo_register_handler(&intel_dsm_handler);
 }
 
 void intel_unregister_dsm_handler(void)
 {
-       vga_switcheroo_unregister_handler();
 }
index c55c77043357cb0243a4b368a1e6d63b7a4af398..8df574316063fb751d683b4b9d5c0d59b82f42f1 100644 (file)
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+/* Here's the desired hotplug mode */
+#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 |               \
+                          ADPA_CRT_HOTPLUG_WARMUP_10MS |               \
+                          ADPA_CRT_HOTPLUG_SAMPLE_4S |                 \
+                          ADPA_CRT_HOTPLUG_VOLTAGE_50 |                \
+                          ADPA_CRT_HOTPLUG_VOLREF_325MV |              \
+                          ADPA_CRT_HOTPLUG_ENABLE)
+
+struct intel_crt {
+       struct intel_encoder base;
+       bool force_hotplug_required;
+};
+
+static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
+{
+       return container_of(intel_attached_encoder(connector),
+                           struct intel_crt, base);
+}
+
 static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
@@ -129,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
                           dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
        }
 
-       adpa = 0;
+       adpa = ADPA_HOTPLUG_BITS;
        if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                adpa |= ADPA_HSYNC_ACTIVE_HIGH;
        if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -157,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
 static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
+       struct intel_crt *crt = intel_attached_crt(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 adpa, temp;
+       u32 adpa;
        bool ret;
-       bool turn_off_dac = false;
 
-       temp = adpa = I915_READ(PCH_ADPA);
+       /* The first time through, trigger an explicit detection cycle */
+       if (crt->force_hotplug_required) {
+               bool turn_off_dac = HAS_PCH_SPLIT(dev);
+               u32 save_adpa;
 
-       if (HAS_PCH_SPLIT(dev))
-               turn_off_dac = true;
-
-       adpa &= ~ADPA_CRT_HOTPLUG_MASK;
-       if (turn_off_dac)
-               adpa &= ~ADPA_DAC_ENABLE;
-
-       /* disable HPD first */
-       I915_WRITE(PCH_ADPA, adpa);
-       (void)I915_READ(PCH_ADPA);
-
-       adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
-                       ADPA_CRT_HOTPLUG_WARMUP_10MS |
-                       ADPA_CRT_HOTPLUG_SAMPLE_4S |
-                       ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
-                       ADPA_CRT_HOTPLUG_VOLREF_325MV |
-                       ADPA_CRT_HOTPLUG_ENABLE |
-                       ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
-
-       DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
-       I915_WRITE(PCH_ADPA, adpa);
-
-       if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
-                    1000))
-               DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
-
-       if (turn_off_dac) {
-               /* Make sure hotplug is enabled */
-               I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE);
-               (void)I915_READ(PCH_ADPA);
+               crt->force_hotplug_required = 0;
+
+               save_adpa = adpa = I915_READ(PCH_ADPA);
+               DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
+
+               adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
+               if (turn_off_dac)
+                       adpa &= ~ADPA_DAC_ENABLE;
+
+               I915_WRITE(PCH_ADPA, adpa);
+
+               if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
+                            1000))
+                       DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
+
+               if (turn_off_dac) {
+                       I915_WRITE(PCH_ADPA, save_adpa);
+                       POSTING_READ(PCH_ADPA);
+               }
        }
 
        /* Check the status to see if both blue and green are on now */
        adpa = I915_READ(PCH_ADPA);
-       adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK;
-       if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) ||
-               (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO))
+       if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
                ret = true;
        else
                ret = false;
+       DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
 
        return ret;
 }
@@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
        return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
 }
 
-static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
+static bool intel_crt_detect_ddc(struct intel_crt *crt)
 {
-       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-       struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+       struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
 
        /* CRT should always be at 0, but check anyway */
-       if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
+       if (crt->base.type != INTEL_OUTPUT_ANALOG)
                return false;
 
        if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) {
@@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
                return true;
        }
 
-       if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) {
+       if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
                DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
                return true;
        }
@@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
 {
-       struct drm_encoder *encoder = &intel_encoder->base;
+       struct drm_encoder *encoder = &crt->base.base;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -434,7 +443,7 @@ static enum drm_connector_status
 intel_crt_detect(struct drm_connector *connector, bool force)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_encoder *encoder = intel_attached_encoder(connector);
+       struct intel_crt *crt = intel_attached_crt(connector);
        struct drm_crtc *crtc;
        int dpms_mode;
        enum drm_connector_status status;
@@ -443,28 +452,31 @@ intel_crt_detect(struct drm_connector *connector, bool force)
                if (intel_crt_detect_hotplug(connector)) {
                        DRM_DEBUG_KMS("CRT detected via hotplug\n");
                        return connector_status_connected;
-               } else
+               } else {
+                       DRM_DEBUG_KMS("CRT not detected via hotplug\n");
                        return connector_status_disconnected;
+               }
        }
 
-       if (intel_crt_detect_ddc(&encoder->base))
+       if (intel_crt_detect_ddc(crt))
                return connector_status_connected;
 
        if (!force)
                return connector->status;
 
        /* for pre-945g platforms use load detect */
-       if (encoder->base.crtc && encoder->base.crtc->enabled) {
-               status = intel_crt_load_detect(encoder->base.crtc, encoder);
+       crtc = crt->base.base.crtc;
+       if (crtc && crtc->enabled) {
+               status = intel_crt_load_detect(crtc, crt);
        } else {
-               crtc = intel_get_load_detect_pipe(encoder, connector,
+               crtc = intel_get_load_detect_pipe(&crt->base, connector,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       if (intel_crt_detect_ddc(&encoder->base))
+                       if (intel_crt_detect_ddc(crt))
                                status = connector_status_connected;
                        else
-                               status = intel_crt_load_detect(crtc, encoder);
-                       intel_release_load_detect_pipe(encoder,
+                               status = intel_crt_load_detect(crtc, crt);
+                       intel_release_load_detect_pipe(&crt->base,
                                                       connector, dpms_mode);
                } else
                        status = connector_status_unknown;
@@ -536,17 +548,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_encoder *intel_encoder;
+       struct intel_crt *crt;
        struct intel_connector *intel_connector;
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
-       if (!intel_encoder)
+       crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
+       if (!crt)
                return;
 
        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
        if (!intel_connector) {
-               kfree(intel_encoder);
+               kfree(crt);
                return;
        }
 
@@ -554,20 +566,20 @@ void intel_crt_init(struct drm_device *dev)
        drm_connector_init(dev, &intel_connector->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-       drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs,
+       drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
                         DRM_MODE_ENCODER_DAC);
 
-       intel_connector_attach_encoder(intel_connector, intel_encoder);
+       intel_connector_attach_encoder(intel_connector, &crt->base);
 
-       intel_encoder->type = INTEL_OUTPUT_ANALOG;
-       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
-                                  (1 << INTEL_ANALOG_CLONE_BIT) |
-                                  (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+       crt->base.type = INTEL_OUTPUT_ANALOG;
+       crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
+                               1 << INTEL_ANALOG_CLONE_BIT |
+                               1 << INTEL_SDVO_LVDS_CLONE_BIT);
+       crt->base.crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 1;
        connector->doublescan_allowed = 0;
 
-       drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs);
+       drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
@@ -577,5 +589,22 @@ void intel_crt_init(struct drm_device *dev)
        else
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 
+       /*
+        * Configure the automatic hotplug detection stuff
+        */
+       crt->force_hotplug_required = 0;
+       if (HAS_PCH_SPLIT(dev)) {
+               u32 adpa;
+
+               adpa = I915_READ(PCH_ADPA);
+               adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+               adpa |= ADPA_HOTPLUG_BITS;
+               I915_WRITE(PCH_ADPA, adpa);
+               POSTING_READ(PCH_ADPA);
+
+               DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa);
+               crt->force_hotplug_required = 1;
+       }
+
        dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
 }
index 48d8fd686ea91d9fb3ba307036ecd0f5388174e9..d9b7092439ef59ab19acc9546a039ff60f0bb43c 100644 (file)
@@ -1611,6 +1611,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
                wait_event(dev_priv->pending_flip_queue,
                           atomic_read(&obj_priv->pending_flip) == 0);
+
+               /* Big Hammer, we also need to ensure that any pending
+                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+                * current scanout is retired before unpinning the old
+                * framebuffer.
+                */
+               ret = i915_gem_object_flush_gpu(obj_priv, false);
+               if (ret) {
+                       i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj);
+                       mutex_unlock(&dev->struct_mutex);
+                       return ret;
+               }
        }
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
@@ -2108,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
                reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
                temp &= ~(TRANS_DP_PORT_SEL_MASK |
-                         TRANS_DP_SYNC_MASK);
+                         TRANS_DP_SYNC_MASK |
+                         TRANS_DP_BPC_MASK);
                temp |= (TRANS_DP_OUTPUT_ENABLE |
                         TRANS_DP_ENH_FRAMING);
+               temp |= TRANS_DP_8BPC;
 
                if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
                        temp |= TRANS_DP_HSYNC_ACTIVE_HIGH;
@@ -2700,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den)
        }
 }
 
-#define DATA_N 0x800000
-#define LINK_N 0x80000
-
 static void
 ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
                     int link_clock, struct fdi_m_n *m_n)
 {
-       u64 temp;
-
        m_n->tu = 64; /* default size */
 
-       temp = (u64) DATA_N * pixel_clock;
-       temp = div_u64(temp, link_clock);
-       m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
-       m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
-       m_n->gmch_n = DATA_N;
+       /* BUG_ON(pixel_clock > INT_MAX / 36); */
+       m_n->gmch_m = bits_per_pixel * pixel_clock;
+       m_n->gmch_n = link_clock * nlanes * 8;
        fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
 
-       temp = (u64) LINK_N * pixel_clock;
-       m_n->link_m = div_u64(temp, link_clock);
-       m_n->link_n = LINK_N;
+       m_n->link_m = pixel_clock;
+       m_n->link_n = link_clock;
        fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
@@ -3704,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
        /* FDI link */
        if (HAS_PCH_SPLIT(dev)) {
+               int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
                int lane = 0, link_bw, bpp;
                /* CPU eDP doesn't require FDI link, so just set DP M/N
                   according to current link config */
@@ -3787,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
                intel_crtc->fdi_lanes = lane;
 
+               if (pixel_multiplier > 1)
+                       link_bw *= pixel_multiplier;
                ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
        }
 
@@ -5224,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
        .page_flip = intel_crtc_page_flip,
 };
 
+static void intel_sanitize_modesetting(struct drm_device *dev,
+                                      int pipe, int plane)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 reg, val;
+
+       if (HAS_PCH_SPLIT(dev))
+               return;
+
+       /* Who knows what state these registers were left in by the BIOS or
+        * grub?
+        *
+        * If we leave the registers in a conflicting state (e.g. with the
+        * display plane reading from the other pipe than the one we intend
+        * to use) then when we attempt to teardown the active mode, we will
+        * not disable the pipes and planes in the correct order -- leaving
+        * a plane reading from a disabled pipe and possibly leading to
+        * undefined behaviour.
+        */
+
+       reg = DSPCNTR(plane);
+       val = I915_READ(reg);
+
+       if ((val & DISPLAY_PLANE_ENABLE) == 0)
+               return;
+       if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe)
+               return;
+
+       /* This display plane is active and attached to the other CPU pipe. */
+       pipe = !pipe;
+
+       /* Disable the plane and wait for it to stop reading from the pipe. */
+       I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
+       intel_flush_display_plane(dev, plane);
+
+       if (IS_GEN2(dev))
+               intel_wait_for_vblank(dev, pipe);
+
+       if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+               return;
+
+       /* Switch off the pipe. */
+       reg = PIPECONF(pipe);
+       val = I915_READ(reg);
+       if (val & PIPECONF_ENABLE) {
+               I915_WRITE(reg, val & ~PIPECONF_ENABLE);
+               intel_wait_for_pipe_off(dev, pipe);
+       }
+}
 
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
@@ -5275,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 
        setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
                    (unsigned long)intel_crtc);
+
+       intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
 }
 
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -5324,9 +5384,14 @@ static void intel_setup_outputs(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
        bool dpd_is_edp = false;
+       bool has_lvds = false;
 
        if (IS_MOBILE(dev) && !IS_I830(dev))
-               intel_lvds_init(dev);
+               has_lvds = intel_lvds_init(dev);
+       if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
+               /* disable the panel fitter on everything but LVDS */
+               I915_WRITE(PFIT_CONTROL, 0);
+       }
 
        if (HAS_PCH_SPLIT(dev)) {
                dpd_is_edp = intel_dpd_is_edp(dev);
index c8e005553310a5eaeae98e4cb8ed349b4b204164..df648cb4c29641cec581307b1c40a46d812fd58b 100644 (file)
@@ -584,17 +584,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = dev_priv->panel_fixed_mode->clock;
        }
 
-       /* Just use VBT values for eDP */
-       if (is_edp(intel_dp)) {
-               intel_dp->lane_count = dev_priv->edp.lanes;
-               intel_dp->link_bw = dev_priv->edp.rate;
-               adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
-               DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
-                             intel_dp->link_bw, intel_dp->lane_count,
-                             adjusted_mode->clock);
-               return true;
-       }
-
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -613,6 +602,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                }
        }
 
+       if (is_edp(intel_dp)) {
+               /* okay we failed just pick the highest */
+               intel_dp->lane_count = max_lane_count;
+               intel_dp->link_bw = bws[max_clock];
+               adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+               DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+                             "count %d clock %d\n",
+                             intel_dp->link_bw, intel_dp->lane_count,
+                             adjusted_mode->clock);
+
+               return true;
+       }
+
        return false;
 }
 
@@ -1087,21 +1089,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
 }
 
 static uint32_t
-intel_dp_signal_levels(struct intel_dp *intel_dp)
+intel_dp_signal_levels(uint8_t train_set, int lane_count)
 {
-       struct drm_device *dev = intel_dp->base.base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       uint32_t signal_levels = 0;
-       u8 train_set = intel_dp->train_set[0];
-       u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK;
-       u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK;
+       uint32_t        signal_levels = 0;
 
-       if (is_edp(intel_dp)) {
-               vswing = dev_priv->edp.vswing;
-               preemphasis = dev_priv->edp.preemphasis;
-       }
-
-       switch (vswing) {
+       switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
        case DP_TRAIN_VOLTAGE_SWING_400:
        default:
                signal_levels |= DP_VOLTAGE_0_4;
@@ -1116,7 +1108,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp)
                signal_levels |= DP_VOLTAGE_1_2;
                break;
        }
-       switch (preemphasis) {
+       switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
        case DP_TRAIN_PRE_EMPHASIS_0:
        default:
                signal_levels |= DP_PRE_EMPHASIS_0;
@@ -1202,18 +1194,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
        return true;
 }
 
-static bool
-intel_dp_aux_handshake_required(struct intel_dp *intel_dp)
-{
-       struct drm_device *dev = intel_dp->base.base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
-       if (is_edp(intel_dp) && dev_priv->no_aux_handshake)
-               return false;
-
-       return true;
-}
-
 static bool
 intel_dp_set_link_train(struct intel_dp *intel_dp,
                        uint32_t dp_reg_value,
@@ -1226,9 +1206,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
        I915_WRITE(intel_dp->output_reg, dp_reg_value);
        POSTING_READ(intel_dp->output_reg);
 
-       if (!intel_dp_aux_handshake_required(intel_dp))
-               return true;
-
        intel_dp_aux_native_write_1(intel_dp,
                                    DP_TRAINING_PATTERN_SET,
                                    dp_train_pat);
@@ -1261,11 +1238,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
        POSTING_READ(intel_dp->output_reg);
        intel_wait_for_vblank(dev, intel_crtc->pipe);
 
-       if (intel_dp_aux_handshake_required(intel_dp))
-               /* Write the link configuration data */
-               intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
-                                         intel_dp->link_configuration,
-                                         DP_LINK_CONFIGURATION_SIZE);
+       /* Write the link configuration data */
+       intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+                                 intel_dp->link_configuration,
+                                 DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
        if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
@@ -1283,7 +1259,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1297,37 +1273,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        break;
                /* Set training pattern 1 */
 
-               udelay(500);
-               if (intel_dp_aux_handshake_required(intel_dp)) {
+               udelay(100);
+               if (!intel_dp_get_link_status(intel_dp))
+                       break;
+
+               if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+                       clock_recovery = true;
                        break;
-               } else {
-                       if (!intel_dp_get_link_status(intel_dp))
-                               break;
+               }
 
-                       if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
-                               clock_recovery = true;
+               /* Check to see if we've tried the max voltage */
+               for (i = 0; i < intel_dp->lane_count; i++)
+                       if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
-                       }
+               if (i == intel_dp->lane_count)
+                       break;
 
-                       /* Check to see if we've tried the max voltage */
-                       for (i = 0; i < intel_dp->lane_count; i++)
-                               if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
-                                       break;
-                       if (i == intel_dp->lane_count)
+               /* Check to see if we've tried the same voltage 5 times */
+               if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+                       ++tries;
+                       if (tries == 5)
                                break;
+               } else
+                       tries = 0;
+               voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
-                       /* Check to see if we've tried the same voltage 5 times */
-                       if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-                               ++tries;
-                               if (tries == 5)
-                                       break;
-                       } else
-                               tries = 0;
-                       voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-
-                       /* Compute new intel_dp->train_set as requested by target */
-                       intel_get_adjust_train(intel_dp);
-               }
+               /* Compute new intel_dp->train_set as requested by target */
+               intel_get_adjust_train(intel_dp);
        }
 
        intel_dp->DP = DP;
@@ -1354,7 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1368,28 +1340,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                                             DP_TRAINING_PATTERN_2))
                        break;
 
-               udelay(500);
-
-               if (!intel_dp_aux_handshake_required(intel_dp)) {
+               udelay(400);
+               if (!intel_dp_get_link_status(intel_dp))
                        break;
-               } else {
-                       if (!intel_dp_get_link_status(intel_dp))
-                               break;
 
-                       if (intel_channel_eq_ok(intel_dp)) {
-                               channel_eq = true;
-                               break;
-                       }
+               if (intel_channel_eq_ok(intel_dp)) {
+                       channel_eq = true;
+                       break;
+               }
 
-                       /* Try 5 times */
-                       if (tries > 5)
-                               break;
+               /* Try 5 times */
+               if (tries > 5)
+                       break;
 
-                       /* Compute new intel_dp->train_set as requested by target */
-                       intel_get_adjust_train(intel_dp);
-                       ++tries;
-               }
+               /* Compute new intel_dp->train_set as requested by target */
+               intel_get_adjust_train(intel_dp);
+               ++tries;
        }
+
        if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
                reg = DP | DP_LINK_TRAIN_OFF_CPT;
        else
@@ -1408,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t DP = intel_dp->DP;
 
+       if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+               return;
+
        DRM_DEBUG_KMS("\n");
 
        if (is_edp(intel_dp)) {
@@ -1430,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        if (is_edp(intel_dp))
                DP |= DP_LINK_TRAIN_OFF;
+
+       if (!HAS_PCH_CPT(dev) &&
+           I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
+               struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
+               /* Hardware workaround: leaving our transcoder select
+                * set to transcoder B while it's off will prevent the
+                * corresponding HDMI output on transcoder A.
+                *
+                * Combine this with another hardware workaround:
+                * transcoder select bit can only be cleared while the
+                * port is enabled.
+                */
+               DP &= ~DP_PIPEB_SELECT;
+               I915_WRITE(intel_dp->output_reg, DP);
+
+               /* Changes to enable or select take place the vblank
+                * after being written.
+                */
+               intel_wait_for_vblank(intel_dp->base.base.dev,
+                                     intel_crtc->pipe);
+       }
+
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
 }
index 21551fe745416abb4597341b18d647f2529e85ce..e52c6125bb1f05636e59f52420d055fc4e919e9f 100644 (file)
@@ -237,7 +237,7 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
 extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
-extern void intel_lvds_init(struct drm_device *dev);
+extern bool intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
index 2be4f728ed0c7b250550613cc93259462db9735a..3dba086e7eea012947c410738e208a9ef39bfa9e 100644 (file)
@@ -160,7 +160,7 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
        };
        struct intel_gpio *gpio;
 
-       if (pin < 1 || pin > 7)
+       if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
                return NULL;
 
        gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL);
@@ -172,7 +172,8 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
                gpio->reg += PCH_GPIOA - GPIOA;
        gpio->dev_priv = dev_priv;
 
-       snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO%c", "?BACDEF?"[pin]);
+       snprintf(gpio->adapter.name, sizeof(gpio->adapter.name),
+                "i915 GPIO%c", "?BACDE?F"[pin]);
        gpio->adapter.owner = THIS_MODULE;
        gpio->adapter.algo_data = &gpio->algo;
        gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev;
@@ -349,7 +350,7 @@ int intel_setup_gmbus(struct drm_device *dev)
                "panel",
                "dpc",
                "dpb",
-               "reserved"
+               "reserved",
                "dpd",
        };
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -366,8 +367,8 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->adapter.owner = THIS_MODULE;
                bus->adapter.class = I2C_CLASS_DDC;
                snprintf(bus->adapter.name,
-                        I2C_NAME_SIZE,
-                        "gmbus %s",
+                        sizeof(bus->adapter.name),
+                        "i915 gmbus %s",
                         names[i]);
 
                bus->adapter.dev.parent = &dev->pdev->dev;
index 4324a326f98ee28f4d67936b7a4789556344c4fb..25bcedf386fd5e07f93b2c2f77d78dd8dc905170 100644 (file)
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
 /**
  * Sets the power state for the panel.
  */
-static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
+static void intel_lvds_enable(struct intel_lvds *intel_lvds)
 {
        struct drm_device *dev = intel_lvds->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
                lvds_reg = LVDS;
        }
 
-       if (on) {
-               I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
-               I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
-               intel_panel_set_backlight(dev, dev_priv->backlight_level);
-       } else {
-               dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
-               intel_panel_set_backlight(dev, 0);
-               I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+       I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
 
-               if (intel_lvds->pfit_control) {
-                       if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
-                               DRM_ERROR("timed out waiting for panel to power off\n");
-                       I915_WRITE(PFIT_CONTROL, 0);
-                       intel_lvds->pfit_control = 0;
+       if (intel_lvds->pfit_dirty) {
+               /*
+                * Enable automatic panel scaling so that non-native modes
+                * fill the screen.  The panel fitter should only be
+                * adjusted whilst the pipe is disabled, according to
+                * register description and PRM.
+                */
+               DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
+                             intel_lvds->pfit_control,
+                             intel_lvds->pfit_pgm_ratios);
+               if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
+                       DRM_ERROR("timed out waiting for panel to power off\n");
+               } else {
+                       I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
+                       I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
                        intel_lvds->pfit_dirty = false;
                }
+       }
+
+       I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
+       POSTING_READ(lvds_reg);
+
+       intel_panel_set_backlight(dev, dev_priv->backlight_level);
+}
+
+static void intel_lvds_disable(struct intel_lvds *intel_lvds)
+{
+       struct drm_device *dev = intel_lvds->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 ctl_reg, lvds_reg;
+
+       if (HAS_PCH_SPLIT(dev)) {
+               ctl_reg = PCH_PP_CONTROL;
+               lvds_reg = PCH_LVDS;
+       } else {
+               ctl_reg = PP_CONTROL;
+               lvds_reg = LVDS;
+       }
+
+       dev_priv->backlight_level = intel_panel_get_backlight(dev);
+       intel_panel_set_backlight(dev, 0);
+
+       I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
+
+       if (intel_lvds->pfit_control) {
+               if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
+                       DRM_ERROR("timed out waiting for panel to power off\n");
 
-               I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
+               I915_WRITE(PFIT_CONTROL, 0);
+               intel_lvds->pfit_dirty = true;
        }
+
+       I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
        POSTING_READ(lvds_reg);
 }
 
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
        if (mode == DRM_MODE_DPMS_ON)
-               intel_lvds_set_power(intel_lvds, true);
+               intel_lvds_enable(intel_lvds);
        else
-               intel_lvds_set_power(intel_lvds, false);
+               intel_lvds_disable(intel_lvds);
 
        /* XXX: We never power down the LVDS pairs. */
 }
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
        /* Always do a full power on as we do not know what state
         * we were left in.
         */
-       intel_lvds_set_power(intel_lvds, true);
+       intel_lvds_enable(intel_lvds);
 }
 
 static void intel_lvds_mode_set(struct drm_encoder *encoder,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode)
 {
-       struct drm_device *dev = encoder->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
        /*
         * The LVDS pin pair will already have been turned on in the
         * intel_crtc_mode_set since it has a large impact on the DPLL
         * settings.
         */
-
-       if (HAS_PCH_SPLIT(dev))
-               return;
-
-       if (!intel_lvds->pfit_dirty)
-               return;
-
-       /*
-        * Enable automatic panel scaling so that non-native modes fill the
-        * screen.  Should be enabled before the pipe is enabled, according to
-        * register description and PRM.
-        */
-       DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
-                     intel_lvds->pfit_control,
-                     intel_lvds->pfit_pgm_ratios);
-       if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
-               DRM_ERROR("timed out waiting for panel to power off\n");
-
-       I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
-       I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
-       intel_lvds->pfit_dirty = false;
 }
 
 /**
@@ -837,7 +847,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
  * Create the connector, register the LVDS DDC bus, and try to figure out what
  * modes we can display on the LVDS panel (if present).
  */
-void intel_lvds_init(struct drm_device *dev)
+bool intel_lvds_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds;
@@ -853,37 +863,37 @@ void intel_lvds_init(struct drm_device *dev)
 
        /* Skip init on machines we know falsely report LVDS */
        if (dmi_check_system(intel_no_lvds))
-               return;
+               return false;
 
        pin = GMBUS_PORT_PANEL;
        if (!lvds_is_present_in_vbt(dev, &pin)) {
                DRM_DEBUG_KMS("LVDS is not present in VBT\n");
-               return;
+               return false;
        }
 
        if (HAS_PCH_SPLIT(dev)) {
                if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
-                       return;
+                       return false;
                if (dev_priv->edp.support) {
                        DRM_DEBUG_KMS("disable LVDS for eDP support\n");
-                       return;
+                       return false;
                }
        }
 
        if (!intel_lvds_ddc_probe(dev, pin)) {
                DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
-               return;
+               return false;
        }
 
        intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
        if (!intel_lvds) {
-               return;
+               return false;
        }
 
        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
        if (!intel_connector) {
                kfree(intel_lvds);
-               return;
+               return false;
        }
 
        if (!HAS_PCH_SPLIT(dev)) {
@@ -1026,7 +1036,7 @@ out:
        /* keep the LVDS connector */
        dev_priv->int_lvds_connector = connector;
        drm_sysfs_connector_add(connector);
-       return;
+       return true;
 
 failed:
        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1034,4 +1044,5 @@ failed:
        drm_encoder_cleanup(encoder);
        kfree(intel_lvds);
        kfree(intel_connector);
+       return false;
 }
index b83306f9244b6c887d84976b4f1801449445941a..89a65be8a3f364359edaf6add71b6259affa3cbd 100644 (file)
@@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev,
 
        /* G45 ring initialization fails to reset head to zero */
        if (head != 0) {
-               DRM_ERROR("%s head not reset to zero "
-                               "ctl %08x head %08x tail %08x start %08x\n",
-                               ring->name,
-                               I915_READ_CTL(ring),
-                               I915_READ_HEAD(ring),
-                               I915_READ_TAIL(ring),
-                               I915_READ_START(ring));
+               DRM_DEBUG_KMS("%s head not reset to zero "
+                             "ctl %08x head %08x tail %08x start %08x\n",
+                             ring->name,
+                             I915_READ_CTL(ring),
+                             I915_READ_HEAD(ring),
+                             I915_READ_TAIL(ring),
+                             I915_READ_START(ring));
 
                I915_WRITE_HEAD(ring, 0);
 
-               DRM_ERROR("%s head forced to zero "
-                               "ctl %08x head %08x tail %08x start %08x\n",
-                               ring->name,
-                               I915_READ_CTL(ring),
-                               I915_READ_HEAD(ring),
-                               I915_READ_TAIL(ring),
-                               I915_READ_START(ring));
+               if (I915_READ_HEAD(ring) & HEAD_ADDR) {
+                       DRM_ERROR("failed to set %s head to zero "
+                                 "ctl %08x head %08x tail %08x start %08x\n",
+                                 ring->name,
+                                 I915_READ_CTL(ring),
+                                 I915_READ_HEAD(ring),
+                                 I915_READ_TAIL(ring),
+                                 I915_READ_START(ring));
+               }
        }
 
        I915_WRITE_CTL(ring,
index de158b76bcd572da1e261713c66d43fa4428f72c..d97e6cb52d34a102705d9ab59f030cb551333e16 100644 (file)
@@ -107,7 +107,8 @@ struct intel_sdvo {
         * This is set if we treat the device as HDMI, instead of DVI.
         */
        bool is_hdmi;
-       bool has_audio;
+       bool has_hdmi_monitor;
+       bool has_hdmi_audio;
 
        /**
         * This is set if we detect output of sdvo device as LVDS and
@@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        if (!intel_sdvo_set_target_input(intel_sdvo))
                return;
 
-       if (intel_sdvo->is_hdmi &&
+       if (intel_sdvo->has_hdmi_monitor &&
            !intel_sdvo_set_avi_infoframe(intel_sdvo))
                return;
 
@@ -1063,7 +1064,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        }
        if (intel_crtc->pipe == 1)
                sdvox |= SDVO_PIPE_B_SELECT;
-       if (intel_sdvo->has_audio)
+       if (intel_sdvo->has_hdmi_audio)
                sdvox |= SDVO_AUDIO_ENABLE;
 
        if (INTEL_INFO(dev)->gen >= 4) {
@@ -1295,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector)
        return drm_get_edid(connector, &sdvo->ddc);
 }
 
-static struct drm_connector *
-intel_find_analog_connector(struct drm_device *dev)
-{
-       struct drm_connector *connector;
-       struct intel_sdvo *encoder;
-
-       list_for_each_entry(encoder,
-                           &dev->mode_config.encoder_list,
-                           base.base.head) {
-               if (encoder->base.type == INTEL_OUTPUT_ANALOG) {
-                       list_for_each_entry(connector,
-                                           &dev->mode_config.connector_list,
-                                           head) {
-                               if (&encoder->base ==
-                                   intel_attached_encoder(connector))
-                                       return connector;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-static int
-intel_analog_is_connected(struct drm_device *dev)
-{
-       struct drm_connector *analog_connector;
-
-       analog_connector = intel_find_analog_connector(dev);
-       if (!analog_connector)
-               return false;
-
-       if (analog_connector->funcs->detect(analog_connector, false) ==
-                       connector_status_disconnected)
-               return false;
-
-       return true;
-}
-
 /* Mac mini hack -- use the same DDC as the analog connector */
 static struct edid *
 intel_sdvo_get_analog_edid(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
 
-       if (!intel_analog_is_connected(connector->dev))
-               return NULL;
-
-       return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+       return drm_get_edid(connector,
+                           &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
 }
 
 enum drm_connector_status
@@ -1388,8 +1348,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
                /* DDC bus is shared, match EDID to connector type */
                if (edid->input & DRM_EDID_INPUT_DIGITAL) {
                        status = connector_status_connected;
-                       intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
-                       intel_sdvo->has_audio = drm_detect_monitor_audio(edid);
+                       if (intel_sdvo->is_hdmi) {
+                               intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
+                               intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
+                       }
                }
                connector->display_info.raw_edid = NULL;
                kfree(edid);
@@ -1398,7 +1360,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
        if (status == connector_status_connected) {
                struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
                if (intel_sdvo_connector->force_audio)
-                       intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0;
+                       intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0;
        }
 
        return status;
@@ -1415,10 +1377,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
        if (!intel_sdvo_write_cmd(intel_sdvo,
                                  SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
                return connector_status_unknown;
-       if (intel_sdvo->is_tv) {
-               /* add 30ms delay when the output type is SDVO-TV */
+
+       /* add 30ms delay when the output type might be TV */
+       if (intel_sdvo->caps.output_flags &
+           (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
                mdelay(30);
-       }
+
        if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
                return connector_status_unknown;
 
@@ -1472,8 +1436,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
                edid = intel_sdvo_get_analog_edid(connector);
 
        if (edid != NULL) {
-               drm_mode_connector_update_edid_property(connector, edid);
-               drm_add_edid_modes(connector, edid);
+               if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+                       drm_mode_connector_update_edid_property(connector, edid);
+                       drm_add_edid_modes(connector, edid);
+               }
                connector->display_info.raw_edid = NULL;
                kfree(edid);
        }
@@ -1713,12 +1679,12 @@ intel_sdvo_set_property(struct drm_connector *connector,
 
                intel_sdvo_connector->force_audio = val;
 
-               if (val > 0 && intel_sdvo->has_audio)
+               if (val > 0 && intel_sdvo->has_hdmi_audio)
                        return 0;
-               if (val < 0 && !intel_sdvo->has_audio)
+               if (val < 0 && !intel_sdvo->has_hdmi_audio)
                        return 0;
 
-               intel_sdvo->has_audio = val > 0;
+               intel_sdvo->has_hdmi_audio = val > 0;
                goto done;
        }
 
@@ -2070,6 +2036,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_set_colorimetry(intel_sdvo,
                                           SDVO_COLORIMETRY_RGB256);
                connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+               intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
                intel_sdvo->is_hdmi = true;
        }
        intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
@@ -2077,8 +2045,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 
-       intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
-
        return true;
 }
 
index 406228f4a2a05e549090f8a4e4fca09253546833..b14c811105756706103fe770bc140f24e0a604a7 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/backlight.h>
+#include <linux/acpi.h>
 
 #include "drmP.h"
 #include "nouveau_drv.h"
@@ -136,6 +137,14 @@ int nouveau_backlight_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
+#ifdef CONFIG_ACPI
+       if (acpi_video_backlight_support()) {
+               NV_INFO(dev, "ACPI backlight interface available, "
+                            "not registering our own\n");
+               return 0;
+       }
+#endif
+
        switch (dev_priv->card_type) {
        case NV_40:
                return nouveau_nv40_backlight_init(dev);
index 5f21030a293bbc3f373a76631a5e092a0075ea3f..b2293576f27895f3b67e41e563675ab52519b3ad 100644 (file)
@@ -6829,7 +6829,7 @@ nouveau_bios_posted(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        unsigned htotal;
 
-       if (dev_priv->chipset >= NV_50) {
+       if (dev_priv->card_type >= NV_50) {
                if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
                    NVReadVgaCrtc(dev, 0, 0x1a) == 0)
                        return false;
index 80353e2b8409fdfe34b620b54ce8fdc119af5acd..c41e1c200ef5f2143ea670b45eb3f1d0633864e2 100644 (file)
@@ -143,8 +143,10 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
        nvbo->no_vm = no_vm;
        nvbo->tile_mode = tile_mode;
        nvbo->tile_flags = tile_flags;
+       nvbo->bo.bdev = &dev_priv->ttm.bdev;
 
-       nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size);
+       nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo),
+                              &align, &size);
        align >>= PAGE_SHIFT;
 
        nouveau_bo_placement_set(nvbo, flags, 0);
@@ -176,6 +178,31 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
                pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
 }
 
+static void
+set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
+{
+       struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+
+       if (dev_priv->card_type == NV_10 &&
+           nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) {
+               /*
+                * Make sure that the color and depth buffers are handled
+                * by independent memory controller units. Up to a 9x
+                * speed up when alpha-blending and depth-test are enabled
+                * at the same time.
+                */
+               int vram_pages = dev_priv->vram_size >> PAGE_SHIFT;
+
+               if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) {
+                       nvbo->placement.fpfn = vram_pages / 2;
+                       nvbo->placement.lpfn = ~0;
+               } else {
+                       nvbo->placement.fpfn = 0;
+                       nvbo->placement.lpfn = vram_pages / 2;
+               }
+       }
+}
+
 void
 nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 {
@@ -190,6 +217,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
        pl->busy_placement = nvbo->busy_placements;
        set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
                           type | busy, flags);
+
+       set_placement_range(nvbo, type);
 }
 
 int
@@ -525,7 +554,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                stride  = 16 * 4;
                height  = amount / stride;
 
-               if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+               if (new_mem->mem_type == TTM_PL_VRAM &&
+                   nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
                                return ret;
@@ -546,7 +576,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                        BEGIN_RING(chan, NvSubM2MF, 0x0200, 1);
                        OUT_RING  (chan, 1);
                }
-               if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+               if (old_mem->mem_type == TTM_PL_VRAM &&
+                   nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
                                return ret;
@@ -753,7 +784,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
        if (dev_priv->card_type == NV_50) {
                ret = nv50_mem_vm_bind_linear(dev,
                                              offset + dev_priv->vm_vram_base,
-                                             new_mem->size, nvbo->tile_flags,
+                                             new_mem->size,
+                                             nouveau_bo_tile_layout(nvbo),
                                              offset);
                if (ret)
                        return ret;
@@ -894,7 +926,8 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
         * nothing to do here.
         */
        if (bo->mem.mem_type != TTM_PL_VRAM) {
-               if (dev_priv->card_type < NV_50 || !nvbo->tile_flags)
+               if (dev_priv->card_type < NV_50 ||
+                   !nouveau_bo_tile_layout(nvbo))
                        return 0;
        }
 
index 0871495096fa86f1278f825c8420f8e14f1e6b38..52c356e9a3d177b92ed5013e8f55247a56468f5d 100644 (file)
@@ -281,7 +281,7 @@ detect_analog:
        nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
        if (!nv_encoder && !nouveau_tv_disable)
                nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
-       if (nv_encoder) {
+       if (nv_encoder && force) {
                struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
                struct drm_encoder_helper_funcs *helper =
                                                encoder->helper_private;
@@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector)
        return ret;
 }
 
+static unsigned
+get_tmds_link_bandwidth(struct drm_connector *connector)
+{
+       struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+       struct dcb_entry *dcb = nv_connector->detected_encoder->dcb;
+
+       if (dcb->location != DCB_LOC_ON_CHIP ||
+           dev_priv->chipset >= 0x46)
+               return 165000;
+       else if (dev_priv->chipset >= 0x40)
+               return 155000;
+       else if (dev_priv->chipset >= 0x18)
+               return 135000;
+       else
+               return 112000;
+}
+
 static int
 nouveau_connector_mode_valid(struct drm_connector *connector,
                             struct drm_display_mode *mode)
 {
-       struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
        struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
                max_clock = 400000;
                break;
        case OUTPUT_TMDS:
-               if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
-                   !nv_encoder->dcb->duallink_possible)
-                       max_clock = 165000;
-               else
-                       max_clock = 330000;
+               max_clock = get_tmds_link_bandwidth(connector);
+               if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
+                       max_clock *= 2;
                break;
        case OUTPUT_ANALOG:
                max_clock = nv_encoder->dcb->crtconf.maxfreq;
@@ -709,44 +724,6 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
        return NULL;
 }
 
-void
-nouveau_connector_set_polling(struct drm_connector *connector)
-{
-       struct drm_device *dev = connector->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc;
-       bool spare_crtc = false;
-
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-               spare_crtc |= !crtc->enabled;
-
-       connector->polled = 0;
-
-       switch (connector->connector_type) {
-       case DRM_MODE_CONNECTOR_VGA:
-       case DRM_MODE_CONNECTOR_TV:
-               if (dev_priv->card_type >= NV_50 ||
-                   (nv_gf4_disp_arch(dev) && spare_crtc))
-                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-               break;
-
-       case DRM_MODE_CONNECTOR_DVII:
-       case DRM_MODE_CONNECTOR_DVID:
-       case DRM_MODE_CONNECTOR_HDMIA:
-       case DRM_MODE_CONNECTOR_DisplayPort:
-       case DRM_MODE_CONNECTOR_eDP:
-               if (dev_priv->card_type >= NV_50)
-                       connector->polled = DRM_CONNECTOR_POLL_HPD;
-               else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
-                        spare_crtc)
-                       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-               break;
-
-       default:
-               break;
-       }
-}
-
 static const struct drm_connector_helper_funcs
 nouveau_connector_helper_funcs = {
        .get_modes = nouveau_connector_get_modes,
@@ -872,6 +849,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
                                        dev->mode_config.scaling_mode_property,
                                        nv_connector->scaling_mode);
                }
+               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
                /* fall-through */
        case DCB_CONNECTOR_TV_0:
        case DCB_CONNECTOR_TV_1:
@@ -888,11 +866,16 @@ nouveau_connector_create(struct drm_device *dev, int index)
                                dev->mode_config.dithering_mode_property,
                                nv_connector->use_dithering ?
                                DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
+
+               if (dcb->type != DCB_CONNECTOR_LVDS) {
+                       if (dev_priv->card_type >= NV_50)
+                               connector->polled = DRM_CONNECTOR_POLL_HPD;
+                       else
+                               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               }
                break;
        }
 
-       nouveau_connector_set_polling(connector);
-
        drm_sysfs_connector_add(connector);
        dcb->drm = connector;
        return dcb->drm;
index c21ed6b16f88d41aebdee888997c12a7249fdd03..711b1e9203aff075c16757fd41394a5ea06d33e7 100644 (file)
@@ -52,9 +52,6 @@ static inline struct nouveau_connector *nouveau_connector(
 struct drm_connector *
 nouveau_connector_create(struct drm_device *, int index);
 
-void
-nouveau_connector_set_polling(struct drm_connector *);
-
 int
 nouveau_connector_bpp(struct drm_connector *);
 
index 3a07e580d27af548fe2fd247b4e7df4c67994956..1c7db64c03bf03b45070939f16bc5a0092820ba0 100644 (file)
@@ -100,6 +100,9 @@ struct nouveau_bo {
        int pin_refcnt;
 };
 
+#define nouveau_bo_tile_layout(nvbo)                           \
+       ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)
+
 static inline struct nouveau_bo *
 nouveau_bo(struct ttm_buffer_object *bo)
 {
@@ -304,6 +307,7 @@ struct nouveau_fifo_engine {
        void (*destroy_context)(struct nouveau_channel *);
        int  (*load_context)(struct nouveau_channel *);
        int  (*unload_context)(struct drm_device *);
+       void (*tlb_flush)(struct drm_device *dev);
 };
 
 struct nouveau_pgraph_object_method {
@@ -336,6 +340,7 @@ struct nouveau_pgraph_engine {
        void (*destroy_context)(struct nouveau_channel *);
        int  (*load_context)(struct nouveau_channel *);
        int  (*unload_context)(struct drm_device *);
+       void (*tlb_flush)(struct drm_device *dev);
 
        void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
                                  uint32_t size, uint32_t pitch);
@@ -485,13 +490,13 @@ enum nv04_fp_display_regs {
 };
 
 struct nv04_crtc_reg {
-       unsigned char MiscOutReg;     /* */
+       unsigned char MiscOutReg;
        uint8_t CRTC[0xa0];
        uint8_t CR58[0x10];
        uint8_t Sequencer[5];
        uint8_t Graphics[9];
        uint8_t Attribute[21];
-       unsigned char DAC[768];       /* Internal Colorlookuptable */
+       unsigned char DAC[768];
 
        /* PCRTC regs */
        uint32_t fb_start;
@@ -539,43 +544,9 @@ struct nv04_output_reg {
 };
 
 struct nv04_mode_state {
-       uint32_t bpp;
-       uint32_t width;
-       uint32_t height;
-       uint32_t interlace;
-       uint32_t repaint0;
-       uint32_t repaint1;
-       uint32_t screen;
-       uint32_t scale;
-       uint32_t dither;
-       uint32_t extra;
-       uint32_t fifo;
-       uint32_t pixel;
-       uint32_t horiz;
-       int arbitration0;
-       int arbitration1;
-       uint32_t pll;
-       uint32_t pllB;
-       uint32_t vpll;
-       uint32_t vpll2;
-       uint32_t vpllB;
-       uint32_t vpll2B;
+       struct nv04_crtc_reg crtc_reg[2];
        uint32_t pllsel;
        uint32_t sel_clk;
-       uint32_t general;
-       uint32_t crtcOwner;
-       uint32_t head;
-       uint32_t head2;
-       uint32_t cursorConfig;
-       uint32_t cursor0;
-       uint32_t cursor1;
-       uint32_t cursor2;
-       uint32_t timingH;
-       uint32_t timingV;
-       uint32_t displayV;
-       uint32_t crtcSync;
-
-       struct nv04_crtc_reg crtc_reg[2];
 };
 
 enum nouveau_card_type {
@@ -613,6 +584,12 @@ struct drm_nouveau_private {
        struct work_struct irq_work;
        struct work_struct hpd_work;
 
+       struct {
+               spinlock_t lock;
+               uint32_t hpd0_bits;
+               uint32_t hpd1_bits;
+       } hpd_state;
+
        struct list_head vbl_waiting;
 
        struct {
@@ -1045,6 +1022,7 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
+extern void nv50_fifo_tlb_flush(struct drm_device *dev);
 
 /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
@@ -1122,6 +1100,8 @@ extern int  nv50_graph_load_context(struct nouveau_channel *);
 extern int  nv50_graph_unload_context(struct drm_device *);
 extern void nv50_graph_context_switch(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
+extern void nv50_graph_tlb_flush(struct drm_device *dev);
+extern void nv86_graph_tlb_flush(struct drm_device *dev);
 
 /* nvc0_graph.c */
 extern int  nvc0_graph_init(struct drm_device *);
@@ -1239,7 +1219,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
 extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
-extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
 
 /* nouveau_fence.c */
 struct nouveau_fence;
index 441b12420bb1b713fb56b98edad389d31fe367ea..ab1bbfbf266e6a63755264ad461484f3608a10c1 100644 (file)
@@ -249,6 +249,7 @@ alloc_semaphore(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_semaphore *sema;
+       int ret;
 
        if (!USE_SEMA(dev))
                return NULL;
@@ -257,10 +258,14 @@ alloc_semaphore(struct drm_device *dev)
        if (!sema)
                goto fail;
 
+       ret = drm_mm_pre_get(&dev_priv->fence.heap);
+       if (ret)
+               goto fail;
+
        spin_lock(&dev_priv->fence.lock);
        sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0);
        if (sema->mem)
-               sema->mem = drm_mm_get_block(sema->mem, 4, 0);
+               sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0);
        spin_unlock(&dev_priv->fence.lock);
 
        if (!sema->mem)
index 5c4c929d7f744d6911c1a16b67924ab770b6de5c..9a1fdcf400c2fea235544f062fe8b33cd1b01fd4 100644 (file)
@@ -107,23 +107,29 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep)
 }
 
 static bool
-nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) {
-       switch (tile_flags) {
-       case 0x0000:
-       case 0x1800:
-       case 0x2800:
-       case 0x4800:
-       case 0x7000:
-       case 0x7400:
-       case 0x7a00:
-       case 0xe000:
-               break;
-       default:
-               NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
-               return false;
+nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       if (dev_priv->card_type >= NV_50) {
+               switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
+               case 0x0000:
+               case 0x1800:
+               case 0x2800:
+               case 0x4800:
+               case 0x7000:
+               case 0x7400:
+               case 0x7a00:
+               case 0xe000:
+                       return true;
+               }
+       } else {
+               if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
+                       return true;
        }
 
-       return true;
+       NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
+       return false;
 }
 
 int
index bed669a54a2da0692af9a9a1cd4a89064f4d0fd0..b9672a05c411f12866035884acf8778a4742eb9c 100644 (file)
@@ -519,11 +519,11 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
 
        struct pll_lims pll_lim;
        struct nouveau_pll_vals pv;
-       uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+       enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0;
 
-       if (get_pll_limits(dev, pllreg, &pll_lim))
+       if (get_pll_limits(dev, pll, &pll_lim))
                return;
-       nouveau_hw_get_pllvals(dev, pllreg, &pv);
+       nouveau_hw_get_pllvals(dev, pll, &pv);
 
        if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
            pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
@@ -536,7 +536,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
        pv.M1 = pll_lim.vco1.max_m;
        pv.N1 = pll_lim.vco1.min_n;
        pv.log2P = pll_lim.max_usable_log2p;
-       nouveau_hw_setpll(dev, pllreg, &pv);
+       nouveau_hw_setpll(dev, pll_lim.reg, &pv);
 }
 
 /*
index 869130f83602f6cf027a2329eb7be49eafb88ccc..2989090b94349abdcd05096f89735f641a748c3b 100644 (file)
@@ -415,6 +415,25 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
        NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos);
 }
 
+static inline void
+nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       NVWriteCRTC(dev, head, NV_PCRTC_START, offset);
+
+       if (dev_priv->card_type == NV_04) {
+               /*
+                * Hilarious, the 24th bit doesn't want to stick to
+                * PCRTC_START...
+                */
+               int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX);
+
+               NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX,
+                              (cre_heb & ~0x40) | ((offset >> 18) & 0x40));
+       }
+}
+
 static inline void
 nv_show_cursor(struct drm_device *dev, int head, bool show)
 {
index fdd7e3de79c895138c93706bc023048772f93026..cb389d014326ae4c89b78724f3438a023e0f06b7 100644 (file)
@@ -256,7 +256,7 @@ nouveau_i2c_find(struct drm_device *dev, int index)
        if (index >= DCB_MAX_NUM_I2C_ENTRIES)
                return NULL;
 
-       if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) {
+       if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) {
                uint32_t reg = 0xe500, val;
 
                if (i2c->port_type == 6) {
index 6fd51a51c60861e697f43755593f4ad2a1830c9c..7bfd9e6c9d67194b298047d7670a54a996c16750 100644 (file)
 #include "nouveau_connector.h"
 #include "nv50_display.h"
 
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
+
+static int nouveau_ratelimit(void)
+{
+       return __ratelimit(&nouveau_ratelimit_state);
+}
+
 void
 nouveau_irq_preinstall(struct drm_device *dev)
 {
@@ -53,6 +60,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
        if (dev_priv->card_type >= NV_50) {
                INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
                INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
+               spin_lock_init(&dev_priv->hpd_state.lock);
                INIT_LIST_HEAD(&dev_priv->vbl_waiting);
        }
 }
@@ -202,8 +210,8 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                }
 
                if (status & NV_PFIFO_INTR_DMA_PUSHER) {
-                       u32 get = nv_rd32(dev, 0x003244);
-                       u32 put = nv_rd32(dev, 0x003240);
+                       u32 dma_get = nv_rd32(dev, 0x003244);
+                       u32 dma_put = nv_rd32(dev, 0x003240);
                        u32 push = nv_rd32(dev, 0x003220);
                        u32 state = nv_rd32(dev, 0x003228);
 
@@ -213,16 +221,18 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                                u32 ib_get = nv_rd32(dev, 0x003334);
                                u32 ib_put = nv_rd32(dev, 0x003330);
 
-                               NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
+                               if (nouveau_ratelimit())
+                                       NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
                                             "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
                                             "State 0x%08x Push 0x%08x\n",
-                                       chid, ho_get, get, ho_put, put, ib_get, ib_put,
-                                       state, push);
+                                               chid, ho_get, dma_get, ho_put,
+                                               dma_put, ib_get, ib_put, state,
+                                               push);
 
                                /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
                                nv_wr32(dev, 0x003364, 0x00000000);
-                               if (get != put || ho_get != ho_put) {
-                                       nv_wr32(dev, 0x003244, put);
+                               if (dma_get != dma_put || ho_get != ho_put) {
+                                       nv_wr32(dev, 0x003244, dma_put);
                                        nv_wr32(dev, 0x003328, ho_put);
                                } else
                                if (ib_get != ib_put) {
@@ -231,10 +241,10 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                        } else {
                                NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
                                             "Put 0x%08x State 0x%08x Push 0x%08x\n",
-                                       chid, get, put, state, push);
+                                       chid, dma_get, dma_put, state, push);
 
-                               if (get != put)
-                                       nv_wr32(dev, 0x003244, put);
+                               if (dma_get != dma_put)
+                                       nv_wr32(dev, 0x003244, dma_put);
                        }
 
                        nv_wr32(dev, 0x003228, 0x00000000);
@@ -266,8 +276,9 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
                }
 
                if (status) {
-                       NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
-                               status, chid);
+                       if (nouveau_ratelimit())
+                               NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
+                                       status, chid);
                        nv_wr32(dev, NV03_PFIFO_INTR_0, status);
                        status = 0;
                }
@@ -544,13 +555,6 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource)
                nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap);
 }
 
-static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
-
-static int nouveau_ratelimit(void)
-{
-       return __ratelimit(&nouveau_ratelimit_state);
-}
-
 
 static inline void
 nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource)
index a163c7c612e78eb6b6718620ee75773cd49a26f7..fe4a30dc4b42e929f283d35e1094b26a422f4f2e 100644 (file)
@@ -33,9 +33,9 @@
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
-#include "nouveau_drv.h"
 
-#define MIN(a,b) a < b ? a : b
+#include "nouveau_drv.h"
+#include "nouveau_pm.h"
 
 /*
  * NV10-NV40 tiling helpers
@@ -175,11 +175,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                        }
                }
        }
-       dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 5);
-       nv50_vm_flush(dev, 0);
-       nv50_vm_flush(dev, 4);
+       dev_priv->engine.instmem.flush(dev);
+       dev_priv->engine.fifo.tlb_flush(dev);
+       dev_priv->engine.graph.tlb_flush(dev);
        nv50_vm_flush(dev, 6);
        return 0;
 }
@@ -209,11 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
                        pte++;
                }
        }
-       dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 5);
-       nv50_vm_flush(dev, 0);
-       nv50_vm_flush(dev, 4);
+       dev_priv->engine.instmem.flush(dev);
+       dev_priv->engine.fifo.tlb_flush(dev);
+       dev_priv->engine.graph.tlb_flush(dev);
        nv50_vm_flush(dev, 6);
 }
 
@@ -653,6 +651,7 @@ nouveau_mem_gart_init(struct drm_device *dev)
 void
 nouveau_mem_timing_init(struct drm_device *dev)
 {
+       /* cards < NVC0 only */
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
        struct nouveau_pm_memtimings *memtimings = &pm->memtimings;
@@ -719,14 +718,14 @@ nouveau_mem_timing_init(struct drm_device *dev)
                tUNK_19 = 1;
                tUNK_20 = 0;
                tUNK_21 = 0;
-               switch (MIN(recordlen,21)) {
-               case 21:
+               switch (min(recordlen, 22)) {
+               case 22:
                        tUNK_21 = entry[21];
-               case 20:
+               case 21:
                        tUNK_20 = entry[20];
-               case 19:
+               case 20:
                        tUNK_19 = entry[19];
-               case 18:
+               case 19:
                        tUNK_18 = entry[18];
                default:
                        tUNK_0  = entry[0];
@@ -756,24 +755,30 @@ nouveau_mem_timing_init(struct drm_device *dev)
                timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
                if(recordlen > 19) {
                        timing->reg_100228 += (tUNK_19 - 1) << 24;
-               } else {
+               }/* I cannot back-up this else-statement right now
+                        else {
                        timing->reg_100228 += tUNK_12 << 24;
-               }
+               }*/
 
                /* XXX: reg_10022c */
+               timing->reg_10022c = tUNK_2 - 1;
 
                timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
                                      tUNK_13 << 8  | tUNK_13);
 
                /* XXX: +6? */
                timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
-               if(tUNK_10 > tUNK_11) {
-                       timing->reg_100234 += tUNK_10 << 16;
-               } else {
-                       timing->reg_100234 += tUNK_11 << 16;
+               timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
+
+               /* XXX; reg_100238, reg_10023c
+                * reg: 0x00??????
+                * reg_10023c:
+                *      0 for pre-NV50 cards
+                *      0x????0202 for NV50+ cards (empirical evidence) */
+               if(dev_priv->card_type >= NV_50) {
+                       timing->reg_10023c = 0x202;
                }
 
-               /* XXX; reg_100238, reg_10023c */
                NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
                         timing->reg_100220, timing->reg_100224,
                         timing->reg_100228, timing->reg_10022c);
index 896cf8634144a2b5cf7f69fdd006c848b4b2eb79..dd572adca02ad0232df35715257ccc597adf86f3 100644 (file)
@@ -129,7 +129,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
                        if (ramin == NULL) {
                                spin_unlock(&dev_priv->ramin_lock);
                                nouveau_gpuobj_ref(NULL, &gpuobj);
-                               return ret;
+                               return -ENOMEM;
                        }
 
                        ramin = drm_mm_get_block_atomic(ramin, size, align);
index 1c99c55d6d468a91fb09cda39d5660d3bf712aa5..9f7b158f5825c7dfd97b5f112afef7a9858e7b23 100644 (file)
@@ -284,6 +284,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
        }
 }
 
+#ifdef CONFIG_HWMON
 static ssize_t
 nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
 {
@@ -395,10 +396,12 @@ static struct attribute *hwmon_attributes[] = {
 static const struct attribute_group hwmon_attrgroup = {
        .attrs = hwmon_attributes,
 };
+#endif
 
 static int
 nouveau_hwmon_init(struct drm_device *dev)
 {
+#ifdef CONFIG_HWMON
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
        struct device *hwmon_dev;
@@ -425,13 +428,14 @@ nouveau_hwmon_init(struct drm_device *dev)
        }
 
        pm->hwmon = hwmon_dev;
-
+#endif
        return 0;
 }
 
 static void
 nouveau_hwmon_fini(struct drm_device *dev)
 {
+#ifdef CONFIG_HWMON
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
 
@@ -439,6 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
                sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup);
                hwmon_device_unregister(pm->hwmon);
        }
+#endif
 }
 
 int
index 7f16697cc96ce6438896414735b5fa4d12a84a34..2d8580927ca4579075cd870e5cfdf6459c44d9c6 100644 (file)
@@ -153,26 +153,42 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
        return -ENOMEM;
 }
 
+static struct nouveau_ramht_entry *
+nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle)
+{
+       struct nouveau_ramht *ramht = chan ? chan->ramht : NULL;
+       struct nouveau_ramht_entry *entry;
+       unsigned long flags;
+
+       if (!ramht)
+               return NULL;
+
+       spin_lock_irqsave(&ramht->lock, flags);
+       list_for_each_entry(entry, &ramht->entries, head) {
+               if (entry->channel == chan &&
+                   (!handle || entry->handle == handle)) {
+                       list_del(&entry->head);
+                       spin_unlock_irqrestore(&ramht->lock, flags);
+
+                       return entry;
+               }
+       }
+       spin_unlock_irqrestore(&ramht->lock, flags);
+
+       return NULL;
+}
+
 static void
-nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
+nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle)
 {
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
        struct nouveau_gpuobj *ramht = chan->ramht->gpuobj;
-       struct nouveau_ramht_entry *entry, *tmp;
+       unsigned long flags;
        u32 co, ho;
 
-       list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) {
-               if (entry->channel != chan || entry->handle != handle)
-                       continue;
-
-               nouveau_gpuobj_ref(NULL, &entry->gpuobj);
-               list_del(&entry->head);
-               kfree(entry);
-               break;
-       }
-
+       spin_lock_irqsave(&chan->ramht->lock, flags);
        co = ho = nouveau_ramht_hash_handle(chan, handle);
        do {
                if (nouveau_ramht_entry_valid(dev, ramht, co) &&
@@ -184,7 +200,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
                        nv_wo32(ramht, co + 0, 0x00000000);
                        nv_wo32(ramht, co + 4, 0x00000000);
                        instmem->flush(dev);
-                       return;
+                       goto out;
                }
 
                co += 8;
@@ -194,17 +210,22 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
 
        NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
                 chan->id, handle);
+out:
+       spin_unlock_irqrestore(&chan->ramht->lock, flags);
 }
 
 void
 nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
 {
-       struct nouveau_ramht *ramht = chan->ramht;
-       unsigned long flags;
+       struct nouveau_ramht_entry *entry;
 
-       spin_lock_irqsave(&ramht->lock, flags);
-       nouveau_ramht_remove_locked(chan, handle);
-       spin_unlock_irqrestore(&ramht->lock, flags);
+       entry = nouveau_ramht_remove_entry(chan, handle);
+       if (!entry)
+               return;
+
+       nouveau_ramht_remove_hash(chan, entry->handle);
+       nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+       kfree(entry);
 }
 
 struct nouveau_gpuobj *
@@ -265,23 +286,19 @@ void
 nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr,
                  struct nouveau_channel *chan)
 {
-       struct nouveau_ramht_entry *entry, *tmp;
+       struct nouveau_ramht_entry *entry;
        struct nouveau_ramht *ramht;
-       unsigned long flags;
 
        if (ref)
                kref_get(&ref->refcount);
 
        ramht = *ptr;
        if (ramht) {
-               spin_lock_irqsave(&ramht->lock, flags);
-               list_for_each_entry_safe(entry, tmp, &ramht->entries, head) {
-                       if (entry->channel != chan)
-                               continue;
-
-                       nouveau_ramht_remove_locked(chan, entry->handle);
+               while ((entry = nouveau_ramht_remove_entry(chan, 0))) {
+                       nouveau_ramht_remove_hash(chan, entry->handle);
+                       nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+                       kfree(entry);
                }
-               spin_unlock_irqrestore(&ramht->lock, flags);
 
                kref_put(&ramht->refcount, nouveau_ramht_del);
        }
index 288bacac7e5aefc2f3c6c9b4f461a7e48d6e9ce7..d4ac970070386cea340283ba459194eb8b1de50a 100644 (file)
@@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
        dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv50_vm_flush(dev, 5); /* PGRAPH */
-               nv50_vm_flush(dev, 0); /* PFIFO */
+               dev_priv->engine.fifo.tlb_flush(dev);
+               dev_priv->engine.graph.tlb_flush(dev);
        }
 
        nvbe->bound = true;
@@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        dev_priv->engine.instmem.flush(nvbe->dev);
 
        if (dev_priv->card_type == NV_50) {
-               nv50_vm_flush(dev, 5);
-               nv50_vm_flush(dev, 0);
+               dev_priv->engine.fifo.tlb_flush(dev);
+               dev_priv->engine.graph.tlb_flush(dev);
        }
 
        nvbe->bound = false;
@@ -224,7 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev)
        int i, ret;
 
        if (dev_priv->card_type < NV_50) {
-               aper_size = (64 * 1024 * 1024);
+               if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024)
+                       aper_size = 64 * 1024 * 1024;
+               else
+                       aper_size = 512 * 1024 * 1024;
+
                obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
                obj_size += 8; /* ctxdma header */
        } else {
index ed7757f14083a17e3122250ca83aa8ee2959ddec..049f755567e5c83b047298f74ff1c24b6ceea5fe 100644 (file)
@@ -354,6 +354,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->graph.destroy_context   = nv50_graph_destroy_context;
                engine->graph.load_context      = nv50_graph_load_context;
                engine->graph.unload_context    = nv50_graph_unload_context;
+               if (dev_priv->chipset != 0x86)
+                       engine->graph.tlb_flush = nv50_graph_tlb_flush;
+               else {
+                       /* from what i can see nvidia do this on every
+                        * pre-NVA3 board except NVAC, but, we've only
+                        * ever seen problems on NV86
+                        */
+                       engine->graph.tlb_flush = nv86_graph_tlb_flush;
+               }
                engine->fifo.channels           = 128;
                engine->fifo.init               = nv50_fifo_init;
                engine->fifo.takedown           = nv50_fifo_takedown;
@@ -365,6 +374,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->fifo.destroy_context    = nv50_fifo_destroy_context;
                engine->fifo.load_context       = nv50_fifo_load_context;
                engine->fifo.unload_context     = nv50_fifo_unload_context;
+               engine->fifo.tlb_flush          = nv50_fifo_tlb_flush;
                engine->display.early_init      = nv50_display_early_init;
                engine->display.late_takedown   = nv50_display_late_takedown;
                engine->display.create          = nv50_display_create;
@@ -1041,6 +1051,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
        case NOUVEAU_GETPARAM_PTIMER_TIME:
                getparam->value = dev_priv->engine.timer.read(dev);
                break;
+       case NOUVEAU_GETPARAM_HAS_BO_USAGE:
+               getparam->value = 1;
+               break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
                 * address is the same. User is supposed to know the card
@@ -1051,7 +1064,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                }
                /* FALLTHRU */
        default:
-               NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
+               NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
                return -EINVAL;
        }
 
@@ -1066,7 +1079,7 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
 
        switch (setparam->param) {
        default:
-               NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
+               NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param);
                return -EINVAL;
        }
 
index 16bbbf1eff63bc5ef37038e37d85fccc7f407a8d..7ecc4adc1e4575aca6ef2791752c25300ff7668b 100644 (file)
@@ -191,7 +191,7 @@ nv40_temp_get(struct drm_device *dev)
        int offset = sensor->offset_mult / sensor->offset_div;
        int core_temp;
 
-       if (dev_priv->chipset >= 0x50) {
+       if (dev_priv->card_type >= NV_50) {
                core_temp = nv_rd32(dev, 0x20008);
        } else {
                core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
index c71abc2a34d5d9cf22a01d3c3bf455a29c5d1dbf..40e180741629e056f72445ffab06104760bd70ec 100644 (file)
@@ -158,7 +158,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct drm_device *dev = crtc->dev;
-       struct drm_connector *connector;
        unsigned char seq1 = 0, crtc17 = 0;
        unsigned char crtc1A;
 
@@ -213,10 +212,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
        NVVgaSeqReset(dev, nv_crtc->index, false);
 
        NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
-
-       /* Update connector polling modes */
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-               nouveau_connector_set_polling(connector);
 }
 
 static bool
@@ -831,7 +826,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
        /* Update the framebuffer location. */
        regp->fb_start = nv_crtc->fb.offset & ~3;
        regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8);
-       NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start);
+       nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start);
 
        /* Update the arbitration parameters. */
        nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel,
index c936403b26e22f7b4bcc1b4fee4fa6809498689b..ef23550407b5d7da95c0a4a5a6c35b82670ad4e5 100644 (file)
@@ -185,14 +185,15 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
        struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
 
-       /* For internal panels and gpu scaling on DVI we need the native mode */
-       if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
-               if (!nv_connector->native_mode)
-                       return false;
+       if (!nv_connector->native_mode ||
+           nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
+           mode->hdisplay > nv_connector->native_mode->hdisplay ||
+           mode->vdisplay > nv_connector->native_mode->vdisplay) {
+               nv_encoder->mode = *adjusted_mode;
+
+       } else {
                nv_encoder->mode = *nv_connector->native_mode;
                adjusted_mode->clock = nv_connector->native_mode->clock;
-       } else {
-               nv_encoder->mode = *adjusted_mode;
        }
 
        return true;
index 6a6eb697d38e0b387941b05b38dadc8a5bd371f1..eb1c70dd82ed41540629792dc7264452f511e6f3 100644 (file)
@@ -76,6 +76,15 @@ nv04_pm_clock_set(struct drm_device *dev, void *pre_state)
                reg += 4;
 
        nouveau_hw_setpll(dev, reg, &state->calc);
+
+       if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) {
+               if (dev_priv->card_type == NV_20)
+                       nv_mask(dev, 0x1002c4, 0, 1 << 20);
+
+               /* Reset the DLLs */
+               nv_mask(dev, 0x1002c0, 0, 1 << 8);
+       }
+
        kfree(state);
 }
 
index 2cdc2bfe717924bf4f8e29237c11efcc0865408b..de81151648f831c5a7c97b9491d3670c356276f5 100644 (file)
@@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
               int *N, int *fN, int *M, int *P)
 {
        fixed20_12 fb_div, a, b;
+       u32 refclk = pll->refclk / 10;
+       u32 max_vco_freq = pll->vco1.maxfreq / 10;
+       u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
+       clk /= 10;
 
-       *P = pll->vco1.maxfreq / clk;
+       *P = max_vco_freq / clk;
        if (*P > pll->max_p)
                *P = pll->max_p;
        if (*P < pll->min_p)
                *P = pll->min_p;
 
-       /* *M = ceil(refclk / pll->vco.max_inputfreq); */
-       a.full = dfixed_const(pll->refclk);
-       b.full = dfixed_const(pll->vco1.max_inputfreq);
+       /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
+       a.full = dfixed_const(refclk + max_vco_inputfreq);
+       b.full = dfixed_const(max_vco_inputfreq);
        a.full = dfixed_div(a, b);
-       a.full = dfixed_ceil(a);
+       a.full = dfixed_floor(a);
        *M = dfixed_trunc(a);
 
        /* fb_div = (vco * *M) / refclk; */
        fb_div.full = dfixed_const(clk * *P);
        fb_div.full = dfixed_mul(fb_div, a);
-       a.full = dfixed_const(pll->refclk);
+       a.full = dfixed_const(refclk);
        fb_div.full = dfixed_div(fb_div, a);
 
        /* *N = floor(fb_div); */
index 16380d52cd885599f349219c903f12cf7b9c6159..56476d0c6de8ee5255ff6c8916070a5c5ed86aec 100644 (file)
@@ -546,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
        }
 
        nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
-       nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
+       nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
        nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
        if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
                ret = RING_SPACE(evo, 2);
@@ -578,7 +578,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
                                  fb->nvbo->tile_mode);
        }
        if (dev_priv->chipset == 0x50)
-               OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format);
+               OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
        else
                OUT_RING(evo, format);
 
index 55c9663ef2bf8ddd4df2cf15b452daed66abc583..f624c611ddeaf39cb1c46010d7da30e4461c35ad 100644 (file)
@@ -1032,11 +1032,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
        struct drm_connector *connector;
        const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
        uint32_t unplug_mask, plug_mask, change_mask;
-       uint32_t hpd0, hpd1 = 0;
+       uint32_t hpd0, hpd1;
 
-       hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
+       spin_lock_irq(&dev_priv->hpd_state.lock);
+       hpd0 = dev_priv->hpd_state.hpd0_bits;
+       dev_priv->hpd_state.hpd0_bits = 0;
+       hpd1 = dev_priv->hpd_state.hpd1_bits;
+       dev_priv->hpd_state.hpd1_bits = 0;
+       spin_unlock_irq(&dev_priv->hpd_state.lock);
+
+       hpd0 &= nv_rd32(dev, 0xe050);
        if (dev_priv->chipset >= 0x90)
-               hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
+               hpd1 &= nv_rd32(dev, 0xe070);
 
        plug_mask   = (hpd0 & 0x0000ffff) | (hpd1 << 16);
        unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
@@ -1078,10 +1085,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
                        helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
        }
 
-       nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
-       if (dev_priv->chipset >= 0x90)
-               nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
-
        drm_helper_hpd_irq_event(dev);
 }
 
@@ -1092,8 +1095,22 @@ nv50_display_irq_handler(struct drm_device *dev)
        uint32_t delayed = 0;
 
        if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
-               if (!work_pending(&dev_priv->hpd_work))
-                       queue_work(dev_priv->wq, &dev_priv->hpd_work);
+               uint32_t hpd0_bits, hpd1_bits = 0;
+
+               hpd0_bits = nv_rd32(dev, 0xe054);
+               nv_wr32(dev, 0xe054, hpd0_bits);
+
+               if (dev_priv->chipset >= 0x90) {
+                       hpd1_bits = nv_rd32(dev, 0xe074);
+                       nv_wr32(dev, 0xe074, hpd1_bits);
+               }
+
+               spin_lock(&dev_priv->hpd_state.lock);
+               dev_priv->hpd_state.hpd0_bits |= hpd0_bits;
+               dev_priv->hpd_state.hpd1_bits |= hpd1_bits;
+               spin_unlock(&dev_priv->hpd_state.lock);
+
+               queue_work(dev_priv->wq, &dev_priv->hpd_work);
        }
 
        while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
index a46a961102f39052832856cac762e3cfe8ae1f88..1da65bd60c109f89ea44e20a8eb561ec35a0f237 100644 (file)
@@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev)
        return 0;
 }
 
+void
+nv50_fifo_tlb_flush(struct drm_device *dev)
+{
+       nv50_vm_flush(dev, 5);
+}
index cbf5ae2f67d4a110de1bb9d9c129224fbcdd6c3c..8b669d0af6105fb934c3485457e7db18fb43e0ad 100644 (file)
@@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
        { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
        {}
 };
+
+void
+nv50_graph_tlb_flush(struct drm_device *dev)
+{
+       nv50_vm_flush(dev, 0);
+}
+
+void
+nv86_graph_tlb_flush(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+       bool idle, timeout = false;
+       unsigned long flags;
+       u64 start;
+       u32 tmp;
+
+       spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+       nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
+
+       start = ptimer->read(dev);
+       do {
+               idle = true;
+
+               for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+
+               for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+
+               for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) {
+                       if ((tmp & 7) == 1)
+                               idle = false;
+               }
+       } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000));
+
+       if (timeout) {
+               NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: "
+                             "0x%08x 0x%08x 0x%08x 0x%08x\n",
+                        nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
+                        nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
+       }
+
+       nv50_vm_flush(dev, 0);
+
+       nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
+       spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+}
index a53fc974332b38ec659513e91a8421017e43c411..b773229b764793c1ee974462431ab5d9a4e57385 100644 (file)
@@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
        }
        dev_priv->engine.instmem.flush(dev);
 
-       nv50_vm_flush(dev, 4);
        nv50_vm_flush(dev, 6);
 
        gpuobj->im_bound = 1;
index 8e421f644a5435d44b6a0bc26f0edf3039b78c21..05efb5b9f13e841d265e3219d33e279e781de22f 100644 (file)
@@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
+                       (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
                        ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
index 488c36c8f5e6069ebbb6cf5f9b830747a61c062e..4dc5b4714c5a6ae1919246ac55ed32d3bacc44ac 100644 (file)
@@ -1650,7 +1650,36 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                }
        }
 
-       rdev->config.evergreen.tile_config = gb_addr_config;
+       /* setup tiling info dword.  gb_addr_config is not adequate since it does
+        * not have bank info, so create a custom tiling dword.
+        * bits 3:0   num_pipes
+        * bits 7:4   num_banks
+        * bits 11:8  group_size
+        * bits 15:12 row_size
+        */
+       rdev->config.evergreen.tile_config = 0;
+       switch (rdev->config.evergreen.max_tile_pipes) {
+       case 1:
+       default:
+               rdev->config.evergreen.tile_config |= (0 << 0);
+               break;
+       case 2:
+               rdev->config.evergreen.tile_config |= (1 << 0);
+               break;
+       case 4:
+               rdev->config.evergreen.tile_config |= (2 << 0);
+               break;
+       case 8:
+               rdev->config.evergreen.tile_config |= (3 << 0);
+               break;
+       }
+       rdev->config.evergreen.tile_config |=
+               ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
+       rdev->config.evergreen.tile_config |=
+               ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8;
+       rdev->config.evergreen.tile_config |=
+               ((gb_addr_config & 0x30000000) >> 28) << 12;
+
        WREG32(GB_BACKEND_MAP, gb_backend_map);
        WREG32(GB_ADDR_CONFIG, gb_addr_config);
        WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
index ac3b6dde23db7ca1fd5f80083436cb49fcce0312..e0e590110dd47ffb06b2161ed1058e731620c826 100644 (file)
@@ -459,7 +459,7 @@ int evergreen_blit_init(struct radeon_device *rdev)
        obj_size += evergreen_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
-       r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &rdev->r600_blit.shader_obj);
        if (r) {
                DRM_ERROR("evergreen failed to allocate shader\n");
index 0f806cc7dc75f02f5bb00f98fc0d65b662aad688..a322d4f647bd2cbe479f6b482f1249ada5de454e 100644 (file)
@@ -1195,8 +1195,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                                mc->vram_end, mc->real_vram_size >> 20);
        } else {
                u64 base = 0;
-               if (rdev->flags & RADEON_IS_IGP)
-                       base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+               if (rdev->flags & RADEON_IS_IGP) {
+                       base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF;
+                       base <<= 24;
+               }
                radeon_vram_location(rdev, &rdev->mc, base);
                rdev->mc.gtt_base_align = 0;
                radeon_gtt_location(rdev, mc);
@@ -2718,7 +2720,7 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev)
        /* Allocate ring buffer */
        if (rdev->ih.ring_obj == NULL) {
                r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
-                                    true,
+                                    PAGE_SIZE, true,
                                     RADEON_GEM_DOMAIN_GTT,
                                     &rdev->ih.ring_obj);
                if (r) {
index 8362974ef41ac9eac713f1e66377661aa7106c0b..86e5aa07f0db32ffe410f1c2dea0330fefd89d9d 100644 (file)
@@ -501,7 +501,7 @@ int r600_blit_init(struct radeon_device *rdev)
        obj_size += r6xx_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
-       r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &rdev->r600_blit.shader_obj);
        if (r) {
                DRM_ERROR("r600 failed to allocate shader\n");
index 37cc2aa9f923cbace55e151d33870d1ac910a6a2..0f90fc3482ce205df9991bcd1d7c1170abd912ca 100644 (file)
@@ -50,6 +50,7 @@ struct r600_cs_track {
        u32                     nsamples;
        u32                     cb_color_base_last[8];
        struct radeon_bo        *cb_color_bo[8];
+       u64                     cb_color_bo_mc[8];
        u32                     cb_color_bo_offset[8];
        struct radeon_bo        *cb_color_frag_bo[8];
        struct radeon_bo        *cb_color_tile_bo[8];
@@ -67,6 +68,7 @@ struct r600_cs_track {
        u32                     db_depth_size;
        u32                     db_offset;
        struct radeon_bo        *db_bo;
+       u64                     db_bo_mc;
 };
 
 static inline int r600_bpe_from_format(u32 *bpe, u32 format)
@@ -140,6 +142,68 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format)
        return 0;
 }
 
+struct array_mode_checker {
+       int array_mode;
+       u32 group_size;
+       u32 nbanks;
+       u32 npipes;
+       u32 nsamples;
+       u32 bpe;
+};
+
+/* returns alignment in pixels for pitch/height/depth and bytes for base */
+static inline int r600_get_array_mode_alignment(struct array_mode_checker *values,
+                                               u32 *pitch_align,
+                                               u32 *height_align,
+                                               u32 *depth_align,
+                                               u64 *base_align)
+{
+       u32 tile_width = 8;
+       u32 tile_height = 8;
+       u32 macro_tile_width = values->nbanks;
+       u32 macro_tile_height = values->npipes;
+       u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples;
+       u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
+
+       switch (values->array_mode) {
+       case ARRAY_LINEAR_GENERAL:
+               /* technically tile_width/_height for pitch/height */
+               *pitch_align = 1; /* tile_width */
+               *height_align = 1; /* tile_height */
+               *depth_align = 1;
+               *base_align = 1;
+               break;
+       case ARRAY_LINEAR_ALIGNED:
+               *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe));
+               *height_align = tile_height;
+               *depth_align = 1;
+               *base_align = values->group_size;
+               break;
+       case ARRAY_1D_TILED_THIN1:
+               *pitch_align = max((u32)tile_width,
+                                  (u32)(values->group_size /
+                                        (tile_height * values->bpe * values->nsamples)));
+               *height_align = tile_height;
+               *depth_align = 1;
+               *base_align = values->group_size;
+               break;
+       case ARRAY_2D_TILED_THIN1:
+               *pitch_align = max((u32)macro_tile_width,
+                                 (u32)(((values->group_size / tile_height) /
+                                        (values->bpe * values->nsamples)) *
+                                       values->nbanks)) * tile_width;
+               *height_align = macro_tile_height * tile_height;
+               *depth_align = 1;
+               *base_align = max(macro_tile_bytes,
+                                 (*pitch_align) * values->bpe * (*height_align) * values->nsamples);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static void r600_cs_track_init(struct r600_cs_track *track)
 {
        int i;
@@ -153,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track)
                track->cb_color_info[i] = 0;
                track->cb_color_bo[i] = NULL;
                track->cb_color_bo_offset[i] = 0xFFFFFFFF;
+               track->cb_color_bo_mc[i] = 0xFFFFFFFF;
        }
        track->cb_target_mask = 0xFFFFFFFF;
        track->cb_shader_mask = 0xFFFFFFFF;
        track->db_bo = NULL;
+       track->db_bo_mc = 0xFFFFFFFF;
        /* assume the biggest format and that htile is enabled */
        track->db_depth_info = 7 | (1 << 25);
        track->db_depth_view = 0xFFFFC000;
@@ -168,7 +234,10 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 {
        struct r600_cs_track *track = p->track;
-       u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
+       u32 bpe = 0, slice_tile_max, size, tmp;
+       u32 height, height_align, pitch, pitch_align, depth_align;
+       u64 base_offset, base_align;
+       struct array_mode_checker array_check;
        volatile u32 *ib = p->ib->ptr;
        unsigned array_mode;
 
@@ -183,60 +252,40 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        i, track->cb_color_info[i]);
                return -EINVAL;
        }
-       /* pitch is the number of 8x8 tiles per row */
-       pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
+       /* pitch in pixels */
+       pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8;
        slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
        slice_tile_max *= 64;
-       height = slice_tile_max / (pitch * 8);
+       height = slice_tile_max / pitch;
        if (height > 8192)
                height = 8192;
        array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
+
+       base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i];
+       array_check.array_mode = array_mode;
+       array_check.group_size = track->group_size;
+       array_check.nbanks = track->nbanks;
+       array_check.npipes = track->npipes;
+       array_check.nsamples = track->nsamples;
+       array_check.bpe = bpe;
+       if (r600_get_array_mode_alignment(&array_check,
+                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+               dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
+                        G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
+                        track->cb_color_info[i]);
+               return -EINVAL;
+       }
        switch (array_mode) {
        case V_0280A0_ARRAY_LINEAR_GENERAL:
-               /* technically height & 0x7 */
                break;
        case V_0280A0_ARRAY_LINEAR_ALIGNED:
-               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               if (!IS_ALIGNED(height, 8)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        case V_0280A0_ARRAY_1D_TILED_THIN1:
-               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
                /* avoid breaking userspace */
                if (height > 7)
                        height &= ~0x7;
-               if (!IS_ALIGNED(height, 8)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        case V_0280A0_ARRAY_2D_TILED_THIN1:
-               pitch_align = max((u32)track->nbanks,
-                                 (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               if (!IS_ALIGNED((height / 8), track->npipes)) {
-                       dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
-                                __func__, __LINE__, height);
-                       return -EINVAL;
-               }
                break;
        default:
                dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -244,8 +293,24 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        track->cb_color_info[i]);
                return -EINVAL;
        }
+
+       if (!IS_ALIGNED(pitch, pitch_align)) {
+               dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+                        __func__, __LINE__, pitch);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(height, height_align)) {
+               dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+                        __func__, __LINE__, height);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(base_offset, base_align)) {
+               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+               return -EINVAL;
+       }
+
        /* check offset */
-       tmp = height * pitch * 8 * bpe;
+       tmp = height * pitch * bpe;
        if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
                if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
                        /* the initial DDX does bad things with the CB size occasionally */
@@ -260,15 +325,11 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
                        return -EINVAL;
                }
        }
-       if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
-               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
-               return -EINVAL;
-       }
        /* limit max tile */
-       tmp = (height * pitch * 8) >> 6;
+       tmp = (height * pitch) >> 6;
        if (tmp < slice_tile_max)
                slice_tile_max = tmp;
-       tmp = S_028060_PITCH_TILE_MAX(pitch - 1) |
+       tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
                S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
        ib[track->cb_color_size_idx[i]] = tmp;
        return 0;
@@ -310,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
        /* Check depth buffer */
        if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
                G_028800_Z_ENABLE(track->db_depth_control)) {
-               u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max;
+               u32 nviews, bpe, ntiles, size, slice_tile_max;
+               u32 height, height_align, pitch, pitch_align, depth_align;
+               u64 base_offset, base_align;
+               struct array_mode_checker array_check;
+               int array_mode;
+
                if (track->db_bo == NULL) {
                        dev_warn(p->dev, "z/stencil with no depth buffer\n");
                        return -EINVAL;
@@ -353,41 +419,34 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                        ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
                } else {
                        size = radeon_bo_size(track->db_bo);
-                       pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
+                       /* pitch in pixels */
+                       pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
                        slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        slice_tile_max *= 64;
-                       height = slice_tile_max / (pitch * 8);
+                       height = slice_tile_max / pitch;
                        if (height > 8192)
                                height = 8192;
-                       switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
+                       base_offset = track->db_bo_mc + track->db_offset;
+                       array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
+                       array_check.array_mode = array_mode;
+                       array_check.group_size = track->group_size;
+                       array_check.nbanks = track->nbanks;
+                       array_check.npipes = track->npipes;
+                       array_check.nsamples = track->nsamples;
+                       array_check.bpe = bpe;
+                       if (r600_get_array_mode_alignment(&array_check,
+                                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+                               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                        G_028010_ARRAY_MODE(track->db_depth_info),
+                                        track->db_depth_info);
+                               return -EINVAL;
+                       }
+                       switch (array_mode) {
                        case V_028010_ARRAY_1D_TILED_THIN1:
-                               pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
-                               if (!IS_ALIGNED(pitch, pitch_align)) {
-                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
-                                                __func__, __LINE__, pitch);
-                                       return -EINVAL;
-                               }
                                /* don't break userspace */
                                height &= ~0x7;
-                               if (!IS_ALIGNED(height, 8)) {
-                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
-                                                __func__, __LINE__, height);
-                                       return -EINVAL;
-                               }
                                break;
                        case V_028010_ARRAY_2D_TILED_THIN1:
-                               pitch_align = max((u32)track->nbanks,
-                                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
-                               if (!IS_ALIGNED(pitch, pitch_align)) {
-                                       dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
-                                                __func__, __LINE__, pitch);
-                                       return -EINVAL;
-                               }
-                               if (!IS_ALIGNED((height / 8), track->npipes)) {
-                                       dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
-                                                __func__, __LINE__, height);
-                                       return -EINVAL;
-                               }
                                break;
                        default:
                                dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
@@ -395,15 +454,27 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                                         track->db_depth_info);
                                return -EINVAL;
                        }
-                       if (!IS_ALIGNED(track->db_offset, track->group_size)) {
-                               dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset);
+
+                       if (!IS_ALIGNED(pitch, pitch_align)) {
+                               dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+                                        __func__, __LINE__, pitch);
+                               return -EINVAL;
+                       }
+                       if (!IS_ALIGNED(height, height_align)) {
+                               dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+                                        __func__, __LINE__, height);
                                return -EINVAL;
                        }
+                       if (!IS_ALIGNED(base_offset, base_align)) {
+                               dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+                               return -EINVAL;
+                       }
+
                        ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
                        nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
                        tmp = ntiles * bpe * 64 * nviews;
                        if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
-                               dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n",
+                               dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n",
                                                track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
                                                radeon_bo_size(track->db_bo));
                                return -EINVAL;
@@ -954,6 +1025,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                track->cb_color_base_last[tmp] = ib[idx];
                track->cb_color_bo[tmp] = reloc->robj;
+               track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset;
                break;
        case DB_DEPTH_BASE:
                r = r600_cs_packet_next_reloc(p, &reloc);
@@ -965,6 +1037,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                track->db_offset = radeon_get_ib_value(p, idx) << 8;
                ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                track->db_bo = reloc->robj;
+               track->db_bo_mc = reloc->lobj.gpu_offset;
                break;
        case DB_HTILE_DATA_BASE:
        case SQ_PGM_START_FS:
@@ -1086,16 +1159,25 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
 static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
                                              struct radeon_bo *texture,
                                              struct radeon_bo *mipmap,
+                                             u64 base_offset,
+                                             u64 mip_offset,
                                              u32 tiling_flags)
 {
        struct r600_cs_track *track = p->track;
        u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
-       u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align;
+       u32 word0, word1, l0_size, mipmap_size;
+       u32 height_align, pitch, pitch_align, depth_align;
+       u64 base_align;
+       struct array_mode_checker array_check;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
                return 0;
 
+       /* convert to bytes */
+       base_offset <<= 8;
+       mip_offset <<= 8;
+
        word0 = radeon_get_ib_value(p, idx + 0);
        if (tiling_flags & RADEON_TILING_MACRO)
                word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
@@ -1128,46 +1210,38 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 i
                return -EINVAL;
        }
 
-       pitch = G_038000_PITCH(word0) + 1;
-       switch (G_038000_TILE_MODE(word0)) {
-       case V_038000_ARRAY_LINEAR_GENERAL:
-               pitch_align = 1;
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_LINEAR_ALIGNED:
-               pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_1D_TILED_THIN1:
-               pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                                __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       case V_038000_ARRAY_2D_TILED_THIN1:
-               pitch_align = max((u32)track->nbanks,
-                                 (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
-               if (!IS_ALIGNED(pitch, pitch_align)) {
-                       dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
-                               __func__, __LINE__, pitch);
-                       return -EINVAL;
-               }
-               /* XXX check height align */
-               break;
-       default:
-               dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
-                        G_038000_TILE_MODE(word0), word0);
+       /* pitch in texels */
+       pitch = (G_038000_PITCH(word0) + 1) * 8;
+       array_check.array_mode = G_038000_TILE_MODE(word0);
+       array_check.group_size = track->group_size;
+       array_check.nbanks = track->nbanks;
+       array_check.npipes = track->npipes;
+       array_check.nsamples = 1;
+       array_check.bpe = bpe;
+       if (r600_get_array_mode_alignment(&array_check,
+                                         &pitch_align, &height_align, &depth_align, &base_align)) {
+               dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
+                        __func__, __LINE__, G_038000_TILE_MODE(word0));
+               return -EINVAL;
+       }
+
+       /* XXX check height as well... */
+
+       if (!IS_ALIGNED(pitch, pitch_align)) {
+               dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+                        __func__, __LINE__, pitch);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(base_offset, base_align)) {
+               dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n",
+                        __func__, __LINE__, base_offset);
+               return -EINVAL;
+       }
+       if (!IS_ALIGNED(mip_offset, base_align)) {
+               dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n",
+                        __func__, __LINE__, mip_offset);
                return -EINVAL;
        }
-       /* XXX check offset align */
 
        word0 = radeon_get_ib_value(p, idx + 4);
        word1 = radeon_get_ib_value(p, idx + 5);
@@ -1402,7 +1476,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                                mipmap = reloc->robj;
                                r = r600_check_texture_resource(p,  idx+(i*7)+1,
-                                                               texture, mipmap, reloc->lobj.tiling_flags);
+                                                               texture, mipmap,
+                                                               base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2),
+                                                               mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3),
+                                                               reloc->lobj.tiling_flags);
                                if (r)
                                        return r;
                                ib[idx+1+(i*7)+2] += base_offset;
index d84612ae47e0786228f7d80a4a311aadbdde88ce..33cda016b083be82ca99f6a382da813d28e777a2 100644 (file)
@@ -86,6 +86,7 @@
 #define R600_HDP_NONSURFACE_BASE                                0x2c04
 
 #define R600_BUS_CNTL                                           0x5420
+#       define R600_BIOS_ROM_DIS                                (1 << 1)
 #define R600_CONFIG_CNTL                                        0x5424
 #define R600_CONFIG_MEMSIZE                                     0x5428
 #define R600_CONFIG_F0_BASE                                     0x542C
index 966a793e225b79a5bfdf3f8bf4c1f413ee2b3dc5..bff4dc4f410f8d5b514539c8ffecd914436a7f90 100644 (file)
 #define PTE_READABLE                           (1 << 5)
 #define PTE_WRITEABLE                          (1 << 6)
 
+/* tiling bits */
+#define     ARRAY_LINEAR_GENERAL              0x00000000
+#define     ARRAY_LINEAR_ALIGNED              0x00000001
+#define     ARRAY_1D_TILED_THIN1              0x00000002
+#define     ARRAY_2D_TILED_THIN1              0x00000004
+
 /* Registers */
 #define        ARB_POP                                         0x2418
 #define        ENABLE_TC128                                    (1 << 30)
index 73f600d39ad4bb79c4dfdeddee97972a8caeaec0..3a7095743d441b1bf71da544bd0f19007408362c 100644 (file)
@@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
                (rdev->family == CHIP_RS400) ||                 \
                (rdev->family == CHIP_RS480))
 #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
+#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600)  ||   \
+                           (rdev->family == CHIP_RS690)  ||    \
+                           (rdev->family == CHIP_RS740)  ||    \
+                           (rdev->family >= CHIP_R600))
 #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
 #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
 #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
index 87ead090c7d5a5195af6cf8d15be5a5809ff9678..bc5a2c3382d92fbd10efca3f29f69a927e381fc0 100644 (file)
@@ -98,6 +98,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
                                }
                        }
 
+                       /* some DCE3 boards have bad data for this entry */
+                       if (ASIC_IS_DCE3(rdev)) {
+                               if ((i == 4) &&
+                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (gpio->sucI2cId.ucAccess == 0x94))
+                                       gpio->sucI2cId.ucAccess = 0x14;
+                       }
+
                        if (gpio->sucI2cId.ucAccess == id) {
                                i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
                                i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
@@ -174,6 +182,14 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
                                }
                        }
 
+                       /* some DCE3 boards have bad data for this entry */
+                       if (ASIC_IS_DCE3(rdev)) {
+                               if ((i == 4) &&
+                                   (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+                                   (gpio->sucI2cId.ucAccess == 0x94))
+                                       gpio->sucI2cId.ucAccess = 0x14;
+                       }
+
                        i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
                        i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
                        i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
index 7932dc4d6b90bde396e258108247402ec90ce8ca..c558685cc637698a83fb7ceed220df897f988b44 100644 (file)
@@ -41,7 +41,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
 
        size = bsize;
        n = 1024;
-       r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, sdomain, &sobj);
        if (r) {
                goto out_cleanup;
        }
@@ -53,7 +53,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
        if (r) {
                goto out_cleanup;
        }
-       r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, ddomain, &dobj);
        if (r) {
                goto out_cleanup;
        }
index 654787ec43f4d33687f2c7dd0e0318c17be92dd6..8f2c7b50dcf57df6267be12ef349479597dd0f62 100644 (file)
@@ -130,6 +130,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
        }
        return true;
 }
+
 static bool r700_read_disabled_bios(struct radeon_device *rdev)
 {
        uint32_t viph_control;
@@ -143,7 +144,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
        bool r;
 
        viph_control = RREG32(RADEON_VIPH_CONTROL);
-       bus_cntl = RREG32(RADEON_BUS_CNTL);
+       bus_cntl = RREG32(R600_BUS_CNTL);
        d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
        d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
        vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -152,7 +153,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
        /* disable VIP */
        WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
        /* enable the rom */
-       WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+       WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
        /* Disable VGA mode */
        WREG32(AVIVO_D1VGA_CONTROL,
               (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -191,7 +192,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
                        cg_spll_status = RREG32(R600_CG_SPLL_STATUS);
        }
        WREG32(RADEON_VIPH_CONTROL, viph_control);
-       WREG32(RADEON_BUS_CNTL, bus_cntl);
+       WREG32(R600_BUS_CNTL, bus_cntl);
        WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
        WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
        WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
@@ -216,7 +217,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
        bool r;
 
        viph_control = RREG32(RADEON_VIPH_CONTROL);
-       bus_cntl = RREG32(RADEON_BUS_CNTL);
+       bus_cntl = RREG32(R600_BUS_CNTL);
        d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
        d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
        vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -231,7 +232,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
        /* disable VIP */
        WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
        /* enable the rom */
-       WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+       WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
        /* Disable VGA mode */
        WREG32(AVIVO_D1VGA_CONTROL,
               (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -262,7 +263,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
 
        /* restore regs */
        WREG32(RADEON_VIPH_CONTROL, viph_control);
-       WREG32(RADEON_BUS_CNTL, bus_cntl);
+       WREG32(R600_BUS_CNTL, bus_cntl);
        WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
        WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
        WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
index 7b7ea269549ccef95c1e6c343083071774e7e9de..137b8075f6e7c434fc02b5e328c19d06127f8e05 100644 (file)
@@ -571,6 +571,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
        }
 
        if (clk_mask && data_mask) {
+               /* system specific masks */
                i2c.mask_clk_mask = clk_mask;
                i2c.mask_data_mask = data_mask;
                i2c.a_clk_mask = clk_mask;
@@ -579,7 +580,19 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
                i2c.en_data_mask = data_mask;
                i2c.y_clk_mask = clk_mask;
                i2c.y_data_mask = data_mask;
+       } else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
+                  (ddc_line == RADEON_MDGPIO_MASK)) {
+               /* default gpiopad masks */
+               i2c.mask_clk_mask = (0x20 << 8);
+               i2c.mask_data_mask = 0x80;
+               i2c.a_clk_mask = (0x20 << 8);
+               i2c.a_data_mask = 0x80;
+               i2c.en_clk_mask = (0x20 << 8);
+               i2c.en_data_mask = 0x80;
+               i2c.y_clk_mask = (0x20 << 8);
+               i2c.y_data_mask = 0x80;
        } else {
+               /* default masks for ddc pads */
                i2c.mask_clk_mask = RADEON_GPIO_EN_1;
                i2c.mask_data_mask = RADEON_GPIO_EN_0;
                i2c.a_clk_mask = RADEON_GPIO_A_1;
@@ -716,7 +729,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
                                        clk = RBIOS8(offset + 3 + (i * 5) + 3);
                                        data = RBIOS8(offset + 3 + (i * 5) + 4);
                                        i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
-                                                                   clk, data);
+                                                                   (1 << clk), (1 << data));
                                        rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
                                        break;
                                }
index fe6c74780f18e67bb55ea5fdeefdbb038ffadbf1..8afaf7a7459e1c27ece79fee57d384d1bcaf67d9 100644 (file)
@@ -1008,9 +1008,21 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
 static int radeon_dp_get_modes(struct drm_connector *connector)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
        int ret;
 
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
+       }
        ret = radeon_ddc_get_modes(radeon_connector);
+       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
+       }
+
        return ret;
 }
 
@@ -1029,8 +1041,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                /* eDP is always DP */
                radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
                if (radeon_dp_getdpcd(radeon_connector))
                        ret = connector_status_connected;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
        } else {
                radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
                if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
@@ -1157,6 +1175,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1172,6 +1192,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              1);
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1208,6 +1230,11 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      rdev->mode_info.load_detect_property,
                                                      1);
                }
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_HDMIA:
        case DRM_MODE_CONNECTOR_HDMIB:
@@ -1238,6 +1265,11 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      0);
                }
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_DisplayPort:
        case DRM_MODE_CONNECTOR_eDP:
@@ -1275,6 +1307,9 @@ radeon_add_atom_connector(struct drm_device *dev,
                                                      rdev->mode_info.underscan_vborder_property,
                                                      0);
                }
+               connector->interlace_allowed = true;
+               /* in theory with a DP to VGA converter... */
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
@@ -1290,6 +1325,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              radeon_atombios_get_tv_info(rdev));
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_LVDS:
                radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -1308,6 +1345,8 @@ radeon_add_atom_connector(struct drm_device *dev,
                                              dev->mode_config.scaling_mode_property,
                                              DRM_MODE_SCALE_FULLSCREEN);
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        }
 
@@ -1385,6 +1424,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
                connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVIA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1400,6 +1441,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              1);
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = true;
+               connector->doublescan_allowed = true;
                break;
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_DVID:
@@ -1417,6 +1460,11 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                                      1);
                }
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = true;
+               if (connector_type == DRM_MODE_CONNECTOR_DVII)
+                       connector->doublescan_allowed = true;
+               else
+                       connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_SVIDEO:
        case DRM_MODE_CONNECTOR_Composite:
@@ -1439,6 +1487,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              radeon_combios_get_tv_info(rdev));
                /* no HPD on analog connectors */
                radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        case DRM_MODE_CONNECTOR_LVDS:
                drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -1452,6 +1502,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                                              dev->mode_config.scaling_mode_property,
                                              DRM_MODE_SCALE_FULLSCREEN);
                subpixel_order = SubPixelHorizontalRGB;
+               connector->interlace_allowed = false;
+               connector->doublescan_allowed = false;
                break;
        }
 
index 8adfedfe547f6b6455676deaa26dada2592ff6a5..e12e79326cb115a490ed5d94e0eda2a84ee400db 100644 (file)
@@ -180,7 +180,7 @@ int radeon_wb_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+               r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
                if (r) {
                        dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
@@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
                mc->mc_vram_size = mc->aper_size;
        }
        mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
-       dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
+       dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
                        mc->mc_vram_size >> 20, mc->vram_start,
                        mc->vram_end, mc->real_vram_size >> 20);
 }
@@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
        }
        mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
-       dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
+       dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
                        mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
 }
 
index f678257c42e6ab54f668951b93e685cf04d287d5..041943df966be15803ebedc2e5291fa00953745e 100644 (file)
@@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
                return false;
        }
 }
+
 void
 radeon_link_encoder_connector(struct drm_device *dev)
 {
@@ -228,6 +229,27 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
        return NULL;
 }
 
+struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *other_encoder;
+       struct radeon_encoder *other_radeon_encoder;
+
+       if (radeon_encoder->is_ext_encoder)
+               return NULL;
+
+       list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
+               if (other_encoder == encoder)
+                       continue;
+               other_radeon_encoder = to_radeon_encoder(other_encoder);
+               if (other_radeon_encoder->is_ext_encoder &&
+                   (radeon_encoder->devices & other_radeon_encoder->devices))
+                       return other_encoder;
+       }
+       return NULL;
+}
+
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
                             struct drm_display_mode *adjusted_mode)
 {
@@ -426,52 +448,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
 
 }
 
-void
-atombios_external_tmds_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
-       int index = 0;
-
-       memset(&args, 0, sizeof(args));
-
-       index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
-
-       args.sXTmdsEncoder.ucEnable = action;
-
-       if (radeon_encoder->pixel_clock > 165000)
-               args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
-
-       /*if (pScrn->rgbBits == 8)*/
-       args.sXTmdsEncoder.ucMisc |= (1 << 1);
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
+union dvo_encoder_control {
+       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+};
 
-static void
-atombios_ddia_setup(struct drm_encoder *encoder, int action)
+void
+atombios_dvo_setup(struct drm_encoder *encoder, int action)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       DVO_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0;
+       union dvo_encoder_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
 
        memset(&args, 0, sizeof(args));
 
-       index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+       if (ASIC_IS_DCE3(rdev)) {
+               /* DCE3+ */
+               args.dvo_v3.ucAction = action;
+               args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               args.dvo_v3.ucDVOConfig = 0; /* XXX */
+       } else if (ASIC_IS_DCE2(rdev)) {
+               /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
+               args.dvo.sDVOEncoder.ucAction = action;
+               args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               /* DFP1, CRT1, TV1 depending on the type of port */
+               args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
+
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
+       } else {
+               /* R4xx, R5xx */
+               args.ext_tmds.sXTmdsEncoder.ucEnable = action;
 
-       args.sDVOEncoder.ucAction = action;
-       args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+               if (radeon_encoder->pixel_clock > 165000)
+                       args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 
-       if (radeon_encoder->pixel_clock > 165000)
-               args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
+               /*if (pScrn->rgbBits == 8)*/
+               args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
+       }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
 }
 
 union lvds_encoder_control {
@@ -532,14 +551,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
                                if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
                                if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
-                                       args.v1.ucMisc |= (1 << 1);
+                                       args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
                        } else {
                                if (dig->linkb)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
                                if (radeon_encoder->pixel_clock > 165000)
                                        args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
                                /*if (pScrn->rgbBits == 8) */
-                               args.v1.ucMisc |= (1 << 1);
+                               args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
                        }
                        break;
                case 2:
@@ -595,6 +614,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
 int
 atombios_get_encoder_mode(struct drm_encoder *encoder)
 {
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct drm_connector *connector;
@@ -602,9 +622,20 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        struct radeon_connector_atom_dig *dig_connector;
 
        connector = radeon_get_connector_for_encoder(encoder);
-       if (!connector)
-               return 0;
-
+       if (!connector) {
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+                       return ATOM_ENCODER_MODE_DVI;
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               default:
+                       return ATOM_ENCODER_MODE_CRT;
+               }
+       }
        radeon_connector = to_radeon_connector(connector);
 
        switch (connector->connector_type) {
@@ -834,6 +865,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        memset(&args, 0, sizeof(args));
 
        switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
@@ -978,6 +1012,105 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+void
+atombios_set_edp_panel_power(struct drm_connector *connector, int action)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       union dig_transmitter_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+       uint8_t frev, crev;
+
+       if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+               return;
+
+       if (!ASIC_IS_DCE4(rdev))
+               return;
+
+       if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) ||
+           (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
+               return;
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       memset(&args, 0, sizeof(args));
+
+       args.v1.ucAction = action;
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+union external_encoder_control {
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
+};
+
+static void
+atombios_external_encoder_setup(struct drm_encoder *encoder,
+                               struct drm_encoder *ext_encoder,
+                               int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       union external_encoder_control args;
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
+       u8 frev, crev;
+       int dp_clock = 0;
+       int dp_lane_count = 0;
+       int connector_object_id = 0;
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               struct radeon_connector_atom_dig *dig_connector =
+                       radeon_connector->con_priv;
+
+               dp_clock = dig_connector->dp_clock;
+               dp_lane_count = dig_connector->dp_lane_count;
+               connector_object_id =
+                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+       }
+
+       memset(&args, 0, sizeof(args));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               /* no params on frev 1 */
+               break;
+       case 2:
+               switch (crev) {
+               case 1:
+               case 2:
+                       args.v1.sDigEncoder.ucAction = action;
+                       args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+                               if (dp_clock == 270000)
+                                       args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+                               args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
+                       } else if (radeon_encoder->pixel_clock > 165000)
+                               args.v1.sDigEncoder.ucLaneNum = 8;
+                       else
+                               args.v1.sDigEncoder.ucLaneNum = 4;
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+                       return;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+               return;
+       }
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
 static void
 atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
 {
@@ -1021,6 +1154,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
        DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
        int index = 0;
        bool is_dig = false;
@@ -1043,9 +1177,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
                index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
                break;
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               if (ASIC_IS_DCE3(rdev))
+                       is_dig = true;
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
                index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
                break;
@@ -1082,34 +1221,85 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
                                struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 
+                               if (connector &&
+                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig *radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       atombios_set_edp_panel_power(connector,
+                                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
+                                       radeon_dig_connector->edp_on = true;
+                               }
                                dp_link_train(encoder, connector);
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
                        }
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
                        break;
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
                        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+                               if (connector &&
+                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig *radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       atombios_set_edp_panel_power(connector,
+                                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
+                                       radeon_dig_connector->edp_on = false;
+                               }
                        }
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
                        break;
                }
        } else {
                switch (mode) {
                case DRM_MODE_DPMS_ON:
                        args.ucAction = ATOM_ENABLE;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               args.ucAction = ATOM_LCD_BLON;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                        break;
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
                        args.ucAction = ATOM_DISABLE;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               args.ucAction = ATOM_LCD_BLOFF;
+                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       }
                        break;
                }
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
        }
+
+       if (ext_encoder) {
+               int action;
+
+               switch (mode) {
+               case DRM_MODE_DPMS_ON:
+               default:
+                       action = ATOM_ENABLE;
+                       break;
+               case DRM_MODE_DPMS_STANDBY:
+               case DRM_MODE_DPMS_SUSPEND:
+               case DRM_MODE_DPMS_OFF:
+                       action = ATOM_DISABLE;
+                       break;
+               }
+               atombios_external_encoder_setup(encoder, ext_encoder, action);
+       }
+
        radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
 
 }
@@ -1242,7 +1432,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
                break;
        default:
                DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
-               break;
+               return;
        }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
@@ -1357,6 +1547,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
 
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
@@ -1400,11 +1591,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
                }
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-               atombios_ddia_setup(encoder, ATOM_ENABLE);
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+               atombios_dvo_setup(encoder, ATOM_ENABLE);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1419,6 +1608,11 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
                }
                break;
        }
+
+       if (ext_encoder) {
+               atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
+       }
+
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
        if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
@@ -1595,11 +1789,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
                }
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DDI:
-               atombios_ddia_setup(encoder, ATOM_DISABLE);
-               break;
        case ENCODER_OBJECT_ID_INTERNAL_DVO1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_external_tmds_setup(encoder, ATOM_DISABLE);
+               atombios_dvo_setup(encoder, ATOM_DISABLE);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1621,6 +1813,53 @@ disable_done:
        radeon_encoder->active_device = 0;
 }
 
+/* these are handled by the primary encoders */
+static void radeon_atom_ext_prepare(struct drm_encoder *encoder)
+{
+
+}
+
+static void radeon_atom_ext_commit(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+
+}
+
+static void radeon_atom_ext_disable(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
+{
+
+}
+
+static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
+                                      struct drm_display_mode *mode,
+                                      struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
+       .dpms = radeon_atom_ext_dpms,
+       .mode_fixup = radeon_atom_ext_mode_fixup,
+       .prepare = radeon_atom_ext_prepare,
+       .mode_set = radeon_atom_ext_mode_set,
+       .commit = radeon_atom_ext_commit,
+       .disable = radeon_atom_ext_disable,
+       /* no detect for TMDS/LVDS yet */
+};
+
 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
        .dpms = radeon_atom_encoder_dpms,
        .mode_fixup = radeon_atom_mode_fixup,
@@ -1730,6 +1969,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
        radeon_encoder->devices = supported_device;
        radeon_encoder->rmx_type = RMX_OFF;
        radeon_encoder->underscan_type = UNDERSCAN_OFF;
+       radeon_encoder->is_ext_encoder = false;
 
        switch (radeon_encoder->encoder_id) {
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -1771,6 +2011,9 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
                        radeon_encoder->rmx_type = RMX_FULL;
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
                        radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+               } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
                } else {
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
                        radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
@@ -1779,5 +2022,22 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
                }
                drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
                break;
+       case ENCODER_OBJECT_ID_SI170B:
+       case ENCODER_OBJECT_ID_CH7303:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
+       case ENCODER_OBJECT_ID_TITFP513:
+       case ENCODER_OBJECT_ID_VT1623:
+       case ENCODER_OBJECT_ID_HDMI_SI1930:
+               /* these are handled by the primary encoders */
+               radeon_encoder->is_ext_encoder = true;
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+               else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               else
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+               drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
+               break;
        }
 }
index e65b90317fab282df8b97b6b11b277ea867a2647..65016117d95f2f4e332bc6bdd0d9de63e8dbeafe 100644 (file)
@@ -79,8 +79,8 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
 
        if (rdev->gart.table.vram.robj == NULL) {
                r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
-                                       true, RADEON_GEM_DOMAIN_VRAM,
-                                       &rdev->gart.table.vram.robj);
+                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+                                    &rdev->gart.table.vram.robj);
                if (r) {
                        return r;
                }
index d1e595d9172396b8104d19c7a1d0a87d3b14b772..df95eb83dac6d52e4cad7f6570d6cca9e2807b1f 100644 (file)
@@ -67,7 +67,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
        if (alignment < PAGE_SIZE) {
                alignment = PAGE_SIZE;
        }
-       r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
+       r = radeon_bo_create(rdev, gobj, size, alignment, kernel, initial_domain, &robj);
        if (r) {
                if (r != -ERESTARTSYS)
                        DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
index 0cfbba02c4d03773df29eb07efe74010a989002b..ded2a45bc95cd5f2845b9d32009d98dc00105c5f 100644 (file)
@@ -896,7 +896,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
             ((rdev->family <= CHIP_RS480) ||
              ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
                /* set the radeon hw i2c adapter */
-               sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+               snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                        "Radeon i2c hw bus %s", name);
                i2c->adapter.algo = &radeon_i2c_algo;
                ret = i2c_add_adapter(&i2c->adapter);
                if (ret) {
@@ -905,7 +906,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
                }
        } else {
                /* set the radeon bit adapter */
-               sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+               snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                        "Radeon i2c bit bus %s", name);
                i2c->adapter.algo_data = &i2c->algo.bit;
                i2c->algo.bit.pre_xfer = pre_xfer;
                i2c->algo.bit.post_xfer = post_xfer;
@@ -946,6 +948,8 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
        i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
        i2c->dev = dev;
+       snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+                "Radeon aux bus %s", name);
        i2c_set_adapdata(&i2c->adapter, i2c);
        i2c->adapter.algo_data = &i2c->algo.dp;
        i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
index 2f349a300195992c9450c9ddd1d6e091eed23ef8..465746bd51b76e4b88cbb1812f7729be430a6da7 100644 (file)
@@ -76,7 +76,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
                default:
                        DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
                                  crtc);
-                       return EINVAL;
+                       return -EINVAL;
                }
        } else {
                switch (crtc) {
@@ -89,7 +89,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
                default:
                        DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
                                  crtc);
-                       return EINVAL;
+                       return -EINVAL;
                }
        }
 
index 0b8397000f4c68ae98e80df717a652cb2ddf6253..59f834ba283dd3fa15dde00b373c6a330d62decc 100644 (file)
@@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
 
        if (rdev->is_atom_bios) {
                radeon_encoder->pixel_clock = adjusted_mode->clock;
-               atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+               atombios_dvo_setup(encoder, ATOM_ENABLE);
                fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
        } else {
                fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
index 680f57644e865ce2a5e4fdc97b5154a7dffb11a5..e301c6f9e0595889a28a4ab99a10e530d41f2112 100644 (file)
@@ -375,6 +375,7 @@ struct radeon_encoder {
        int hdmi_config_offset;
        int hdmi_audio_workaround;
        int hdmi_buffer_status;
+       bool is_ext_encoder;
 };
 
 struct radeon_connector_atom_dig {
@@ -385,6 +386,7 @@ struct radeon_connector_atom_dig {
        u8 dp_sink_type;
        int dp_clock;
        int dp_lane_count;
+       bool edp_on;
 };
 
 struct radeon_gpio_rec {
@@ -523,9 +525,10 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev
 struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
 struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
-extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
+extern void atombios_dvo_setup(struct drm_encoder *encoder, int action);
 extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
+extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
index 8eb183466015326f7ca93b2647e85a610fe91f6f..a598d0049aa5938900a84c656c3cd9677010ee20 100644 (file)
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
        u32 c = 0;
 
        rbo->placement.fpfn = 0;
-       rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
+       rbo->placement.lpfn = 0;
        rbo->placement.placement = rbo->placements;
        rbo->placement.busy_placement = rbo->placements;
        if (domain & RADEON_GEM_DOMAIN_VRAM)
@@ -86,11 +86,13 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
 }
 
 int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
-                       unsigned long size, bool kernel, u32 domain,
-                       struct radeon_bo **bo_ptr)
+                    unsigned long size, int byte_align, bool kernel, u32 domain,
+                    struct radeon_bo **bo_ptr)
 {
        struct radeon_bo *bo;
        enum ttm_bo_type type;
+       unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+       unsigned long max_size = 0;
        int r;
 
        if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -103,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
        }
        *bo_ptr = NULL;
 
+       /* maximun bo size is the minimun btw visible vram and gtt size */
+       max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
+       if ((page_align << PAGE_SHIFT) >= max_size) {
+               printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
+                       __func__, __LINE__, page_align  >> (20 - PAGE_SHIFT), max_size >> 20);
+               return -ENOMEM;
+       }
+
 retry:
        bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
        if (bo == NULL)
@@ -115,7 +125,7 @@ retry:
        /* Kernel allocation are uninterruptible */
        mutex_lock(&rdev->vram_mutex);
        r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
-                       &bo->placement, 0, 0, !kernel, NULL, size,
+                       &bo->placement, page_align, 0, !kernel, NULL, size,
                        &radeon_ttm_bo_destroy);
        mutex_unlock(&rdev->vram_mutex);
        if (unlikely(r != 0)) {
index 3481bc7f6f582b08a0c2a9ff079fa9787defb6cd..d143702b244a4febdd51aa69ca7023e19d692a62 100644 (file)
@@ -137,9 +137,10 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
 }
 
 extern int radeon_bo_create(struct radeon_device *rdev,
-                               struct drm_gem_object *gobj, unsigned long size,
-                               bool kernel, u32 domain,
-                               struct radeon_bo **bo_ptr);
+                           struct drm_gem_object *gobj, unsigned long size,
+                           int byte_align,
+                           bool kernel, u32 domain,
+                           struct radeon_bo **bo_ptr);
 extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
 extern void radeon_bo_kunmap(struct radeon_bo *bo);
 extern void radeon_bo_unref(struct radeon_bo **bo);
index 6ea798ce821896dd4b2704461b260578a63a2516..06e79822a2bff74b68fb74793c9ec906ad0834a1 100644 (file)
@@ -176,8 +176,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
        INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib);
        /* Allocate 1M object buffer */
        r = radeon_bo_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
-                               true, RADEON_GEM_DOMAIN_GTT,
-                               &rdev->ib_pool.robj);
+                            PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT,
+                            &rdev->ib_pool.robj);
        if (r) {
                DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
                return r;
@@ -332,7 +332,7 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
        rdev->cp.ring_size = ring_size;
        /* Allocate ring buffer */
        if (rdev->cp.ring_obj == NULL) {
-               r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
+               r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, PAGE_SIZE, true,
                                        RADEON_GEM_DOMAIN_GTT,
                                        &rdev->cp.ring_obj);
                if (r) {
index 313c96bc09da1dcfcb0703ed3aa82a2038af0731..5b44f652145c45cb5b1b588fa263fb318739a168 100644 (file)
@@ -52,7 +52,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                goto out_cleanup;
        }
 
-       r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
+       r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
                                &vram_obj);
        if (r) {
                DRM_ERROR("Failed to create VRAM object\n");
@@ -71,7 +71,7 @@ void radeon_test_moves(struct radeon_device *rdev)
                void **gtt_start, **gtt_end;
                void **vram_start, **vram_end;
 
-               r = radeon_bo_create(rdev, NULL, size, true,
+               r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true,
                                         RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
                if (r) {
                        DRM_ERROR("Failed to create GTT object %d\n", i);
index 01c2c736a1daff116284db0f84f3896977e6eecb..1272e4b6a1d45469add57610a397c213704d5446 100644 (file)
@@ -529,7 +529,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
                DRM_ERROR("Failed initializing VRAM heap.\n");
                return r;
        }
-       r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
+       r = radeon_bo_create(rdev, NULL, 256 * 1024, PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_VRAM,
                                &rdev->stollen_vga_memory);
        if (r) {
index 245374e2b778b7706e9bf828c8a65876c1e11a00..4dfead8cee33907ae025c9c58adede92c12db4f6 100644 (file)
@@ -915,8 +915,8 @@ static int rv770_vram_scratch_init(struct radeon_device *rdev)
 
        if (rdev->vram_scratch.robj == NULL) {
                r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
-                                       true, RADEON_GEM_DOMAIN_VRAM,
-                                       &rdev->vram_scratch.robj);
+                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+                                    &rdev->vram_scratch.robj);
                if (r) {
                        return r;
                }
index 3ca77dc03915017e78d0e7f7e8e479d9f279fc56..148a322d8f5d7c45d0487351635f89eb9a9a0949 100644 (file)
@@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
        int ret;
 
        while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
+               /**
+                * Deadlock avoidance for multi-bo reserving.
+                */
                if (use_sequence && bo->seq_valid &&
                        (sequence - bo->val_seq < (1 << 31))) {
                        return -EAGAIN;
@@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
        }
 
        if (use_sequence) {
+               /**
+                * Wake up waiters that may need to recheck for deadlock,
+                * if we decreased the sequence number.
+                */
+               if (unlikely((bo->val_seq - sequence < (1 << 31))
+                            || !bo->seq_valid))
+                       wake_up_all(&bo->event_queue);
+
                bo->val_seq = sequence;
                bo->seq_valid = true;
        } else {
index 36e129f0023ffc3d6407b9c0251376aa3fc9f5c0..5408b1b7996f054dee95b9ed5aac4e9d63ee99a1 100644 (file)
@@ -862,7 +862,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
                              &vmw_vram_sys_placement, true,
                              &vmw_user_dmabuf_destroy);
        if (unlikely(ret != 0))
-               return ret;
+               goto out_no_dmabuf;
 
        tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
        ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
@@ -870,19 +870,21 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
                                   false,
                                   ttm_buffer_type,
                                   &vmw_user_dmabuf_release, NULL);
-       if (unlikely(ret != 0)) {
-               ttm_bo_unref(&tmp);
-       else {
+       if (unlikely(ret != 0))
+               goto out_no_base_object;
+       else {
                rep->handle = vmw_user_bo->base.hash.key;
                rep->map_handle = vmw_user_bo->dma.base.addr_space_offset;
                rep->cur_gmr_id = vmw_user_bo->base.hash.key;
                rep->cur_gmr_offset = 0;
        }
-       ttm_bo_unref(&tmp);
 
+out_no_base_object:
+       ttm_bo_unref(&tmp);
+out_no_dmabuf:
        ttm_read_unlock(&vmaster->lock);
 
-       return 0;
+       return ret;
 }
 
 int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
index 515345b11ac95b380942638ce25f8ea8afccd472..88cb04e7962bad32e0410b90826ff3b4a55c25a9 100644 (file)
@@ -1386,6 +1386,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
index 54b017ad258d29cf5e726ad04ee3297235a22366..5a1b52e0eb85f1ecfd7035f317c3b6577bf5d7cb 100644 (file)
@@ -221,7 +221,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
        struct egalax_data *td;
        struct hid_report *report;
 
-       td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL);
+       td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
        if (!td) {
                dev_err(&hdev->dev, "cannot allocate eGalax data\n");
                return -ENOMEM;
index bb0b3659437b1a98302f159f2e1773db21a0e2ee..d8d372bae3cc16d3d5f43dda55ee89214d05d2d4 100644 (file)
@@ -174,7 +174,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
 
                clear_bit(*old_keycode, dev->keybit);
                set_bit(usage->code, dev->keybit);
-               dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
+               dbg_hid("Assigned keycode %d to HID usage code %x\n",
                        usage->code, usage->hid);
 
                /*
@@ -203,8 +203,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
  *
  * as seen in the HID specification v1.11 6.2.2.7 Global Items.
  *
- * Only exponent 1 length units are processed. Centimeters are converted to
- * inches. Degrees are converted to radians.
+ * Only exponent 1 length units are processed. Centimeters and inches are
+ * converted to millimeters. Degrees are converted to radians.
  */
 static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
 {
@@ -225,13 +225,16 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
         */
        if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
                if (field->unit == 0x11) {              /* If centimeters */
-                       /* Convert to inches */
-                       prev = logical_extents;
-                       logical_extents *= 254;
-                       if (logical_extents < prev)
+                       /* Convert to millimeters */
+                       unit_exponent += 1;
+               } else if (field->unit == 0x13) {       /* If inches */
+                       /* Convert to millimeters */
+                       prev = physical_extents;
+                       physical_extents *= 254;
+                       if (physical_extents < prev)
                                return 0;
-                       unit_exponent += 2;
-               } else if (field->unit != 0x13) {       /* If not inches */
+                       unit_exponent -= 1;
+               } else {
                        return 0;
                }
        } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
index 15434c814793409bd7d00a2e0a4ee20ea8302456..25be4e1461bde288497ab2ed5363842934a18df4 100644 (file)
@@ -256,6 +256,8 @@ static const struct hid_device_id tm_devices[] = {
                .driver_data = (unsigned long)ff_joystick },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),   /* FGT Force Feedback Wheel */
                .driver_data = (unsigned long)ff_joystick },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a),   /* F430 Force Feedback Wheel */
+               .driver_data = (unsigned long)ff_joystick },
        { }
 };
 MODULE_DEVICE_TABLE(hid, tm_devices);
index 8a4b32dca9f74fd03621f3deffe0912929ee5cf3..e1f07483691f7823b46db14c38dc0d8daa536a13 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/hid.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 #include <linux/hidraw.h>
 
index fedd88df9a18477de2699cb07e48feade407312f..984feb351a5a3205de716fdb68ad9e5f983bdadd 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
index 937983407e2a47b12569d9ca4305af174e78f405..c4c40be0edbfd6afb00a7e6dbf6a0b20a5544b3f 100644 (file)
@@ -497,12 +497,14 @@ static unsigned long chipset_ids[] = {
        0
 };
 
+#ifdef MODULE
 static struct pci_device_id i5k_amb_ids[] __devinitdata = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, i5k_amb_ids);
+#endif
 
 static int __devinit i5k_amb_probe(struct platform_device *pdev)
 {
index 9f4bae07f7194ebff499b2902895dc44c507d974..8853afce85ce138464787fc9182e27be9206ef1f 100644 (file)
@@ -186,7 +186,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int lis3lv02d_i2c_suspend(struct device *dev)
 {
        struct i2c_client *client = container_of(dev, struct i2c_client, dev);
@@ -213,12 +213,9 @@ static int lis3lv02d_i2c_resume(struct device *dev)
 
        return 0;
 }
-#else
-#define lis3lv02d_i2c_suspend  NULL
-#define lis3lv02d_i2c_resume   NULL
-#define lis3lv02d_i2c_shutdown NULL
-#endif
+#endif /* CONFIG_PM_SLEEP */
 
+#ifdef CONFIG_PM_RUNTIME
 static int lis3_i2c_runtime_suspend(struct device *dev)
 {
        struct i2c_client *client = container_of(dev, struct i2c_client, dev);
@@ -236,6 +233,7 @@ static int lis3_i2c_runtime_resume(struct device *dev)
        lis3lv02d_poweron(lis3);
        return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
 static const struct i2c_device_id lis3lv02d_id[] = {
        {"lis3lv02d", 0 },
index b923074b2cbebcef73d91b5b7f23cfd47cb133f1..30f06e956bfb77e4f183e524657c21dbc211d1fe 100644 (file)
@@ -75,8 +75,7 @@ config I2C_HELPER_AUTO
          In doubt, say Y.
 
 config I2C_SMBUS
-       tristate
-       prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO
+       tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
        help
          Say Y here if you want support for SMBus extensions to the I2C
          specification. At the moment, the only supported extension is
index 3998dd620a032586970a60f556aa6292318ce84a..f1cfe7e5508bb1cf65a82fac5903472927c3d184 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 menu "I2C Algorithms"
-       depends on !I2C_HELPER_AUTO
+       visible if !I2C_HELPER_AUTO
 
 config I2C_ALGOBIT
        tristate "I2C bit-banging interfaces"
@@ -15,15 +15,3 @@ config I2C_ALGOPCA
        tristate "I2C PCA 9564 interfaces"
 
 endmenu
-
-# In automatic configuration mode, we still have to define the
-# symbols to avoid unmet dependencies.
-
-if I2C_HELPER_AUTO
-config I2C_ALGOBIT
-       tristate
-config I2C_ALGOPCF
-       tristate
-config I2C_ALGOPCA
-       tristate
-endif
index bb7e19280821c1074c6efd23a992f243ba33d258..9b737ff133e21d143982a57df0a581753450a6f3 100644 (file)
@@ -277,36 +277,6 @@ void ib_ud_header_init(int                     payload_bytes,
 }
 EXPORT_SYMBOL(ib_ud_header_init);
 
-/**
- * ib_lrh_header_pack - Pack LRH header struct into wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_pack() packs the LRH header structure @lrh into
- * wire format in the buffer @buf.
- */
-int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf)
-{
-       ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf);
-       return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_pack);
-
-/**
- * ib_lrh_header_unpack - Unpack LRH structure from wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_unpack() unpacks the LRH header structure from
- * wire format (in buf) into @lrh.
- */
-int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
-{
-       ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
-       return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_unpack);
-
 /**
  * ib_ud_header_pack - Pack UD header struct into wire format
  * @header:UD header struct
index 5440da0e59b4d8b475c2cd3e437fcb04e456a334..1b1146f87124e2618ef80a8303fabe681a464782 100644 (file)
@@ -40,18 +40,21 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
        dst->grh.sgid_index        = src->grh.sgid_index;
        dst->grh.hop_limit         = src->grh.hop_limit;
        dst->grh.traffic_class     = src->grh.traffic_class;
+       memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
        dst->dlid                  = src->dlid;
        dst->sl                    = src->sl;
        dst->src_path_bits         = src->src_path_bits;
        dst->static_rate           = src->static_rate;
        dst->is_global             = src->ah_flags & IB_AH_GRH ? 1 : 0;
        dst->port_num              = src->port_num;
+       dst->reserved              = 0;
 }
 EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
 
 void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
                             struct ib_qp_attr *src)
 {
+       dst->qp_state           = src->qp_state;
        dst->cur_qp_state       = src->cur_qp_state;
        dst->path_mtu           = src->path_mtu;
        dst->path_mig_state     = src->path_mig_state;
@@ -83,6 +86,7 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
        dst->rnr_retry          = src->rnr_retry;
        dst->alt_port_num       = src->alt_port_num;
        dst->alt_timeout        = src->alt_timeout;
+       memset(dst->reserved, 0, sizeof(dst->reserved));
 }
 EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
 
index 6078992da3f04d6de686838c46ccfd61f6f43922..9292a15ad7c4885b3920724eeeb27b9765051bc4 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>
 #include <asm/pgtable.h>
 
 #include "ipath_kernel.h"
index bf3e20cd029859f2beb23e962fa2640e30faf44c..30e09caf0da95af71ce17e4017eaefb13db6cb7d 100644 (file)
@@ -219,7 +219,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
        struct net_device *ndev;
        enum ib_mtu tmp;
 
-       props->active_width     = IB_WIDTH_4X;
+       props->active_width     = IB_WIDTH_1X;
        props->active_speed     = 4;
        props->port_cap_flags   = IB_PORT_CM_SUP;
        props->gid_tbl_len      = to_mdev(ibdev)->dev->caps.gid_table_len[port];
@@ -242,7 +242,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
        tmp = iboe_get_mtu(ndev->mtu);
        props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256;
 
-       props->state            = netif_running(ndev) &&  netif_oper_up(ndev) ?
+       props->state            = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
                                        IB_PORT_ACTIVE : IB_PORT_DOWN;
        props->phys_state       = state_to_phys_state(props->state);
 
index 9a7794ac34c1ead2f08a9da3078db777ee1ef1ec..2001f20a43618e74b927733d8d54b410af084979 100644 (file)
@@ -1816,6 +1816,11 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
                                    MLX4_WQE_CTRL_FENCE : 0) | size;
 
+               if (be16_to_cpu(vlan) < 0x1000) {
+                       ctrl->ins_vlan = 1 << 6;
+                       ctrl->vlan_tag = vlan;
+               }
+
                /*
                 * Make sure descriptor is fully written before
                 * setting ownership bit (because HW can start
@@ -1831,11 +1836,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
                        (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh;
 
-               if (be16_to_cpu(vlan) < 0x1000) {
-                       ctrl->ins_vlan = 1 << 6;
-                       ctrl->vlan_tag = vlan;
-               }
-
                stamp = ind + qp->sq_spare_wqes;
                ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
 
index cfc1d65c4577bf4ed2ce07bc2ea1924f406bd445..1e1e347a771531aa767f912a5fe38d3c2f2ac2dc 100644 (file)
@@ -1123,7 +1123,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr)
        }
 }
 
-static int srp_queuecommand(struct scsi_cmnd *scmnd,
+static int srp_queuecommand_lck(struct scsi_cmnd *scmnd,
                            void (*done)(struct scsi_cmnd *))
 {
        struct srp_target_port *target = host_to_target(scmnd->device->host);
@@ -1196,6 +1196,8 @@ err:
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
+static DEF_SCSI_QCMD(srp_queuecommand)
+
 static int srp_alloc_iu_bufs(struct srp_target_port *target)
 {
        int i;
index 7f26ca6ecf75dc6f15185771a8bae6cfb24ce58d..db409d6bd5d2b9672ad94f370564f870bed25b19 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
-#include <linux/smp_lock.h>
 #include "input-compat.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -753,7 +752,7 @@ static int input_default_setkeycode(struct input_dev *dev,
        if (index >= dev->keycodemax)
                return -EINVAL;
 
-       if (dev->keycodesize < sizeof(dev->keycode) &&
+       if (dev->keycodesize < sizeof(ke->keycode) &&
                        (ke->keycode >> (dev->keycodesize * 8)))
                return -EINVAL;
 
index d53b9e900234e7ba95c2c0b9500a830b96c07803..27b6a3ce18caf2e996177e6c313fff2b21a4ad19 100644 (file)
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
                goto err_free_tgfx;
         }
 
+       parport_put_port(pp);
        return tgfx;
 
  err_free_dev:
index b8c51b9781dbfb5e51c9a9d84071f534bf44e1d1..3a87f3ba5f75ee1f6a94973c2a5414f0653e48a8 100644 (file)
@@ -179,6 +179,22 @@ config KEYBOARD_GPIO
          To compile this driver as a module, choose M here: the
          module will be called gpio_keys.
 
+config KEYBOARD_GPIO_POLLED
+       tristate "Polled GPIO buttons"
+       depends on GENERIC_GPIO
+       select INPUT_POLLDEV
+       help
+         This driver implements support for buttons connected
+         to GPIO pins that are not capable of generating interrupts.
+
+         Say Y here if your device has buttons connected
+         directly to such GPIO pins.  Your board-specific
+         setup logic must also provide a platform device,
+         with configuration data saying which GPIOs are used.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gpio_keys_polled.
+
 config KEYBOARD_TCA6416
        tristate "TCA6416 Keypad Support"
        depends on I2C
index a34452e8ebe2a1cb190f82d5c5f9c037860fcf07..622de73a445dbe620db5ae86d5e8ccd2bd90aeb2 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN)           += bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_DAVINCI)         += davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
+obj-$(CONFIG_KEYBOARD_GPIO_POLLED)     += gpio_keys_polled.o
 obj-$(CONFIG_KEYBOARD_TCA6416)         += tca6416-keypad.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)         += hilkbd.o
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
new file mode 100644 (file)
index 0000000..4c17aff
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  Driver for buttons on GPIO lines not capable of generating interrupts
+ *
+ *  Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
+ *
+ *  This file was based on: /drivers/input/misc/cobalt_btns.c
+ *     Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  also was based on: /drivers/input/keyboard/gpio_keys.c
+ *     Copyright 2005 Phil Blundell
+ *
+ *  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/slab.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#define DRV_NAME       "gpio-keys-polled"
+
+struct gpio_keys_button_data {
+       int last_state;
+       int count;
+       int threshold;
+       int can_sleep;
+};
+
+struct gpio_keys_polled_dev {
+       struct input_polled_dev *poll_dev;
+       struct device *dev;
+       struct gpio_keys_platform_data *pdata;
+       struct gpio_keys_button_data data[0];
+};
+
+static void gpio_keys_polled_check_state(struct input_dev *input,
+                                        struct gpio_keys_button *button,
+                                        struct gpio_keys_button_data *bdata)
+{
+       int state;
+
+       if (bdata->can_sleep)
+               state = !!gpio_get_value_cansleep(button->gpio);
+       else
+               state = !!gpio_get_value(button->gpio);
+
+       if (state != bdata->last_state) {
+               unsigned int type = button->type ?: EV_KEY;
+
+               input_event(input, type, button->code,
+                           !!(state ^ button->active_low));
+               input_sync(input);
+               bdata->count = 0;
+               bdata->last_state = state;
+       }
+}
+
+static void gpio_keys_polled_poll(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+       struct input_dev *input = dev->input;
+       int i;
+
+       for (i = 0; i < bdev->pdata->nbuttons; i++) {
+               struct gpio_keys_button_data *bdata = &bdev->data[i];
+
+               if (bdata->count < bdata->threshold)
+                       bdata->count++;
+               else
+                       gpio_keys_polled_check_state(input, &pdata->buttons[i],
+                                                    bdata);
+       }
+}
+
+static void gpio_keys_polled_open(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+       if (pdata->enable)
+               pdata->enable(bdev->dev);
+}
+
+static void gpio_keys_polled_close(struct input_polled_dev *dev)
+{
+       struct gpio_keys_polled_dev *bdev = dev->private;
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+
+       if (pdata->disable)
+               pdata->disable(bdev->dev);
+}
+
+static int __devinit gpio_keys_polled_probe(struct platform_device *pdev)
+{
+       struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+       struct device *dev = &pdev->dev;
+       struct gpio_keys_polled_dev *bdev;
+       struct input_polled_dev *poll_dev;
+       struct input_dev *input;
+       int error;
+       int i;
+
+       if (!pdata || !pdata->poll_interval)
+               return -EINVAL;
+
+       bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
+                      pdata->nbuttons * sizeof(struct gpio_keys_button_data),
+                      GFP_KERNEL);
+       if (!bdev) {
+               dev_err(dev, "no memory for private data\n");
+               return -ENOMEM;
+       }
+
+       poll_dev = input_allocate_polled_device();
+       if (!poll_dev) {
+               dev_err(dev, "no memory for polled device\n");
+               error = -ENOMEM;
+               goto err_free_bdev;
+       }
+
+       poll_dev->private = bdev;
+       poll_dev->poll = gpio_keys_polled_poll;
+       poll_dev->poll_interval = pdata->poll_interval;
+       poll_dev->open = gpio_keys_polled_open;
+       poll_dev->close = gpio_keys_polled_close;
+
+       input = poll_dev->input;
+
+       input->evbit[0] = BIT(EV_KEY);
+       input->name = pdev->name;
+       input->phys = DRV_NAME"/input0";
+       input->dev.parent = &pdev->dev;
+
+       input->id.bustype = BUS_HOST;
+       input->id.vendor = 0x0001;
+       input->id.product = 0x0001;
+       input->id.version = 0x0100;
+
+       for (i = 0; i < pdata->nbuttons; i++) {
+               struct gpio_keys_button *button = &pdata->buttons[i];
+               struct gpio_keys_button_data *bdata = &bdev->data[i];
+               unsigned int gpio = button->gpio;
+               unsigned int type = button->type ?: EV_KEY;
+
+               if (button->wakeup) {
+                       dev_err(dev, DRV_NAME " does not support wakeup\n");
+                       error = -EINVAL;
+                       goto err_free_gpio;
+               }
+
+               error = gpio_request(gpio,
+                                    button->desc ? button->desc : DRV_NAME);
+               if (error) {
+                       dev_err(dev, "unable to claim gpio %u, err=%d\n",
+                               gpio, error);
+                       goto err_free_gpio;
+               }
+
+               error = gpio_direction_input(gpio);
+               if (error) {
+                       dev_err(dev,
+                               "unable to set direction on gpio %u, err=%d\n",
+                               gpio, error);
+                       goto err_free_gpio;
+               }
+
+               bdata->can_sleep = gpio_cansleep(gpio);
+               bdata->last_state = -1;
+               bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+                                               pdata->poll_interval);
+
+               input_set_capability(input, type, button->code);
+       }
+
+       bdev->poll_dev = poll_dev;
+       bdev->dev = dev;
+       bdev->pdata = pdata;
+       platform_set_drvdata(pdev, bdev);
+
+       error = input_register_polled_device(poll_dev);
+       if (error) {
+               dev_err(dev, "unable to register polled device, err=%d\n",
+                       error);
+               goto err_free_gpio;
+       }
+
+       /* report initial state of the buttons */
+       for (i = 0; i < pdata->nbuttons; i++)
+               gpio_keys_polled_check_state(input, &pdata->buttons[i],
+                                        &bdev->data[i]);
+
+       return 0;
+
+err_free_gpio:
+       while (--i >= 0)
+               gpio_free(pdata->buttons[i].gpio);
+
+       input_free_polled_device(poll_dev);
+
+err_free_bdev:
+       kfree(bdev);
+
+       platform_set_drvdata(pdev, NULL);
+       return error;
+}
+
+static int __devexit gpio_keys_polled_remove(struct platform_device *pdev)
+{
+       struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
+       struct gpio_keys_platform_data *pdata = bdev->pdata;
+       int i;
+
+       input_unregister_polled_device(bdev->poll_dev);
+
+       for (i = 0; i < pdata->nbuttons; i++)
+               gpio_free(pdata->buttons[i].gpio);
+
+       input_free_polled_device(bdev->poll_dev);
+
+       kfree(bdev);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver gpio_keys_polled_driver = {
+       .probe  = gpio_keys_polled_probe,
+       .remove = __devexit_p(gpio_keys_polled_remove),
+       .driver = {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init gpio_keys_polled_init(void)
+{
+       return platform_driver_register(&gpio_keys_polled_driver);
+}
+
+static void __exit gpio_keys_polled_exit(void)
+{
+       platform_driver_unregister(&gpio_keys_polled_driver);
+}
+
+module_init(gpio_keys_polled_init);
+module_exit(gpio_keys_polled_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_DESCRIPTION("Polled GPIO Buttons driver");
+MODULE_ALIAS("platform:" DRV_NAME);
index 613a3652f98f5f787fa619807f10de67aa8634c5..0aefaa8858714ba6e9963a9e6cd1f0c13fbab963 100644 (file)
@@ -51,7 +51,8 @@
 #define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
 #define SYN_CAP_PRODUCT_ID(ec)         (((ec) & 0xff0000) >> 16)
-#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100100)
+#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100000) /* 1-button ClickPad */
+#define SYN_CAP_CLICKPAD2BTN(ex0c)     ((ex0c) & 0x000100) /* 2-button ClickPad */
 #define SYN_CAP_MAX_DIMENSIONS(ex0c)   ((ex0c) & 0x020000)
 
 /* synaptics modes query bits */
index 3c287dd879d32be0b68f732ab020974c38ac10f5..4225f5d6b15f475e7822d78a1d26ce3e5e35301d 100644 (file)
@@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev)
        gscps2_reset(ps2port);
        ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
 
-       snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
+       snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
                 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
        strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
        serio->id.type          = SERIO_8042;
index cd82bb12591593be230f06fbf89aa2a52f6b73b2..b7ba4597f7f0256a7fb4f14b76894a3b76f0ccb6 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/serio.h>
index 57b25b84d1fcfded0408788dbd8cbd2d0dcb3e8f..0a619c558bfb40a8223c94301462d6387f7dc388 100644 (file)
@@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(pointer_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletPointerMode, store_tabletPointerMode);
 
 /***********************************************************************
@@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co
 }
 
 static DEVICE_ATTR(coordinate_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletCoordinateMode, store_tabletCoordinateMode);
 
 /***********************************************************************
@@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch
 }
 
 static DEVICE_ATTR(tool_mode,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletToolMode, store_tabletToolMode);
 
 /***********************************************************************
@@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(xtilt,
-                  S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
+                  S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt);
 
 /***********************************************************************
  * support routines for the 'ytilt' file. Note that this file
@@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(ytilt,
-                  S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
+                  S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt);
 
 /***********************************************************************
  * support routines for the 'jitter' file. Note that this file
@@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(jitter,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletJitterDelay, store_tabletJitterDelay);
 
 /***********************************************************************
@@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
 }
 
 static DEVICE_ATTR(delay,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletProgrammableDelay, store_tabletProgrammableDelay);
 
 /***********************************************************************
@@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(stylus_upper,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletStylusUpper, store_tabletStylusUpper);
 
 /***********************************************************************
@@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(stylus_lower,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletStylusLower, store_tabletStylusLower);
 
 /***********************************************************************
@@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c
 }
 
 static DEVICE_ATTR(mouse_left,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseLeft, store_tabletMouseLeft);
 
 /***********************************************************************
@@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(mouse_middle,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseMiddle, store_tabletMouseMiddle);
 
 /***********************************************************************
@@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const
 }
 
 static DEVICE_ATTR(mouse_right,
-                  S_IRUGO | S_IWUGO,
+                  S_IRUGO | S_IWUSR,
                   show_tabletMouseRight, store_tabletMouseRight);
 
 /***********************************************************************
@@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
 }
 
 static DEVICE_ATTR(wheel,
-                  S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);
+                  S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel);
 
 /***********************************************************************
  * support routines for the 'execute' file. Note that this file
@@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
 }
 
 static DEVICE_ATTR(execute,
-                  S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);
+                  S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute);
 
 /***********************************************************************
  * support routines for the 'odm_code' file. Note that this file
index b3252ef1e2797e6b7f640322bb8cbf4a6ecc61bd..4852b440960abadea47ab158dc8e6e6140970b06 100644 (file)
@@ -1436,6 +1436,12 @@ static struct wacom_features wacom_features_0xD2 =
        { "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xD3 =
        { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13530, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD8 =
+       { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13530, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDA =
+       { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN,  14720,  9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xDB =
+       { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN,  21648, 13530, 1023, 63, BAMBOO_PT };
 
 #define USB_DEVICE_WACOM(prod)                                 \
        USB_DEVICE(USB_VENDOR_ID_WACOM, prod),                  \
@@ -1504,6 +1510,9 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD1) },
        { USB_DEVICE_WACOM(0xD2) },
        { USB_DEVICE_WACOM(0xD3) },
+       { USB_DEVICE_WACOM(0xD8) },
+       { USB_DEVICE_WACOM(0xDA) },
+       { USB_DEVICE_WACOM(0xDB) },
        { USB_DEVICE_WACOM(0xF0) },
        { USB_DEVICE_WACOM(0xCC) },
        { USB_DEVICE_WACOM(0x90) },
index f45f80f6d3369b03f8b6e1e6a8bcebc827cf3377..73fd6642b681b92a074b6e8ab2619b65768292f7 100644 (file)
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = {
 
 #ifdef CONFIG_TOUCHSCREEN_USB_ITM
        {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
+       {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM},
 #endif
 
 #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
index 2e847a90bad0d601f8bcc5f9a7bd4d7440f929c0..f2b5bab5e6a191761d2f56331c792ca8f7f78182 100644 (file)
@@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup);
 static int __init icn_init(void)
 {
        char *p;
-       char rev[10];
+       char rev[20];
 
        memset(&dev, 0, sizeof(icn_dev));
        dev.memaddr = (membase & 0x0ffc000);
@@ -1637,9 +1637,10 @@ static int __init icn_init(void)
        spin_lock_init(&dev.devlock);
 
        if ((p = strchr(revision, ':'))) {
-               strcpy(rev, p + 1);
+               strncpy(rev, p + 1, 20);
                p = strchr(rev, '$');
-               *p = 0;
+               if (p)
+                       *p = 0;
        } else
                strcpy(rev, " ??? ");
        printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
index 77b8fd20cd9046b8e0c785c041c7569285aa6043..6f190f4cdbc00e4917c457dcd004060c3b8976ba 100644 (file)
@@ -7,20 +7,20 @@ menuconfig NEW_LEDS
          This is not related to standard keyboard LEDs which are controlled
          via the input system.
 
-if NEW_LEDS
-
 config LEDS_CLASS
        bool "LED Class Support"
+       depends on NEW_LEDS
        help
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
 
-if LEDS_CLASS
+if NEW_LEDS
 
 comment "LED drivers"
 
 config LEDS_88PM860X
        tristate "LED Support for Marvell 88PM860x PMIC"
+       depends on LEDS_CLASS
        depends on MFD_88PM860X
        help
          This option enables support for on-chip LED drivers found on Marvell
@@ -28,6 +28,7 @@ config LEDS_88PM860X
 
 config LEDS_ATMEL_PWM
        tristate "LED Support using Atmel PWM outputs"
+       depends on LEDS_CLASS
        depends on ATMEL_PWM
        help
          This option enables support for LEDs driven using outputs
@@ -35,6 +36,7 @@ config LEDS_ATMEL_PWM
 
 config LEDS_LOCOMO
        tristate "LED Support for Locomo device"
+       depends on LEDS_CLASS
        depends on SHARP_LOCOMO
        help
          This option enables support for the LEDs on Sharp Locomo.
@@ -42,6 +44,7 @@ config LEDS_LOCOMO
 
 config LEDS_MIKROTIK_RB532
        tristate "LED Support for Mikrotik Routerboard 532"
+       depends on LEDS_CLASS
        depends on MIKROTIK_RB532
        help
          This option enables support for the so called "User LED" of
@@ -49,6 +52,7 @@ config LEDS_MIKROTIK_RB532
 
 config LEDS_S3C24XX
        tristate "LED Support for Samsung S3C24XX GPIO LEDs"
+       depends on LEDS_CLASS
        depends on ARCH_S3C2410
        help
          This option enables support for LEDs connected to GPIO lines
@@ -56,12 +60,14 @@ config LEDS_S3C24XX
 
 config LEDS_AMS_DELTA
        tristate "LED Support for the Amstrad Delta (E3)"
+       depends on LEDS_CLASS
        depends on MACH_AMS_DELTA
        help
          This option enables support for the LEDs on Amstrad Delta (E3).
 
 config LEDS_NET48XX
        tristate "LED Support for Soekris net48xx series Error LED"
+       depends on LEDS_CLASS
        depends on SCx200_GPIO
        help
          This option enables support for the Soekris net4801 and net4826 error
@@ -79,18 +85,21 @@ config LEDS_NET5501
 
 config LEDS_FSG
        tristate "LED Support for the Freecom FSG-3"
+       depends on LEDS_CLASS
        depends on MACH_FSG
        help
          This option enables support for the LEDs on the Freecom FSG-3.
 
 config LEDS_WRAP
        tristate "LED Support for the WRAP series LEDs"
+       depends on LEDS_CLASS
        depends on SCx200_GPIO
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
 
 config LEDS_ALIX2
        tristate "LED Support for ALIX.2 and ALIX.3 series"
+       depends on LEDS_CLASS
        depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
        help
          This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
@@ -98,12 +107,14 @@ config LEDS_ALIX2
 
 config LEDS_H1940
        tristate "LED Support for iPAQ H1940 device"
+       depends on LEDS_CLASS
        depends on ARCH_H1940
        help
          This option enables support for the LEDs on the h1940.
 
 config LEDS_COBALT_QUBE
        tristate "LED Support for the Cobalt Qube series front LED"
+       depends on LEDS_CLASS
        depends on MIPS_COBALT
        help
          This option enables support for the front LED on Cobalt Qube series
@@ -117,6 +128,7 @@ config LEDS_COBALT_RAQ
 
 config LEDS_SUNFIRE
        tristate "LED support for SunFire servers."
+       depends on LEDS_CLASS
        depends on SPARC64
        select LEDS_TRIGGERS
        help
@@ -125,6 +137,7 @@ config LEDS_SUNFIRE
 
 config LEDS_HP6XX
        tristate "LED Support for the HP Jornada 6xx"
+       depends on LEDS_CLASS
        depends on SH_HP6XX
        help
          This option enables LED support for the handheld
@@ -132,6 +145,7 @@ config LEDS_HP6XX
 
 config LEDS_PCA9532
        tristate "LED driver for PCA9532 dimmer"
+       depends on LEDS_CLASS
        depends on I2C && INPUT && EXPERIMENTAL
        help
          This option enables support for NXP pca9532
@@ -140,6 +154,7 @@ config LEDS_PCA9532
 
 config LEDS_GPIO
        tristate "LED Support for GPIO connected LEDs"
+       depends on LEDS_CLASS
        depends on GENERIC_GPIO
        help
          This option enables support for the LEDs connected to GPIO
@@ -167,6 +182,7 @@ config LEDS_GPIO_OF
 
 config LEDS_LP3944
        tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for LEDs connected to the National
@@ -196,6 +212,7 @@ config LEDS_LP5523
 
 config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook"
+       depends on LEDS_CLASS
        depends on X86 && SERIO_I8042 && DMI
        help
          This driver makes the mail LED accessible from userspace
@@ -226,6 +243,7 @@ config LEDS_CLEVO_MAIL
 
 config LEDS_PCA955X
        tristate "LED Support for PCA955x I2C chips"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for LEDs connected to PCA955x
@@ -234,6 +252,7 @@ config LEDS_PCA955X
 
 config LEDS_WM831X_STATUS
        tristate "LED support for status LEDs on WM831x PMICs"
+       depends on LEDS_CLASS
        depends on MFD_WM831X
        help
          This option enables support for the status LEDs of the WM831x
@@ -241,6 +260,7 @@ config LEDS_WM831X_STATUS
 
 config LEDS_WM8350
        tristate "LED Support for WM8350 AudioPlus PMIC"
+       depends on LEDS_CLASS
        depends on MFD_WM8350
        help
          This option enables support for LEDs driven by the Wolfson
@@ -248,6 +268,7 @@ config LEDS_WM8350
 
 config LEDS_DA903X
        tristate "LED Support for DA9030/DA9034 PMIC"
+       depends on LEDS_CLASS
        depends on PMIC_DA903X
        help
          This option enables support for on-chip LED drivers found
@@ -255,6 +276,7 @@ config LEDS_DA903X
 
 config LEDS_DAC124S085
        tristate "LED Support for DAC124S085 SPI DAC"
+       depends on LEDS_CLASS
        depends on SPI
        help
          This option enables support for DAC124S085 SPI DAC from NatSemi,
@@ -262,18 +284,21 @@ config LEDS_DAC124S085
 
 config LEDS_PWM
        tristate "PWM driven LED Support"
+       depends on LEDS_CLASS
        depends on HAVE_PWM
        help
          This option enables support for pwm driven LEDs
 
 config LEDS_REGULATOR
        tristate "REGULATOR driven LED support"
+       depends on LEDS_CLASS
        depends on REGULATOR
        help
          This option enables support for regulator driven LEDs.
 
 config LEDS_BD2802
        tristate "LED driver for BD2802 RGB LED"
+       depends on LEDS_CLASS
        depends on I2C
        help
          This option enables support for BD2802GU RGB LED driver chips
@@ -281,6 +306,7 @@ config LEDS_BD2802
 
 config LEDS_INTEL_SS4200
        tristate "LED driver for Intel NAS SS4200 series"
+       depends on LEDS_CLASS
        depends on PCI && DMI
        help
          This option enables support for the Intel SS4200 series of
@@ -290,6 +316,7 @@ config LEDS_INTEL_SS4200
 
 config LEDS_LT3593
        tristate "LED driver for LT3593 controllers"
+       depends on LEDS_CLASS
        depends on GENERIC_GPIO
        help
          This option enables support for LEDs driven by a Linear Technology
@@ -298,6 +325,7 @@ config LEDS_LT3593
 
 config LEDS_ADP5520
        tristate "LED Support for ADP5520/ADP5501 PMIC"
+       depends on LEDS_CLASS
        depends on PMIC_ADP5520
        help
          This option enables support for on-chip LED drivers found
@@ -308,6 +336,7 @@ config LEDS_ADP5520
 
 config LEDS_DELL_NETBOOKS
        tristate "External LED on Dell Business Netbooks"
+       depends on LEDS_CLASS
        depends on X86 && ACPI_WMI
        help
          This adds support for the Latitude 2100 and similar
@@ -315,6 +344,7 @@ config LEDS_DELL_NETBOOKS
 
 config LEDS_MC13783
        tristate "LED Support for MC13783 PMIC"
+       depends on LEDS_CLASS
        depends on MFD_MC13783
        help
          This option enable support for on-chip LED drivers found
@@ -322,6 +352,7 @@ config LEDS_MC13783
 
 config LEDS_NS2
        tristate "LED support for Network Space v2 GPIO LEDs"
+       depends on LEDS_CLASS
        depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
        default y
        help
@@ -340,17 +371,17 @@ config LEDS_NETXBIG
 
 config LEDS_TRIGGERS
        bool "LED Trigger support"
+       depends on LEDS_CLASS
        help
          This option enables trigger support for the leds class.
          These triggers allow kernel events to drive the LEDs and can
          be configured via sysfs. If unsure, say Y.
 
-if LEDS_TRIGGERS
-
 comment "LED Triggers"
 
 config LEDS_TRIGGER_TIMER
        tristate "LED Timer Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a programmable timer
          via sysfs. Some LED hardware can be programmed to start
@@ -362,12 +393,14 @@ config LEDS_TRIGGER_TIMER
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
        depends on IDE_GD_ATA
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
 
 config LEDS_TRIGGER_HEARTBEAT
        tristate "LED Heartbeat Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a CPU load average.
          The flash frequency is a hyperbolic function of the 1-minute
@@ -376,6 +409,7 @@ config LEDS_TRIGGER_HEARTBEAT
 
 config LEDS_TRIGGER_BACKLIGHT
        tristate "LED backlight Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled as a backlight device: they
          turn off and on when the display is blanked and unblanked.
@@ -384,6 +418,7 @@ config LEDS_TRIGGER_BACKLIGHT
 
 config LEDS_TRIGGER_GPIO
        tristate "LED GPIO Trigger"
+       depends on LEDS_TRIGGERS
        depends on GPIOLIB
        help
          This allows LEDs to be controlled by gpio events. It's good
@@ -396,6 +431,7 @@ config LEDS_TRIGGER_GPIO
 
 config LEDS_TRIGGER_DEFAULT_ON
        tristate "LED Default ON Trigger"
+       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be initialised in the ON state.
          If unsure, say Y.
@@ -403,8 +439,4 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
        depends on LEDS_TRIGGERS
 
-endif # LEDS_TRIGGERS
-
-endif # LEDS_CLASS
-
 endif # NEW_LEDS
index 3782f31f06d20b413463e5f198c77bc9f4434bde..33facd0c45d10c146867cbf2e74c050a360166b5 100644 (file)
@@ -125,11 +125,22 @@ struct lp5521_chip {
        u8                      num_leds;
 };
 
-#define cdev_to_led(c)         container_of(c, struct lp5521_led, cdev)
-#define engine_to_lp5521(eng)  container_of((eng), struct lp5521_chip, \
-                                               engines[(eng)->id - 1])
-#define led_to_lp5521(led)     container_of((led), struct lp5521_chip, \
-                                               leds[(led)->id])
+static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev)
+{
+       return container_of(cdev, struct lp5521_led, cdev);
+}
+
+static inline struct lp5521_chip *engine_to_lp5521(struct lp5521_engine *engine)
+{
+       return container_of(engine, struct lp5521_chip,
+                           engines[engine->id - 1]);
+}
+
+static inline struct lp5521_chip *led_to_lp5521(struct lp5521_led *led)
+{
+       return container_of(led, struct lp5521_chip,
+                           leds[led->id]);
+}
 
 static void lp5521_led_brightness_work(struct work_struct *work);
 
@@ -185,14 +196,17 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
 
        /* move current engine to direct mode and remember the state */
        ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
        ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode);
 
        /* For loading, all the engines to load mode */
        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
 
        addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE;
        i2c_smbus_write_i2c_block_data(client,
@@ -231,10 +245,6 @@ static int lp5521_configure(struct i2c_client *client,
 
        lp5521_init_engine(chip, attr_group);
 
-       lp5521_write(client, LP5521_REG_RESET, 0xff);
-
-       usleep_range(10000, 20000);
-
        /* Set all PWMs to direct control mode */
        ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
 
@@ -251,8 +261,8 @@ static int lp5521_configure(struct i2c_client *client,
        ret |= lp5521_write(client, LP5521_REG_ENABLE,
                        LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
                        LP5521_EXEC_RUN);
-       /* enable takes 500us */
-       usleep_range(500, 20000);
+       /* enable takes 500us. 1 - 2 ms leaves some margin */
+       usleep_range(1000, 2000);
 
        return ret;
 }
@@ -305,7 +315,8 @@ static int lp5521_detect(struct i2c_client *client)
                        LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
        if (ret)
                return ret;
-       usleep_range(1000, 10000);
+       /* enable takes 500us. 1 - 2 ms leaves some margin */
+       usleep_range(1000, 2000);
        ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
        if (ret)
                return ret;
@@ -693,11 +704,16 @@ static int lp5521_probe(struct i2c_client *client,
 
        if (pdata->enable) {
                pdata->enable(0);
-               usleep_range(1000, 10000);
+               usleep_range(1000, 2000); /* Keep enable down at least 1ms */
                pdata->enable(1);
-               usleep_range(1000, 10000); /* Spec says min 500us */
+               usleep_range(1000, 2000); /* 500us abs min. */
        }
 
+       lp5521_write(client, LP5521_REG_RESET, 0xff);
+       usleep_range(10000, 20000); /*
+                                    * Exact value is not available. 10 - 20ms
+                                    * appears to be enough for reset.
+                                    */
        ret = lp5521_detect(client);
 
        if (ret) {
index 1e11fcc08b285b9c7d61590621616bba6ad78411..0cc4ead2fd8b35cdeef653a211b40a2e885b1630 100644 (file)
@@ -134,15 +134,18 @@ struct lp5523_chip {
        u8                      num_leds;
 };
 
-#define cdev_to_led(c)          container_of(c, struct lp5523_led, cdev)
+static inline struct lp5523_led *cdev_to_led(struct led_classdev *cdev)
+{
+       return container_of(cdev, struct lp5523_led, cdev);
+}
 
-static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
+static inline struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
 {
        return container_of(engine, struct lp5523_chip,
                            engines[engine->id - 1]);
 }
 
-static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
+static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
 {
        return container_of(led, struct lp5523_chip,
                            leds[led->id]);
@@ -200,13 +203,9 @@ static int lp5523_configure(struct i2c_client *client)
                { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
        };
 
-       lp5523_write(client, LP5523_REG_RESET, 0xff);
-
-       usleep_range(10000, 100000);
-
        ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
-       /* Chip startup time after reset is 500 us */
-       usleep_range(1000, 10000);
+       /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
+       usleep_range(1000, 2000);
 
        ret |= lp5523_write(client, LP5523_REG_CONFIG,
                            LP5523_AUTO_INC | LP5523_PWR_SAVE |
@@ -243,8 +242,8 @@ static int lp5523_configure(struct i2c_client *client)
                return -1;
        }
 
-       /* Wait 3ms and check the engine status */
-       usleep_range(3000, 20000);
+       /* Let the programs run for couple of ms and check the engine status */
+       usleep_range(3000, 6000);
        lp5523_read(client, LP5523_REG_STATUS, &status);
        status &= LP5523_ENG_STATUS_MASK;
 
@@ -449,10 +448,10 @@ static ssize_t lp5523_selftest(struct device *dev,
        /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
        lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL,
                                    LP5523_EN_LEDTEST | 16);
-       usleep_range(3000, 10000);
+       usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
        ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
        if (!(status & LP5523_LEDTEST_DONE))
-               usleep_range(3000, 10000);
+               usleep_range(3000, 6000); /* Was not ready. Wait little bit */
 
        ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
        vdd--;  /* There may be some fluctuation in measurement */
@@ -468,16 +467,16 @@ static ssize_t lp5523_selftest(struct device *dev,
                        chip->pdata->led_config[i].led_current);
 
                lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff);
-               /* let current stabilize 2ms before measurements start */
-               usleep_range(2000, 10000);
+               /* let current stabilize 2 - 4ms before measurements start */
+               usleep_range(2000, 4000);
                lp5523_write(chip->client,
                             LP5523_REG_LED_TEST_CTRL,
                             LP5523_EN_LEDTEST | i);
-               /* ledtest takes 2.7ms */
-               usleep_range(3000, 10000);
+               /* ADC conversion time is 2.7 ms typically */
+               usleep_range(3000, 6000);
                ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
                if (!(status & LP5523_LEDTEST_DONE))
-                       usleep_range(3000, 10000);
+                       usleep_range(3000, 6000);/* Was not ready. Wait. */
                ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
 
                if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
@@ -930,11 +929,16 @@ static int lp5523_probe(struct i2c_client *client,
 
        if (pdata->enable) {
                pdata->enable(0);
-               usleep_range(1000, 10000);
+               usleep_range(1000, 2000); /* Keep enable down at least 1ms */
                pdata->enable(1);
-               usleep_range(1000, 10000); /* Spec says min 500us */
+               usleep_range(1000, 2000); /* 500us abs min. */
        }
 
+       lp5523_write(client, LP5523_REG_RESET, 0xff);
+       usleep_range(10000, 20000); /*
+                                    * Exact value is not available. 10 - 20ms
+                                    * appears to be enough for reset.
+                                    */
        ret = lp5523_detect(client);
        if (ret)
                goto fail2;
index a688293abd0b43a0f9e8135d0ce4d43812307f0a..614ebebaaa28cdcf7d7c765b1c0c959fd7ac4782 100644 (file)
@@ -102,6 +102,7 @@ static struct dmi_system_id __initdata nas_led_whitelist[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
                }
        },
+       {}
 };
 
 /*
index 3d7355ff7308eac1e578092149027bc54809ee84..fa51af11c6f1e9d927967753b86530ea45a2b600 100644 (file)
@@ -102,6 +102,7 @@ config ADB_PMU_LED
 config ADB_PMU_LED_IDE
        bool "Use front LED as IDE LED by default"
        depends on ADB_PMU_LED
+       depends on LEDS_CLASS
        select LEDS_TRIGGERS
        select LEDS_TRIGGER_IDE_DISK
        help
index 324a3663fcdaa35dc9d0553f532543aa8019dd38..84c46a161927999ebfc6c5d56d98e76247e66ae4 100644 (file)
@@ -1337,7 +1337,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
        md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
                       rdev->sb_page);
        md_super_wait(rdev->mddev);
-       return num_sectors / 2; /* kB for sysfs */
+       return num_sectors;
 }
 
 
@@ -1704,7 +1704,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
        md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
                       rdev->sb_page);
        md_super_wait(rdev->mddev);
-       return num_sectors / 2; /* kB for sysfs */
+       return num_sectors;
 }
 
 static struct super_type super_types[] = {
@@ -4338,6 +4338,8 @@ static int md_alloc(dev_t dev, char *name)
        if (mddev->kobj.sd &&
            sysfs_create_group(&mddev->kobj, &md_bitmap_group))
                printk(KERN_DEBUG "pointless warning\n");
+
+       blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA);
  abort:
        mutex_unlock(&disks_mutex);
        if (!error && mddev->kobj.sd) {
index 45f8324196ec61c86cd7164868e3f8bc66ada03c..845cf95b612c452b799033f6b4f4a2903715b623 100644 (file)
@@ -1161,6 +1161,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
                 * is not possible.
                 */
                if (!test_bit(Faulty, &rdev->flags) &&
+                   !mddev->recovery_disabled &&
                    mddev->degraded < conf->raid_disks) {
                        err = -EBUSY;
                        goto abort;
index 2385e6cca63589f6ffff1445a4d2a564ef743207..78b089526e028745a30f32bccc90cd384ba632b3 100644 (file)
@@ -31,7 +31,7 @@ config MEDIA_TUNER
        select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
 
-menuconfig MEDIA_TUNER_CUSTOMISE
+config MEDIA_TUNER_CUSTOMISE
        bool "Customize analog and hybrid tuner modules to build"
        depends on MEDIA_TUNER
        default y if EMBEDDED
@@ -44,7 +44,8 @@ menuconfig MEDIA_TUNER_CUSTOMISE
 
          If unsure say N.
 
-if MEDIA_TUNER_CUSTOMISE
+menu "Customize TV tuners"
+       visible if MEDIA_TUNER_CUSTOMISE
 
 config MEDIA_TUNER_SIMPLE
        tristate "Simple tuner support"
@@ -185,5 +186,4 @@ config MEDIA_TUNER_TDA18218
        default m if MEDIA_TUNER_CUSTOMISE
        help
          NXP TDA18218 silicon tuner driver.
-
-endif # MEDIA_TUNER_CUSTOMISE
+endmenu
index 4d0646da6087b05e02c87767232417c2b1f94d93..7ea517b7e18626fd5723c255cb0aee2a102970a8 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 
 #include "dvb_ca_en50221.h"
index 1589d5a5cb4696ab2114019780866aab93622135..cad6634610ea5fb0d6ea59e6c86e322bd1e9638e 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/list.h>
 #include <linux/freezer.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 #include <asm/processor.h>
 
index e9062b08a4857e39896ca14adeebdbd300907d18..96b27016670e3c7f18091e167057172767271feb 100644 (file)
@@ -12,9 +12,8 @@ config DVB_FE_CUSTOMISE
 
          If unsure say N.
 
-if DVB_FE_CUSTOMISE
-
 menu "Customise DVB Frontends"
+       visible if DVB_FE_CUSTOMISE
 
 comment "Multistandard (satellite) frontends"
        depends on DVB_CORE
@@ -619,5 +618,3 @@ config DVB_DUMMY_FE
        tristate "Dummy frontend driver"
        default n
 endmenu
-
-endif
index 4caeb163a66668da958cdae28058c2e0bb67a3af..3a7ef71087be7110174df8df4968bc65b995a04f 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index 48f980b21d663ad94b89b17689d62737104b6ac4..3832e5983c19104b92c29d273392dfdae53cc074 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index c3ae956714e77501954d17bc1a34843200365b2f..d28554f8ce9961f1102a9a22e8f28d71f057e7cd 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/div64.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/byteorder/generic.h>
 #include <linux/firmware.h>
index b540e8072e9295ca8551e65858e5f2670e381d0c..e6b2d085a449ae0a7ba4a424a70014e5a03b7112 100644 (file)
@@ -58,7 +58,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
index 6a435786b63d96ee099aedceee8dca026f9ca935..03829e6818bd4bc156d922c7c19ee8daaabc0fc8 100644 (file)
@@ -291,7 +291,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
                goto unregister_v4l2_dev;
        }
 
-       sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL,
+       sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter,
                                        pdata->subdev_board_info, NULL);
        if (!sd) {
                dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
index ea12782359a024d415dcda5cc87f724ba423f7ae..b9914d7a0c9ffeef06a0b7f02bd2f82c10f1dd9f 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
index ac16e815e2750e2e8e37295b082f6a7da988a0a1..6830d2848bd7f911d5084dcd7a757366a8567dc5 100644 (file)
@@ -112,7 +112,7 @@ config VIDEO_IR_I2C
 #
 
 menu "Encoders/decoders and other helper chips"
-       depends on !VIDEO_HELPER_CHIPS_AUTO
+       visible if !VIDEO_HELPER_CHIPS_AUTO
 
 comment "Audio decoders"
 
index 0453816d4ec3a1e2f910b724c294224ccbd6eb20..01be89fa5c7896e7595f3fde2047db16f160121a 100644 (file)
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
                   be abstracted out if we ever need to support a different
                   demod) */
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "au8522", 0x8e >> 1, NULL);
+                               "au8522", 0x8e >> 1, NULL);
                if (sd == NULL)
                        printk(KERN_ERR "analog subdev registration failed\n");
        }
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
        if (dev->board.tuner_type != TUNER_ABSENT) {
                /* Load the tuner module, which does the attach */
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->board.tuner_addr, NULL);
+                               "tuner", dev->board.tuner_addr, NULL);
                if (sd == NULL)
                        printk(KERN_ERR "tuner subdev registration fail\n");
 
index 87d8b006ef77deb182ace69eae34da0ce7db7348..49efcf660ba66cad6dc1e796beb23ea6282b7ca0 100644 (file)
@@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "saa6588", 0, addrs);
+                       &btv->c.i2c_adap, "saa6588", 0, addrs);
                btv->has_saa6588 = (sd != NULL);
        }
 
@@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400", 0, addrs);
+                       &btv->c.i2c_adap, "msp3400", 0, addrs);
                if (btv->sd_msp34xx)
                        return;
                goto no_audio;
@@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+                               &btv->c.i2c_adap, "tda7432", 0, addrs))
                        return;
                goto no_audio;
        }
@@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
        case 3: {
                /* The user specified that we should probe for tvaudio */
                btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+                       &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
                if (btv->sd_tvaudio)
                        return;
                goto no_audio;
@@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv)
           found is really something else (e.g. a tea6300). */
        if (!bttv_tvcards[btv->c.type].no_msp34xx) {
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400",
+                       &btv->c.i2c_adap, "msp3400",
                        0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
        } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
                btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                       &btv->c.i2c_adap, NULL, "msp3400",
+                       &btv->c.i2c_adap, "msp3400",
                        0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
        }
 
@@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
                };
 
                if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+                               &btv->c.i2c_adap, "tda7432", 0, addrs))
                        return;
        }
 
        /* Now see if we can find one of the tvaudio devices. */
        btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-               &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+               &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
        if (btv->sd_tvaudio)
                return;
 
@@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv)
                /* Load tuner module before issuing tuner config call! */
                if (bttv_tvcards[btv->c.type].has_radio)
                        v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
                v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
-                               &btv->c.i2c_adap, NULL, "tuner",
+                               &btv->c.i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
 
                tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
index 3da6e80e1041358e594836fbd9b8146b4dfedb7d..a529619e51f687d1386c6c673a0feaa9ba8d517a 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include "bttvp.h"
index 7bc36670071a8ba333ed0d67999d5f9079adc895..260c666ce9317266fb271ffead70ea1605e99db1 100644 (file)
@@ -2066,8 +2066,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 
        cam->sensor_addr = 0x42;
        cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
-                       "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr,
-                       NULL);
+                       "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
        if (cam->sensor == NULL) {
                ret = -ENODEV;
                goto out_smbus;
index a09caf8831705b3381892eb72b8e8304918eb5b9..e71a026f3419140a314217b923c428d25e9b9f73 100644 (file)
@@ -122,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
        if (hw == CX18_HW_TUNER) {
                /* special tuner group handling */
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->radio);
+                               adap, type, 0, cx->card_i2c->radio);
                if (sd != NULL)
                        sd->grp_id = hw;
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->demod);
+                               adap, type, 0, cx->card_i2c->demod);
                if (sd != NULL)
                        sd->grp_id = hw;
                sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
-                               adap, NULL, type, 0, cx->card_i2c->tv);
+                               adap, type, 0, cx->card_i2c->tv);
                if (sd != NULL)
                        sd->grp_id = hw;
                return sd != NULL ? 0 : -1;
@@ -144,7 +144,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
                return -1;
 
        /* It's an I2C device other than an analog tuner or IR chip */
-       sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx],
+       sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
                                 NULL);
        if (sd != NULL)
                sd->grp_id = hw;
index 56c2d8195ac6fb301f27016f18543fa13c5b4904..2c78d188bb0650dcd9c33b5a5495cf568c49043a 100644 (file)
@@ -560,7 +560,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
        if (dev->board.decoder == CX231XX_AVDECODER) {
                dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                        &dev->i2c_bus[0].i2c_adap,
-                                       NULL, "cx25840", 0x88 >> 1, NULL);
+                                       "cx25840", 0x88 >> 1, NULL);
                if (dev->sd_cx25840 == NULL)
                        cx231xx_info("cx25840 subdev registration failure\n");
                cx25840_call(dev, core, load_fw);
@@ -571,7 +571,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
        if (dev->board.tuner_type != TUNER_ABSENT) {
                dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                                    &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
-                                                   NULL, "tuner",
+                                                   "tuner",
                                                    dev->tuner_addr, NULL);
                if (dev->sd_tuner == NULL)
                        cx231xx_info("tuner subdev registration failure\n");
index db054004e462fe4f0fab90705066b24ae3a4abed..8861309268b170d8f6effd11b17365e11ea846a5 100644 (file)
@@ -1247,7 +1247,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
        case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
                dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                &dev->i2c_bus[2].i2c_adap,
-                               NULL, "cx25840", 0x88 >> 1, NULL);
+                               "cx25840", 0x88 >> 1, NULL);
                if (dev->sd_cx25840) {
                        dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
                        v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
index 3cc9f462d08d9d1d391b8cfcec5fbebc6b6c66d4..8b2fb8a4375cf21313d766eaec0e35f41aacf9d7 100644 (file)
@@ -1507,10 +1507,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
                if (dev->tuner_addr)
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                &dev->i2c_bus[1].i2c_adap,
-                               NULL, "tuner", dev->tuner_addr, NULL);
+                               "tuner", dev->tuner_addr, NULL);
                else
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_bus[1].i2c_adap, NULL,
+                               &dev->i2c_bus[1].i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
                if (sd) {
                        struct tuner_setup tun_setup;
index 417d1d5c73c4fead58a7c0133454debaed8a7f73..d7c94848249e1252018e58e25417d6fdd710cc47 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
index b26fcba8600cf49bb4761f3194958e093081f0c1..9b9e169cce90862ee92f7d80ab7851cdb3cf81cb 100644 (file)
@@ -3515,19 +3515,18 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
                   later code configures a tea5767.
                 */
                v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "tuner",
-                               0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+                               "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
                if (has_demod)
                        v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap, NULL, "tuner",
+                               &core->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (core->board.tuner_addr == ADDR_UNSET) {
                        v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap, NULL, "tuner",
+                               &core->i2c_adap, "tuner",
                                0, has_demod ? tv_addrs + 4 : tv_addrs);
                } else {
                        v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "tuner", core->board.tuner_addr, NULL);
+                               "tuner", core->board.tuner_addr, NULL);
                }
        }
 
index d2f159daa8b506d34c5f027f8650a64a7518d184..62cea9549404bf29d3d58e004af015dcb132f779 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
@@ -1896,14 +1895,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 
        if (core->board.audio_chip == V4L2_IDENT_WM8775)
                v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               NULL, "wm8775", 0x36 >> 1, NULL);
+                               "wm8775", 0x36 >> 1, NULL);
 
        if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
                /* This probes for a tda9874 as is used on some
                   Pixelview Ultra boards. */
-               v4l2_i2c_new_subdev(&core->v4l2_dev,
-                               &core->i2c_adap,
-                               NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
+               v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+                               "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
        }
 
        switch (core->boardnr) {
index d8e38cc4ec40c8b1a7dd8803f3d6e6b8e0d95bff..7333a9bb2549deeffc8b122d16406a6308f4b812 100644 (file)
@@ -1986,7 +1986,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
                vpfe_dev->sd[i] =
                        v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
                                                  i2c_adap,
-                                                 NULL,
                                                  &sdinfo->board_info,
                                                  NULL);
                if (vpfe_dev->sd[i]) {
index 6ac6acd16352b6ee4f277a1790b74d0c5c2a56fc..193abab6b355e90b619a3a57d4ab434a551640b5 100644 (file)
@@ -2013,7 +2013,6 @@ static __init int vpif_probe(struct platform_device *pdev)
                vpif_obj.sd[i] =
                        v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
                                                  i2c_adap,
-                                                 NULL,
                                                  &subdevdata->board_info,
                                                  NULL);
 
index 685f6a6ee603cf40456d17c80c5fe9ef9a526909..412c65d54fe1a3e9397aae9455edf49fc295862c 100644 (file)
@@ -1553,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
        for (i = 0; i < subdev_count; i++) {
                vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-                                               i2c_adap, NULL,
+                                               i2c_adap,
                                                &subdevdata[i].board_info,
                                                NULL);
                if (!vpif_obj.sd[i]) {
index 54859233f31188e3b1e4d6f7aed45b37113ae27a..f7e9168157a502d38b543ec89212984fa5620531 100644 (file)
@@ -2554,39 +2554,39 @@ void em28xx_card_setup(struct em28xx *dev)
        /* request some modules */
        if (dev->board.has_msp34xx)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "msp3400", 0, msp3400_addrs);
+                       "msp3400", 0, msp3400_addrs);
 
        if (dev->board.decoder == EM28XX_SAA711X)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "saa7115_auto", 0, saa711x_addrs);
+                       "saa7115_auto", 0, saa711x_addrs);
 
        if (dev->board.decoder == EM28XX_TVP5150)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvp5150", 0, tvp5150_addrs);
+                       "tvp5150", 0, tvp5150_addrs);
 
        if (dev->em28xx_sensor == EM28XX_MT9V011) {
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                        &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs);
+                        &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
                v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
        }
 
 
        if (dev->board.adecoder == EM28XX_TVAUDIO)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvaudio", dev->board.tvaudio_addr, NULL);
+                       "tvaudio", dev->board.tvaudio_addr, NULL);
 
        if (dev->board.tuner_type != TUNER_ABSENT) {
                int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
 
                if (dev->board.radio.type)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->board.radio_addr, NULL);
+                               "tuner", dev->board.radio_addr, NULL);
 
                if (has_demod)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (dev->tuner_addr == 0) {
                        enum v4l2_i2c_tuner_type type =
@@ -2594,14 +2594,14 @@ void em28xx_card_setup(struct em28xx *dev)
                        struct v4l2_subdev *sd;
 
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(type));
 
                        if (sd)
                                dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
                } else {
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "tuner", dev->tuner_addr, NULL);
+                               "tuner", dev->tuner_addr, NULL);
                }
        }
 
index 9a075d83dd1fcda95715b12bdf2ee38b2b1aa1fd..b8faff2dd711c7d2c014813996da862106f48d2c 100644 (file)
@@ -1486,7 +1486,7 @@ static int __devinit viu_of_probe(struct platform_device *op,
 
        ad = i2c_get_adapter(0);
        viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
-                       NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
+                       "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
 
        viu_dev->vidq.timeout.function = viu_vid_timeout;
        viu_dev->vidq.timeout.data     = (unsigned long)viu_dev;
index 9e8039ac909edeba272093a9d640abd021e975e8..665191c9b4079a2cae48f453c74832acb21d7b8d 100644 (file)
@@ -239,19 +239,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
                return -1;
        if (hw == IVTV_HW_TUNER) {
                /* special tuner handling */
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->radio);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->radio);
                if (sd)
                        sd->grp_id = 1 << idx;
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->demod);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->demod);
                if (sd)
                        sd->grp_id = 1 << idx;
-               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type,
-                               0, itv->card_i2c->tv);
+               sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+                               itv->card_i2c->tv);
                if (sd)
                        sd->grp_id = 1 << idx;
                return sd ? 0 : -1;
@@ -267,17 +264,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
        /* It's an I2C device other than an analog tuner or IR chip */
        if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
                sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx]));
+                               adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
        } else if (hw == IVTV_HW_CX25840) {
                struct cx25840_platform_data pdata;
 
                pdata.pvr150_workaround = itv->pvr150_workaround;
                sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
-                               adap, NULL, type, 0, &pdata, hw_addrs[idx],
-                               NULL);
+                               adap, type, 0, &pdata, hw_addrs[idx], NULL);
        } else {
                sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-                               adap, NULL, type, hw_addrs[idx], NULL);
+                               adap, type, hw_addrs[idx], NULL);
        }
        if (sd)
                sd->grp_id = 1 << idx;
index 94ba698d0ad4228d3d07e6653d594773c42ab3c0..4e8fd965f151c64f493f08f3c088c5055af79877 100644 (file)
@@ -185,17 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev)
        }
 
        mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "saa7111", I2C_SAA7111A, NULL);
+                       "saa7111", I2C_SAA7111A, NULL);
        mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6420", I2C_TEA6420_1, NULL);
+                       "tea6420", I2C_TEA6420_1, NULL);
        mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6420", I2C_TEA6420_2, NULL);
+                       "tea6420", I2C_TEA6420_2, NULL);
        mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tea6415c", I2C_TEA6415C, NULL);
+                       "tea6415c", I2C_TEA6415C, NULL);
        mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tda9840", I2C_TDA9840, NULL);
+                       "tda9840", I2C_TDA9840, NULL);
        mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-                       NULL, "tuner", I2C_TUNER, NULL);
+                       "tuner", I2C_TUNER, NULL);
 
        /* check if all devices are present */
        if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
index bef202752cc8da599aa08f05262c328628bd1e0a..66ad516bdfd97070380b1592d14be35ea978acc0 100644 (file)
@@ -2088,16 +2088,14 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
                           " Setting up with specified i2c address 0x%x",
                           mid, i2caddr[0]);
                sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
-                                        NULL, fname,
-                                        i2caddr[0], NULL);
+                                        fname, i2caddr[0], NULL);
        } else {
                pvr2_trace(PVR2_TRACE_INIT,
                           "Module ID %u:"
                           " Setting up with address probe list",
                           mid);
                sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
-                                               NULL, fname,
-                                               0, i2caddr);
+                                        fname, 0, i2caddr);
        }
 
        if (!sd) {
index e62beb4efdb472e811609ec96717013ca6ffa74d..f3dc89da4c4eefcd23f7c457c75322c5eb96b0c9 100644 (file)
@@ -62,7 +62,6 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 #include <linux/usb/input.h>
 #endif
index f5a46c45871713df2eab2c0f43bccff5717fc05d..a845753665c1ed267002353703877b33c9d8f1db 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
index e8f13d3e2df14f4b226ac50c6a798f506365f002..1b93207c89e84efbbf6a4e3e8357a7af7f32f90d 100644 (file)
@@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
                return ERR_PTR(-ENOMEM);
 
        sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap,
-                                      MODULE_NAME, isp_info->board_info, NULL);
+                                      isp_info->board_info, NULL);
        if (!sd) {
                v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n");
                return NULL;
index 0911cb580e186a61ac8a2f781eea1eee05954089..1d4d0a49ea52d78405b952acc8c4c2a2f9b844af 100644 (file)
@@ -7551,22 +7551,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                   so we do not need to probe for a radio tuner device. */
                if (dev->radio_type != UNSET)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                dev->radio_addr, NULL);
                if (has_demod)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (dev->tuner_addr == ADDR_UNSET) {
                        enum v4l2_i2c_tuner_type type =
                                has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(type));
                } else {
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "tuner",
+                               &dev->i2c_adap, "tuner",
                                dev->tuner_addr, NULL);
                }
        }
index 764d7d219fedb8bef804630b940d6a39a29e0649..756a27812260ac2882dfbfa384ca9b2e3a32be4d 100644 (file)
@@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
        if (card_is_empress(dev)) {
                struct v4l2_subdev *sd =
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                               NULL, "saa6752hs",
+                               "saa6752hs",
                                saa7134_boards[dev->board].empress_addr, NULL);
 
                if (sd)
@@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                struct v4l2_subdev *sd;
 
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-                               &dev->i2c_adap, NULL, "saa6588",
+                               &dev->i2c_adap, "saa6588",
                                0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
                if (sd) {
                        printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
index 1467a30a434fe29d677d3289d322e6d34a940cff..b890aafe7d640bcc141b2c6edddb3009d73c5245 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
index 1d9c5cbbbc52cbef4c8f4fe97719967b0f5250b7..041ae8e20f685fdd6a37831dca38862f5fa06927 100644 (file)
@@ -58,7 +58,6 @@
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
 #include <media/videobuf-dvb.h>
-#include <linux/smp_lock.h>
 #include <dvb_demux.h>
 #include <dvb_frontend.h>
 #include <dvb_net.h>
index 0f4906136b8f9d1fb48054c7b88903f53f00a218..4e5a8cf76dedf7807b5a11ef5369f3f86c3c537c 100644 (file)
@@ -1406,7 +1406,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
                goto ereset;
 
        subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
-                       NULL, vou_pdata->board_info, NULL);
+                       vou_pdata->board_info, NULL);
        if (!subdev) {
                ret = -ENOMEM;
                goto ei2cnd;
index 43848a751d11510c20b82205fe92bf43b2260aed..335120c2021bc2cdbf5de98b59f58cc001144ad5 100644 (file)
@@ -896,7 +896,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
        icl->board_info->platform_data = icd;
 
        subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
-                               NULL, icl->board_info, NULL);
+                               icl->board_info, NULL);
        if (!subdev)
                goto ei2cnd;
 
index e3bbae26e3ce7c7112f6abce46a41e856424b056..81dd53bb52673c5e5efdc1ba20a9b73429e80cfc 100644 (file)
@@ -251,7 +251,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
                   hit-and-miss. */
                mdelay(10);
                v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "saa7115_auto", 0, saa711x_addrs);
                break;
        }
@@ -261,14 +261,14 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
                struct tuner_setup tun_setup;
 
                sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                /* depending on whether we found a demod or not, select
                   the tuner type. */
                type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
                sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
-                               &usbvision->i2c_adap, NULL,
+                               &usbvision->i2c_adap,
                                "tuner", 0, v4l2_i2c_tuner_addrs(type));
 
                if (sd == NULL)
index db6b828594f513ac562485692e918f63798e41dc..011c0c386995966cddaba715a7b13ced0a122a61 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
index 9294282b5add27c04ada832d498f7f11aa0ef323..b5eb1f3950b133c6ed76b5e32adc894b07fb3bdf 100644 (file)
@@ -368,18 +368,15 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
 /* Load an i2c sub-device. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter, const char *module_name,
-               struct i2c_board_info *info, const unsigned short *probe_addrs)
+               struct i2c_adapter *adapter, struct i2c_board_info *info,
+               const unsigned short *probe_addrs)
 {
        struct v4l2_subdev *sd = NULL;
        struct i2c_client *client;
 
        BUG_ON(!v4l2_dev);
 
-       if (module_name)
-               request_module(module_name);
-       else
-               request_module(I2C_MODULE_PREFIX "%s", info->type);
+       request_module(I2C_MODULE_PREFIX "%s", info->type);
 
        /* Create the i2c client */
        if (info->addr == 0 && probe_addrs)
@@ -432,8 +429,7 @@ error:
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
 
 struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                int irq, void *platform_data,
                u8 addr, const unsigned short *probe_addrs)
 {
@@ -447,8 +443,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
        info.irq = irq;
        info.platform_data = platform_data;
 
-       return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
-                       &info, probe_addrs);
+       return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
 
index 86294ed35c9b643cc7bab7411904476d0f7467a7..e30e8dfb62052b70bf8d596c80c697d6a23405f3 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <media/v4l2-ioctl.h>
 
 #ifdef CONFIG_COMPAT
index 02a21bccae1836b464455eb14d6e64788715f228..9eda7cc03121c1c1ceb3632fca58bff4e8701ca8 100644 (file)
@@ -1360,7 +1360,7 @@ static __devinit int viacam_probe(struct platform_device *pdev)
         */
        sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
        cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter,
-                       "ov7670", "ov7670", 0x42 >> 1, NULL);
+                       "ov7670", 0x42 >> 1, NULL);
        if (cam->sensor == NULL) {
                dev_err(&pdev->dev, "Unable to find the sensor!\n");
                ret = -ENODEV;
index e5e005dc15543a2ab7d86aa6c0331ff60b540f46..7e7eec48f8b12bd305a6f92539ba650ec727f9f2 100644 (file)
@@ -4334,10 +4334,10 @@ static int __init vino_module_init(void)
 
        vino_drvdata->decoder =
                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
-                              NULL, "saa7191", 0, I2C_ADDRS(0x45));
+                              "saa7191", 0, I2C_ADDRS(0x45));
        vino_drvdata->camera =
                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
-                              NULL, "indycam", 0, I2C_ADDRS(0x2b));
+                              "indycam", 0, I2C_ADDRS(0x2b));
 
        dprintk("init complete!\n");
 
index 7e6d62467eaaa7bd1e913d5ce104608005ccbc58..e520abf9f4c3d8fc40d108ef2fbf47e55db772f5 100644 (file)
@@ -1343,13 +1343,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
        }
 
        zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
-               &zr->i2c_adapter, NULL, zr->card.i2c_decoder,
+               &zr->i2c_adapter, zr->card.i2c_decoder,
                0, zr->card.addrs_decoder);
 
        if (zr->card.i2c_encoder)
                zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
-                       &zr->i2c_adapter,
-                       NULL, zr->card.i2c_encoder,
+                       &zr->i2c_adapter, zr->card.i2c_encoder,
                        0, zr->card.addrs_encoder);
 
        dprintk(2,
index e15220ff52fc7b150da7a11e04c1f7d84c4a5d55..d784c36707c0b12c318c1f2be20fe98b425eabad 100644 (file)
@@ -97,8 +97,7 @@ static u8     mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
 
 static int mptfc_target_alloc(struct scsi_target *starget);
 static int mptfc_slave_alloc(struct scsi_device *sdev);
-static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
-                     void (*done)(struct scsi_cmnd *));
+static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
 static void mptfc_target_destroy(struct scsi_target *starget);
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void __devexit mptfc_remove(struct pci_dev *pdev);
@@ -650,7 +649,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
 }
 
 static int
-mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        struct mptfc_rport_info *ri;
        struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
@@ -681,6 +680,8 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptfc_qcmd)
+
 /*
  *     mptfc_display_port_link_speed - displaying link speed
  *     @ioc: Pointer to MPT_ADAPTER structure
index 83a5115f025113d89eb2c793901b443691d5f397..d48c2c6058e1d12f62316d2541cd36dfdb27daaa 100644 (file)
@@ -1889,7 +1889,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
 }
 
 static int
-mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        MPT_SCSI_HOST   *hd;
        MPT_ADAPTER     *ioc;
@@ -1913,6 +1913,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptsas_qcmd)
+
 /**
  *     mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
  *             if the device under question is currently in the
index 0e2803155ae20a1cacb1d67037e4d7de0d6155e8..6d9568d2ec59693235e2bf886c6daf46199e659f 100644 (file)
@@ -780,7 +780,7 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
 }
 
 static int
-mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptspi_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
        VirtDevice      *vdevice = SCpnt->device->hostdata;
@@ -805,6 +805,8 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return mptscsih_qcmd(SCpnt,done);
 }
 
+static DEF_SCSI_QCMD(mptspi_qcmd)
+
 static void mptspi_slave_destroy(struct scsi_device *sdev)
 {
        struct scsi_target *starget = scsi_target(sdev);
index ea6b2197da8a2fc38afd18aaebd3d0a32338a993..97bdf82ec9059ddced228220d21bbb3e64dc2b99 100644 (file)
@@ -506,7 +506,7 @@ static struct i2o_driver i2o_scsi_driver = {
  *     Locks: takes the controller lock on error path only
  */
 
-static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+static int i2o_scsi_queuecommand_lck(struct scsi_cmnd *SCpnt,
                                 void (*done) (struct scsi_cmnd *))
 {
        struct i2o_controller *c;
@@ -688,7 +688,9 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 
       exit:
        return rc;
-};
+}
+
+static DEF_SCSI_QCMD(i2o_scsi_queuecommand)
 
 /**
  *     i2o_scsi_abort - abort a running command
index ca47e62850752b80772bd3d77a246bfe1109b742..307aada5fffeca067520a55eecb6c020c80bd7a6 100644 (file)
@@ -183,9 +183,7 @@ static int  isl29020_probe(struct i2c_client *client,
 
 static int isl29020_remove(struct i2c_client *client)
 {
-       struct als_data *data = i2c_get_clientdata(client);
        sysfs_remove_group(&client->dev.kobj, &m_als_gr);
-       kfree(data);
        return 0;
 }
 
@@ -245,6 +243,6 @@ static void  __exit sensor_isl29020_exit(void)
 module_init(sensor_isl29020_init);
 module_exit(sensor_isl29020_exit);
 
-MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
 MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
 MODULE_LICENSE("GPL v2");
index d551f09ccb792175d49a83c4a929df7394f50a8a..6956f7e7d43921ec80f5e450a471429bc21f55fc 100644 (file)
@@ -439,18 +439,23 @@ xpc_discovery(void)
         * nodes that can comprise an access protection grouping. The access
         * protection is in regards to memory, IOI and IPI.
         */
-       max_regions = 64;
        region_size = xp_region_size;
 
-       switch (region_size) {
-       case 128:
-               max_regions *= 2;
-       case 64:
-               max_regions *= 2;
-       case 32:
-               max_regions *= 2;
-               region_size = 16;
-               DBUG_ON(!is_shub2());
+       if (is_uv())
+               max_regions = 256;
+       else {
+               max_regions = 64;
+
+               switch (region_size) {
+               case 128:
+                       max_regions *= 2;
+               case 64:
+                       max_regions *= 2;
+               case 32:
+                       max_regions *= 2;
+                       region_size = 16;
+                       DBUG_ON(!is_shub2());
+               }
        }
 
        for (region = 0; region < max_regions; region++) {
index 8f86d702e46eebce56bdb00f6f22d4d6b8205100..31ae07a36576678fb27dbd294623f6f8ac21cc9d 100644 (file)
@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)
 
        if (host->caps & MMC_CAP_DISABLE)
                cancel_delayed_work(&host->disable);
-       cancel_delayed_work(&host->detect);
+       cancel_delayed_work_sync(&host->detect);
        mmc_flush_scheduled_work();
 
        /* clear pm flags now and let card drivers set them as needed */
index 995261f7fd70165e92caa8a3ec16f0e75e2e2fcc..77f93c3b88086d5ee802da97ae03754d86c82e9a 100644 (file)
@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        struct mmc_card *oldcard)
 {
        struct mmc_card *card;
-       int err, ddr = MMC_SDR_MODE;
+       int err, ddr = 0;
        u32 cid[4];
        unsigned int max_dtr;
 
@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                               1 << bus_width, ddr);
                        err = 0;
                } else {
-                       mmc_card_set_ddr_mode(card);
+                       if (ddr)
+                               mmc_card_set_ddr_mode(card);
+                       else
+                               ddr = MMC_SDR_MODE;
+
                        mmc_set_bus_width_ddr(card->host, bus_width, ddr);
                }
        }
index c3ad1058cd318627b8290c756c6a2f2e0d2d8027..efef5f94ac429081c5211a984a100b575c5fd986 100644 (file)
@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
        BUG_ON(!host->card);
 
        /* Make sure card is powered before detecting it */
-       err = pm_runtime_get_sync(&host->card->dev);
-       if (err < 0)
-               goto out;
+       if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+               err = pm_runtime_get_sync(&host->card->dev);
+               if (err < 0)
+                       goto out;
+       }
 
        mmc_claim_host(host);
 
@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host)
 
        mmc_release_host(host);
 
+       /*
+        * Tell PM core it's OK to power off the card now.
+        *
+        * The _sync variant is used in order to ensure that the card
+        * is left powered off in case an error occurred, and the card
+        * is going to be removed.
+        *
+        * Since there is no specific reason to believe a new user
+        * is about to show up at this point, the _sync variant is
+        * desirable anyway.
+        */
+       if (host->caps & MMC_CAP_POWER_OFF_CARD)
+               pm_runtime_put_sync(&host->card->dev);
+
 out:
        if (err) {
                mmc_sdio_remove(host);
@@ -568,9 +584,6 @@ out:
                mmc_detach_bus(host);
                mmc_release_host(host);
        }
-
-       /* Tell PM core that we're done */
-       pm_runtime_put(&host->card->dev);
 }
 
 /*
@@ -718,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
        card = host->card;
 
        /*
-        * Let runtime PM core know our card is active
+        * Enable runtime PM only if supported by host+card+board
         */
-       err = pm_runtime_set_active(&card->dev);
-       if (err)
-               goto remove;
+       if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+               /*
+                * Let runtime PM core know our card is active
+                */
+               err = pm_runtime_set_active(&card->dev);
+               if (err)
+                       goto remove;
 
-       /*
-        * Enable runtime PM for this card
-        */
-       pm_runtime_enable(&card->dev);
+               /*
+                * Enable runtime PM for this card
+                */
+               pm_runtime_enable(&card->dev);
+       }
 
        /*
         * The number of functions on the card is encoded inside
@@ -745,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
                        goto remove;
 
                /*
-                * Enable Runtime PM for this func
+                * Enable Runtime PM for this func (if supported)
                 */
-               pm_runtime_enable(&card->sdio_func[i]->dev);
+               if (host->caps & MMC_CAP_POWER_OFF_CARD)
+                       pm_runtime_enable(&card->sdio_func[i]->dev);
        }
 
        mmc_release_host(host);
index 2716c7ab6bbfb6fd76ae2ff3084f7d61b4dcc198..203da443e339a65b90e1ff47bc5240f9ba2ca07e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/mmc/sdio_func.h>
 
 #include "sdio_cis.h"
@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
         * it should call pm_runtime_put_noidle() in its probe routine and
         * pm_runtime_get_noresume() in its remove routine.
         */
-       ret = pm_runtime_get_sync(dev);
-       if (ret < 0)
-               goto out;
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
+               ret = pm_runtime_get_sync(dev);
+               if (ret < 0)
+                       goto out;
+       }
 
        /* Set the default block size so the driver is sure it's something
         * sensible. */
@@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev)
        return 0;
 
 disable_runtimepm:
-       pm_runtime_put_noidle(dev);
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+               pm_runtime_put_noidle(dev);
 out:
        return ret;
 }
@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
 {
        struct sdio_driver *drv = to_sdio_driver(dev->driver);
        struct sdio_func *func = dev_to_sdio_func(dev);
-       int ret;
+       int ret = 0;
 
        /* Make sure card is powered before invoking ->remove() */
-       ret = pm_runtime_get_sync(dev);
-       if (ret < 0)
-               goto out;
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
+               ret = pm_runtime_get_sync(dev);
+               if (ret < 0)
+                       goto out;
+       }
 
        drv->remove(func);
 
@@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev)
        }
 
        /* First, undo the increment made directly above */
-       pm_runtime_put_noidle(dev);
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+               pm_runtime_put_noidle(dev);
 
        /* Then undo the runtime PM settings in sdio_bus_probe() */
-       pm_runtime_put_noidle(dev);
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+               pm_runtime_put_noidle(dev);
 
 out:
        return ret;
@@ -191,6 +199,8 @@ out:
 
 static int sdio_bus_pm_prepare(struct device *dev)
 {
+       struct sdio_func *func = dev_to_sdio_func(dev);
+
        /*
         * Resume an SDIO device which was suspended at run time at this
         * point, in order to allow standard SDIO suspend/resume paths
@@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev)
         * since there is little point in failing system suspend if a
         * device can't be resumed.
         */
-       pm_runtime_resume(dev);
+       if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+               pm_runtime_resume(dev);
 
        return 0;
 }
index 82a1079bbdc78bff7afc459b7aa3444461bcfe9b..5d46021cbb57f3a75b995ba11c25fa518aae9f37 100644 (file)
@@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
         * Monitor a 0->1 transition first
         */
        if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
-               while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit))
+               while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
                                        && (i++ < limit))
                        cpu_relax();
        }
index 2e9cca19c90b62b6ac3ac5bdbf86d92155b9e1fe..9b82910b9dbb3ec01ab07a0ff2f19f6ec59a9ed7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/sdhci-pltfm.h>
+#include <mach/hardware.h>
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
@@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
        clk_enable(clk);
        pltfm_host->clk = clk;
 
+       if (cpu_is_mx35() || cpu_is_mx51())
+               host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+       /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
+       if (cpu_is_mx25() || cpu_is_mx35())
+               host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+
        return 0;
 }
 
@@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 };
 
 struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
-       .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK
-                       | SDHCI_QUIRK_BROKEN_ADMA,
+       .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
        /* ADMA has issues. Might be fixable */
-       /* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */
        .ops = &sdhci_esdhc_ops,
        .init = esdhc_pltfm_init,
        .exit = esdhc_pltfm_exit,
index 55746bac2f440bea1b982b48e9add0e35f57a6db..3d9c2460d437ca7e8171e490becb7e6c5211ce7f 100644 (file)
@@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = {
  * ADMA operation is disabled for Moorestown platform due to
  * hardware bugs.
  */
-static int mrst_hc1_probe(struct sdhci_pci_chip *chip)
+static int mrst_hc_probe(struct sdhci_pci_chip *chip)
 {
        /*
-        * slots number is fixed here for MRST as SDIO3 is never used and has
-        * hardware bugs.
+        * slots number is fixed here for MRST as SDIO3/5 are never used and
+        * have hardware bugs.
         */
        chip->num_slots = 1;
        return 0;
@@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
        .quirks         = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
 };
 
-static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = {
+static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
        .quirks         = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
-       .probe          = mrst_hc1_probe,
+       .probe          = mrst_hc_probe,
 };
 
 static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
@@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
                .device         = PCI_DEVICE_ID_INTEL_MRST_SD1,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .driver_data    = (kernel_ulong_t)&sdhci_intel_mrst_hc1,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_MRST_SD2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
        },
 
        {
@@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct sdhci_pci_chip *chip;
        struct sdhci_pci_slot *slot;
+       mmc_pm_flag_t slot_pm_flags;
        mmc_pm_flag_t pm_flags = 0;
        int i, ret;
 
@@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
                        return ret;
                }
 
-               pm_flags |= slot->host->mmc->pm_flags;
+               slot_pm_flags = slot->host->mmc->pm_flags;
+               if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+                       sdhci_enable_irq_wakeups(slot->host);
+
+               pm_flags |= slot_pm_flags;
        }
 
        if (chip->fixes && chip->fixes->suspend) {
@@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 
        pci_save_state(pdev);
        if (pm_flags & MMC_PM_KEEP_POWER) {
-               if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+               if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
+                       pci_pme_active(pdev, true);
                        pci_enable_wake(pdev, PCI_D3hot, 1);
+               }
                pci_set_power_state(pdev, PCI_D3hot);
        } else {
                pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
index fc406ac5d1933166e9f08757a936d285f2843170..5a61208cbc66c8f41f2f760b7321f07f1cd8e131 100644 (file)
@@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
        if (pdata->quirks)
                host->quirks |= pdata->quirks;
 
+       /* If slot design supports 8 bit data, indicate this to MMC. */
+       if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
+               host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
        ret = sdhci_add_host(host);
        if (ret) {
                dev_err(&pdev->dev, "failed to add host\n");
index 782c0ee3c9251c6f804087308b097b44faca4f04..a25db426c91026ad4368d7e2ae0c700f28231a08 100644 (file)
@@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        if (host->ops->platform_send_init_74_clocks)
                host->ops->platform_send_init_74_clocks(host, ios->power_mode);
 
-       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-
-       if (ios->bus_width == MMC_BUS_WIDTH_8)
-               ctrl |= SDHCI_CTRL_8BITBUS;
-       else
-               ctrl &= ~SDHCI_CTRL_8BITBUS;
+       /*
+        * If your platform has 8-bit width support but is not a v3 controller,
+        * or if it requires special setup code, you should implement that in
+        * platform_8bit_width().
+        */
+       if (host->ops->platform_8bit_width)
+               host->ops->platform_8bit_width(host, ios->bus_width);
+       else {
+               ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+               if (ios->bus_width == MMC_BUS_WIDTH_8) {
+                       ctrl &= ~SDHCI_CTRL_4BITBUS;
+                       if (host->version >= SDHCI_SPEC_300)
+                               ctrl |= SDHCI_CTRL_8BITBUS;
+               } else {
+                       if (host->version >= SDHCI_SPEC_300)
+                               ctrl &= ~SDHCI_CTRL_8BITBUS;
+                       if (ios->bus_width == MMC_BUS_WIDTH_4)
+                               ctrl |= SDHCI_CTRL_4BITBUS;
+                       else
+                               ctrl &= ~SDHCI_CTRL_4BITBUS;
+               }
+               sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+       }
 
-       if (ios->bus_width == MMC_BUS_WIDTH_4)
-               ctrl |= SDHCI_CTRL_4BITBUS;
-       else
-               ctrl &= ~SDHCI_CTRL_4BITBUS;
+       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
        if ((ios->timing == MMC_TIMING_SD_HS ||
             ios->timing == MMC_TIMING_MMC_HS)
@@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host)
 
 EXPORT_SYMBOL_GPL(sdhci_resume_host);
 
+void sdhci_enable_irq_wakeups(struct sdhci_host *host)
+{
+       u8 val;
+       val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
+       val |= SDHCI_WAKE_ON_INT;
+       sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
+}
+
+EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
+
 #endif /* CONFIG_PM */
 
 /*****************************************************************************\
@@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host)
                mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
        else
                mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
+
        mmc->f_max = host->max_clk;
        mmc->caps |= MMC_CAP_SDIO_IRQ;
 
+       /*
+        * A controller may support 8-bit width, but the board itself
+        * might not have the pins brought out.  Boards that support
+        * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in
+        * their platform code before calling sdhci_add_host(), and we
+        * won't assume 8-bit width for hosts without that CAP.
+        */
        if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
-               mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+               mmc->caps |= MMC_CAP_4_BIT_DATA;
 
        if (caps & SDHCI_CAN_DO_HISPD)
                mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
index b7b8a3b28b01b00ff41b311cc6d3afde3bafeff3..e42d7f00c06050cfc25079c6b0a3e9942f2a66b4 100644 (file)
@@ -76,7 +76,7 @@
 #define   SDHCI_CTRL_ADMA1     0x08
 #define   SDHCI_CTRL_ADMA32    0x10
 #define   SDHCI_CTRL_ADMA64    0x18
-#define  SDHCI_CTRL_8BITBUS    0x20
+#define   SDHCI_CTRL_8BITBUS   0x20
 
 #define SDHCI_POWER_CONTROL    0x29
 #define  SDHCI_POWER_ON                0x01
@@ -87,6 +87,9 @@
 #define SDHCI_BLOCK_GAP_CONTROL        0x2A
 
 #define SDHCI_WAKE_UP_CONTROL  0x2B
+#define  SDHCI_WAKE_ON_INT     0x01
+#define  SDHCI_WAKE_ON_INSERT  0x02
+#define  SDHCI_WAKE_ON_REMOVE  0x04
 
 #define SDHCI_CLOCK_CONTROL    0x2C
 #define  SDHCI_DIVIDER_SHIFT   8
 #define  SDHCI_CLOCK_BASE_SHIFT        8
 #define  SDHCI_MAX_BLOCK_MASK  0x00030000
 #define  SDHCI_MAX_BLOCK_SHIFT  16
+#define  SDHCI_CAN_DO_8BIT     0x00040000
 #define  SDHCI_CAN_DO_ADMA2    0x00080000
 #define  SDHCI_CAN_DO_ADMA1    0x00100000
 #define  SDHCI_CAN_DO_HISPD    0x00200000
@@ -212,6 +216,8 @@ struct sdhci_ops {
        unsigned int    (*get_max_clock)(struct sdhci_host *host);
        unsigned int    (*get_min_clock)(struct sdhci_host *host);
        unsigned int    (*get_timeout_clock)(struct sdhci_host *host);
+       int             (*platform_8bit_width)(struct sdhci_host *host,
+                                              int width);
        void (*platform_send_init_74_clocks)(struct sdhci_host *host,
                                             u8 power_mode);
        unsigned int    (*get_ro)(struct sdhci_host *host);
@@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
 extern int sdhci_resume_host(struct sdhci_host *host);
+extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
 #endif
 
 #endif /* __SDHCI_HW_H */
index b4ead4a13c98a255d0d280ad4bec6ad5ee50b518..f8f65df9b01746052a5fe457f3e9419a98e63ee2 100644 (file)
@@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
        struct usb_device *usb_dev = interface_to_usbdev(intf);
        struct mmc_host *mmc;
        struct ushc_data *ushc;
-       int ret = -ENOMEM;
+       int ret;
 
        mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
        if (mmc == NULL)
@@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
        mmc->max_blk_count = 511;
 
        ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (ushc->int_urb == NULL)
+       if (ushc->int_urb == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
-       if (ushc->int_data == NULL)
+       if (ushc->int_data == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
                         usb_rcvintpipe(usb_dev,
                                        intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
@@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
                         intf->cur_altsetting->endpoint[0].desc.bInterval);
 
        ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (ushc->cbw_urb == NULL)
+       if (ushc->cbw_urb == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
-       if (ushc->cbw == NULL)
+       if (ushc->cbw == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        ushc->cbw->signature = USHC_CBW_SIGNATURE;
 
        usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),
@@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
                          cbw_callback, ushc);
 
        ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (ushc->data_urb == NULL)
+       if (ushc->data_urb == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
 
        ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (ushc->csw_urb == NULL)
+       if (ushc->csw_urb == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
-       if (ushc->csw == NULL)
+       if (ushc->csw == NULL) {
+               ret = -ENOMEM;
                goto err;
+       }
        usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
                          ushc->csw, sizeof(struct ushc_csw),
                          csw_callback, ushc);
index c2960ac9f39c9e863216c91b607e157c0ff65271..811775aa8ee80082aa5803a13b3537f2022e5936 100644 (file)
@@ -482,10 +482,17 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
        uint32_t data = 0;
        struct ubi_vid_hdr vid_hdr;
 
-       addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
+       /*
+        * It is important to first invalidate the EC header, and then the VID
+        * header. Otherwise a power cut may lead to valid EC header and
+        * invalid VID header, in which case UBI will treat this PEB as
+        * corrupted and will try to preserve it, and print scary warnings (see
+        * the header comment in scan.c for more information).
+        */
+       addr = (loff_t)pnum * ubi->peb_size;
        err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
        if (!err) {
-               addr -= ubi->vid_hdr_aloffset;
+               addr += ubi->vid_hdr_aloffset;
                err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
                                      (void *)&data);
                if (!err)
@@ -494,18 +501,24 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 
        /*
         * We failed to write to the media. This was observed with Spansion
-        * S29GL512N NOR flash. Most probably the eraseblock erasure was
-        * interrupted at a very inappropriate moment, so it became unwritable.
-        * In this case we probably anyway have garbage in this PEB.
+        * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+        * was interrupted at a very inappropriate moment, so it became
+        * unwritable. In this case we probably anyway have garbage in this
+        * PEB.
         */
        err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
-       if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
-               /*
-                * The VID header is corrupted, so we can safely erase this
-                * PEB and not afraid that it will be treated as a valid PEB in
-                * case of an unclean reboot.
-                */
-               return 0;
+       if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) {
+               struct ubi_ec_hdr ec_hdr;
+
+               err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
+               if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
+                       /*
+                        * Both VID and EC headers are corrupted, so we can
+                        * safely erase this PEB and not afraid that it will be
+                        * treated as a valid PEB in case of an unclean reboot.
+                        */
+                       return 0;
+       }
 
        /*
         * The PEB contains a valid VID header, but we cannot invalidate it.
index 3c631863bf40b5b3b5db70e28f4e6b3937e4be49..79ca304fc4db61e9a6be5b44223d3d8af895dd63 100644 (file)
@@ -787,16 +787,15 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
                 * erased, so it became unstable and corrupted, and should be
                 * erased.
                 */
-               return 0;
+               err = 0;
+               goto out_unlock;
        }
 
        if (err)
-               return err;
+               goto out_unlock;
 
-       if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) {
-               mutex_unlock(&ubi->buf_mutex);
-               return 0;
-       }
+       if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size))
+               goto out_unlock;
 
        ubi_err("PEB %d contains corrupted VID header, and the data does not "
                "contain all 0xFF, this may be a non-UBI PEB or a severe VID "
@@ -806,8 +805,11 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
                pnum, ubi->leb_start, ubi->leb_size);
        ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
                               ubi->peb_buf1, ubi->leb_size, 1);
+       err = 1;
+
+out_unlock:
        mutex_unlock(&ubi->buf_mutex);
-       return 1;
+       return err;
 }
 
 /**
@@ -951,6 +953,10 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
                         * impossible to distinguish it from a PEB which just
                         * contains garbage because of a power cut during erase
                         * operation. So we just schedule this PEB for erasure.
+                        *
+                        * Besides, in case of NOR flash, we deliberatly
+                        * corrupt both headers because NOR flash erasure is
+                        * slow and can start from the end.
                         */
                        err = 0;
                else
index e1da258bbfb7bfd89c24354e7deb626f4da777f9..0a92436f05389883e8485bdf13fafc19cccd2ca2 100644 (file)
@@ -699,7 +699,8 @@ DEFINE_WINDOW_IO(32)
 #define DEVICE_PCI(dev) NULL
 #endif
 
-#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+#define VORTEX_PCI(vp)                                                 \
+       ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))
 
 #ifdef CONFIG_EISA
 #define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
@@ -707,7 +708,8 @@ DEFINE_WINDOW_IO(32)
 #define DEVICE_EISA(dev) NULL
 #endif
 
-#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+#define VORTEX_EISA(vp)                                                        \
+       ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))
 
 /* The action to take with a media selection timer tick.
    Note that we deviate from the 3Com order by checking 10base2 before AUI.
index ac422cd332eadd687823fcc4db7ca2eaef997fea..dd16e83933a28f817c1eaa0d47003cb4482c3aa5 100644 (file)
@@ -490,13 +490,11 @@ static inline unsigned int cp_rx_csum_ok (u32 status)
 {
        unsigned int protocol = (status >> 16) & 0x3;
 
-       if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
+       if (((protocol == RxProtoTCP) && !(status & TCPFail)) ||
+           ((protocol == RxProtoUDP) && !(status & UDPFail)))
                return 1;
-       else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
-               return 1;
-       else if ((protocol == RxProtoIP) && (!(status & IPFail)))
-               return 1;
-       return 0;
+       else
+               return 0;
 }
 
 static int cp_rx_poll(struct napi_struct *napi, int budget)
index f6668cdaac85487b3c621b881af0c9afd975595b..4f1755bddf6b05d97b42433c3595a304976504fb 100644 (file)
@@ -2543,10 +2543,10 @@ config PCH_GBE
        depends on PCI
        select MII
        ---help---
-         This is a gigabit ethernet driver for Topcliff PCH.
-         Topcliff PCH is the platform controller hub that is used in Intel's
+         This is a gigabit ethernet driver for EG20T PCH.
+         EG20T PCH is the platform controller hub that is used in Intel's
          general embedded platform.
-         Topcliff PCH has Gigabit Ethernet interface.
+         EG20T PCH has Gigabit Ethernet interface.
          Using this interface, it is able to access system devices connected
          to Gigabit Ethernet.
          This driver enables Gigabit Ethernet function.
@@ -2945,6 +2945,18 @@ source "drivers/s390/net/Kconfig"
 
 source "drivers/net/caif/Kconfig"
 
+config TILE_NET
+       tristate "Tilera GBE/XGBE network driver support"
+       depends on TILE
+       default y
+       select CRC32
+       help
+         This is a standard Linux network device driver for the
+         on-chip Tilera Gigabit Ethernet and XAUI interfaces.
+
+         To compile this driver as a module, choose M here: the module
+         will be called tile_net.
+
 config XEN_NETDEV_FRONTEND
        tristate "Xen network device frontend driver"
        depends on XEN
index 652fc6b98039431832aaceda6f1b4a637720c126..b90738d13994318dcf2a06442cd7eba52629b9a7 100644 (file)
@@ -301,3 +301,4 @@ obj-$(CONFIG_CAIF) += caif/
 
 obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
 obj-$(CONFIG_PCH_GBE) += pch_gbe/
+obj-$(CONFIG_TILE_NET) += tile/
index 919080b2c3a50eb48bea7311ac0db4e8d3e8103e..1bf67200994827fd76250e718b3bdf4a67a609e8 100644 (file)
@@ -82,7 +82,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw)
        addr[0] = addr[1] = 0;
        AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
        if (atl1c_check_eeprom_exist(hw)) {
-               if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) {
+               if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
                        /* Enable OTP CLK */
                        if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
                                otp_ctrl_data |= OTP_CTRL_CLK_EN;
index 43489f89c142f7d10e25f0454287ef28939fd228..53eff9ba6e9500a3ea2327a55a42fcb9d9aeefea 100644 (file)
@@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
        spin_lock_irqsave(&aup->lock, flags);
 
        if (force_reset || (!aup->mac_enabled)) {
-               writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+               writel(MAC_EN_CLOCK_ENABLE, aup->enable);
                au_sync_delay(2);
                writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
-                               | MAC_EN_CLOCK_ENABLE), &aup->enable);
+                               | MAC_EN_CLOCK_ENABLE), aup->enable);
                au_sync_delay(2);
 
                aup->mac_enabled = 1;
@@ -503,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
 
        au1000_hard_stop(dev);
 
-       writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+       writel(MAC_EN_CLOCK_ENABLE, aup->enable);
        au_sync_delay(2);
-       writel(0, &aup->enable);
+       writel(0, aup->enable);
        au_sync_delay(2);
 
        aup->tx_full = 0;
@@ -1119,7 +1119,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
        /* set a random MAC now in case platform_data doesn't provide one */
        random_ether_addr(dev->dev_addr);
 
-       writel(0, &aup->enable);
+       writel(0, aup->enable);
        aup->mac_enabled = 0;
 
        pd = pdev->dev.platform_data;
index c36cd2ffbadcaa41e15a043a937d1b1ad62c22b4..93354eee2cfd1e679929054c9cc28fe7b35dea51 100644 (file)
@@ -2458,6 +2458,12 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
        int status, i = 0, num_imgs = 0;
        const u8 *p;
 
+       if (!netif_running(adapter->netdev)) {
+               dev_err(&adapter->pdev->dev,
+                       "Firmware load not allowed (interface is down)\n");
+               return -EPERM;
+       }
+
        strcpy(fw_file, func);
 
        status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
index e9ad16f00b56755847eb887a898c999ef2c08c04..9709b8569666d56ff84fb263429eb6f27c244033 100644 (file)
@@ -9064,7 +9064,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        default:
                pr_err("Unknown board_type (%ld), aborting\n",
                           ent->driver_data);
-               return ENODEV;
+               return -ENODEV;
        }
 
        cid_count += CNIC_CONTEXT_USE;
index bdb68a600382bdcfbe8a9e2cf70f8360821e2567..71a169740d05daf463b04f2ff591a943f8c1847e 100644 (file)
@@ -878,8 +878,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
        rcu_read_lock();
        in_dev = __in_dev_get_rcu(dev);
        if (in_dev) {
+               read_lock(&in_dev->mc_list_lock);
                for (im = in_dev->mc_list; im; im = im->next)
                        ip_mc_rejoin_group(im);
+               read_unlock(&in_dev->mc_list_lock);
        }
 
        rcu_read_unlock();
index 8b4cea57a6c5c47f585f5fcae935771e575dcd18..20da1996d354d563d8a2616276de477041b2368d 100644 (file)
@@ -635,8 +635,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
 
        ndev = alloc_netdev(sizeof(struct cfspi),
                        "cfspi%d", cfspi_setup);
-       if (!dev)
-               return -ENODEV;
+       if (!ndev)
+               return -ENOMEM;
 
        cfspi = netdev_priv(ndev);
        netif_stop_queue(ndev);
index c3449bbc585a682b57a39b306f251f9691e27e0b..d887a76cd39dad036eb289d88f5a666d898eb63a 100644 (file)
@@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
 }
 
 /*
- * Collect up to maxaddrs worth of a netdevice's unicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
  */
-static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
-                                              const u8 **addr,
-                                              unsigned int maxaddrs)
+static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
+                                                       const u8 **addr,
+                                                       unsigned int offset,
+                                                       unsigned int maxaddrs)
 {
+       unsigned int index = 0;
        unsigned int naddr = 0;
        const struct netdev_hw_addr *ha;
 
-       for_each_dev_addr(dev, ha) {
-               addr[naddr++] = ha->addr;
-               if (naddr >= maxaddrs)
-                       break;
-       }
+       for_each_dev_addr(dev, ha)
+               if (index++ >= offset) {
+                       addr[naddr++] = ha->addr;
+                       if (naddr >= maxaddrs)
+                               break;
+               }
        return naddr;
 }
 
 /*
- * Collect up to maxaddrs worth of a netdevice's multicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
  */
-static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
-                                              const u8 **addr,
-                                              unsigned int maxaddrs)
+static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
+                                                       const u8 **addr,
+                                                       unsigned int offset,
+                                                       unsigned int maxaddrs)
 {
+       unsigned int index = 0;
        unsigned int naddr = 0;
        const struct netdev_hw_addr *ha;
 
-       netdev_for_each_mc_addr(ha, dev) {
-               addr[naddr++] = ha->addr;
-               if (naddr >= maxaddrs)
-                       break;
-       }
+       netdev_for_each_mc_addr(ha, dev)
+               if (index++ >= offset) {
+                       addr[naddr++] = ha->addr;
+                       if (naddr >= maxaddrs)
+                               break;
+               }
        return naddr;
 }
 
@@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
        u64 mhash = 0;
        u64 uhash = 0;
        bool free = true;
-       u16 filt_idx[7];
+       unsigned int offset, naddr;
        const u8 *addr[7];
-       int ret, naddr = 0;
+       int ret;
        const struct port_info *pi = netdev_priv(dev);
 
        /* first do the secondary unicast addresses */
-       naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
-       if (naddr > 0) {
+       for (offset = 0; ; offset += naddr) {
+               naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
+                                                    ARRAY_SIZE(addr));
+               if (naddr == 0)
+                       break;
+
                ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
-                                         naddr, addr, filt_idx, &uhash, sleep);
+                                         naddr, addr, NULL, &uhash, sleep);
                if (ret < 0)
                        return ret;
 
@@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
        }
 
        /* next set up the multicast addresses */
-       naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
-       if (naddr > 0) {
+       for (offset = 0; ; offset += naddr) {
+               naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
+                                                    ARRAY_SIZE(addr));
+               if (naddr == 0)
+                       break;
+
                ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
-                                         naddr, addr, filt_idx, &mhash, sleep);
+                                         naddr, addr, NULL, &mhash, sleep);
                if (ret < 0)
                        return ret;
+               free = false;
        }
 
        return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
index e306c20dfaee3fd2c54a7d4e3497ddd8ba787d19..19520afe1a12d70dd06748bba1a27e7bf65af526 100644 (file)
@@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
                        unsigned int naddr, const u8 **addr, u16 *idx,
                        u64 *hash, bool sleep_ok)
 {
-       int i, ret;
+       int offset, ret = 0;
+       unsigned nfilters = 0;
+       unsigned int rem = naddr;
        struct fw_vi_mac_cmd cmd, rpl;
-       struct fw_vi_mac_exact *p;
-       size_t len16;
 
-       if (naddr > ARRAY_SIZE(cmd.u.exact))
+       if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
                return -EINVAL;
-       len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
-                                     u.exact[naddr]), 16);
 
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
-                                    FW_CMD_REQUEST |
-                                    FW_CMD_WRITE |
-                                    (free ? FW_CMD_EXEC : 0) |
-                                    FW_VI_MAC_CMD_VIID(viid));
-       cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
-                                           FW_CMD_LEN16(len16));
+       for (offset = 0; offset < naddr; /**/) {
+               unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
+                                        ? rem
+                                        : ARRAY_SIZE(cmd.u.exact));
+               size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
+                                                    u.exact[fw_naddr]), 16);
+               struct fw_vi_mac_exact *p;
+               int i;
 
-       for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
-               p->valid_to_idx =
-                       cpu_to_be16(FW_VI_MAC_CMD_VALID |
-                                   FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
-               memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
-       }
+               memset(&cmd, 0, sizeof(cmd));
+               cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
+                                            FW_CMD_REQUEST |
+                                            FW_CMD_WRITE |
+                                            (free ? FW_CMD_EXEC : 0) |
+                                            FW_VI_MAC_CMD_VIID(viid));
+               cmd.freemacs_to_len16 =
+                       cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
+                                   FW_CMD_LEN16(len16));
+
+               for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
+                       p->valid_to_idx = cpu_to_be16(
+                               FW_VI_MAC_CMD_VALID |
+                               FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+                       memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
+               }
+
+
+               ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
+                                       sleep_ok);
+               if (ret && ret != -ENOMEM)
+                       break;
 
-       ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok);
-       if (ret)
-               return ret;
-
-       for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) {
-               u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
-
-               if (idx)
-                       idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES
-                                 ? 0xffff
-                                 : index);
-               if (index < FW_CLS_TCAM_NUM_ENTRIES)
-                       ret++;
-               else if (hash)
-                       *hash |= (1 << hash_mac_addr(addr[i]));
+               for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
+                       u16 index = FW_VI_MAC_CMD_IDX_GET(
+                               be16_to_cpu(p->valid_to_idx));
+
+                       if (idx)
+                               idx[offset+i] =
+                                       (index >= FW_CLS_TCAM_NUM_ENTRIES
+                                        ? 0xffff
+                                        : index);
+                       if (index < FW_CLS_TCAM_NUM_ENTRIES)
+                               nfilters++;
+                       else if (hash)
+                               *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
+               }
+
+               free = false;
+               offset += fw_naddr;
+               rem -= fw_naddr;
        }
+
+       /*
+        * If there were no errors or we merely ran out of room in our MAC
+        * address arena, return the number of filters actually written.
+        */
+       if (ret == 0 || ret == -ENOMEM)
+               ret = nfilters;
        return ret;
 }
 
index 4686c3983fc3044f0e0af47cf75dee71b6dadb02..4d62f7bfa0367578471f2773f04a365fed7db972 100644 (file)
@@ -31,7 +31,7 @@
 
 char e1000_driver_name[] = "e1000";
 static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-#define DRV_VERSION "7.3.21-k6-NAPI"
+#define DRV_VERSION "7.3.21-k8-NAPI"
 const char e1000_driver_version[] = DRV_VERSION;
 static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -485,9 +485,6 @@ void e1000_down(struct e1000_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        u32 rctl, tctl;
 
-       /* signal that we're down so the interrupt handler does not
-        * reschedule our watchdog timer */
-       set_bit(__E1000_DOWN, &adapter->flags);
 
        /* disable receives in the hardware */
        rctl = er32(RCTL);
@@ -508,6 +505,13 @@ void e1000_down(struct e1000_adapter *adapter)
 
        e1000_irq_disable(adapter);
 
+       /*
+        * Setting DOWN must be after irq_disable to prevent
+        * a screaming interrupt.  Setting DOWN also prevents
+        * timers and tasks from rescheduling.
+        */
+       set_bit(__E1000_DOWN, &adapter->flags);
+
        del_timer_sync(&adapter->tx_fifo_stall_timer);
        del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_info_timer);
index 182b2a7be8dcd02673bd9512d2760cb61b86b884..3d0af08483a16792874d46958c2821641f5b7f97 100644 (file)
@@ -400,6 +400,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
                        skb_arr_rq1[index] = netdev_alloc_skb(dev,
                                                              EHEA_L_PKT_SIZE);
                        if (!skb_arr_rq1[index]) {
+                               ehea_info("Unable to allocate enough skb in the array\n");
                                pr->rq1_skba.os_skbs = fill_wqes - i;
                                break;
                        }
@@ -422,13 +423,20 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
        struct net_device *dev = pr->port->netdev;
        int i;
 
-       for (i = 0; i < pr->rq1_skba.len; i++) {
+       if (nr_rq1a > pr->rq1_skba.len) {
+               ehea_error("NR_RQ1A bigger than skb array len\n");
+               return;
+       }
+
+       for (i = 0; i < nr_rq1a; i++) {
                skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
-               if (!skb_arr_rq1[i])
+               if (!skb_arr_rq1[i]) {
+                       ehea_info("No enough memory to allocate skb array\n");
                        break;
+               }
        }
        /* Ring doorbell */
-       ehea_update_rq1a(pr->qp, nr_rq1a);
+       ehea_update_rq1a(pr->qp, i);
 }
 
 static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -735,8 +743,10 @@ static int ehea_proc_rwqes(struct net_device *dev,
 
                                        skb = netdev_alloc_skb(dev,
                                                               EHEA_L_PKT_SIZE);
-                                       if (!skb)
+                                       if (!skb) {
+                                               ehea_info("Not enough memory to allocate skb\n");
                                                break;
+                                       }
                                }
                                skb_copy_to_linear_data(skb, ((char *)cqe) + 64,
                                                 cqe->num_bytes_transfered - 4);
index 49e4ce1246a75e01c30a623de0031707fe0273c9..d1bec6269173844cfb17786c99936beee8dfd197 100644 (file)
@@ -577,11 +577,10 @@ static int gfar_parse_group(struct device_node *np,
                        irq_of_parse_and_map(np, 1);
                priv->gfargrp[priv->num_grps].interruptError =
                        irq_of_parse_and_map(np,2);
-               if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 ||
-                       priv->gfargrp[priv->num_grps].interruptReceive < 0 ||
-                       priv->gfargrp[priv->num_grps].interruptError < 0) {
+               if (priv->gfargrp[priv->num_grps].interruptTransmit == NO_IRQ ||
+                   priv->gfargrp[priv->num_grps].interruptReceive  == NO_IRQ ||
+                   priv->gfargrp[priv->num_grps].interruptError    == NO_IRQ)
                        return -EINVAL;
-               }
        }
 
        priv->gfargrp[priv->num_grps].grp_id = priv->num_grps;
index dc019809234352418978474531efa675a4e879a2..aa93655c3aa7c1da10f8aeda9eaf2a1535b06756 100644 (file)
@@ -88,16 +88,14 @@ static const char *ipg_brand_name[] = {
        "IC PLUS IP1000 1000/100/10 based NIC",
        "Sundance Technology ST2021 based NIC",
        "Tamarack Microelectronics TC9020/9021 based NIC",
-       "Tamarack Microelectronics TC9020/9021 based NIC",
        "D-Link NIC IP1000A"
 };
 
 static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = {
        { PCI_VDEVICE(SUNDANCE, 0x1023), 0 },
        { PCI_VDEVICE(SUNDANCE, 0x2021), 1 },
-       { PCI_VDEVICE(SUNDANCE, 0x1021), 2 },
-       { PCI_VDEVICE(DLINK,    0x9021), 3 },
-       { PCI_VDEVICE(DLINK,    0x4020), 4 },
+       { PCI_VDEVICE(DLINK,    0x9021), 2 },
+       { PCI_VDEVICE(DLINK,    0x4020), 3 },
        { 0, }
 };
 
index 00b38bccd6d0fd51f19cfe383f71a1f5952d6a43..52a7c86af66347c388d24d29b043fe52e6a2ca5f 100644 (file)
@@ -258,7 +258,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate)
 
        /* Baud Rate Error Correction x 10000 */
        u32 rate_err_array[] = {
-               0000, 0625, 1250, 1875,
+                  0,  625, 1250, 1875,
                2500, 3125, 3750, 4375,
                5000, 5625, 6250, 6875,
                7500, 8125, 8750, 9375,
index b68eee2414c208765849d0136dfb7cb0065f52ba..7a7e18ba278a829bebc488e091fc615e8aed5825 100644 (file)
@@ -289,6 +289,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET);
                dev_cap->bf_reg_size = 1 << (field & 0x1f);
                MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET);
+               if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) {
+                       mlx4_warn(dev, "firmware bug: log2 # of blue flame regs is invalid (%d), forcing 3\n", field & 0x1f);
+                       field = 3;
+               }
                dev_cap->bf_regs_per_page = 1 << (field & 0x3f);
                mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
                         dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
index 472056b47440877f93c83a11d994fca16b99dd96..03a1d280105f72c93b99744b7e69690aff992946 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 - 2010 Intel Corporation.
- * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
  *
  * This code was derived from the Intel e1000e Linux driver.
  *
@@ -2464,8 +2464,8 @@ static void __exit pch_gbe_exit_module(void)
 module_init(pch_gbe_init_module);
 module_exit(pch_gbe_exit_module);
 
-MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");
-MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");
+MODULE_DESCRIPTION("EG20T PCH Gigabit ethernet Driver");
+MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);
index 2510146fc5607db7a26d9b54ad634f8941d65ae2..ef0996a0eaaaa9e39e84d183cbc074be9bff5080 100644 (file)
@@ -434,8 +434,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "using default of "
                                __MODULE_STRING(PCH_GBE_DEFAULT_TXD),
                        .def  = PCH_GBE_DEFAULT_TXD,
-                       .arg  = { .r = { .min = PCH_GBE_MIN_TXD } },
-                       .arg  = { .r = { .max = PCH_GBE_MAX_TXD } }
+                       .arg  = { .r = { .min = PCH_GBE_MIN_TXD,
+                                        .max = PCH_GBE_MAX_TXD } }
                };
                struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
                tx_ring->count = TxDescriptors;
@@ -450,8 +450,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "using default of "
                                __MODULE_STRING(PCH_GBE_DEFAULT_RXD),
                        .def  = PCH_GBE_DEFAULT_RXD,
-                       .arg  = { .r = { .min = PCH_GBE_MIN_RXD } },
-                       .arg  = { .r = { .max = PCH_GBE_MAX_RXD } }
+                       .arg  = { .r = { .min = PCH_GBE_MIN_RXD,
+                                        .max = PCH_GBE_MAX_RXD } }
                };
                struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
                rx_ring->count = RxDescriptors;
index f0bd1a1aba3ab3413a16eab296b4881d99ea1145..e8b9c53c304b63d2ba2b4a530504e5fafb08f6dc 100644 (file)
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/marvell_phy.h>
+#include <linux/of.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#define MII_MARVELL_PHY_PAGE           22
+
 #define MII_M1011_IEVENT               0x13
 #define MII_M1011_IEVENT_CLEAR         0x0000
 
@@ -80,7 +83,6 @@
 #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
@@ -186,13 +188,94 @@ static int marvell_config_aneg(struct phy_device *phydev)
        return 0;
 }
 
+#ifdef CONFIG_OF_MDIO
+/*
+ * Set and/or override some configuration registers based on the
+ * marvell,reg-init property stored in the of_node for the phydev.
+ *
+ * marvell,reg-init = <reg-page reg mask value>,...;
+ *
+ * There may be one or more sets of <reg-page reg mask value>:
+ *
+ * reg-page: which register bank to use.
+ * reg: the register.
+ * mask: if non-zero, ANDed with existing register value.
+ * value: ORed with the masked value and written to the regiser.
+ *
+ */
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+       const __be32 *paddr;
+       int len, i, saved_page, current_page, page_changed, ret;
+
+       if (!phydev->dev.of_node)
+               return 0;
+
+       paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len);
+       if (!paddr || len < (4 * sizeof(*paddr)))
+               return 0;
+
+       saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE);
+       if (saved_page < 0)
+               return saved_page;
+       page_changed = 0;
+       current_page = saved_page;
+
+       ret = 0;
+       len /= sizeof(*paddr);
+       for (i = 0; i < len - 3; i += 4) {
+               u16 reg_page = be32_to_cpup(paddr + i);
+               u16 reg = be32_to_cpup(paddr + i + 1);
+               u16 mask = be32_to_cpup(paddr + i + 2);
+               u16 val_bits = be32_to_cpup(paddr + i + 3);
+               int val;
+
+               if (reg_page != current_page) {
+                       current_page = reg_page;
+                       page_changed = 1;
+                       ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page);
+                       if (ret < 0)
+                               goto err;
+               }
+
+               val = 0;
+               if (mask) {
+                       val = phy_read(phydev, reg);
+                       if (val < 0) {
+                               ret = val;
+                               goto err;
+                       }
+                       val &= mask;
+               }
+               val |= val_bits;
+
+               ret = phy_write(phydev, reg, val);
+               if (ret < 0)
+                       goto err;
+
+       }
+err:
+       if (page_changed) {
+               i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page);
+               if (ret == 0)
+                       ret = i;
+       }
+       return ret;
+}
+#else
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+       return 0;
+}
+#endif /* CONFIG_OF_MDIO */
+
 static int m88e1121_config_aneg(struct phy_device *phydev)
 {
        int err, oldpage, mscr;
 
-       oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+       oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
 
-       err = phy_write(phydev, MII_88E1121_PHY_PAGE,
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
                        MII_88E1121_PHY_MSCR_PAGE);
        if (err < 0)
                return err;
@@ -218,7 +301,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
                        return err;
        }
 
-       phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
+       phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
 
        err = phy_write(phydev, MII_BMCR, BMCR_RESET);
        if (err < 0)
@@ -229,11 +312,11 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+       oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
 
-       phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
+       phy_write(phydev, MII_MARVELL_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, oldpage);
+       phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
 
        err = genphy_config_aneg(phydev);
 
@@ -244,9 +327,9 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
 {
        int err, oldpage, mscr;
 
-       oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+       oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
 
-       err = phy_write(phydev, MII_88E1121_PHY_PAGE,
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
                        MII_88E1121_PHY_MSCR_PAGE);
        if (err < 0)
                return err;
@@ -258,7 +341,7 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       err = phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
        if (err < 0)
                return err;
 
@@ -368,6 +451,9 @@ static int m88e1111_config_init(struct phy_device *phydev)
                        return err;
        }
 
+       err = marvell_of_reg_init(phydev);
+       if (err < 0)
+               return err;
 
        err = phy_write(phydev, MII_BMCR, BMCR_RESET);
        if (err < 0)
@@ -398,7 +484,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
        int err;
 
        /* Change address */
-       err = phy_write(phydev, 0x16, 0x0002);
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
        if (err < 0)
                return err;
 
@@ -408,7 +494,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
                return err;
 
        /* Change address */
-       err = phy_write(phydev, 0x16, 0x0003);
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003);
        if (err < 0)
                return err;
 
@@ -420,8 +506,42 @@ static int m88e1118_config_init(struct phy_device *phydev)
        if (err < 0)
                return err;
 
+       err = marvell_of_reg_init(phydev);
+       if (err < 0)
+               return err;
+
        /* Reset address */
-       err = phy_write(phydev, 0x16, 0x0);
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
+       if (err < 0)
+               return err;
+
+       err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+static int m88e1149_config_init(struct phy_device *phydev)
+{
+       int err;
+
+       /* Change address */
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
+       if (err < 0)
+               return err;
+
+       /* Enable 1000 Mbit */
+       err = phy_write(phydev, 0x15, 0x1048);
+       if (err < 0)
+               return err;
+
+       err = marvell_of_reg_init(phydev);
+       if (err < 0)
+               return err;
+
+       /* Reset address */
+       err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
        if (err < 0)
                return err;
 
@@ -491,6 +611,10 @@ static int m88e1145_config_init(struct phy_device *phydev)
                }
        }
 
+       err = marvell_of_reg_init(phydev);
+       if (err < 0)
+               return err;
+
        return 0;
 }
 
@@ -684,6 +808,19 @@ static struct phy_driver marvell_drivers[] = {
                .config_intr = &marvell_config_intr,
                .driver = { .owner = THIS_MODULE },
        },
+       {
+               .phy_id = MARVELL_PHY_ID_88E1149R,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1149R",
+               .features = PHY_GBIT_FEATURES,
+               .flags = PHY_HAS_INTERRUPT,
+               .config_init = &m88e1149_config_init,
+               .config_aneg = &m88e1118_config_aneg,
+               .read_status = &genphy_read_status,
+               .ack_interrupt = &marvell_ack_interrupt,
+               .config_intr = &marvell_config_intr,
+               .driver = { .owner = THIS_MODULE },
+       },
        {
                .phy_id = MARVELL_PHY_ID_88E1240,
                .phy_id_mask = MARVELL_PHY_ID_MASK,
@@ -735,6 +872,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = {
        { 0x01410e10, 0xfffffff0 },
        { 0x01410cb0, 0xfffffff0 },
        { 0x01410cd0, 0xfffffff0 },
+       { 0x01410e50, 0xfffffff0 },
        { 0x01410e30, 0xfffffff0 },
        { 0x01410e90, 0xfffffff0 },
        { }
index 09cf56d0416a8c24c78780c7eb374fcebf01cffc..39659976a1acfb1589834368aab20080c894d6eb 100644 (file)
@@ -2584,16 +2584,16 @@ ppp_create_interface(struct net *net, int unit, int *retp)
         */
        dev_net_set(dev, net);
 
-       ret = -EEXIST;
        mutex_lock(&pn->all_ppp_mutex);
 
        if (unit < 0) {
                unit = unit_get(&pn->units_idr, ppp);
                if (unit < 0) {
-                       *retp = unit;
+                       ret = unit;
                        goto out2;
                }
        } else {
+               ret = -EEXIST;
                if (unit_find(&pn->units_idr, unit))
                        goto out2; /* unit already exists */
                /*
@@ -2668,10 +2668,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
                ppp->closing = 1;
                ppp_unlock(ppp);
                unregister_netdev(ppp->dev);
+               unit_put(&pn->units_idr, ppp->file.index);
        } else
                ppp_unlock(ppp);
 
-       unit_put(&pn->units_idr, ppp->file.index);
        ppp->file.dead = 1;
        ppp->owner = NULL;
        wake_up_interruptible(&ppp->file.rwait);
@@ -2859,8 +2859,7 @@ static void __exit ppp_cleanup(void)
  * by holding all_ppp_mutex
  */
 
-/* associate pointer with specified number */
-static int unit_set(struct idr *p, void *ptr, int n)
+static int __unit_alloc(struct idr *p, void *ptr, int n)
 {
        int unit, err;
 
@@ -2871,10 +2870,24 @@ again:
        }
 
        err = idr_get_new_above(p, ptr, n, &unit);
-       if (err == -EAGAIN)
-               goto again;
+       if (err < 0) {
+               if (err == -EAGAIN)
+                       goto again;
+               return err;
+       }
+
+       return unit;
+}
+
+/* associate pointer with specified number */
+static int unit_set(struct idr *p, void *ptr, int n)
+{
+       int unit;
 
-       if (unit != n) {
+       unit = __unit_alloc(p, ptr, n);
+       if (unit < 0)
+               return unit;
+       else if (unit != n) {
                idr_remove(p, unit);
                return -EINVAL;
        }
@@ -2885,19 +2898,7 @@ again:
 /* get new free unit number and associate pointer with it */
 static int unit_get(struct idr *p, void *ptr)
 {
-       int unit, err;
-
-again:
-       if (!idr_pre_get(p, GFP_KERNEL)) {
-               printk(KERN_ERR "PPP: No free memory for idr\n");
-               return -ENOMEM;
-       }
-
-       err = idr_get_new_above(p, ptr, 0, &unit);
-       if (err == -EAGAIN)
-               goto again;
-
-       return unit;
+       return __unit_alloc(p, ptr, 0);
 }
 
 /* put unit number back to a pool */
index c30e0fe55a314858828c2caa4d464b0c2301fe81..528eaef5308fa59460c8697ffc4fc0400d74a6cb 100644 (file)
@@ -62,15 +62,15 @@ static const u32 default_msg =
 /* NETIF_MSG_PKTDATA | */
     NETIF_MSG_HW | NETIF_MSG_WOL | 0;
 
-static int debug = 0x00007fff; /* defaults above */
-module_param(debug, int, 0);
+static int debug = -1; /* defaults above */
+module_param(debug, int, 0664);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
 #define MSIX_IRQ 0
 #define MSI_IRQ 1
 #define LEG_IRQ 2
 static int qlge_irq_type = MSIX_IRQ;
-module_param(qlge_irq_type, int, MSIX_IRQ);
+module_param(qlge_irq_type, int, 0664);
 MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
 
 static int qlge_mpi_coredump;
index 4c4d16905efb7253a055978e736edc93381cdd69..7d33ef4bcb4a1d6ca7125d6780e173889ebbb0d8 100644 (file)
@@ -4440,8 +4440,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
        u32 status = opts1 & RxProtoMask;
 
        if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
-           ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
-           ((status == RxProtoIP) && !(opts1 & IPFail)))
+           ((status == RxProtoUDP) && !(opts1 & UDPFail)))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        else
                skb_checksum_none_assert(skb);
diff --git a/drivers/net/tile/Makefile b/drivers/net/tile/Makefile
new file mode 100644 (file)
index 0000000..f634f14
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the TILE on-chip networking support.
+#
+
+obj-$(CONFIG_TILE_NET) += tile_net.o
+ifdef CONFIG_TILEGX
+tile_net-objs := tilegx.o mpipe.o iorpc_mpipe.o dma_queue.o
+else
+tile_net-objs := tilepro.o
+endif
diff --git a/drivers/net/tile/tilepro.c b/drivers/net/tile/tilepro.c
new file mode 100644 (file)
index 0000000..0e6bac5
--- /dev/null
@@ -0,0 +1,2406 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>      /* printk() */
+#include <linux/slab.h>        /* kmalloc() */
+#include <linux/errno.h>       /* error codes */
+#include <linux/types.h>       /* size_t */
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/skbuff.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/hugetlb.h>
+#include <linux/in6.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <asm/checksum.h>
+#include <asm/homecache.h>
+
+#include <hv/drv_xgbe_intf.h>
+#include <hv/drv_xgbe_impl.h>
+#include <hv/hypervisor.h>
+#include <hv/netio_intf.h>
+
+/* For TSO */
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+
+/* There is no singlethread_cpu, so schedule work on the current cpu. */
+#define singlethread_cpu -1
+
+
+/*
+ * First, "tile_net_init_module()" initializes all four "devices" which
+ * can be used by linux.
+ *
+ * Then, "ifconfig DEVICE up" calls "tile_net_open()", which analyzes
+ * the network cpus, then uses "tile_net_open_aux()" to initialize
+ * LIPP/LEPP, and then uses "tile_net_open_inner()" to register all
+ * the tiles, provide buffers to LIPP, allow ingress to start, and
+ * turn on hypervisor interrupt handling (and NAPI) on all tiles.
+ *
+ * If registration fails due to the link being down, then "retry_work"
+ * is used to keep calling "tile_net_open_inner()" until it succeeds.
+ *
+ * If "ifconfig DEVICE down" is called, it uses "tile_net_stop()" to
+ * stop egress, drain the LIPP buffers, unregister all the tiles, stop
+ * LIPP/LEPP, and wipe the LEPP queue.
+ *
+ * We start out with the ingress interrupt enabled on each CPU.  When
+ * this interrupt fires, we disable it, and call "napi_schedule()".
+ * This will cause "tile_net_poll()" to be called, which will pull
+ * packets from the netio queue, filtering them out, or passing them
+ * to "netif_receive_skb()".  If our budget is exhausted, we will
+ * return, knowing we will be called again later.  Otherwise, we
+ * reenable the ingress interrupt, and call "napi_complete()".
+ *
+ *
+ * NOTE: The use of "native_driver" ensures that EPP exists, and that
+ * "epp_sendv" is legal, and that "LIPP" is being used.
+ *
+ * NOTE: Failing to free completions for an arbitrarily long time
+ * (which is defined to be illegal) does in fact cause bizarre
+ * problems.  The "egress_timer" helps prevent this from happening.
+ *
+ * NOTE: The egress code can be interrupted by the interrupt handler.
+ */
+
+
+/* HACK: Allow use of "jumbo" packets. */
+/* This should be 1500 if "jumbo" is not set in LIPP. */
+/* This should be at most 10226 (10240 - 14) if "jumbo" is set in LIPP. */
+/* ISSUE: This has not been thoroughly tested (except at 1500). */
+#define TILE_NET_MTU 1500
+
+/* HACK: Define to support GSO. */
+/* ISSUE: This may actually hurt performance of the TCP blaster. */
+/* #define TILE_NET_GSO */
+
+/* Define this to collapse "duplicate" acks. */
+/* #define IGNORE_DUP_ACKS */
+
+/* HACK: Define this to verify incoming packets. */
+/* #define TILE_NET_VERIFY_INGRESS */
+
+/* Use 3000 to enable the Linux Traffic Control (QoS) layer, else 0. */
+#define TILE_NET_TX_QUEUE_LEN 0
+
+/* Define to dump packets (prints out the whole packet on tx and rx). */
+/* #define TILE_NET_DUMP_PACKETS */
+
+/* Define to enable debug spew (all PDEBUG's are enabled). */
+/* #define TILE_NET_DEBUG */
+
+
+/* Define to activate paranoia checks. */
+/* #define TILE_NET_PARANOIA */
+
+/* Default transmit lockup timeout period, in jiffies. */
+#define TILE_NET_TIMEOUT (5 * HZ)
+
+/* Default retry interval for bringing up the NetIO interface, in jiffies. */
+#define TILE_NET_RETRY_INTERVAL (5 * HZ)
+
+/* Number of ports (xgbe0, xgbe1, gbe0, gbe1). */
+#define TILE_NET_DEVS 4
+
+
+
+/* Paranoia. */
+#if NET_IP_ALIGN != LIPP_PACKET_PADDING
+#error "NET_IP_ALIGN must match LIPP_PACKET_PADDING."
+#endif
+
+
+/* Debug print. */
+#ifdef TILE_NET_DEBUG
+#define PDEBUG(fmt, args...) net_printk(fmt, ## args)
+#else
+#define PDEBUG(fmt, args...)
+#endif
+
+
+MODULE_AUTHOR("Tilera");
+MODULE_LICENSE("GPL");
+
+
+#define IS_MULTICAST(mac_addr) \
+       (((u8 *)(mac_addr))[0] & 0x01)
+
+#define IS_BROADCAST(mac_addr) \
+       (((u16 *)(mac_addr))[0] == 0xffff)
+
+
+/*
+ * Queue of incoming packets for a specific cpu and device.
+ *
+ * Includes a pointer to the "system" data, and the actual "user" data.
+ */
+struct tile_netio_queue {
+       netio_queue_impl_t *__system_part;
+       netio_queue_user_impl_t __user_part;
+
+};
+
+
+/*
+ * Statistics counters for a specific cpu and device.
+ */
+struct tile_net_stats_t {
+       u32 rx_packets;
+       u32 rx_bytes;
+       u32 tx_packets;
+       u32 tx_bytes;
+};
+
+
+/*
+ * Info for a specific cpu and device.
+ *
+ * ISSUE: There is a "dev" pointer in "napi" as well.
+ */
+struct tile_net_cpu {
+       /* The NAPI struct. */
+       struct napi_struct napi;
+       /* Packet queue. */
+       struct tile_netio_queue queue;
+       /* Statistics. */
+       struct tile_net_stats_t stats;
+       /* ISSUE: Is this needed? */
+       bool napi_enabled;
+       /* True if this tile has succcessfully registered with the IPP. */
+       bool registered;
+       /* True if the link was down last time we tried to register. */
+       bool link_down;
+       /* True if "egress_timer" is scheduled. */
+       bool egress_timer_scheduled;
+       /* Number of small sk_buffs which must still be provided. */
+       unsigned int num_needed_small_buffers;
+       /* Number of large sk_buffs which must still be provided. */
+       unsigned int num_needed_large_buffers;
+       /* A timer for handling egress completions. */
+       struct timer_list egress_timer;
+};
+
+
+/*
+ * Info for a specific device.
+ */
+struct tile_net_priv {
+       /* Our network device. */
+       struct net_device *dev;
+       /* The actual egress queue. */
+       lepp_queue_t *epp_queue;
+       /* Protects "epp_queue->cmd_tail" and "epp_queue->comp_tail" */
+       spinlock_t cmd_lock;
+       /* Protects "epp_queue->comp_head". */
+       spinlock_t comp_lock;
+       /* The hypervisor handle for this interface. */
+       int hv_devhdl;
+       /* The intr bit mask that IDs this device. */
+       u32 intr_id;
+       /* True iff "tile_net_open_aux()" has succeeded. */
+       int partly_opened;
+       /* True iff "tile_net_open_inner()" has succeeded. */
+       int fully_opened;
+       /* Effective network cpus. */
+       struct cpumask network_cpus_map;
+       /* Number of network cpus. */
+       int network_cpus_count;
+       /* Credits per network cpu. */
+       int network_cpus_credits;
+       /* Network stats. */
+       struct net_device_stats stats;
+       /* For NetIO bringup retries. */
+       struct delayed_work retry_work;
+       /* Quick access to per cpu data. */
+       struct tile_net_cpu *cpu[NR_CPUS];
+};
+
+
+/*
+ * The actual devices (xgbe0, xgbe1, gbe0, gbe1).
+ */
+static struct net_device *tile_net_devs[TILE_NET_DEVS];
+
+/*
+ * The "tile_net_cpu" structures for each device.
+ */
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe0);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe1);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe0);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe1);
+
+
+/*
+ * True if "network_cpus" was specified.
+ */
+static bool network_cpus_used;
+
+/*
+ * The actual cpus in "network_cpus".
+ */
+static struct cpumask network_cpus_map;
+
+
+
+#ifdef TILE_NET_DEBUG
+/*
+ * printk with extra stuff.
+ *
+ * We print the CPU we're running in brackets.
+ */
+static void net_printk(char *fmt, ...)
+{
+       int i;
+       int len;
+       va_list args;
+       static char buf[256];
+
+       len = sprintf(buf, "tile_net[%2.2d]: ", smp_processor_id());
+       va_start(args, fmt);
+       i = vscnprintf(buf + len, sizeof(buf) - len - 1, fmt, args);
+       va_end(args);
+       buf[255] = '\0';
+       pr_notice(buf);
+}
+#endif
+
+
+#ifdef TILE_NET_DUMP_PACKETS
+/*
+ * Dump a packet.
+ */
+static void dump_packet(unsigned char *data, unsigned long length, char *s)
+{
+       unsigned long i;
+       static unsigned int count;
+
+       pr_info("dump_packet(data %p, length 0x%lx s %s count 0x%x)\n",
+              data, length, s, count++);
+
+       pr_info("\n");
+
+       for (i = 0; i < length; i++) {
+               if ((i & 0xf) == 0)
+                       sprintf(buf, "%8.8lx:", i);
+               sprintf(buf + strlen(buf), " %2.2x", data[i]);
+               if ((i & 0xf) == 0xf || i == length - 1)
+                       pr_info("%s\n", buf);
+       }
+}
+#endif
+
+
+/*
+ * Provide support for the __netio_fastio1() swint
+ * (see <hv/drv_xgbe_intf.h> for how it is used).
+ *
+ * The fastio swint2 call may clobber all the caller-saved registers.
+ * It rarely clobbers memory, but we allow for the possibility in
+ * the signature just to be on the safe side.
+ *
+ * Also, gcc doesn't seem to allow an input operand to be
+ * clobbered, so we fake it with dummy outputs.
+ *
+ * This function can't be static because of the way it is declared
+ * in the netio header.
+ */
+inline int __netio_fastio1(u32 fastio_index, u32 arg0)
+{
+       long result, clobber_r1, clobber_r10;
+       asm volatile("swint2"
+                    : "=R00" (result),
+                      "=R01" (clobber_r1), "=R10" (clobber_r10)
+                    : "R10" (fastio_index), "R01" (arg0)
+                    : "memory", "r2", "r3", "r4",
+                      "r5", "r6", "r7", "r8", "r9",
+                      "r11", "r12", "r13", "r14",
+                      "r15", "r16", "r17", "r18", "r19",
+                      "r20", "r21", "r22", "r23", "r24",
+                      "r25", "r26", "r27", "r28", "r29");
+       return result;
+}
+
+
+/*
+ * Provide a linux buffer to LIPP.
+ */
+static void tile_net_provide_linux_buffer(struct tile_net_cpu *info,
+                                         void *va, bool small)
+{
+       struct tile_netio_queue *queue = &info->queue;
+
+       /* Convert "va" and "small" to "linux_buffer_t". */
+       unsigned int buffer = ((unsigned int)(__pa(va) >> 7) << 1) + small;
+
+       __netio_fastio_free_buffer(queue->__user_part.__fastio_index, buffer);
+}
+
+
+/*
+ * Provide a linux buffer for LIPP.
+ */
+static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
+                                          bool small)
+{
+       /* ISSUE: What should we use here? */
+       unsigned int large_size = NET_IP_ALIGN + TILE_NET_MTU + 100;
+
+       /* Round up to ensure to avoid "false sharing" with last cache line. */
+       unsigned int buffer_size =
+                (((small ? LIPP_SMALL_PACKET_SIZE : large_size) +
+                  CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE());
+
+       /*
+        * ISSUE: Since CPAs are 38 bits, and we can only encode the
+        * high 31 bits in a "linux_buffer_t", the low 7 bits must be
+        * zero, and thus, we must align the actual "va" mod 128.
+        */
+       const unsigned long align = 128;
+
+       struct sk_buff *skb;
+       void *va;
+
+       struct sk_buff **skb_ptr;
+
+       /* Note that "dev_alloc_skb()" adds NET_SKB_PAD more bytes, */
+       /* and also "reserves" that many bytes. */
+       /* ISSUE: Can we "share" the NET_SKB_PAD bytes with "skb_ptr"? */
+       int len = sizeof(*skb_ptr) + align + buffer_size;
+
+       while (1) {
+
+               /* Allocate (or fail). */
+               skb = dev_alloc_skb(len);
+               if (skb == NULL)
+                       return false;
+
+               /* Make room for a back-pointer to 'skb'. */
+               skb_reserve(skb, sizeof(*skb_ptr));
+
+               /* Make sure we are aligned. */
+               skb_reserve(skb, -(long)skb->data & (align - 1));
+
+               /* This address is given to IPP. */
+               va = skb->data;
+
+               if (small)
+                       break;
+
+               /* ISSUE: This has never been observed! */
+               /* Large buffers must not span a huge page. */
+               if (((((long)va & ~HPAGE_MASK) + 1535) & HPAGE_MASK) == 0)
+                       break;
+               pr_err("Leaking unaligned linux buffer at %p.\n", va);
+       }
+
+       /* Skip two bytes to satisfy LIPP assumptions. */
+       /* Note that this aligns IP on a 16 byte boundary. */
+       /* ISSUE: Do this when the packet arrives? */
+       skb_reserve(skb, NET_IP_ALIGN);
+
+       /* Save a back-pointer to 'skb'. */
+       skb_ptr = va - sizeof(*skb_ptr);
+       *skb_ptr = skb;
+
+       /* Invalidate the packet buffer. */
+       if (!hash_default)
+               __inv_buffer(skb->data, buffer_size);
+
+       /* Make sure "skb_ptr" has been flushed. */
+       __insn_mf();
+
+#ifdef TILE_NET_PARANOIA
+#if CHIP_HAS_CBOX_HOME_MAP()
+       if (hash_default) {
+               HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)va);
+               if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+                       panic("Non-coherent ingress buffer!");
+       }
+#endif
+#endif
+
+       /* Provide the new buffer. */
+       tile_net_provide_linux_buffer(info, va, small);
+
+       return true;
+}
+
+
+/*
+ * Provide linux buffers for LIPP.
+ */
+static void tile_net_provide_needed_buffers(struct tile_net_cpu *info)
+{
+       while (info->num_needed_small_buffers != 0) {
+               if (!tile_net_provide_needed_buffer(info, true))
+                       goto oops;
+               info->num_needed_small_buffers--;
+       }
+
+       while (info->num_needed_large_buffers != 0) {
+               if (!tile_net_provide_needed_buffer(info, false))
+                       goto oops;
+               info->num_needed_large_buffers--;
+       }
+
+       return;
+
+oops:
+
+       /* Add a description to the page allocation failure dump. */
+       pr_notice("Could not provide a linux buffer to LIPP.\n");
+}
+
+
+/*
+ * Grab some LEPP completions, and store them in "comps", of size
+ * "comps_size", and return the number of completions which were
+ * stored, so the caller can free them.
+ *
+ * If "pending" is not NULL, it will be set to true if there might
+ * still be some pending completions caused by this tile, else false.
+ */
+static unsigned int tile_net_lepp_grab_comps(struct net_device *dev,
+                                            struct sk_buff *comps[],
+                                            unsigned int comps_size,
+                                            bool *pending)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       lepp_queue_t *eq = priv->epp_queue;
+
+       unsigned int n = 0;
+
+       unsigned int comp_head;
+       unsigned int comp_busy;
+       unsigned int comp_tail;
+
+       spin_lock(&priv->comp_lock);
+
+       comp_head = eq->comp_head;
+       comp_busy = eq->comp_busy;
+       comp_tail = eq->comp_tail;
+
+       while (comp_head != comp_busy && n < comps_size) {
+               comps[n++] = eq->comps[comp_head];
+               LEPP_QINC(comp_head);
+       }
+
+       if (pending != NULL)
+               *pending = (comp_head != comp_tail);
+
+       eq->comp_head = comp_head;
+
+       spin_unlock(&priv->comp_lock);
+
+       return n;
+}
+
+
+/*
+ * Make sure the egress timer is scheduled.
+ *
+ * Note that we use "schedule if not scheduled" logic instead of the more
+ * obvious "reschedule" logic, because "reschedule" is fairly expensive.
+ */
+static void tile_net_schedule_egress_timer(struct tile_net_cpu *info)
+{
+       if (!info->egress_timer_scheduled) {
+               mod_timer_pinned(&info->egress_timer, jiffies + 1);
+               info->egress_timer_scheduled = true;
+       }
+}
+
+
+/*
+ * The "function" for "info->egress_timer".
+ *
+ * This timer will reschedule itself as long as there are any pending
+ * completions expected (on behalf of any tile).
+ *
+ * ISSUE: Realistically, will the timer ever stop scheduling itself?
+ *
+ * ISSUE: This timer is almost never actually needed, so just use a global
+ * timer that can run on any tile.
+ *
+ * ISSUE: Maybe instead track number of expected completions, and free
+ * only that many, resetting to zero if "pending" is ever false.
+ */
+static void tile_net_handle_egress_timer(unsigned long arg)
+{
+       struct tile_net_cpu *info = (struct tile_net_cpu *)arg;
+       struct net_device *dev = info->napi.dev;
+
+       struct sk_buff *olds[32];
+       unsigned int wanted = 32;
+       unsigned int i, nolds = 0;
+       bool pending;
+
+       /* The timer is no longer scheduled. */
+       info->egress_timer_scheduled = false;
+
+       nolds = tile_net_lepp_grab_comps(dev, olds, wanted, &pending);
+
+       for (i = 0; i < nolds; i++)
+               kfree_skb(olds[i]);
+
+       /* Reschedule timer if needed. */
+       if (pending)
+               tile_net_schedule_egress_timer(info);
+}
+
+
+#ifdef IGNORE_DUP_ACKS
+
+/*
+ * Help detect "duplicate" ACKs.  These are sequential packets (for a
+ * given flow) which are exactly 66 bytes long, sharing everything but
+ * ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32,
+ * Tstamps=10@0x38.  The ID's are +1, the Hsum's are -1, the Ack's are
+ * +N, and the Tstamps are usually identical.
+ *
+ * NOTE: Apparently truly duplicate acks (with identical "ack" values),
+ * should not be collapsed, as they are used for some kind of flow control.
+ */
+static bool is_dup_ack(char *s1, char *s2, unsigned int len)
+{
+       int i;
+
+       unsigned long long ignorable = 0;
+
+       /* Identification. */
+       ignorable |= (1ULL << 0x12);
+       ignorable |= (1ULL << 0x13);
+
+       /* Header checksum. */
+       ignorable |= (1ULL << 0x18);
+       ignorable |= (1ULL << 0x19);
+
+       /* ACK. */
+       ignorable |= (1ULL << 0x2a);
+       ignorable |= (1ULL << 0x2b);
+       ignorable |= (1ULL << 0x2c);
+       ignorable |= (1ULL << 0x2d);
+
+       /* WinSize. */
+       ignorable |= (1ULL << 0x30);
+       ignorable |= (1ULL << 0x31);
+
+       /* Checksum. */
+       ignorable |= (1ULL << 0x32);
+       ignorable |= (1ULL << 0x33);
+
+       for (i = 0; i < len; i++, ignorable >>= 1) {
+
+               if ((ignorable & 1) || (s1[i] == s2[i]))
+                       continue;
+
+#ifdef TILE_NET_DEBUG
+               /* HACK: Mention non-timestamp diffs. */
+               if (i < 0x38 && i != 0x2f &&
+                   net_ratelimit())
+                       pr_info("Diff at 0x%x\n", i);
+#endif
+
+               return false;
+       }
+
+#ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS
+       /* HACK: Do not suppress truly duplicate ACKs. */
+       /* ISSUE: Is this actually necessary or helpful? */
+       if (s1[0x2a] == s2[0x2a] &&
+           s1[0x2b] == s2[0x2b] &&
+           s1[0x2c] == s2[0x2c] &&
+           s1[0x2d] == s2[0x2d]) {
+               return false;
+       }
+#endif
+
+       return true;
+}
+
+#endif
+
+
+
+/*
+ * Like "tile_net_handle_packets()", but just discard packets.
+ */
+static void tile_net_discard_packets(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+
+       while (qup->__packet_receive_read !=
+              qsp->__packet_receive_queue.__packet_write) {
+
+               int index = qup->__packet_receive_read;
+
+               int index2_aux = index + sizeof(netio_pkt_t);
+               int index2 =
+                       ((index2_aux ==
+                         qsp->__packet_receive_queue.__last_packet_plus_one) ?
+                        0 : index2_aux);
+
+               netio_pkt_t *pkt = (netio_pkt_t *)
+                       ((unsigned long) &qsp[1] + index);
+
+               /* Extract the "linux_buffer_t". */
+               unsigned int buffer = pkt->__packet.word;
+
+               /* Convert "linux_buffer_t" to "va". */
+               void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+               /* Acquire the associated "skb". */
+               struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+               struct sk_buff *skb = *skb_ptr;
+
+               kfree_skb(skb);
+
+               /* Consume this packet. */
+               qup->__packet_receive_read = index2;
+       }
+}
+
+
+/*
+ * Handle the next packet.  Return true if "processed", false if "filtered".
+ */
+static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
+{
+       struct net_device *dev = info->napi.dev;
+
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+       struct tile_net_stats_t *stats = &info->stats;
+
+       int filter;
+
+       int index2_aux = index + sizeof(netio_pkt_t);
+       int index2 =
+               ((index2_aux ==
+                 qsp->__packet_receive_queue.__last_packet_plus_one) ?
+                0 : index2_aux);
+
+       netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long) &qsp[1] + index);
+
+       netio_pkt_metadata_t *metadata = NETIO_PKT_METADATA(pkt);
+
+       /* Extract the packet size. */
+       unsigned long len =
+               (NETIO_PKT_CUSTOM_LENGTH(pkt) +
+                NET_IP_ALIGN - NETIO_PACKET_PADDING);
+
+       /* Extract the "linux_buffer_t". */
+       unsigned int buffer = pkt->__packet.word;
+
+       /* Extract "small" (vs "large"). */
+       bool small = ((buffer & 1) != 0);
+
+       /* Convert "linux_buffer_t" to "va". */
+       void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+       /* Extract the packet data pointer. */
+       /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */
+       unsigned char *buf = va + NET_IP_ALIGN;
+
+#ifdef IGNORE_DUP_ACKS
+
+       static int other;
+       static int final;
+       static int keep;
+       static int skip;
+
+#endif
+
+       /* Invalidate the packet buffer. */
+       if (!hash_default)
+               __inv_buffer(buf, len);
+
+       /* ISSUE: Is this needed? */
+       dev->last_rx = jiffies;
+
+#ifdef TILE_NET_DUMP_PACKETS
+       dump_packet(buf, len, "rx");
+#endif /* TILE_NET_DUMP_PACKETS */
+
+#ifdef TILE_NET_VERIFY_INGRESS
+       if (!NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt) &&
+           NETIO_PKT_L4_CSUM_CALCULATED_M(metadata, pkt)) {
+               /*
+                * FIXME: This complains about UDP packets
+                * with a "zero" checksum (bug 6624).
+                */
+#ifdef TILE_NET_PANIC_ON_BAD
+               dump_packet(buf, len, "rx");
+               panic("Bad L4 checksum.");
+#else
+               pr_warning("Bad L4 checksum on %d byte packet.\n", len);
+#endif
+       }
+       if (!NETIO_PKT_L3_CSUM_CORRECT_M(metadata, pkt) &&
+           NETIO_PKT_L3_CSUM_CALCULATED_M(metadata, pkt)) {
+               dump_packet(buf, len, "rx");
+               panic("Bad L3 checksum.");
+       }
+       switch (NETIO_PKT_STATUS_M(metadata, pkt)) {
+       case NETIO_PKT_STATUS_OVERSIZE:
+               if (len >= 64) {
+                       dump_packet(buf, len, "rx");
+                       panic("Unexpected OVERSIZE.");
+               }
+               break;
+       case NETIO_PKT_STATUS_BAD:
+#ifdef TILE_NET_PANIC_ON_BAD
+               dump_packet(buf, len, "rx");
+               panic("Unexpected BAD packet.");
+#else
+               pr_warning("Unexpected BAD %d byte packet.\n", len);
+#endif
+       }
+#endif
+
+       filter = 0;
+
+       if (!(dev->flags & IFF_UP)) {
+               /* Filter packets received before we're up. */
+               filter = 1;
+       } else if (!(dev->flags & IFF_PROMISC)) {
+               /*
+                * FIXME: Implement HW multicast filter.
+                */
+               if (!IS_MULTICAST(buf) && !IS_BROADCAST(buf)) {
+                       /* Filter packets not for our address. */
+                       const u8 *mine = dev->dev_addr;
+                       filter = compare_ether_addr(mine, buf);
+               }
+       }
+
+#ifdef IGNORE_DUP_ACKS
+
+       if (len != 66) {
+               /* FIXME: Must check "is_tcp_ack(buf, len)" somehow. */
+
+               other++;
+
+       } else if (index2 ==
+                  qsp->__packet_receive_queue.__packet_write) {
+
+               final++;
+
+       } else {
+
+               netio_pkt_t *pkt2 = (netio_pkt_t *)
+                       ((unsigned long) &qsp[1] + index2);
+
+               netio_pkt_metadata_t *metadata2 =
+                       NETIO_PKT_METADATA(pkt2);
+
+               /* Extract the packet size. */
+               unsigned long len2 =
+                       (NETIO_PKT_CUSTOM_LENGTH(pkt2) +
+                        NET_IP_ALIGN - NETIO_PACKET_PADDING);
+
+               if (len2 == 66 &&
+                   NETIO_PKT_FLOW_HASH_M(metadata, pkt) ==
+                   NETIO_PKT_FLOW_HASH_M(metadata2, pkt2)) {
+
+                       /* Extract the "linux_buffer_t". */
+                       unsigned int buffer2 = pkt2->__packet.word;
+
+                       /* Convert "linux_buffer_t" to "va". */
+                       void *va2 =
+                               __va((phys_addr_t)(buffer2 >> 1) << 7);
+
+                       /* Extract the packet data pointer. */
+                       /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */
+                       unsigned char *buf2 = va2 + NET_IP_ALIGN;
+
+                       /* Invalidate the packet buffer. */
+                       if (!hash_default)
+                               __inv_buffer(buf2, len2);
+
+                       if (is_dup_ack(buf, buf2, len)) {
+                               skip++;
+                               filter = 1;
+                       } else {
+                               keep++;
+                       }
+               }
+       }
+
+       if (net_ratelimit())
+               pr_info("Other %d Final %d Keep %d Skip %d.\n",
+                       other, final, keep, skip);
+
+#endif
+
+       if (filter) {
+
+               /* ISSUE: Update "drop" statistics? */
+
+               tile_net_provide_linux_buffer(info, va, small);
+
+       } else {
+
+               /* Acquire the associated "skb". */
+               struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+               struct sk_buff *skb = *skb_ptr;
+
+               /* Paranoia. */
+               if (skb->data != buf)
+                       panic("Corrupt linux buffer from LIPP! "
+                             "VA=%p, skb=%p, skb->data=%p\n",
+                             va, skb, skb->data);
+
+               /* Encode the actual packet length. */
+               skb_put(skb, len);
+
+               /* NOTE: This call also sets "skb->dev = dev". */
+               skb->protocol = eth_type_trans(skb, dev);
+
+               /* ISSUE: Discard corrupt packets? */
+               /* ISSUE: Discard packets with bad checksums? */
+
+               /* Avoid recomputing TCP/UDP checksums. */
+               if (NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt))
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+               netif_receive_skb(skb);
+
+               stats->rx_packets++;
+               stats->rx_bytes += len;
+
+               if (small)
+                       info->num_needed_small_buffers++;
+               else
+                       info->num_needed_large_buffers++;
+       }
+
+       /* Return four credits after every fourth packet. */
+       if (--qup->__receive_credit_remaining == 0) {
+               u32 interval = qup->__receive_credit_interval;
+               qup->__receive_credit_remaining = interval;
+               __netio_fastio_return_credits(qup->__fastio_index, interval);
+       }
+
+       /* Consume this packet. */
+       qup->__packet_receive_read = index2;
+
+       return !filter;
+}
+
+
+/*
+ * Handle some packets for the given device on the current CPU.
+ *
+ * ISSUE: The "rotting packet" race condition occurs if a packet
+ * arrives after the queue appears to be empty, and before the
+ * hypervisor interrupt is re-enabled.
+ */
+static int tile_net_poll(struct napi_struct *napi, int budget)
+{
+       struct net_device *dev = napi->dev;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+
+       unsigned int work = 0;
+
+       while (1) {
+               int index = qup->__packet_receive_read;
+               if (index == qsp->__packet_receive_queue.__packet_write)
+                       break;
+
+               if (tile_net_poll_aux(info, index)) {
+                       if (++work >= budget)
+                               goto done;
+               }
+       }
+
+       napi_complete(&info->napi);
+
+       /* Re-enable hypervisor interrupts. */
+       enable_percpu_irq(priv->intr_id);
+
+       /* HACK: Avoid the "rotting packet" problem. */
+       if (qup->__packet_receive_read !=
+           qsp->__packet_receive_queue.__packet_write)
+               napi_schedule(&info->napi);
+
+       /* ISSUE: Handle completions? */
+
+done:
+
+       tile_net_provide_needed_buffers(info);
+
+       return work;
+}
+
+
+/*
+ * Handle an ingress interrupt for the given device on the current cpu.
+ */
+static irqreturn_t tile_net_handle_ingress_interrupt(int irq, void *dev_ptr)
+{
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+       /* Disable hypervisor interrupt. */
+       disable_percpu_irq(priv->intr_id);
+
+       napi_schedule(&info->napi);
+
+       return IRQ_HANDLED;
+}
+
+
+/*
+ * One time initialization per interface.
+ */
+static int tile_net_open_aux(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       int ret;
+       int dummy;
+       unsigned int epp_lotar;
+
+       /*
+        * Find out where EPP memory should be homed.
+        */
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&epp_lotar, sizeof(epp_lotar),
+                          NETIO_EPP_SHM_OFF);
+       if (ret < 0) {
+               pr_err("could not read epp_shm_queue lotar.\n");
+               return -EIO;
+       }
+
+       /*
+        * Home the page on the EPP.
+        */
+       {
+               int epp_home = hv_lotar_to_cpu(epp_lotar);
+               struct page *page = virt_to_page(priv->epp_queue);
+               homecache_change_page_home(page, 0, epp_home);
+       }
+
+       /*
+        * Register the EPP shared memory queue.
+        */
+       {
+               netio_ipp_address_t ea = {
+                       .va = 0,
+                       .pa = __pa(priv->epp_queue),
+                       .pte = hv_pte(0),
+                       .size = PAGE_SIZE,
+               };
+               ea.pte = hv_pte_set_lotar(ea.pte, epp_lotar);
+               ea.pte = hv_pte_set_mode(ea.pte, HV_PTE_MODE_CACHE_TILE_L3);
+               ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+                                   (HV_VirtAddr)&ea,
+                                   sizeof(ea),
+                                   NETIO_EPP_SHM_OFF);
+               if (ret < 0)
+                       return -EIO;
+       }
+
+       /*
+        * Start LIPP/LEPP.
+        */
+       if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                         sizeof(dummy), NETIO_IPP_START_SHIM_OFF) < 0) {
+               pr_warning("Failed to start LIPP/LEPP.\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Register with hypervisor on each CPU.
+ *
+ * Strangely, this function does important things even if it "fails",
+ * which is especially common if the link is not up yet.  Hopefully
+ * these things are all "harmless" if done twice!
+ */
+static void tile_net_register(void *dev_ptr)
+{
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info;
+
+       struct tile_netio_queue *queue;
+
+       /* Only network cpus can receive packets. */
+       int queue_id =
+               cpumask_test_cpu(my_cpu, &priv->network_cpus_map) ? 0 : 255;
+
+       netio_input_config_t config = {
+               .flags = 0,
+               .num_receive_packets = priv->network_cpus_credits,
+               .queue_id = queue_id
+       };
+
+       int ret = 0;
+       netio_queue_impl_t *queuep;
+
+       PDEBUG("tile_net_register(queue_id %d)\n", queue_id);
+
+       if (!strcmp(dev->name, "xgbe0"))
+               info = &__get_cpu_var(hv_xgbe0);
+       else if (!strcmp(dev->name, "xgbe1"))
+               info = &__get_cpu_var(hv_xgbe1);
+       else if (!strcmp(dev->name, "gbe0"))
+               info = &__get_cpu_var(hv_gbe0);
+       else if (!strcmp(dev->name, "gbe1"))
+               info = &__get_cpu_var(hv_gbe1);
+       else
+               BUG();
+
+       /* Initialize the egress timer. */
+       init_timer(&info->egress_timer);
+       info->egress_timer.data = (long)info;
+       info->egress_timer.function = tile_net_handle_egress_timer;
+
+       priv->cpu[my_cpu] = info;
+
+       /*
+        * Register ourselves with the IPP.
+        */
+       ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+                           (HV_VirtAddr)&config,
+                           sizeof(netio_input_config_t),
+                           NETIO_IPP_INPUT_REGISTER_OFF);
+       PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+              ret);
+       if (ret < 0) {
+               printk(KERN_DEBUG "hv_dev_pwrite NETIO_IPP_INPUT_REGISTER_OFF"
+                      " failure %d\n", ret);
+               info->link_down = (ret == NETIO_LINK_DOWN);
+               return;
+       }
+
+       /*
+        * Get the pointer to our queue's system part.
+        */
+
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&queuep,
+                          sizeof(netio_queue_impl_t *),
+                          NETIO_IPP_INPUT_REGISTER_OFF);
+       PDEBUG("hv_dev_pread(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+              ret);
+       PDEBUG("queuep %p\n", queuep);
+       if (ret <= 0) {
+               /* ISSUE: Shouldn't this be a fatal error? */
+               pr_err("hv_dev_pread NETIO_IPP_INPUT_REGISTER_OFF failure\n");
+               return;
+       }
+
+       queue = &info->queue;
+
+       queue->__system_part = queuep;
+
+       memset(&queue->__user_part, 0, sizeof(netio_queue_user_impl_t));
+
+       /* This is traditionally "config.num_receive_packets / 2". */
+       queue->__user_part.__receive_credit_interval = 4;
+       queue->__user_part.__receive_credit_remaining =
+               queue->__user_part.__receive_credit_interval;
+
+       /*
+        * Get a fastio index from the hypervisor.
+        * ISSUE: Shouldn't this check the result?
+        */
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&queue->__user_part.__fastio_index,
+                          sizeof(queue->__user_part.__fastio_index),
+                          NETIO_IPP_GET_FASTIO_OFF);
+       PDEBUG("hv_dev_pread(NETIO_IPP_GET_FASTIO_OFF) returned %d\n", ret);
+
+       netif_napi_add(dev, &info->napi, tile_net_poll, 64);
+
+       /* Now we are registered. */
+       info->registered = true;
+}
+
+
+/*
+ * Unregister with hypervisor on each CPU.
+ */
+static void tile_net_unregister(void *dev_ptr)
+{
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+       int ret = 0;
+       int dummy = 0;
+
+       /* Do nothing if never registered. */
+       if (info == NULL)
+               return;
+
+       /* Do nothing if already unregistered. */
+       if (!info->registered)
+               return;
+
+       /*
+        * Unregister ourselves with LIPP.
+        */
+       ret = hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                           sizeof(dummy), NETIO_IPP_INPUT_UNREGISTER_OFF);
+       PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_UNREGISTER_OFF) returned %d\n",
+              ret);
+       if (ret < 0) {
+               /* FIXME: Just panic? */
+               pr_err("hv_dev_pwrite NETIO_IPP_INPUT_UNREGISTER_OFF"
+                      " failure %d\n", ret);
+       }
+
+       /*
+        * Discard all packets still in our NetIO queue.  Hopefully,
+        * once the unregister call is complete, there will be no
+        * packets still in flight on the IDN.
+        */
+       tile_net_discard_packets(dev);
+
+       /* Reset state. */
+       info->num_needed_small_buffers = 0;
+       info->num_needed_large_buffers = 0;
+
+       /* Cancel egress timer. */
+       del_timer(&info->egress_timer);
+       info->egress_timer_scheduled = false;
+
+       netif_napi_del(&info->napi);
+
+       /* Now we are unregistered. */
+       info->registered = false;
+}
+
+
+/*
+ * Helper function for "tile_net_stop()".
+ *
+ * Also used to handle registration failure in "tile_net_open_inner()",
+ * when "fully_opened" is known to be false, and the various extra
+ * steps in "tile_net_stop()" are not necessary.  ISSUE: It might be
+ * simpler if we could just call "tile_net_stop()" anyway.
+ */
+static void tile_net_stop_aux(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       int dummy = 0;
+
+       /* Unregister all tiles, so LIPP will stop delivering packets. */
+       on_each_cpu(tile_net_unregister, (void *)dev, 1);
+
+       /* Stop LIPP/LEPP. */
+       if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                         sizeof(dummy), NETIO_IPP_STOP_SHIM_OFF) < 0)
+               panic("Failed to stop LIPP/LEPP!\n");
+
+       priv->partly_opened = 0;
+}
+
+
+/*
+ * Disable ingress interrupts for the given device on the current cpu.
+ */
+static void tile_net_disable_intr(void *dev_ptr)
+{
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+       /* Disable hypervisor interrupt. */
+       disable_percpu_irq(priv->intr_id);
+
+       /* Disable NAPI if needed. */
+       if (info != NULL && info->napi_enabled) {
+               napi_disable(&info->napi);
+               info->napi_enabled = false;
+       }
+}
+
+
+/*
+ * Enable ingress interrupts for the given device on the current cpu.
+ */
+static void tile_net_enable_intr(void *dev_ptr)
+{
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+       /* Enable hypervisor interrupt. */
+       enable_percpu_irq(priv->intr_id);
+
+       /* Enable NAPI. */
+       napi_enable(&info->napi);
+       info->napi_enabled = true;
+}
+
+
+/*
+ * tile_net_open_inner does most of the work of bringing up the interface.
+ * It's called from tile_net_open(), and also from tile_net_retry_open().
+ * The return value is 0 if the interface was brought up, < 0 if
+ * tile_net_open() should return the return value as an error, and > 0 if
+ * tile_net_open() should return success and schedule a work item to
+ * periodically retry the bringup.
+ */
+static int tile_net_open_inner(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info;
+       struct tile_netio_queue *queue;
+       unsigned int irq;
+       int i;
+
+       /*
+        * First try to register just on the local CPU, and handle any
+        * semi-expected "link down" failure specially.  Note that we
+        * do NOT call "tile_net_stop_aux()", unlike below.
+        */
+       tile_net_register(dev);
+       info = priv->cpu[my_cpu];
+       if (!info->registered) {
+               if (info->link_down)
+                       return 1;
+               return -EAGAIN;
+       }
+
+       /*
+        * Now register everywhere else.  If any registration fails,
+        * even for "link down" (which might not be possible), we
+        * clean up using "tile_net_stop_aux()".
+        */
+       smp_call_function(tile_net_register, (void *)dev, 1);
+       for_each_online_cpu(i) {
+               if (!priv->cpu[i]->registered) {
+                       tile_net_stop_aux(dev);
+                       return -EAGAIN;
+               }
+       }
+
+       queue = &info->queue;
+
+       /*
+        * Set the device intr bit mask.
+        * The tile_net_register above sets per tile __intr_id.
+        */
+       priv->intr_id = queue->__system_part->__intr_id;
+       BUG_ON(!priv->intr_id);
+
+       /*
+        * Register the device interrupt handler.
+        * The __ffs() function returns the index into the interrupt handler
+        * table from the interrupt bit mask which should have one bit
+        * and one bit only set.
+        */
+       irq = __ffs(priv->intr_id);
+       tile_irq_activate(irq, TILE_IRQ_PERCPU);
+       BUG_ON(request_irq(irq, tile_net_handle_ingress_interrupt,
+                          0, dev->name, (void *)dev) != 0);
+
+       /* ISSUE: How could "priv->fully_opened" ever be "true" here? */
+
+       if (!priv->fully_opened) {
+
+               int dummy = 0;
+
+               /* Allocate initial buffers. */
+
+               int max_buffers =
+                       priv->network_cpus_count * priv->network_cpus_credits;
+
+               info->num_needed_small_buffers =
+                       min(LIPP_SMALL_BUFFERS, max_buffers);
+
+               info->num_needed_large_buffers =
+                       min(LIPP_LARGE_BUFFERS, max_buffers);
+
+               tile_net_provide_needed_buffers(info);
+
+               if (info->num_needed_small_buffers != 0 ||
+                   info->num_needed_large_buffers != 0)
+                       panic("Insufficient memory for buffer stack!");
+
+               /* Start LIPP/LEPP and activate "ingress" at the shim. */
+               if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                                 sizeof(dummy), NETIO_IPP_INPUT_INIT_OFF) < 0)
+                       panic("Failed to activate the LIPP Shim!\n");
+
+               priv->fully_opened = 1;
+       }
+
+       /* On each tile, enable the hypervisor to trigger interrupts. */
+       /* ISSUE: Do this before starting LIPP/LEPP? */
+       on_each_cpu(tile_net_enable_intr, (void *)dev, 1);
+
+       /* Start our transmit queue. */
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+
+/*
+ * Called periodically to retry bringing up the NetIO interface,
+ * if it doesn't come up cleanly during tile_net_open().
+ */
+static void tile_net_open_retry(struct work_struct *w)
+{
+       struct delayed_work *dw =
+               container_of(w, struct delayed_work, work);
+
+       struct tile_net_priv *priv =
+               container_of(dw, struct tile_net_priv, retry_work);
+
+       /*
+        * Try to bring the NetIO interface up.  If it fails, reschedule
+        * ourselves to try again later; otherwise, tell Linux we now have
+        * a working link.  ISSUE: What if the return value is negative?
+        */
+       if (tile_net_open_inner(priv->dev))
+               schedule_delayed_work_on(singlethread_cpu, &priv->retry_work,
+                                        TILE_NET_RETRY_INTERVAL);
+       else
+               netif_carrier_on(priv->dev);
+}
+
+
+/*
+ * Called when a network interface is made active.
+ *
+ * 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.
+ *
+ * If the actual link is not available yet, then we tell Linux that
+ * we have no carrier, and we keep checking until the link comes up.
+ */
+static int tile_net_open(struct net_device *dev)
+{
+       int ret = 0;
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       /*
+        * We rely on priv->partly_opened to tell us if this is the
+        * first time this interface is being brought up. If it is
+        * set, the IPP was already initialized and should not be
+        * initialized again.
+        */
+       if (!priv->partly_opened) {
+
+               int count;
+               int credits;
+
+               /* Initialize LIPP/LEPP, and start the Shim. */
+               ret = tile_net_open_aux(dev);
+               if (ret < 0) {
+                       pr_err("tile_net_open_aux failed: %d\n", ret);
+                       return ret;
+               }
+
+               /* Analyze the network cpus. */
+
+               if (network_cpus_used)
+                       cpumask_copy(&priv->network_cpus_map,
+                                    &network_cpus_map);
+               else
+                       cpumask_copy(&priv->network_cpus_map, cpu_online_mask);
+
+
+               count = cpumask_weight(&priv->network_cpus_map);
+
+               /* Limit credits to available buffers, and apply min. */
+               credits = max(16, (LIPP_LARGE_BUFFERS / count) & ~1);
+
+               /* Apply "GBE" max limit. */
+               /* ISSUE: Use higher limit for XGBE? */
+               credits = min(NETIO_MAX_RECEIVE_PKTS, credits);
+
+               priv->network_cpus_count = count;
+               priv->network_cpus_credits = credits;
+
+#ifdef TILE_NET_DEBUG
+               pr_info("Using %d network cpus, with %d credits each\n",
+                      priv->network_cpus_count, priv->network_cpus_credits);
+#endif
+
+               priv->partly_opened = 1;
+       }
+
+       /*
+        * Attempt to bring up the link.
+        */
+       ret = tile_net_open_inner(dev);
+       if (ret <= 0) {
+               if (ret == 0)
+                       netif_carrier_on(dev);
+               return ret;
+       }
+
+       /*
+        * We were unable to bring up the NetIO interface, but we want to
+        * try again in a little bit.  Tell Linux that we have no carrier
+        * so it doesn't try to use the interface before the link comes up
+        * and then remember to try again later.
+        */
+       netif_carrier_off(dev);
+       schedule_delayed_work_on(singlethread_cpu, &priv->retry_work,
+                                TILE_NET_RETRY_INTERVAL);
+
+       return 0;
+}
+
+
+/*
+ * Disables a network interface.
+ *
+ * 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.
+ *
+ * ISSUE: Can this can be called while "tile_net_poll()" is running?
+ */
+static int tile_net_stop(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       bool pending = true;
+
+       PDEBUG("tile_net_stop()\n");
+
+       /* ISSUE: Only needed if not yet fully open. */
+       cancel_delayed_work_sync(&priv->retry_work);
+
+       /* Can't transmit any more. */
+       netif_stop_queue(dev);
+
+       /*
+        * Disable hypervisor interrupts on each tile.
+        */
+       on_each_cpu(tile_net_disable_intr, (void *)dev, 1);
+
+       /*
+        * Unregister the interrupt handler.
+        * The __ffs() function returns the index into the interrupt handler
+        * table from the interrupt bit mask which should have one bit
+        * and one bit only set.
+        */
+       if (priv->intr_id)
+               free_irq(__ffs(priv->intr_id), dev);
+
+       /*
+        * Drain all the LIPP buffers.
+        */
+
+       while (true) {
+               int buffer;
+
+               /* NOTE: This should never fail. */
+               if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer,
+                                sizeof(buffer), NETIO_IPP_DRAIN_OFF) < 0)
+                       break;
+
+               /* Stop when done. */
+               if (buffer == 0)
+                       break;
+
+               {
+                       /* Convert "linux_buffer_t" to "va". */
+                       void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+                       /* Acquire the associated "skb". */
+                       struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+                       struct sk_buff *skb = *skb_ptr;
+
+                       kfree_skb(skb);
+               }
+       }
+
+       /* Stop LIPP/LEPP. */
+       tile_net_stop_aux(dev);
+
+
+       priv->fully_opened = 0;
+
+
+       /*
+        * XXX: ISSUE: It appears that, in practice anyway, by the
+        * time we get here, there are no pending completions.
+        */
+       while (pending) {
+
+               struct sk_buff *olds[32];
+               unsigned int wanted = 32;
+               unsigned int i, nolds = 0;
+
+               nolds = tile_net_lepp_grab_comps(dev, olds,
+                                                wanted, &pending);
+
+               /* ISSUE: We have never actually seen this debug spew. */
+               if (nolds != 0)
+                       pr_info("During tile_net_stop(), grabbed %d comps.\n",
+                              nolds);
+
+               for (i = 0; i < nolds; i++)
+                       kfree_skb(olds[i]);
+       }
+
+
+       /* Wipe the EPP queue. */
+       memset(priv->epp_queue, 0, sizeof(lepp_queue_t));
+
+       /* Evict the EPP queue. */
+       finv_buffer(priv->epp_queue, PAGE_SIZE);
+
+       return 0;
+}
+
+
+/*
+ * Prepare the "frags" info for the resulting LEPP command.
+ *
+ * If needed, flush the memory used by the frags.
+ */
+static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
+                                     struct sk_buff *skb,
+                                     void *b_data, unsigned int b_len)
+{
+       unsigned int i, n = 0;
+
+       struct skb_shared_info *sh = skb_shinfo(skb);
+
+       phys_addr_t cpa;
+
+       if (b_len != 0) {
+
+               if (!hash_default)
+                       finv_buffer_remote(b_data, b_len);
+
+               cpa = __pa(b_data);
+               frags[n].cpa_lo = cpa;
+               frags[n].cpa_hi = cpa >> 32;
+               frags[n].length = b_len;
+               frags[n].hash_for_home = hash_default;
+               n++;
+       }
+
+       for (i = 0; i < sh->nr_frags; i++) {
+
+               skb_frag_t *f = &sh->frags[i];
+               unsigned long pfn = page_to_pfn(f->page);
+
+               /* FIXME: Compute "hash_for_home" properly. */
+               /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */
+               int hash_for_home = hash_default;
+
+               /* FIXME: Hmmm. */
+               if (!hash_default) {
+                       void *va = pfn_to_kaddr(pfn) + f->page_offset;
+                       BUG_ON(PageHighMem(f->page));
+                       finv_buffer_remote(va, f->size);
+               }
+
+               cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset;
+               frags[n].cpa_lo = cpa;
+               frags[n].cpa_hi = cpa >> 32;
+               frags[n].length = f->size;
+               frags[n].hash_for_home = hash_for_home;
+               n++;
+       }
+
+       return n;
+}
+
+
+/*
+ * This function takes "skb", consisting of a header template and a
+ * payload, and hands it to LEPP, to emit as one or more segments,
+ * each consisting of a possibly modified header, plus a piece of the
+ * payload, via a process known as "tcp segmentation offload".
+ *
+ * Usually, "data" will contain the header template, of size "sh_len",
+ * and "sh->frags" will contain "skb->data_len" bytes of payload, and
+ * there will be "sh->gso_segs" segments.
+ *
+ * Sometimes, if "sendfile()" requires copying, we will be called with
+ * "data" containing the header and payload, with "frags" being empty.
+ *
+ * In theory, "sh->nr_frags" could be 3, but in practice, it seems
+ * that this will never actually happen.
+ *
+ * See "emulate_large_send_offload()" for some reference code, which
+ * does not handle checksumming.
+ *
+ * ISSUE: How do we make sure that high memory DMA does not migrate?
+ */
+static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_net_stats_t *stats = &info->stats;
+
+       struct skb_shared_info *sh = skb_shinfo(skb);
+
+       unsigned char *data = skb->data;
+
+       /* The ip header follows the ethernet header. */
+       struct iphdr *ih = ip_hdr(skb);
+       unsigned int ih_len = ih->ihl * 4;
+
+       /* Note that "nh == ih", by definition. */
+       unsigned char *nh = skb_network_header(skb);
+       unsigned int eh_len = nh - data;
+
+       /* The tcp header follows the ip header. */
+       struct tcphdr *th = (struct tcphdr *)(nh + ih_len);
+       unsigned int th_len = th->doff * 4;
+
+       /* The total number of header bytes. */
+       /* NOTE: This may be less than skb_headlen(skb). */
+       unsigned int sh_len = eh_len + ih_len + th_len;
+
+       /* The number of payload bytes at "skb->data + sh_len". */
+       /* This is non-zero for sendfile() without HIGHDMA. */
+       unsigned int b_len = skb_headlen(skb) - sh_len;
+
+       /* The total number of payload bytes. */
+       unsigned int d_len = b_len + skb->data_len;
+
+       /* The maximum payload size. */
+       unsigned int p_len = sh->gso_size;
+
+       /* The total number of segments. */
+       unsigned int num_segs = sh->gso_segs;
+
+       /* The temporary copy of the command. */
+       u32 cmd_body[(LEPP_MAX_CMD_SIZE + 3) / 4];
+       lepp_tso_cmd_t *cmd = (lepp_tso_cmd_t *)cmd_body;
+
+       /* Analyze the "frags". */
+       unsigned int num_frags =
+               tile_net_tx_frags(cmd->frags, skb, data + sh_len, b_len);
+
+       /* The size of the command, including frags and header. */
+       size_t cmd_size = LEPP_TSO_CMD_SIZE(num_frags, sh_len);
+
+       /* The command header. */
+       lepp_tso_cmd_t cmd_init = {
+               .tso = true,
+               .header_size = sh_len,
+               .ip_offset = eh_len,
+               .tcp_offset = eh_len + ih_len,
+               .payload_size = p_len,
+               .num_frags = num_frags,
+       };
+
+       unsigned long irqflags;
+
+       lepp_queue_t *eq = priv->epp_queue;
+
+       struct sk_buff *olds[4];
+       unsigned int wanted = 4;
+       unsigned int i, nolds = 0;
+
+       unsigned int cmd_head, cmd_tail, cmd_next;
+       unsigned int comp_tail;
+
+       unsigned int free_slots;
+
+
+       /* Paranoia. */
+       BUG_ON(skb->protocol != htons(ETH_P_IP));
+       BUG_ON(ih->protocol != IPPROTO_TCP);
+       BUG_ON(skb->ip_summed != CHECKSUM_PARTIAL);
+       BUG_ON(num_frags > LEPP_MAX_FRAGS);
+       /*--BUG_ON(num_segs != (d_len + (p_len - 1)) / p_len); */
+       BUG_ON(num_segs <= 1);
+
+
+       /* Finish preparing the command. */
+
+       /* Copy the command header. */
+       *cmd = cmd_init;
+
+       /* Copy the "header". */
+       memcpy(&cmd->frags[num_frags], data, sh_len);
+
+
+       /* Prefetch and wait, to minimize time spent holding the spinlock. */
+       prefetch_L1(&eq->comp_tail);
+       prefetch_L1(&eq->cmd_tail);
+       mb();
+
+
+       /* Enqueue the command. */
+
+       spin_lock_irqsave(&priv->cmd_lock, irqflags);
+
+       /*
+        * Handle completions if needed to make room.
+        * HACK: Spin until there is sufficient room.
+        */
+       free_slots = lepp_num_free_comp_slots(eq);
+       if (free_slots < 1) {
+spin:
+               nolds += tile_net_lepp_grab_comps(dev, olds + nolds,
+                                                 wanted - nolds, NULL);
+               if (lepp_num_free_comp_slots(eq) < 1)
+                       goto spin;
+       }
+
+       cmd_head = eq->cmd_head;
+       cmd_tail = eq->cmd_tail;
+
+       /* NOTE: The "gotos" below are untested. */
+
+       /* Prepare to advance, detecting full queue. */
+       cmd_next = cmd_tail + cmd_size;
+       if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+               goto spin;
+       if (cmd_next > LEPP_CMD_LIMIT) {
+               cmd_next = 0;
+               if (cmd_next == cmd_head)
+                       goto spin;
+       }
+
+       /* Copy the command. */
+       memcpy(&eq->cmds[cmd_tail], cmd, cmd_size);
+
+       /* Advance. */
+       cmd_tail = cmd_next;
+
+       /* Record "skb" for eventual freeing. */
+       comp_tail = eq->comp_tail;
+       eq->comps[comp_tail] = skb;
+       LEPP_QINC(comp_tail);
+       eq->comp_tail = comp_tail;
+
+       /* Flush before allowing LEPP to handle the command. */
+       __insn_mf();
+
+       eq->cmd_tail = cmd_tail;
+
+       spin_unlock_irqrestore(&priv->cmd_lock, irqflags);
+
+       if (nolds == 0)
+               nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL);
+
+       /* Handle completions. */
+       for (i = 0; i < nolds; i++)
+               kfree_skb(olds[i]);
+
+       /* Update stats. */
+       stats->tx_packets += num_segs;
+       stats->tx_bytes += (num_segs * sh_len) + d_len;
+
+       /* Make sure the egress timer is scheduled. */
+       tile_net_schedule_egress_timer(info);
+
+       return NETDEV_TX_OK;
+}
+
+
+/*
+ * Transmit a packet (called by the kernel via "hard_start_xmit" hook).
+ */
+static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_net_stats_t *stats = &info->stats;
+
+       unsigned long irqflags;
+
+       struct skb_shared_info *sh = skb_shinfo(skb);
+
+       unsigned int len = skb->len;
+       unsigned char *data = skb->data;
+
+       unsigned int csum_start = skb->csum_start - skb_headroom(skb);
+
+       lepp_frag_t frags[LEPP_MAX_FRAGS];
+
+       unsigned int num_frags;
+
+       lepp_queue_t *eq = priv->epp_queue;
+
+       struct sk_buff *olds[4];
+       unsigned int wanted = 4;
+       unsigned int i, nolds = 0;
+
+       unsigned int cmd_size = sizeof(lepp_cmd_t);
+
+       unsigned int cmd_head, cmd_tail, cmd_next;
+       unsigned int comp_tail;
+
+       lepp_cmd_t cmds[LEPP_MAX_FRAGS];
+
+       unsigned int free_slots;
+
+
+       /*
+        * This is paranoia, since we think that if the link doesn't come
+        * up, telling Linux we have no carrier will keep it from trying
+        * to transmit.  If it does, though, we can't execute this routine,
+        * since data structures we depend on aren't set up yet.
+        */
+       if (!info->registered)
+               return NETDEV_TX_BUSY;
+
+
+       /* Save the timestamp. */
+       dev->trans_start = jiffies;
+
+
+#ifdef TILE_NET_PARANOIA
+#if CHIP_HAS_CBOX_HOME_MAP()
+       if (hash_default) {
+               HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)data);
+               if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+                       panic("Non-coherent egress buffer!");
+       }
+#endif
+#endif
+
+
+#ifdef TILE_NET_DUMP_PACKETS
+       /* ISSUE: Does not dump the "frags". */
+       dump_packet(data, skb_headlen(skb), "tx");
+#endif /* TILE_NET_DUMP_PACKETS */
+
+
+       if (sh->gso_size != 0)
+               return tile_net_tx_tso(skb, dev);
+
+
+       /* Prepare the commands. */
+
+       num_frags = tile_net_tx_frags(frags, skb, data, skb_headlen(skb));
+
+       for (i = 0; i < num_frags; i++) {
+
+               bool final = (i == num_frags - 1);
+
+               lepp_cmd_t cmd = {
+                       .cpa_lo = frags[i].cpa_lo,
+                       .cpa_hi = frags[i].cpa_hi,
+                       .length = frags[i].length,
+                       .hash_for_home = frags[i].hash_for_home,
+                       .send_completion = final,
+                       .end_of_packet = final
+               };
+
+               if (i == 0 && skb->ip_summed == CHECKSUM_PARTIAL) {
+                       cmd.compute_checksum = 1;
+                       cmd.checksum_data.bits.start_byte = csum_start;
+                       cmd.checksum_data.bits.count = len - csum_start;
+                       cmd.checksum_data.bits.destination_byte =
+                               csum_start + skb->csum_offset;
+               }
+
+               cmds[i] = cmd;
+       }
+
+
+       /* Prefetch and wait, to minimize time spent holding the spinlock. */
+       prefetch_L1(&eq->comp_tail);
+       prefetch_L1(&eq->cmd_tail);
+       mb();
+
+
+       /* Enqueue the commands. */
+
+       spin_lock_irqsave(&priv->cmd_lock, irqflags);
+
+       /*
+        * Handle completions if needed to make room.
+        * HACK: Spin until there is sufficient room.
+        */
+       free_slots = lepp_num_free_comp_slots(eq);
+       if (free_slots < 1) {
+spin:
+               nolds += tile_net_lepp_grab_comps(dev, olds + nolds,
+                                                 wanted - nolds, NULL);
+               if (lepp_num_free_comp_slots(eq) < 1)
+                       goto spin;
+       }
+
+       cmd_head = eq->cmd_head;
+       cmd_tail = eq->cmd_tail;
+
+       /* NOTE: The "gotos" below are untested. */
+
+       /* Copy the commands, or fail. */
+       for (i = 0; i < num_frags; i++) {
+
+               /* Prepare to advance, detecting full queue. */
+               cmd_next = cmd_tail + cmd_size;
+               if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+                       goto spin;
+               if (cmd_next > LEPP_CMD_LIMIT) {
+                       cmd_next = 0;
+                       if (cmd_next == cmd_head)
+                               goto spin;
+               }
+
+               /* Copy the command. */
+               *(lepp_cmd_t *)&eq->cmds[cmd_tail] = cmds[i];
+
+               /* Advance. */
+               cmd_tail = cmd_next;
+       }
+
+       /* Record "skb" for eventual freeing. */
+       comp_tail = eq->comp_tail;
+       eq->comps[comp_tail] = skb;
+       LEPP_QINC(comp_tail);
+       eq->comp_tail = comp_tail;
+
+       /* Flush before allowing LEPP to handle the command. */
+       __insn_mf();
+
+       eq->cmd_tail = cmd_tail;
+
+       spin_unlock_irqrestore(&priv->cmd_lock, irqflags);
+
+       if (nolds == 0)
+               nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL);
+
+       /* Handle completions. */
+       for (i = 0; i < nolds; i++)
+               kfree_skb(olds[i]);
+
+       /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */
+       stats->tx_packets++;
+       stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN);
+
+       /* Make sure the egress timer is scheduled. */
+       tile_net_schedule_egress_timer(info);
+
+       return NETDEV_TX_OK;
+}
+
+
+/*
+ * Deal with a transmit timeout.
+ */
+static void tile_net_tx_timeout(struct net_device *dev)
+{
+       PDEBUG("tile_net_tx_timeout()\n");
+       PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies,
+              jiffies - dev->trans_start);
+
+       /* XXX: ISSUE: This doesn't seem useful for us. */
+       netif_wake_queue(dev);
+}
+
+
+/*
+ * Ioctl commands.
+ */
+static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       return -EOPNOTSUPP;
+}
+
+
+/*
+ * Get System Network Statistics.
+ *
+ * Returns the address of the device statistics structure.
+ */
+static struct net_device_stats *tile_net_get_stats(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+       u32 rx_packets = 0;
+       u32 tx_packets = 0;
+       u32 rx_bytes = 0;
+       u32 tx_bytes = 0;
+       int i;
+
+       for_each_online_cpu(i) {
+               if (priv->cpu[i]) {
+                       rx_packets += priv->cpu[i]->stats.rx_packets;
+                       rx_bytes += priv->cpu[i]->stats.rx_bytes;
+                       tx_packets += priv->cpu[i]->stats.tx_packets;
+                       tx_bytes += priv->cpu[i]->stats.tx_bytes;
+               }
+       }
+
+       priv->stats.rx_packets = rx_packets;
+       priv->stats.rx_bytes = rx_bytes;
+       priv->stats.tx_packets = tx_packets;
+       priv->stats.tx_bytes = tx_bytes;
+
+       return &priv->stats;
+}
+
+
+/*
+ * Change the "mtu".
+ *
+ * The "change_mtu" method is usually not needed.
+ * If you need it, it must be like this.
+ */
+static int tile_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+       PDEBUG("tile_net_change_mtu()\n");
+
+       /* Check ranges. */
+       if ((new_mtu < 68) || (new_mtu > 1500))
+               return -EINVAL;
+
+       /* Accept the value. */
+       dev->mtu = new_mtu;
+
+       return 0;
+}
+
+
+/*
+ * Change the Ethernet Address of the NIC.
+ *
+ * The hypervisor driver does not support changing MAC address.  However,
+ * the IPP does not do anything with the MAC address, so the address which
+ * gets used on outgoing packets, and which is accepted on incoming packets,
+ * is completely up to the NetIO program or kernel driver which is actually
+ * handling them.
+ *
+ * Returns 0 on success, negative on failure.
+ */
+static int tile_net_set_mac_address(struct net_device *dev, void *p)
+{
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+
+       /* ISSUE: Note that "dev_addr" is now a pointer. */
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+       return 0;
+}
+
+
+/*
+ * Obtain the MAC address from the hypervisor.
+ * This must be done before opening the device.
+ */
+static int tile_net_get_mac(struct net_device *dev)
+{
+       struct tile_net_priv *priv = netdev_priv(dev);
+
+       char hv_dev_name[32];
+       int len;
+
+       __netio_getset_offset_t offset = { .word = NETIO_IPP_PARAM_OFF };
+
+       int ret;
+
+       /* For example, "xgbe0". */
+       strcpy(hv_dev_name, dev->name);
+       len = strlen(hv_dev_name);
+
+       /* For example, "xgbe/0". */
+       hv_dev_name[len] = hv_dev_name[len - 1];
+       hv_dev_name[len - 1] = '/';
+       len++;
+
+       /* For example, "xgbe/0/native_hash". */
+       strcpy(hv_dev_name + len, hash_default ? "/native_hash" : "/native");
+
+       /* Get the hypervisor handle for this device. */
+       priv->hv_devhdl = hv_dev_open((HV_VirtAddr)hv_dev_name, 0);
+       PDEBUG("hv_dev_open(%s) returned %d %p\n",
+              hv_dev_name, priv->hv_devhdl, &priv->hv_devhdl);
+       if (priv->hv_devhdl < 0) {
+               if (priv->hv_devhdl == HV_ENODEV)
+                       printk(KERN_DEBUG "Ignoring unconfigured device %s\n",
+                                hv_dev_name);
+               else
+                       printk(KERN_DEBUG "hv_dev_open(%s) returned %d\n",
+                                hv_dev_name, priv->hv_devhdl);
+               return -1;
+       }
+
+       /*
+        * Read the hardware address from the hypervisor.
+        * ISSUE: Note that "dev_addr" is now a pointer.
+        */
+       offset.bits.class = NETIO_PARAM;
+       offset.bits.addr = NETIO_PARAM_MAC;
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)dev->dev_addr, dev->addr_len,
+                          offset.word);
+       PDEBUG("hv_dev_pread(NETIO_PARAM_MAC) returned %d\n", ret);
+       if (ret <= 0) {
+               printk(KERN_DEBUG "hv_dev_pread(NETIO_PARAM_MAC) %s failed\n",
+                      dev->name);
+               /*
+                * Since the device is configured by the hypervisor but we
+                * can't get its MAC address, we are most likely running
+                * the simulator, so let's generate a random MAC address.
+                */
+               random_ether_addr(dev->dev_addr);
+       }
+
+       return 0;
+}
+
+
+static struct net_device_ops tile_net_ops = {
+       .ndo_open = tile_net_open,
+       .ndo_stop = tile_net_stop,
+       .ndo_start_xmit = tile_net_tx,
+       .ndo_do_ioctl = tile_net_ioctl,
+       .ndo_get_stats = tile_net_get_stats,
+       .ndo_change_mtu = tile_net_change_mtu,
+       .ndo_tx_timeout = tile_net_tx_timeout,
+       .ndo_set_mac_address = tile_net_set_mac_address
+};
+
+
+/*
+ * The setup function.
+ *
+ * This uses ether_setup() to assign various fields in dev, including
+ * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields.
+ */
+static void tile_net_setup(struct net_device *dev)
+{
+       PDEBUG("tile_net_setup()\n");
+
+       ether_setup(dev);
+
+       dev->netdev_ops = &tile_net_ops;
+
+       dev->watchdog_timeo = TILE_NET_TIMEOUT;
+
+       /* We want lockless xmit. */
+       dev->features |= NETIF_F_LLTX;
+
+       /* We support hardware tx checksums. */
+       dev->features |= NETIF_F_HW_CSUM;
+
+       /* We support scatter/gather. */
+       dev->features |= NETIF_F_SG;
+
+       /* We support TSO. */
+       dev->features |= NETIF_F_TSO;
+
+#ifdef TILE_NET_GSO
+       /* We support GSO. */
+       dev->features |= NETIF_F_GSO;
+#endif
+
+       if (hash_default)
+               dev->features |= NETIF_F_HIGHDMA;
+
+       /* ISSUE: We should support NETIF_F_UFO. */
+
+       dev->tx_queue_len = TILE_NET_TX_QUEUE_LEN;
+
+       dev->mtu = TILE_NET_MTU;
+}
+
+
+/*
+ * Allocate the device structure, register the device, and obtain the
+ * MAC address from the hypervisor.
+ */
+static struct net_device *tile_net_dev_init(const char *name)
+{
+       int ret;
+       struct net_device *dev;
+       struct tile_net_priv *priv;
+       struct page *page;
+
+       /*
+        * Allocate the device structure.  This allocates "priv", calls
+        * tile_net_setup(), and saves "name".  Normally, "name" is a
+        * template, instantiated by register_netdev(), but not for us.
+        */
+       dev = alloc_netdev(sizeof(*priv), name, tile_net_setup);
+       if (!dev) {
+               pr_err("alloc_netdev(%s) failed\n", name);
+               return NULL;
+       }
+
+       priv = netdev_priv(dev);
+
+       /* Initialize "priv". */
+
+       memset(priv, 0, sizeof(*priv));
+
+       /* Save "dev" for "tile_net_open_retry()". */
+       priv->dev = dev;
+
+       INIT_DELAYED_WORK(&priv->retry_work, tile_net_open_retry);
+
+       spin_lock_init(&priv->cmd_lock);
+       spin_lock_init(&priv->comp_lock);
+
+       /* Allocate "epp_queue". */
+       BUG_ON(get_order(sizeof(lepp_queue_t)) != 0);
+       page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
+       if (!page) {
+               free_netdev(dev);
+               return NULL;
+       }
+       priv->epp_queue = page_address(page);
+
+       /* Register the network device. */
+       ret = register_netdev(dev);
+       if (ret) {
+               pr_err("register_netdev %s failed %d\n", dev->name, ret);
+               free_page((unsigned long)priv->epp_queue);
+               free_netdev(dev);
+               return NULL;
+       }
+
+       /* Get the MAC address. */
+       ret = tile_net_get_mac(dev);
+       if (ret < 0) {
+               unregister_netdev(dev);
+               free_page((unsigned long)priv->epp_queue);
+               free_netdev(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+
+
+/*
+ * Module cleanup.
+ */
+static void tile_net_cleanup(void)
+{
+       int i;
+
+       for (i = 0; i < TILE_NET_DEVS; i++) {
+               if (tile_net_devs[i]) {
+                       struct net_device *dev = tile_net_devs[i];
+                       struct tile_net_priv *priv = netdev_priv(dev);
+                       unregister_netdev(dev);
+                       finv_buffer(priv->epp_queue, PAGE_SIZE);
+                       free_page((unsigned long)priv->epp_queue);
+                       free_netdev(dev);
+               }
+       }
+}
+
+
+/*
+ * Module initialization.
+ */
+static int tile_net_init_module(void)
+{
+       pr_info("Tilera IPP Net Driver\n");
+
+       tile_net_devs[0] = tile_net_dev_init("xgbe0");
+       tile_net_devs[1] = tile_net_dev_init("xgbe1");
+       tile_net_devs[2] = tile_net_dev_init("gbe0");
+       tile_net_devs[3] = tile_net_dev_init("gbe1");
+
+       return 0;
+}
+
+
+#ifndef MODULE
+/*
+ * The "network_cpus" boot argument specifies the cpus that are dedicated
+ * to handle ingress packets.
+ *
+ * The parameter should be in the form "network_cpus=m-n[,x-y]", where
+ * m, n, x, y are integer numbers that represent the cpus that can be
+ * neither a dedicated cpu nor a dataplane cpu.
+ */
+static int __init network_cpus_setup(char *str)
+{
+       int rc = cpulist_parse_crop(str, &network_cpus_map);
+       if (rc != 0) {
+               pr_warning("network_cpus=%s: malformed cpu list\n",
+                      str);
+       } else {
+
+               /* Remove dedicated cpus. */
+               cpumask_and(&network_cpus_map, &network_cpus_map,
+                           cpu_possible_mask);
+
+
+               if (cpumask_empty(&network_cpus_map)) {
+                       pr_warning("Ignoring network_cpus='%s'.\n",
+                              str);
+               } else {
+                       char buf[1024];
+                       cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map);
+                       pr_info("Linux network CPUs: %s\n", buf);
+                       network_cpus_used = true;
+               }
+       }
+
+       return 0;
+}
+__setup("network_cpus=", network_cpus_setup);
+#endif
+
+
+module_init(tile_net_init_module);
+module_exit(tile_net_cleanup);
index 05a95586f3c52f76ead1b26bb6545b3a18b1a076..055b87ab4f075b66afb7cc4d33c58b440d4f83be 100644 (file)
@@ -899,7 +899,8 @@ struct ucc_geth_hardware_statistics {
 #define UCC_GETH_UTFS_INIT                      512    /* Tx virtual FIFO size
                                                         */
 #define UCC_GETH_UTFET_INIT                     256    /* 1/2 utfs */
-#define UCC_GETH_UTFTT_INIT                     512
+#define UCC_GETH_UTFTT_INIT                     256    /* 1/2 utfs
+                                                          due to errata */
 /* Gigabit Ethernet (1000 Mbps) */
 #define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/   /* Rx virtual
                                                                   FIFO size */
index b154a94de03e61927cdc063c8671867108cf7b89..62e9e8dc8190d69314529cd42d0d2b7f06228746 100644 (file)
@@ -2994,12 +2994,14 @@ static int hso_probe(struct usb_interface *interface,
 
        case HSO_INTF_BULK:
                /* It's a regular bulk interface */
-               if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) &&
-                   !disable_net)
-                       hso_dev = hso_create_net_device(interface, port_spec);
-               else
+               if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
+                       if (!disable_net)
+                               hso_dev =
+                                   hso_create_net_device(interface, port_spec);
+               } else {
                        hso_dev =
                            hso_create_bulk_serial_device(interface, port_spec);
+               }
                if (!hso_dev)
                        goto exit;
                break;
index d81ad83978855ac4929a93f082139afd63f8cc41..24297b274cd475ac855114394784c7eeaab2bcd0 100644 (file)
@@ -498,7 +498,6 @@ norbuff:
 static int x25_asy_close(struct net_device *dev)
 {
        struct x25_asy *sl = netdev_priv(dev);
-       int err;
 
        spin_lock(&sl->lock);
        if (sl->tty)
@@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev)
        netif_stop_queue(dev);
        sl->rcount = 0;
        sl->xleft  = 0;
-       err = lapb_unregister(dev);
-       if (err != LAPB_OK)
-               printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
-                       err);
        spin_unlock(&sl->lock);
        return 0;
 }
@@ -582,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
        if (err)
                return err;
        /* Done.  We have linked the TTY line to a channel. */
-       return sl->dev->base_addr;
+       return 0;
 }
 
 
@@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
 static void x25_asy_close_tty(struct tty_struct *tty)
 {
        struct x25_asy *sl = tty->disc_data;
+       int err;
 
        /* First make sure we're connected. */
        if (!sl || sl->magic != X25_ASY_MAGIC)
@@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty)
                dev_close(sl->dev);
        rtnl_unlock();
 
+       err = lapb_unregister(sl->dev);
+       if (err != LAPB_OK)
+               printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
+                       err);
+
        tty->disc_data = NULL;
        sl->tty = NULL;
        x25_asy_free(sl);
index 966b9496a9dd4b51cf5c1f850fc987ea4b6ffff2..195406db3bd899b28f96c7b8214428822c3735db 100644 (file)
@@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
        int addr, eep_start_loc;
        eep_data = (u16 *)eep;
 
-       if (ah->hw_version.devid == 0x7015)
+       if (AR9287_HTC_DEVID(ah))
                eep_start_loc = AR9287_HTC_EEP_START_LOC;
        else
                eep_start_loc = AR9287_EEP_START_LOC;
index f7ec31b4ddd3a9af801dcb8211763f21e6ab7e09..dfb6560dab9205c7502cc0a546c3549635d696f2 100644 (file)
@@ -36,8 +36,13 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */
+       { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */
+       { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
+       { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
        { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
        { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
+       { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
+       { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */
        { },
 };
 
@@ -806,6 +811,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                firm_offset = AR7010_FIRMWARE_TEXT;
                break;
        default:
@@ -928,6 +935,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
                        hif_dev->fw_name = FIRMWARE_AR7010_1_1;
                else
index 3d7b97f1b3aeebe5840c438b5ccf631de702d6c2..7c8a38d04561c26754147bea9e447724a9e8eb42 100644 (file)
@@ -249,6 +249,8 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
        case 0x7010:
        case 0x7015:
        case 0x9018:
+       case 0xA704:
+       case 0x1200:
                priv->htc->credits = 45;
                break;
        default:
index 3d19b5bc937f9c1c285e23645fcbf6a929037b21..29d80ca783933684b7c5c531cbb970ee7e006cda 100644 (file)
@@ -121,7 +121,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
                        tx_hdr.data_type = ATH9K_HTC_NORMAL;
                }
 
-               if (ieee80211_is_data(fc)) {
+               if (ieee80211_is_data_qos(fc)) {
                        qc = ieee80211_get_qos_ctl(hdr);
                        tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
                }
index 6a0d99eff404b77417856c7f1b7c035eb079359e..92bc5c5f48768ac42ca4b1bd02690d9d38ebed80 100644 (file)
@@ -817,8 +817,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
 
        ath9k_ps_wakeup(sc);
 
-       pm_qos_remove_request(&ath9k_pm_qos_req);
-
        wiphy_rfkill_stop_polling(sc->hw->wiphy);
        ath_deinit_leds(sc);
 
@@ -832,6 +830,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
        }
 
        ieee80211_unregister_hw(hw);
+       pm_qos_remove_request(&ath9k_pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index c76ea53c20ce7dbe41863c00930853a59ccc6cf8..1a62e351ec77c217598a46fae7bdbcc84c1c6050 100644 (file)
@@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
        bool stopped;
 
        spin_lock_bh(&sc->rx.rxbuflock);
-       ath9k_hw_stoppcurecv(ah);
+       ath9k_hw_abortpcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah);
 
index fa05b711e5cdfb7657f94ac420bc87a3f443c1ef..dddf579aacf1c391dfb3e9e73675de1a781760da 100644 (file)
 #define AR_DEVID_7010(_ah) \
        (((_ah)->hw_version.devid == 0x7010) || \
         ((_ah)->hw_version.devid == 0x7015) || \
-        ((_ah)->hw_version.devid == 0x9018))
+        ((_ah)->hw_version.devid == 0x9018) || \
+        ((_ah)->hw_version.devid == 0xA704) || \
+        ((_ah)->hw_version.devid == 0x1200))
+
+#define AR9287_HTC_DEVID(_ah) \
+       (((_ah)->hw_version.devid == 0x7015) || \
+        ((_ah)->hw_version.devid == 0x1200))
 
 #define AR_RADIO_SREV_MAJOR                   0xf0
 #define AR_RAD5133_SREV_MAJOR                 0xc0
index 980ae70ea424f6dc50a93734446536588bea9734..a314c2c2bfbea433849dc60ae7f44f67c2785358 100644 (file)
@@ -647,7 +647,7 @@ init:
        }
 
 unlock:
-       if (err && (vif_id != -1)) {
+       if (err && (vif_id >= 0)) {
                vif_priv->active = false;
                bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
                ar->vifs--;
index 3317039cd28fe5ae6b1e38ff0029bf345fd78d50..7504ed14c72575a7befb91b0c0d9dd2684660af9 100644 (file)
@@ -553,12 +553,12 @@ static int carl9170_usb_flush(struct ar9170 *ar)
                usb_free_urb(urb);
        }
 
-       ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ);
+       ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000);
        if (ret == 0)
                err = -ETIMEDOUT;
 
        /* lets wait a while until the tx - queues are dried out */
-       ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ);
+       ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000);
        if (ret == 0)
                err = -ETIMEDOUT;
 
index 9a55338d957f1768aed1121b393cca2ef862d640..09e2dfd7b175a74534de12fe240761f7a3138302 100644 (file)
@@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func,
 err_free_ssb:
        kfree(sdio);
 err_disable_func:
+       sdio_claim_host(func);
        sdio_disable_func(func);
 err_release_host:
        sdio_release_host(func);
index a38a7bd25f1916431bcf607a89bf4a0c126d5f8a..b9aedf18a04682dea5de87abc363546fcb054cd4 100644 (file)
@@ -57,7 +57,6 @@
 #include <linux/fcntl.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <linux/timer.h>
 
index d9f51485beeee9940ab66e597c47f0d17869da46..9383063d2b16896bfcc740855221c5eccfbf0570 100644 (file)
@@ -349,7 +349,6 @@ static struct irq_chip dino_interrupt_type = {
        .name   = "GSC-PCI",
        .unmask = dino_unmask_irq,
        .mask   = dino_mask_irq,
-       .ack    = no_ack_irq,
 };
 
 
index 1211974f55aac78e8dee465c4300ee028fbfcf62..e860038b0b841952f29021a5fa752f6d9ee4ea3e 100644 (file)
@@ -186,7 +186,6 @@ static struct irq_chip eisa_interrupt_type = {
        .name   =       "EISA",
        .unmask =       eisa_unmask_irq,
        .mask   =       eisa_mask_irq,
-       .ack    =       no_ack_irq,
 };
 
 static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
@@ -340,7 +339,7 @@ static int __init eisa_probe(struct parisc_device *dev)
        setup_irq(2, &irq2_action);
        for (i = 0; i < 16; i++) {
                set_irq_chip_and_handler(i, &eisa_interrupt_type,
-                       handle_level_irq);
+                                        handle_simple_irq);
        }
        
        EISA_bus = 1;
index cce00ed81f37908fd062d34a89ad3f8f49a5d4e3..af212c6a615840e7bf777fb931ff2770d490fb5d 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index e605298e3aeed606bbb2bf57c286fbdea1fc6a9a..772b1939ac218a2b9fc936ce57bc567761f050fc 100644 (file)
@@ -143,7 +143,6 @@ static struct irq_chip gsc_asic_interrupt_type = {
        .name   =       "GSC-ASIC",
        .unmask =       gsc_asic_unmask_irq,
        .mask   =       gsc_asic_mask_irq,
-       .ack    =       no_ack_irq,
 };
 
 int gsc_assign_irq(struct irq_chip *type, void *data)
@@ -153,7 +152,7 @@ int gsc_assign_irq(struct irq_chip *type, void *data)
        if (irq > GSC_IRQ_MAX)
                return NO_IRQ;
 
-       set_irq_chip_and_handler(irq, type, handle_level_irq);
+       set_irq_chip_and_handler(irq, type, handle_simple_irq);
        set_irq_chip_data(irq, data);
 
        return irq++;
index a3120a09c43dd603d9b96b0c5926e77ceebb8095..0327894bf2355c23d3e2b3daae80c8a2cadf7aeb 100644 (file)
@@ -669,6 +669,13 @@ printk("\n");
        DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
                        vi->eoi_addr, vi->eoi_data);
        iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
+
+static void iosapic_eoi_irq(unsigned int irq)
+{
+       struct vector_info *vi = get_irq_chip_data(irq);
+
+       iosapic_eoi(vi->eoi_addr, vi->eoi_data);
        cpu_eoi_irq(irq);
 }
 
@@ -705,6 +712,7 @@ static struct irq_chip iosapic_interrupt_type = {
        .unmask =       iosapic_unmask_irq,
        .mask   =       iosapic_mask_irq,
        .ack    =       cpu_ack_irq,
+       .eoi    =       iosapic_eoi_irq,
 #ifdef CONFIG_SMP
        .set_affinity = iosapic_set_affinity_irq,
 #endif
index 2350e8a86eefe807eaa2be1c814e614a688f2ad0..f2f501e5b6a0cb644b636937506734e436c76283 100644 (file)
@@ -64,6 +64,7 @@ static unsigned int led_diskio    __read_mostly = 1;
 static unsigned int led_lanrxtx   __read_mostly = 1;
 static char lcd_text[32]          __read_mostly;
 static char lcd_text_default[32]  __read_mostly;
+static int  lcd_no_led_support    __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
 
 
 static struct workqueue_struct *led_wq;
@@ -115,7 +116,7 @@ lcd_info __attribute__((aligned(8))) __read_mostly =
        .lcd_width =            16,
        .lcd_cmd_reg_addr =     KITTYHAWK_LCD_CMD,
        .lcd_data_reg_addr =    KITTYHAWK_LCD_DATA,
-       .min_cmd_delay =        40,
+       .min_cmd_delay =        80,
        .reset_cmd1 =           0x80,
        .reset_cmd2 =           0xc0,
 };
@@ -135,6 +136,9 @@ static int start_task(void)
        /* Display the default text now */
        if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
 
+       /* KittyHawk has no LED support on its LCD */
+       if (lcd_no_led_support) return 0;
+
        /* Create the work queue and queue the LED task */
        led_wq = create_singlethread_workqueue("led_wq");       
        queue_delayed_work(led_wq, &led_task, 0);
@@ -248,9 +252,13 @@ static int __init led_create_procfs(void)
 
        proc_pdc_root = proc_mkdir("pdc", 0);
        if (!proc_pdc_root) return -1;
-       ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
-                               &led_proc_fops, (void *)LED_NOLCD); /* LED */
-       if (!ent) return -1;
+
+       if (!lcd_no_led_support)
+       {
+               ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+                                       &led_proc_fops, (void *)LED_NOLCD); /* LED */
+               if (!ent) return -1;
+       }
 
        if (led_type == LED_HASLCD)
        {
@@ -692,6 +700,7 @@ int __init led_init(void)
        case 0x58B:             /* KittyHawk DC2 100 (K200) */
                printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
                                "LED detection skipped.\n", __FILE__, CPU_HVERSION);
+               lcd_no_led_support = 1;
                goto found;     /* use the preinitialized values of lcd_info */
        }
 
index 0846dafdfff10a2f1536fad7393459c4a08b6af0..28241532c0fd1b56c7f6bfa50d788c5fef1e9e3a 100644 (file)
@@ -323,7 +323,6 @@ static struct irq_chip superio_interrupt_type = {
        .name   =       SUPERIO,
        .unmask =       superio_unmask_irq,
        .mask   =       superio_mask_irq,
-       .ack =          no_ack_irq,
 };
 
 #ifdef DEBUG_SUPERIO_INIT
@@ -354,7 +353,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
 #endif
 
        for (i = 0; i < 16; i++) {
-               set_irq_chip_and_handler(i, &superio_interrupt_type, handle_level_irq);
+               set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq);
        }
 
        /*
index f01e344cf4bd673c059044698f50896836d26fad..98e6fdf34d30d136290a794a6b2a62b0764fdf5b 100644 (file)
@@ -49,6 +49,7 @@ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
 obj-$(CONFIG_MN10300) += setup-bus.o
 obj-$(CONFIG_MICROBLAZE) += setup-bus.o
+obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
 
 #
 # ACPI Related PCI FW Functions
index 95712a375cd521954f2a1f130a7ddf73704703cf..63d5042f2079141a8740d77fae118d9c5bb707af 100644 (file)
@@ -715,7 +715,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
        nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        start = vma->vm_pgoff;
        size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-       pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+       pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
                        pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
        if (start >= pci_start && start < pci_start + size &&
                        start + nr <= pci_start + size)
index ea00647f4732fcb83f60db140265e1b1465a3548..27911b55c2a52295a01bf834cbb9eacb3f9455c3 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/capability.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
index f5c63fe9db5c5b6666001ae03a1a4c561c644986..6f9350cabbd51d1574ec52bcf287d4065f8b3c36 100644 (file)
@@ -2136,6 +2136,24 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
                        quirk_unhide_mch_dev6);
 
+#ifdef CONFIG_TILE
+/*
+ * The Tilera TILEmpower platform needs to set the link speed
+ * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
+ * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
+ * capability register of the PEX8624 PCIe switch. The switch
+ * supports link speed auto negotiation, but falsely sets
+ * the link speed to 5GT/s.
+ */
+static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev)
+{
+       if (tile_plx_gen1) {
+               pci_write_config_dword(dev, 0x98, 0x1);
+               mdelay(50);
+       }
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
+#endif /* CONFIG_TILE */
 
 #ifdef CONFIG_PCI_MSI
 /* Some chipsets do not support MSI. We cannot easily rely on setting
index 3753fd0722e72383137d57e839b377721ad86c7a..2fe8cb8e95cd3409d74d04e312388736234c5d0c 100644 (file)
@@ -70,6 +70,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
                va_end(args);
        }
 }
+EXPORT_SYMBOL(soc_pcmcia_debug);
 
 #endif
 
index 60a5a5c6b50ac7d6dfb4767163d30446ef03f80f..d235f44fd7a3ca96f61abb7d90249afa6eed1493 100644 (file)
@@ -81,6 +81,8 @@ MODULE_PARM_DESC(wapf, "WAPF value");
 
 static int wlan_status = 1;
 static int bluetooth_status = 1;
+static int wimax_status = -1;
+static int wwan_status = -1;
 
 module_param(wlan_status, int, 0444);
 MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
@@ -92,6 +94,16 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
 
+module_param(wimax_status, int, 0444);
+MODULE_PARM_DESC(wimax_status, "Set the wireless status on boot "
+                "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+                "default is 1");
+
+module_param(wwan_status, int, 0444);
+MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
+                "(0 = disabled, 1 = enabled, -1 = don't do anything). "
+                "default is 1");
+
 /*
  * Some events we use, same for all Asus
  */
@@ -114,6 +126,8 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
  */
 #define WL_RSTS                0x01    /* internal Wifi */
 #define BT_RSTS                0x02    /* internal Bluetooth */
+#define WM_RSTS                0x08    /* internal wimax */
+#define WW_RSTS                0x20    /* internal wwan */
 
 /* LED */
 #define METHOD_MLED            "MLED"
@@ -132,6 +146,11 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
  */
 #define METHOD_WLAN            "WLED"
 #define METHOD_BLUETOOTH       "BLED"
+
+/* WWAN and WIMAX */
+#define METHOD_WWAN            "GSMC"
+#define METHOD_WIMAX           "WMXC"
+
 #define METHOD_WL_STATUS       "RSTS"
 
 /* Brightness */
@@ -882,6 +901,64 @@ static ssize_t store_bluetooth(struct device *dev,
        return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH);
 }
 
+/*
+ * Wimax
+ */
+static int asus_wimax_set(struct asus_laptop *asus, int status)
+{
+       if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) {
+               pr_warning("Error setting wimax status to %d", status);
+               return -EIO;
+       }
+       return 0;
+}
+
+static ssize_t show_wimax(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS));
+}
+
+static ssize_t store_wimax(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX);
+}
+
+/*
+ * Wwan
+ */
+static int asus_wwan_set(struct asus_laptop *asus, int status)
+{
+       if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) {
+               pr_warning("Error setting wwan status to %d", status);
+               return -EIO;
+       }
+       return 0;
+}
+
+static ssize_t show_wwan(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS));
+}
+
+static ssize_t store_wwan(struct device *dev,
+                              struct device_attribute *attr, const char *buf,
+                              size_t count)
+{
+       struct asus_laptop *asus = dev_get_drvdata(dev);
+
+       return sysfs_acpi_set(asus, buf, count, METHOD_WWAN);
+}
+
 /*
  * Display
  */
@@ -1202,6 +1279,8 @@ static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL);
 static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan);
 static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
                   show_bluetooth, store_bluetooth);
+static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
+static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
 static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
 static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
 static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
@@ -1212,6 +1291,8 @@ static struct attribute *asus_attributes[] = {
        &dev_attr_infos.attr,
        &dev_attr_wlan.attr,
        &dev_attr_bluetooth.attr,
+       &dev_attr_wimax.attr,
+       &dev_attr_wwan.attr,
        &dev_attr_display.attr,
        &dev_attr_ledd.attr,
        &dev_attr_ls_level.attr,
@@ -1239,6 +1320,13 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj,
        } else if (attr == &dev_attr_display.attr) {
                supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL);
 
+       } else if (attr == &dev_attr_wimax.attr) {
+               supported =
+                       !acpi_check_handle(asus->handle, METHOD_WIMAX, NULL);
+
+       } else if (attr == &dev_attr_wwan.attr) {
+               supported = !acpi_check_handle(asus->handle, METHOD_WWAN, NULL);
+
        } else if (attr == &dev_attr_ledd.attr) {
                supported = !acpi_check_handle(handle, METHOD_LEDD, NULL);
 
@@ -1397,7 +1485,8 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
 
        /*
         * The HWRS method return informations about the hardware.
-        * 0x80 bit is for WLAN, 0x100 for Bluetooth.
+        * 0x80 bit is for WLAN, 0x100 for Bluetooth,
+        * 0x40 for WWAN, 0x10 for WIMAX.
         * The significance of others is yet to be found.
         */
        status =
@@ -1440,6 +1529,12 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
        if (wlan_status >= 0)
                asus_wlan_set(asus, !!wlan_status);
 
+       if (wimax_status >= 0)
+               asus_wimax_set(asus, !!wimax_status);
+
+       if (wwan_status >= 0)
+               asus_wwan_set(asus, !!wwan_status);
+
        /* Keyboard Backlight is on by default */
        if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL))
                asus_kled_set(asus, 1);
index 462ceab93f87b84d59796a58ac90703a2ffaddee..0d50fbbe24784e86e3eef1522134ac585d6b6a2c 100644 (file)
@@ -298,8 +298,8 @@ static void eeepc_wmi_notify(u32 value, void *context)
        kfree(obj);
 }
 
-static int store_cpufv(struct device *dev, struct device_attribute *attr,
-                      const char *buf, size_t count)
+static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
 {
        int value;
        struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
index 1dac659b5e0c84e7bc3ccefea144d6a3dc88993c..9e05af9c41cbcd129bc3912c4bff2b6b8ad61b96 100644 (file)
@@ -172,6 +172,8 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
        bios_return = *((struct bios_return *)obj->buffer.pointer);
 
        memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
+
+       kfree(obj);
        return 0;
 }
 
index 3c2c6b91ecb37eeb2f322e4e85c88626cd541a08..94a114aa8e286fd5fc91f97d8c7b416204c19ea2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/sysdev.h>
 #include <linux/dmi.h>
+#include <linux/efi.h>
 #include <linux/mutex.h>
 #include <asm/bios_ebda.h>
 
@@ -220,32 +221,13 @@ static void rtl_teardown_sysfs(void) {
        sysdev_class_unregister(&class_rtl);
 }
 
-static int dmi_check_cb(const struct dmi_system_id *id)
-{
-       RTL_DEBUG("found IBM server '%s'\n", id->ident);
-       return 0;
-}
-
-#define ibm_dmi_entry(NAME, TYPE)                  \
-{                                                  \
-       .ident = NAME,                             \
-       .matches = {                               \
-               DMI_MATCH(DMI_SYS_VENDOR, "IBM"),  \
-               DMI_MATCH(DMI_PRODUCT_NAME, TYPE), \
-       },                                         \
-       .callback = dmi_check_cb                   \
-}
 
 static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = {
-       ibm_dmi_entry("BladeCenter LS21", "7971"),
-       ibm_dmi_entry("BladeCenter LS22", "7901"),
-       ibm_dmi_entry("BladeCenter HS21 XM", "7995"),
-       ibm_dmi_entry("BladeCenter HS22", "7870"),
-       ibm_dmi_entry("BladeCenter HS22V", "7871"),
-       ibm_dmi_entry("System x3550 M2", "7946"),
-       ibm_dmi_entry("System x3650 M2", "7947"),
-       ibm_dmi_entry("System x3550 M3", "7944"),
-       ibm_dmi_entry("System x3650 M3", "7945"),
+       {                                                  \
+               .matches = {                               \
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),  \
+               },                                         \
+       },
        { }
 };
 
@@ -257,7 +239,7 @@ static int __init ibm_rtl_init(void) {
        if (force)
                pr_warning("ibm-rtl: module loaded by force\n");
        /* first ensure that we are running on IBM HW */
-       else if (!dmi_check_system(ibm_rtl_dmi_table))
+       else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
                return -ENODEV;
 
        /* Get the address for the Extended BIOS Data Area */
@@ -302,7 +284,7 @@ static int __init ibm_rtl_init(void) {
                        RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
                              rtl_cmd_width, rtl_cmd_type);
                        addr = ioread32(&rtl_table->cmd_port_address);
-                       RTL_DEBUG("addr = %#llx\n", addr);
+                       RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
                        plen = rtl_cmd_width/sizeof(char);
                        rtl_cmd_addr = rtl_port_map(addr, plen);
                        RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr);
index 42a5469a2459d9cf35f7a014f93e977fa0463df5..35278ad7e628412754e9d8bcc1281cfbfd38c178 100644 (file)
@@ -43,16 +43,18 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
 
 #define dprintk(msg...) pr_debug(DRV_PFX msg)
 
-#define KEYCODE_BASE 0xD0
-#define MSI_WMI_BRIGHTNESSUP   KEYCODE_BASE
-#define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1)
-#define MSI_WMI_VOLUMEUP       (KEYCODE_BASE + 2)
-#define MSI_WMI_VOLUMEDOWN     (KEYCODE_BASE + 3)
+#define SCANCODE_BASE 0xD0
+#define MSI_WMI_BRIGHTNESSUP   SCANCODE_BASE
+#define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1)
+#define MSI_WMI_VOLUMEUP       (SCANCODE_BASE + 2)
+#define MSI_WMI_VOLUMEDOWN     (SCANCODE_BASE + 3)
+#define MSI_WMI_MUTE           (SCANCODE_BASE + 4)
 static struct key_entry msi_wmi_keymap[] = {
        { KE_KEY, MSI_WMI_BRIGHTNESSUP,   {KEY_BRIGHTNESSUP} },
        { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} },
        { KE_KEY, MSI_WMI_VOLUMEUP,       {KEY_VOLUMEUP} },
        { KE_KEY, MSI_WMI_VOLUMEDOWN,     {KEY_VOLUMEDOWN} },
+       { KE_KEY, MSI_WMI_MUTE,           {KEY_MUTE} },
        { KE_END, 0}
 };
 static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1];
@@ -169,7 +171,7 @@ static void msi_wmi_notify(u32 value, void *context)
                        ktime_t diff;
                        cur = ktime_get_real();
                        diff = ktime_sub(cur, last_pressed[key->code -
-                                       KEYCODE_BASE]);
+                                       SCANCODE_BASE]);
                        /* Ignore event if the same event happened in a 50 ms
                           timeframe -> Key press may result in 10-20 GPEs */
                        if (ktime_to_us(diff) < 1000 * 50) {
@@ -178,7 +180,7 @@ static void msi_wmi_notify(u32 value, void *context)
                                         key->code, ktime_to_us(diff));
                                return;
                        }
-                       last_pressed[key->code - KEYCODE_BASE] = cur;
+                       last_pressed[key->code - SCANCODE_BASE] = cur;
 
                        if (key->type == KE_KEY &&
                        /* Brightness is served via acpi video driver */
index 2d61186ad5a2e96708fcec4beb0a8402eb2bc09f..e8c21994b36da2c1bb9eb71af883a597566f532c 100644 (file)
@@ -8497,7 +8497,6 @@ static void ibm_exit(struct ibm_struct *ibm)
                                           ibm->acpi->type,
                                           dispatch_acpi_notify);
                ibm->flags.acpi_notify_installed = 0;
-               ibm->flags.acpi_notify_installed = 0;
        }
 
        if (ibm->flags.proc_created) {
index 06f304f46e0229427e039180abb6731bceb403bd..4276da7291b8e479d26ee7a55041c212a85ca74a 100644 (file)
@@ -135,6 +135,7 @@ static const struct key_entry toshiba_acpi_keymap[] __initconst = {
        { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
        { KE_KEY, 0x142, { KEY_WLAN } },
        { KE_KEY, 0x143, { KEY_PROG1 } },
+       { KE_KEY, 0x17f, { KEY_FN } },
        { KE_KEY, 0xb05, { KEY_PROG2 } },
        { KE_KEY, 0xb06, { KEY_WWW } },
        { KE_KEY, 0xb07, { KEY_MAIL } },
index 104b77c87ef5ae36e0c4502c6487e1fb3aac428e..aecd9a9b549f004d692976ce2a911644e2c56eb7 100644 (file)
@@ -755,7 +755,7 @@ static bool guid_already_parsed(const char *guid_string)
        struct wmi_block *wblock;
 
        list_for_each_entry(wblock, &wmi_block_list, list)
-               if (strncmp(wblock->gblock.guid, guid_string, 16) == 0)
+               if (memcmp(wblock->gblock.guid, guid_string, 16) == 0)
                        return true;
 
        return false;
index e73ebefdf3e0930ba979b3a3a9b348dfe181d730..315b3112aca85ece5a804778c6632a972ad32c7d 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/isapnp.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 extern struct pnp_protocol isapnp_protocol;
index f1d10c974cd43f3387467524822b93d0bd68742f..ba521f0f0fac634753cc79afe84c27c451a6bda7 100644 (file)
@@ -911,7 +911,7 @@ out:
 }
 
 /**
- * set_consumer_device_supply: Bind a regulator to a symbolic supply
+ * set_consumer_device_supply - Bind a regulator to a symbolic supply
  * @rdev:         regulator source
  * @consumer_dev: device the supply applies to
  * @consumer_dev_name: dev_name() string for device supply applies to
@@ -1052,7 +1052,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                        printk(KERN_WARNING
                               "%s: could not add device link %s err %d\n",
                               __func__, dev->kobj.name, err);
-                       device_remove_file(dev, &regulator->dev_attr);
                        goto link_name_err;
                }
        }
@@ -1268,13 +1267,17 @@ static int _regulator_enable(struct regulator_dev *rdev)
 {
        int ret, delay;
 
-       /* do we need to enable the supply regulator first */
-       if (rdev->supply) {
-               ret = _regulator_enable(rdev->supply);
-               if (ret < 0) {
-                       printk(KERN_ERR "%s: failed to enable %s: %d\n",
-                              __func__, rdev_get_name(rdev), ret);
-                       return ret;
+       if (rdev->use_count == 0) {
+               /* do we need to enable the supply regulator first */
+               if (rdev->supply) {
+                       mutex_lock(&rdev->supply->mutex);
+                       ret = _regulator_enable(rdev->supply);
+                       mutex_unlock(&rdev->supply->mutex);
+                       if (ret < 0) {
+                               printk(KERN_ERR "%s: failed to enable %s: %d\n",
+                                      __func__, rdev_get_name(rdev), ret);
+                               return ret;
+                       }
                }
        }
 
@@ -1313,10 +1316,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
                        if (ret < 0)
                                return ret;
 
-                       if (delay >= 1000)
+                       if (delay >= 1000) {
                                mdelay(delay / 1000);
-                       else if (delay)
+                               udelay(delay % 1000);
+                       } else if (delay) {
                                udelay(delay);
+                       }
 
                } else if (ret < 0) {
                        printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
@@ -1359,6 +1364,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
                struct regulator_dev **supply_rdev_ptr)
 {
        int ret = 0;
+       *supply_rdev_ptr = NULL;
 
        if (WARN(rdev->use_count <= 0,
                        "unbalanced disables for %s\n",
@@ -2346,6 +2352,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        if (init_data->supply_regulator && init_data->supply_regulator_dev) {
                dev_err(dev,
                        "Supply regulator specified by both name and dev\n");
+               ret = -EINVAL;
                goto scrub;
        }
 
@@ -2364,6 +2371,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                if (!found) {
                        dev_err(dev, "Failed to find supply %s\n",
                                init_data->supply_regulator);
+                       ret = -ENODEV;
                        goto scrub;
                }
 
index 4597d508a229efe5bb12a985955ebb71931e3ee4..ecd99f59dba879f8d659845fef26875cf218ff70 100644 (file)
@@ -465,8 +465,8 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
        .get_voltage = mc13783_fixed_regulator_get_voltage,
 };
 
-int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
-                                                                       u32 val)
+static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
+                                u32 val)
 {
        struct mc13783 *mc13783 = priv->mc13783;
        int ret;
index 7e5892efc4375d06b5bb2a15426f3abe95a29fba..a57262a4fa6c7a00e8aeb63f9a512ce0f83583b1 100644 (file)
@@ -219,12 +219,12 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
                return -EACCES;
 
        status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
-                       message >> 8, 0x15 /* PB_WORD_MSB */ );
-       if (status >= 0)
+                       message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB);
+       if (status < 0)
                return status;
 
        return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
-                       message, 0x16 /* PB_WORD_LSB */ );
+                       message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
 }
 
 /*----------------------------------------------------------------------*/
index c71d89dba302cd1024ec3c167e5a168c390224c9..83b4615a3b62fc0faa3841dc6ded7844583b18e8 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/device.h>
 #include <linux/poll.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
index eb28fb01a38ad86e23580b53acf81f6a7d719745..f6489eb7e976a8c0aa1851ebbb21901d689030c1 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 
 #include <asm/compat.h>
 #include <asm/ccwdev.h>
index 883e2db02bd3c8351e8195b5b45b12e84dd44fbf..e090a307fdeee341c66502d75ade8edf58f13afe 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/mtio.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 
 #include <asm/uaccess.h>
index 6c408670e08d72336ecfe1e3298a6db285740787..b3a3e8e8656e6db1be5e3a50b63056c43f0897f6 100644 (file)
@@ -209,29 +209,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
        wake_up(&device->state_change_wq);
 }
 
+struct tape_med_state_work_data {
+       struct tape_device *device;
+       enum tape_medium_state state;
+       struct work_struct  work;
+};
+
+static void
+tape_med_state_work_handler(struct work_struct *work)
+{
+       static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
+       static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
+       struct tape_med_state_work_data *p =
+               container_of(work, struct tape_med_state_work_data, work);
+       struct tape_device *device = p->device;
+       char *envp[] = { NULL, NULL };
+
+       switch (p->state) {
+       case MS_UNLOADED:
+               pr_info("%s: The tape cartridge has been successfully "
+                       "unloaded\n", dev_name(&device->cdev->dev));
+               envp[0] = env_state_unloaded;
+               kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+               break;
+       case MS_LOADED:
+               pr_info("%s: A tape cartridge has been mounted\n",
+                       dev_name(&device->cdev->dev));
+               envp[0] = env_state_loaded;
+               kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+               break;
+       default:
+               break;
+       }
+       tape_put_device(device);
+       kfree(p);
+}
+
+static void
+tape_med_state_work(struct tape_device *device, enum tape_medium_state state)
+{
+       struct tape_med_state_work_data *p;
+
+       p = kzalloc(sizeof(*p), GFP_ATOMIC);
+       if (p) {
+               INIT_WORK(&p->work, tape_med_state_work_handler);
+               p->device = tape_get_device(device);
+               p->state = state;
+               schedule_work(&p->work);
+       }
+}
+
 void
 tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
 {
-       if (device->medium_state == newstate)
+       enum tape_medium_state oldstate;
+
+       oldstate = device->medium_state;
+       if (oldstate == newstate)
                return;
+       device->medium_state = newstate;
        switch(newstate){
        case MS_UNLOADED:
                device->tape_generic_status |= GMT_DR_OPEN(~0);
-               if (device->medium_state == MS_LOADED)
-                       pr_info("%s: The tape cartridge has been successfully "
-                               "unloaded\n", dev_name(&device->cdev->dev));
+               if (oldstate == MS_LOADED)
+                       tape_med_state_work(device, MS_UNLOADED);
                break;
        case MS_LOADED:
                device->tape_generic_status &= ~GMT_DR_OPEN(~0);
-               if (device->medium_state == MS_UNLOADED)
-                       pr_info("%s: A tape cartridge has been mounted\n",
-                               dev_name(&device->cdev->dev));
+               if (oldstate == MS_UNLOADED)
+                       tape_med_state_work(device, MS_LOADED);
                break;
        default:
-               // print nothing
                break;
        }
-       device->medium_state = newstate;
        wake_up(&device->state_change_wq);
 }
 
index 9f661426e4a1e28494bbe3054ee412696e0a6ad1..c837d7419a6a974b55383be923e4e4939c00bb62 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/kmod.h>
 #include <linux/cdev.h>
 #include <linux/device.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 
 MODULE_AUTHOR
@@ -249,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
        char cp_command[80];
        char cp_response[160];
        char *onoff, *qid_string;
+       int rc;
 
-       memset(cp_command, 0x00, sizeof(cp_command));
-       memset(cp_response, 0x00, sizeof(cp_response));
-
-        onoff = ((action == 1) ? "ON" : "OFF");
+       onoff = ((action == 1) ? "ON" : "OFF");
        qid_string = ((recording_class_AB == 1) ? " QID * " : "");
 
-        /*
+       /*
         * The recording commands needs to be called with option QID
         * for guests that have previlege classes A or B.
         * Purging has to be done as separate step, because recording
         * can't be switched on as long as records are on the queue.
         * Doing both at the same time doesn't work.
         */
-
-       if (purge) {
+       if (purge && (action == 1)) {
+               memset(cp_command, 0x00, sizeof(cp_command));
+               memset(cp_response, 0x00, sizeof(cp_response));
                snprintf(cp_command, sizeof(cp_command),
                         "RECORDING %s PURGE %s",
                         logptr->recording_name,
                         qid_string);
-
                cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        }
 
@@ -279,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
                logptr->recording_name,
                onoff,
                qid_string);
-
        cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        /* The recording command will usually answer with 'Command complete'
         * on success, but when the specific service was never connected
         * before then there might be an additional informational message
         * 'HCPCRC8072I Recording entry not found' before the
-         * 'Command complete'. So I use strstr rather then the strncmp.
+        * 'Command complete'. So I use strstr rather then the strncmp.
         */
        if (strstr(cp_response,"Command complete"))
-               return 0;
+               rc = 0;
        else
-               return -EIO;
+               rc = -EIO;
+       /*
+        * If we turn recording off, we have to purge any remaining records
+        * afterwards, as a large number of queued records may impact z/VM
+        * performance.
+        */
+       if (purge && (action == 0)) {
+               memset(cp_command, 0x00, sizeof(cp_command));
+               memset(cp_response, 0x00, sizeof(cp_response));
+               snprintf(cp_command, sizeof(cp_command),
+                        "RECORDING %s PURGE %s",
+                        logptr->recording_name,
+                        qid_string);
+               cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
+       }
 
+       return rc;
 }
 
 
index 1de672f21037bd70f57e06b4abcd43a89b65a864..f7e4ae6bf15a5be647bdf4a0223a228880d368a5 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/cdev.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/cio.h>
index a5050e2171504043d48e9aeaa78dc4dffc9536ac..825951b6b83f438a002102f372a90342b624be6f 100644 (file)
@@ -635,7 +635,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
        init_subchannel_id(&mchk_schid);
        mchk_schid.sch_no = crw0->rsid;
        if (crw1)
-               mchk_schid.ssid = (crw1->rsid >> 8) & 3;
+               mchk_schid.ssid = (crw1->rsid >> 4) & 3;
 
        /*
         * Since we are always presented with IPI in the CRW, we have to
index 2ff8a22d42574242eb0a07c1ab1d38f73cc81d6b..e8391b89eff4bbbcb41896b3232c05a4070d8917 100644 (file)
@@ -1455,7 +1455,16 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                break;
        case IO_SCH_UNREG_ATTACH:
        case IO_SCH_UNREG:
-               if (cdev)
+               if (!cdev)
+                       break;
+               if (cdev->private->state == DEV_STATE_SENSE_ID) {
+                       /*
+                        * Note: delayed work triggered by this event
+                        * and repeated calls to sch_event are synchronized
+                        * by the above check for work_pending(cdev).
+                        */
+                       dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
+               } else
                        ccw_device_set_notoper(cdev);
                break;
        case IO_SCH_NOP:
index 752dbee06af582a4c2ac8481cb079658579bfcaa..5d9c66627b6eb7554b63bda327ce62ace37bc590 100644 (file)
@@ -292,8 +292,8 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
                return;
 
        /* reset adapter interrupt indicators */
-       put_indicator(irq_ptr->dsci);
        set_subchannel_ind(irq_ptr, 1);
+       put_indicator(irq_ptr->dsci);
 }
 
 void __exit tiqdio_unregister_thinints(void)
index f5221749d18069dcbb7f917b0bbd09ccadba8dcc..7fca9c10ffcfad9b0901e7ae53fcac9b06697d82 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/compat.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
index 50286d8707f305b981c1e56ffa02df7b3ce3b0d9..6bd2dbc4c31606d5019fb1e76d92ef88583a2140 100644 (file)
@@ -76,7 +76,7 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
        scpnt->scsi_done(scpnt);
 }
 
-static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
+static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
                                  void (*done) (struct scsi_cmnd *))
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
@@ -127,6 +127,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
        return ret;
 }
 
+static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
+
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
index fcf08b3f52c1f2ee6b514c0b88ad2985c4f814da..b7bd5b0cc7aa450e23ebe7f8b0ddc10814b82f05 100644 (file)
@@ -1765,7 +1765,7 @@ out:
 } /* End twa_scsi_eh_reset() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int request_id, retval;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1812,6 +1812,8 @@ out:
        return retval;
 } /* End twa_scsi_queue() */
 
+static DEF_SCSI_QCMD(twa_scsi_queue)
+
 /* This function hands scsi cdb's to the firmware */
 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
 {
index 6a95d111d207269a920fc57c8ceee220ac5d42d8..13e39e1fdfe288b88e9aded1305e21240debc48e 100644 (file)
@@ -1501,7 +1501,7 @@ out:
 } /* End twl_scsi_eh_reset() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int request_id, retval;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1536,6 +1536,8 @@ out:
        return retval;
 } /* End twl_scsi_queue() */
 
+static DEF_SCSI_QCMD(twl_scsi_queue)
+
 /* This function tells the controller to shut down */
 static void __twl_shutdown(TW_Device_Extension *tw_dev)
 {
index b1125341f4c89431521f978ca850135603f2c779..7fe96ff60c581c324a4eaecbf79d8c2e083bf7f8 100644 (file)
@@ -1947,7 +1947,7 @@ static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int r
 } /* End tw_scsiop_test_unit_ready_complete() */
 
 /* This is the main scsi queue function to handle scsi opcodes */
-static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) 
+static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        unsigned char *command = SCpnt->cmnd;
        int request_id = 0;
@@ -2023,6 +2023,8 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
        return retval;
 } /* End tw_scsi_queue() */
 
+static DEF_SCSI_QCMD(tw_scsi_queue)
+
 /* This function is the interrupt service routine */
 static irqreturn_t tw_interrupt(int irq, void *dev_instance) 
 {
index 89fc1c8af86b8774000233247fce6c880187f910..f672491774eb61756c2a36f8af3a36496a7ea53c 100644 (file)
@@ -167,7 +167,7 @@ MODULE_LICENSE("GPL");
 #include "53c700_d.h"
 
 
-STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *);
 STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
@@ -1749,8 +1749,8 @@ NCR_700_intr(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-STATIC int
-NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
+static int
+NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1904,6 +1904,8 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+STATIC DEF_SCSI_QCMD(NCR_700_queuecommand)
+
 STATIC int
 NCR_700_abort(struct scsi_cmnd * SCp)
 {
index fc0b4b81d5522ddaff339d3dc6187ce72a4c7d9a..f66c33b9ab41ac7333d99f3f3423ce497e47ae1d 100644 (file)
@@ -2807,7 +2807,7 @@ static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
   Outgoing Mailbox for execution by the associated Host Adapter.
 */
 
-static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
+static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
 {
        struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
        struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
@@ -2994,6 +2994,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
        return 0;
 }
 
+static DEF_SCSI_QCMD(BusLogic_QueueCommand)
 
 #if 0
 /*
index 73f237a1ed94f6e81ca686ba58a280e54e7056be..649fcb31f26da8e9b5269443574aa82a3dc45fa8 100644 (file)
@@ -1319,7 +1319,7 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T Co
 */
 
 static const char *BusLogic_DriverInfo(struct Scsi_Host *);
-static int BusLogic_QueueCommand(struct scsi_cmnd *, void (*CompletionRoutine) (struct scsi_cmnd *));
+static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *);
 static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *);
 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int BusLogic_SlaveConfigure(struct scsi_device *);
index 5d2f148889adc117f90f2d0650ad2d2aeda047a5..9a5629f94f95aba802857a6d5162db4745235c8a 100644 (file)
@@ -952,7 +952,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
  *     Locks: host lock taken by caller
  */
 
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) 
+static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *instance = cmd->device->host;
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -1021,6 +1021,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
 
 /**
  *     NCR5380_main    -       NCR state machines
index bdc468c9e1d9d6de71ba091041096fd831512ee7..fd40a32b1f6f2d3690ac5d63c361cb9ece6a2120 100644 (file)
@@ -313,7 +313,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
 #endif
 static int NCR5380_abort(Scsi_Cmnd * cmd);
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
        char *buffer, char **start, off_t offset, int length, int inout);
 
index 6961f78742aedbc86de34d810891737eeece4ec9..c91888a0a23cacf61354f0a3f1fdd1f3a08caef2 100644 (file)
@@ -693,7 +693,7 @@ static void wait_intr(void)
 }
 #endif
 
-static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        int i;
 
@@ -726,6 +726,8 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR53c406a_queue)
+
 static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
 {
        DEB(printk("NCR53c406a_reset called\n"));
index dbbc601948e5328e4c9a0bbfeb18ee8ac7f7fd91..dc5ac6e528c4febb2b6dbdc51953a08cfe934938 100644 (file)
@@ -911,7 +911,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc
  *     queue the command down to the controller
  */
 
-static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int inia100_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
        struct orc_scb *scb;
        struct orc_host *host;          /* Point to Host adapter control block */
@@ -930,6 +930,8 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(inia100_queue)
+
 /*****************************************************************************
  Function name  : inia100_abort
  Description    : Abort a queued command.
index 29c0ed1cf50753ba8b674c1193d97c1af4d31624..2c93d9496d62dae64b4c2aaf0b78e60edc61ba17 100644 (file)
@@ -248,7 +248,7 @@ static struct aac_driver_ident aac_drivers[] = {
  *     TODO: unify with aac_scsi_cmd().
  */
 
-static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct aac_dev *dev = (struct aac_dev *)host->hostdata;
@@ -267,6 +267,8 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
        return (aac_scsi_cmd(cmd) ? FAILED : 0);
 }
 
+static DEF_SCSI_QCMD(aac_queuecommand)
+
 /**
  *     aac_info                -       Returns the host adapter name
  *     @shost:         Scsi host to report on
index 0ec3da6f3e12133823588e280fea24cc364cbe03..081c6de92bc5b5e060f3bf20eebbfa1e8b58c5c2 100644 (file)
@@ -9500,7 +9500,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
  * in the 'scp' result field.
  */
 static int
-advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *shost = scp->device->host;
        int asc_res, result = 0;
@@ -9525,6 +9525,8 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
        return result;
 }
 
+static DEF_SCSI_QCMD(advansys_queuecommand)
+
 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
 {
        PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
index 8eab8587ff21b6c35bb31129fd62a30d8ddc9f06..c5169f01c1cdb8502e19111b8bfb175da0b1c585 100644 (file)
@@ -1056,7 +1056,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
  *  queue a command
  *
  */
-static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha152x_queue_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
 #if 0
        if(*SCpnt->cmnd == REQUEST_SENSE) {
@@ -1070,6 +1070,8 @@ static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        return aha152x_internal_queue(SCpnt, NULL, 0, done);
 }
 
+static DEF_SCSI_QCMD(aha152x_queue)
+
 
 /*
  *  
index 4f785f254c1f7f7619f25f0beb4a966c4b733ec4..195823a51aab5292e6ec43183d0e0829b6d9ff93 100644 (file)
@@ -558,7 +558,7 @@ static void aha1542_intr_handle(struct Scsi_Host *shost)
        };
 }
 
-static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int aha1542_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        unchar ahacmd = CMD_START_SCSI;
        unchar direction;
@@ -718,6 +718,8 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(aha1542_queuecommand)
+
 /* Initialize mailboxes */
 static void setup_mailboxes(int bse, struct Scsi_Host *shpnt)
 {
index 1db538552d56b59faaf5053a1e93fcd0dff1c167..b871d2b57f93235652d55761cc66617f2a52c291 100644 (file)
@@ -132,7 +132,7 @@ struct ccb {                        /* Command Control Block 5.3 */
 };
 
 static int aha1542_detect(struct scsi_host_template *);
-static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int aha1542_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_host_reset(Scsi_Cmnd * SCpnt);
index 0107a4cc33319bfef8c8e22cb5dbde9e9a700fe8..d058f1ab82b5612c328bafeba1b48a89c311f2a1 100644 (file)
@@ -331,7 +331,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 {
        unchar direction;
        unchar *cmd = (unchar *) SCpnt->cmnd;
@@ -503,6 +503,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(aha1740_queuecommand)
+
 /* Query the board for its irq_level and irq_type.  Nothing else matters
    in enhanced mode on an EISA bus. */
 
index 88ad8482ef59b6e33cbdfeafe2d1c962ee05be8b..25d066624476e3b60ac0119d803f75bdfe5d721b 100644 (file)
@@ -573,7 +573,7 @@ ahd_linux_info(struct Scsi_Host *host)
  * Queue an SCB to the controller.
  */
 static int
-ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
        struct   ahd_softc *ahd;
        struct   ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -588,6 +588,8 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
        return rtn;
 }
 
+static DEF_SCSI_QCMD(ahd_linux_queue)
+
 static struct scsi_target **
 ahd_linux_target_in_softc(struct scsi_target *starget)
 {
index aeea7a61478e8bca16357299bf33dd5fdf2d2292..4a359bb307c6e38cc9e17cfc547968b6271b98d8 100644 (file)
@@ -528,7 +528,7 @@ ahc_linux_info(struct Scsi_Host *host)
  * Queue an SCB to the controller.
  */
 static int
-ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
        struct   ahc_softc *ahc;
        struct   ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -548,6 +548,8 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
        return rtn;
 }
 
+static DEF_SCSI_QCMD(ahc_linux_queue)
+
 static inline struct scsi_target **
 ahc_linux_target_in_softc(struct scsi_target *starget)
 {
index aee73fafccc834d5922baf4f5322bfede654464b..4ff60a08df0f184c2c84ed32093669e006a39b59 100644 (file)
@@ -10234,7 +10234,7 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
  * Description:
  *   Queue a SCB to the controller.
  *-F*************************************************************************/
-static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+static int aic7xxx_queue_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
   struct aic7xxx_host *p;
   struct aic7xxx_scb *scb;
@@ -10292,6 +10292,8 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
   return (0);
 }
 
+static DEF_SCSI_QCMD(aic7xxx_queue)
+
 /*+F*************************************************************************
  * Function:
  *   aic7xxx_bus_device_reset
index 05a78e515a24101caa7dd6d9b4891cfe86312d3d..17e3df4f016f6590cc86aac3ccc586add42cb2c6 100644 (file)
@@ -85,8 +85,7 @@ static int arcmsr_abort(struct scsi_cmnd *);
 static int arcmsr_bus_reset(struct scsi_cmnd *);
 static int arcmsr_bios_param(struct scsi_device *sdev,
                struct block_device *bdev, sector_t capacity, int *info);
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
-                                       void (*done) (struct scsi_cmnd *));
+static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
                                const struct pci_device_id *id);
 static void arcmsr_remove(struct pci_dev *pdev);
@@ -2081,7 +2080,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
        }
 }
 
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
+static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
        void (* done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
@@ -2124,6 +2123,8 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(arcmsr_queue_command)
+
 static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 {
        struct MessageUnit_A __iomem *reg = acb->pmuA;
index 918ccf8187577f1954f33084d33a77210a53fa48..ec166726b3149d2a270ffc3f1a491262b8c4dcd5 100644 (file)
@@ -2511,7 +2511,7 @@ acornscsi_intr(int irq, void *dev_id)
  *           done - function called on completion, with pointer to command descriptor
  * Returns  : 0, or < 0 on error.
  */
-int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
+static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
                       void (*done)(struct scsi_cmnd *))
 {
     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
@@ -2561,6 +2561,8 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
     return 0;
 }
 
+DEF_SCSI_QCMD(acornscsi_queuecmd)
+
 /*
  * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
  * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
index 9e71ac611146ab86432664af1c2a40c7d2070ea0..2b2ce21e227ea95200ec437f2d2a29f7d1cc356e 100644 (file)
@@ -2198,7 +2198,7 @@ no_command:
  * Returns: 0 on success, else error.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_queue_command(struct scsi_cmnd *SCpnt,
+static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
                         void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2240,6 +2240,8 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt,
        return result;
 }
 
+DEF_SCSI_QCMD(fas216_queue_command)
+
 /**
  * fas216_internal_done - trigger restart of a waiting thread in fas216_noqueue_command
  * @SCpnt: Command to wake
@@ -2263,7 +2265,7 @@ static void fas216_internal_done(struct scsi_cmnd *SCpnt)
  * Returns: scsi result code.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
+static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
                           void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2277,7 +2279,7 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
        BUG_ON(info->scsi.irq != NO_IRQ);
 
        info->internal_done = 0;
-       fas216_queue_command(SCpnt, fas216_internal_done);
+       fas216_queue_command_lck(SCpnt, fas216_internal_done);
 
        /*
         * This wastes time, since we can't return until the command is
@@ -2310,6 +2312,8 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+DEF_SCSI_QCMD(fas216_noqueue_command)
+
 /*
  * Error handler timeout function.  Indicate that we timed out,
  * and wake up any error handler process so it can continue.
index b65f4cf0eec9929af885e1346ff004b16970984f..f30f8d659dc4d47ef70d6e9be3b59f6a44dde00a 100644 (file)
@@ -331,23 +331,21 @@ extern int fas216_init (struct Scsi_Host *instance);
  */
 extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
 
-/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
  * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- *          done  - done function to call once command is complete
+ * Params  : h - host adapter
+ *        : SCpnt - Command to queue
  * Returns : 0 - success, else error
  */
-extern int fas216_queue_command(struct scsi_cmnd *,
-                               void (*done)(struct scsi_cmnd *));
+extern int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_noqueue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
  * Purpose : queue a command for adapter to process, and process it to completion.
- * Params  : SCpnt - Command to queue
- *          done  - done function to call once command is complete
+ * Params  : h - host adapter
+ *        : SCpnt - Command to queue
  * Returns : 0 - success, else error
  */
-extern int fas216_noqueue_command(struct scsi_cmnd *,
-                                 void (*done)(struct scsi_cmnd *));
+extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *);
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
index 158ebc3644d83f2188a1e0007950799db4246652..88b2928b4d3b76a18cf9d8354d8350dd9f5f745c 100644 (file)
@@ -910,7 +910,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
  *
  */
 
-static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
        SETUP_HOSTDATA(cmd->device->host);
        Scsi_Cmnd *tmp;
@@ -1022,6 +1022,8 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
 /*
  * Function : NCR5380_main (void)
  *
index ad7a23aef0ecf29536a21fe64d4f27874ddb6173..3e8658e2f154b82a0e5ad05e628d710f0c1c61e7 100644 (file)
@@ -572,23 +572,6 @@ static void falcon_get_lock(void)
 }
 
 
-/* This is the wrapper function for NCR5380_queue_command(). It just
- * tries to get the lock on the ST-DMA (see above) and then calls the
- * original function.
- */
-
-#if 0
-int atari_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
-{
-       /* falcon_get_lock();
-        * ++guenther: moved to NCR5380_queue_command() to prevent
-        * race condition, see there for an explanation.
-        */
-       return NCR5380_queue_command(cmd, done);
-}
-#endif
-
-
 int __init atari_scsi_detect(struct scsi_host_template *host)
 {
        static int called = 0;
index ab5bdda6903e3f6f650fa63c203ab6401bcd71a4..76029d570beb8634c121c47f6a7eb5e906df9a14 100644 (file)
@@ -605,7 +605,7 @@ handled:
  *
  *     Queue a command to the ATP queue. Called with the host lock held.
  */
-static int atp870u_queuecommand(struct scsi_cmnd * req_p, 
+static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
                         void (*done) (struct scsi_cmnd *))
 {
        unsigned char c;
@@ -694,6 +694,8 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
        return 0;
 }
 
+static DEF_SCSI_QCMD(atp870u_queuecommand)
+
 /**
  *     send_s870       -       send a command to the controller
  *     @host: host
index 8daa716739d1bd6d2a6a4180c008161e7f148f27..8ca967dee66d4eac1b551c82ff5416454e0ffcb6 100644 (file)
@@ -30,8 +30,7 @@ DEFINE_IDR(bfad_im_port_index);
 struct scsi_transport_template *bfad_im_scsi_transport_template;
 struct scsi_transport_template *bfad_im_scsi_vport_transport_template;
 static void bfad_im_itnim_work_handler(struct work_struct *work);
-static int bfad_im_queuecommand(struct scsi_cmnd *cmnd,
-                               void (*done)(struct scsi_cmnd *));
+static int bfad_im_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmnd);
 static int bfad_im_slave_alloc(struct scsi_device *sdev);
 static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
                                struct bfad_itnim_s *itnim);
@@ -1120,7 +1119,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
  * Scsi_Host template entry, queue a SCSI command to the BFAD.
  */
 static int
-bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
        struct bfad_im_port_s *im_port =
                (struct bfad_im_port_s *) cmnd->device->host->hostdata[0];
@@ -1187,6 +1186,8 @@ out_fail_cmd:
        return 0;
 }
 
+static DEF_SCSI_QCMD(bfad_im_queuecommand)
+
 void
 bfad_os_rport_online_wait(struct bfad_s *bfad)
 {
index 54f50b07dac7f36fe5950efb9bdaf34340d4bbed..8f1b5c8bf903bba0e32e398aeaf776915b42890a 100644 (file)
@@ -1080,7 +1080,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
  *        and is expected to be held on return.
  *
  **/
-static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct DeviceCtlBlk *dcb;
        struct ScsiReqBlk *srb;
@@ -1154,6 +1154,7 @@ complete:
        return 0;
 }
 
+static DEF_SCSI_QCMD(dc395x_queue_command)
 
 /*
  * Return the disk geometry for the given SCSI device.
index 23dec006338512a479e60b5e9d0c5281dde2beca..cffcb108ac9639b4fd0a8ea4b32d503206fae319 100644 (file)
@@ -423,7 +423,7 @@ static int adpt_slave_configure(struct scsi_device * device)
        return 0;
 }
 
-static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
        adpt_hba* pHba = NULL;
        struct adpt_device* pDev = NULL;        /* dpt per device information */
@@ -491,6 +491,8 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
        return adpt_scsi_to_i2o(pHba, cmd, pDev);
 }
 
+static DEF_SCSI_QCMD(adpt_queue)
+
 static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
                sector_t capacity, int geom[])
 {
index 337746d460438417281d25c3aa9aec863f3e002d..beded716f93f4cbf4e929e9a354bba46d4c18be2 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 static int adpt_detect(struct scsi_host_template * sht);
-static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 static int adpt_abort(struct scsi_cmnd * cmd);
 static int adpt_reset(struct scsi_cmnd* cmd);
 static int adpt_release(struct Scsi_Host *host);
index 0b205f8c732682583b1d939a408066615b07fa22..cdc621204b667bb4dd317fd09b137afb6950c79b 100644 (file)
@@ -36,7 +36,7 @@ static int dtc_abort(Scsi_Cmnd *);
 static int dtc_biosparam(struct scsi_device *, struct block_device *,
                         sector_t, int*);
 static int dtc_detect(struct scsi_host_template *);
-static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int dtc_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int dtc_bus_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
index d1c31378f6da9823b67e895ae7143578cfa110ee..53925ac178fd1b13fd11747ec2fefa8033f00fa7 100644 (file)
 
 static int eata2x_detect(struct scsi_host_template *);
 static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(struct scsi_cmnd *,
-                              void (*done) (struct scsi_cmnd *));
+static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int eata2x_eh_abort(struct scsi_cmnd *);
 static int eata2x_eh_host_reset(struct scsi_cmnd *);
 static int eata2x_bios_param(struct scsi_device *, struct block_device *,
@@ -1758,7 +1757,7 @@ static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
 
 }
 
-static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
+static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt,
                               void (*done) (struct scsi_cmnd *))
 {
        struct Scsi_Host *shost = SCpnt->device->host;
@@ -1843,6 +1842,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(eata2x_queuecommand)
+
 static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
 {
        struct Scsi_Host *shost = SCarg->device->host;
index 60886c19065e290a4475822d183aa92c8dc4de0c..4a9641e69f54853860e9f6b82999c0955fcb00e4 100644 (file)
@@ -335,7 +335,7 @@ static inline unsigned int eata_pio_send_command(unsigned long base, unsigned ch
        return 0;
 }
 
-static int eata_pio_queue(struct scsi_cmnd *cmd,
+static int eata_pio_queue_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        unsigned int x, y;
@@ -438,6 +438,8 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(eata_pio_queue)
+
 static int eata_pio_abort(struct scsi_cmnd *cmd)
 {
        unsigned int loop = 100;
index e2bc779f86c1d4c7be559eb018904ac3d58ff0a6..57558523c1b8cd67ba8e83aacf8691eba8205928 100644 (file)
@@ -916,7 +916,7 @@ static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
        scsi_track_queue_full(dev, lp->num_tagged - 1);
 }
 
-static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *dev = cmd->device;
        struct esp *esp = shost_priv(dev->host);
@@ -941,6 +941,8 @@ static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
        return 0;
 }
 
+static DEF_SCSI_QCMD(esp_queuecommand)
+
 static int esp_check_gross_error(struct esp *esp)
 {
        if (esp->sreg & ESP_STAT_SPAM) {
index 2ad95aa8f58536a664a4c7d2114c4505d27355fe..a2c6135d337edab43838a94ee9c9ffc1061b216a 100644 (file)
@@ -1072,7 +1072,7 @@ static int fd_mcs_release(struct Scsi_Host *shpnt)
        return 0;
 }
 
-static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int fd_mcs_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *shpnt = SCpnt->device->host;
 
@@ -1122,6 +1122,8 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(fd_mcs_queue)
+
 #if DEBUG_ABORT || DEBUG_RESET
 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
 {
index e296bcc57d5c8920a2b90cf9a0858cac91e60d07..69b7aa54f43fc2e6d943512d35dcb4b2e6de9c2a 100644 (file)
@@ -1419,7 +1419,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
    return IRQ_HANDLED;
 }
 
-static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
+static int fdomain_16x0_queue_lck(struct scsi_cmnd *SCpnt,
                void (*done)(struct scsi_cmnd *))
 {
    if (in_command) {
@@ -1469,6 +1469,8 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
    return 0;
 }
 
+static DEF_SCSI_QCMD(fdomain_16x0_queue)
+
 #if DEBUG_ABORT
 static void print_info(struct scsi_cmnd *SCpnt)
 {
index cbb20b13b2288957ad39781e774bcd8891245da5..92f185081e622657bdb279850caf979200eb63b9 100644 (file)
@@ -246,7 +246,7 @@ void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
 void fnic_update_mac(struct fc_lport *, u8 *new);
 void fnic_update_mac_locked(struct fnic *, u8 *new);
 
-int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fnic_abort_cmd(struct scsi_cmnd *);
 int fnic_device_reset(struct scsi_cmnd *);
 int fnic_host_reset(struct scsi_cmnd *);
index 198cbab3e8941e0016720463e1279e9992ec193f..22d02404d15f6ce1a86a2b2fbccb852d8fd21003 100644 (file)
@@ -349,7 +349,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
  * Routine to send a scsi cdb
  * Called with host_lock held and interrupts disabled.
  */
-int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        struct fc_lport *lp;
        struct fc_rport *rport;
@@ -457,6 +457,8 @@ out:
        return ret;
 }
 
+DEF_SCSI_QCMD(fnic_queuecommand)
+
 /*
  * fnic_fcpio_fw_reset_cmpl_handler
  * Routine to handle fw reset completion
index 921764c9ab2478334eaca4919fef8d4a4263dae3..1bcdb7beb77b37c08a6508318857e4f92363f0a9 100644 (file)
@@ -46,7 +46,7 @@
 static int generic_NCR5380_abort(Scsi_Cmnd *);
 static int generic_NCR5380_detect(struct scsi_host_template *);
 static int generic_NCR5380_release_resources(struct Scsi_Host *);
-static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int generic_NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
 static const char* generic_NCR5380_info(struct Scsi_Host *);
 
index 841101846b88fe98e55a6c601b013ef9119cdf4a..76365700e2d537497dd3d844fc04c6699e92ac6b 100644 (file)
@@ -185,7 +185,7 @@ static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
                                unsigned long arg);
 
 static void gdth_flush(gdth_ha_str *ha);
-static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
+static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
                                struct gdth_cmndinfo *cmndinfo);
 static void gdth_scsi_done(struct scsi_cmnd *scp);
@@ -4004,7 +4004,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se
 }
 
 
-static int gdth_queuecommand(struct scsi_cmnd *scp,
+static int gdth_queuecommand_lck(struct scsi_cmnd *scp,
                                void (*done)(struct scsi_cmnd *))
 {
     gdth_ha_str *ha = shost_priv(scp->device->host);
@@ -4022,6 +4022,8 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
     return __gdth_queuecommand(ha, scp, cmndinfo);
 }
 
+static DEF_SCSI_QCMD(gdth_queuecommand)
+
 static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
                                struct gdth_cmndinfo *cmndinfo)
 {
index c5d0606ad0974edab8c0326f4fadff905413c171..b2fb2b2a6e700e86d7de265503b70cb48830d994 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 #include <linux/blktrace_api.h>
 #include <linux/uaccess.h>
@@ -143,8 +142,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
        void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
        int cmd_type);
 
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
-               void (*done)(struct scsi_cmnd *));
+static int hpsa_scsi_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static void hpsa_scan_start(struct Scsi_Host *);
 static int hpsa_scan_finished(struct Scsi_Host *sh,
        unsigned long elapsed_time);
@@ -1926,7 +1924,7 @@ sglist_finished:
 }
 
 
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd,
        void (*done)(struct scsi_cmnd *))
 {
        struct ctlr_info *h;
@@ -2020,6 +2018,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(hpsa_scsi_queue_command)
+
 static void hpsa_scan_start(struct Scsi_Host *sh)
 {
        struct ctlr_info *h = shost_to_hba(sh);
index 0729f150b33aa038aa690f3122ae03dbd9115a5b..10b65556937b0478885ab5f528ab6098e61a1663 100644 (file)
@@ -751,7 +751,7 @@ static void hptiop_post_req_mv(struct hptiop_hba *hba,
                MVIOP_MU_QUEUE_ADDR_HOST_BIT | size_bit, hba);
 }
 
-static int hptiop_queuecommand(struct scsi_cmnd *scp,
+static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
                                void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = scp->device->host;
@@ -819,6 +819,8 @@ cmd_done:
        return 0;
 }
 
+static DEF_SCSI_QCMD(hptiop_queuecommand)
+
 static const char *hptiop_info(struct Scsi_Host *host)
 {
        return driver_name_long;
index 9a4b69d4f4eb0d80c47117963cecbef3b2a1ebc2..67fc8ffd52e68eeb2bfe311d04d6bc2052895f74 100644 (file)
@@ -39,7 +39,7 @@
 #include <scsi/scsi_host.h>
 
 /* Common forward declarations for all Linux-versions: */
-static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int ibmmca_queuecommand (struct Scsi_Host *, struct scsi_cmnd *);
 static int ibmmca_abort (Scsi_Cmnd *);
 static int ibmmca_host_reset (Scsi_Cmnd *);
 static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
@@ -1691,7 +1691,7 @@ static int __devexit ibmmca_remove(struct device *dev)
 }
 
 /* The following routine is the SCSI command queue for the midlevel driver */
-static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int ibmmca_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        unsigned int ldn;
        unsigned int scsi_cmd;
@@ -1996,6 +1996,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(ibmmca_queuecommand)
+
 static int __ibmmca_abort(Scsi_Cmnd * cmd)
 {
        /* Abort does not work, as the adapter never generates an interrupt on
index 00d08b25425fdf2faea0a1e3bd063167943291fc..57cad7e20caaad0f5bfe4d47e721d494d1ef826d 100644 (file)
@@ -1606,7 +1606,7 @@ static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost)
  * Returns:
  *     0 on success / other on failure
  **/
-static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
                               void (*done) (struct scsi_cmnd *))
 {
        struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
@@ -1672,6 +1672,8 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ibmvfc_queuecommand)
+
 /**
  * ibmvfc_sync_completion - Signal that a synchronous command has completed
  * @evt:       ibmvfc event struct
index 67f78a470f5f091c6775fb17f37c1fd00293e1ac..041958453e2a6e6fc39bc4b727d1c44c904a5f9e 100644 (file)
@@ -713,7 +713,7 @@ static inline u16 lun_from_dev(struct scsi_device *dev)
  * @cmd:       struct scsi_cmnd to be executed
  * @done:      Callback function to be called when cmd is completed
 */
-static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd,
                                 void (*done) (struct scsi_cmnd *))
 {
        struct srp_cmd *srp_cmd;
@@ -766,6 +766,8 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
        return ibmvscsi_send_srp_event(evt_struct, hostdata, 0);
 }
 
+static DEF_SCSI_QCMD(ibmvscsi_queuecommand)
+
 /* ------------------------------------------------------------
  * Routines for driver initialization
  */
index 4734ab0b3ff6ab9297352d532bf5aeb530757fe8..99aa0e5699bc9369eb144fc2c144b4082ce15348 100644 (file)
@@ -926,7 +926,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
        return 0;
 }
 
-static int imm_queuecommand(struct scsi_cmnd *cmd,
+static int imm_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        imm_struct *dev = imm_dev(cmd->device->host);
@@ -949,6 +949,8 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(imm_queuecommand)
+
 /*
  * Apparently the disk->capacity attribute is off by 1 sector 
  * for all disk drives.  We add the one here, but it should really
index 52bdc6df6b92b5363b234b31edc81566bad646ab..6568aab745a0014944f619465bf0fc7bc6429d32 100644 (file)
@@ -334,7 +334,7 @@ static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
 
 static void in2000_execute(struct Scsi_Host *instance);
 
-static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int in2000_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *instance;
        struct IN2000_hostdata *hostdata;
@@ -431,6 +431,8 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
            return 0;
 }
 
+static DEF_SCSI_QCMD(in2000_queuecommand)
+
 
 
 /*
index 0fb8b06b8392cfbbf45ddbef8d291df21ca5414a..5821e1fbce084c9dfe2cf6f9975441245144b9cc 100644 (file)
@@ -396,7 +396,7 @@ struct IN2000_hostdata {
                                                           flags)
 
 static int in2000_detect(struct scsi_host_template *) in2000__INIT;
-static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int in2000_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int in2000_abort(Scsi_Cmnd *);
 static void in2000_setup(char *, int *) in2000__INIT;
 static int in2000_biosparam(struct scsi_device *, struct block_device *,
index 108797761b95c2692fe942148a963c2ef51516ea..9627d062e16b3e819c11db4b5865f2f7a4cb8d85 100644 (file)
@@ -2639,7 +2639,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
  *     will cause the mid layer to call us again later with the command)
  */
 
-static int i91u_queuecommand(struct scsi_cmnd *cmd,
+static int i91u_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
@@ -2656,6 +2656,8 @@ static int i91u_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(i91u_queuecommand)
+
 /**
  *     i91u_bus_reset          -       reset the SCSI bus
  *     @cmnd: Command block we want to trigger the reset for
index fa60d7df44bed7154adf9aa784cecc937db64d23..5bbaee597e8857cbb2c09e66f06a278f2fb46353 100644 (file)
@@ -5709,7 +5709,7 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
  *     SCSI_MLQUEUE_DEVICE_BUSY if device is busy
  *     SCSI_MLQUEUE_HOST_BUSY if host is busy
  **/
-static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
+static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
                            void (*done) (struct scsi_cmnd *))
 {
        struct ipr_ioa_cfg *ioa_cfg;
@@ -5792,6 +5792,8 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ipr_queuecommand)
+
 /**
  * ipr_ioctl - IOCTL handler
  * @sdev:      scsi device struct
index f83a116955f2f1c6409acfae27d2e91719d42276..b2511acd39bd3feeb7f87e6f956ffae6b8e73780 100644 (file)
@@ -232,7 +232,7 @@ static int ips_detect(struct scsi_host_template *);
 static int ips_release(struct Scsi_Host *);
 static int ips_eh_abort(struct scsi_cmnd *);
 static int ips_eh_reset(struct scsi_cmnd *);
-static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
+static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
 static const char *ips_info(struct Scsi_Host *);
 static irqreturn_t do_ipsintr(int, void *);
 static int ips_hainit(ips_ha_t *);
@@ -1046,7 +1046,7 @@ static int ips_eh_reset(struct scsi_cmnd *SC)
 /*    Linux obtains io_request_lock before calling this function            */
 /*                                                                          */
 /****************************************************************************/
-static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
+static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 {
        ips_ha_t *ha;
        ips_passthru_t *pt;
@@ -1137,6 +1137,8 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
        return (0);
 }
 
+static DEF_SCSI_QCMD(ips_queue)
+
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_biosparam                                              */
index e340373b509b6528ea0602d410eb902c3b233321..2924363d142bc4affc6422de1272e73a70957486 100644 (file)
@@ -1753,7 +1753,7 @@ static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
  * This is the i/o strategy routine, called by the SCSI layer. This routine
  * is called with the host_lock held.
  */
-int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
+static int fc_queuecommand_lck(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 {
        struct fc_lport *lport;
        struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
@@ -1851,6 +1851,8 @@ out:
        spin_lock_irq(lport->host->host_lock);
        return rc;
 }
+
+DEF_SCSI_QCMD(fc_queuecommand)
 EXPORT_SYMBOL(fc_queuecommand);
 
 /**
index 633e09036357828b87e1df84dacec85beda24492..c15fde808c33e98ea1b48398afaf951e19eedeaa 100644 (file)
@@ -1599,7 +1599,7 @@ enum {
        FAILURE_SESSION_NOT_READY,
 };
 
-int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
        struct iscsi_cls_session *cls_session;
        struct Scsi_Host *host;
@@ -1736,6 +1736,8 @@ fault:
        spin_lock(host->host_lock);
        return 0;
 }
+
+DEF_SCSI_QCMD(iscsi_queuecommand)
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
 
 int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
index 55f09e92ab5918fd5019cacaded186d2cd1b1c55..29251fabecc65b50643a295bf3ca87c422f920d6 100644 (file)
@@ -189,7 +189,7 @@ int sas_queue_up(struct sas_task *task)
  * Note: XXX: Remove the host unlock/lock pair when SCSI Core can
  * call us without holding an IRQ spinlock...
  */
-int sas_queuecommand(struct scsi_cmnd *cmd,
+static int sas_queuecommand_lck(struct scsi_cmnd *cmd,
                     void (*scsi_done)(struct scsi_cmnd *))
        __releases(host->host_lock)
        __acquires(dev->sata_dev.ap->lock)
@@ -254,6 +254,8 @@ out:
        return res;
 }
 
+DEF_SCSI_QCMD(sas_queuecommand)
+
 static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
 {
        struct sas_task *task = TO_SAS_TASK(cmd);
index f64b65a770b8df3b3f0a3ba47decc0512a8df0a7..581837b3c71a9369c12f31d3b547f555bfca576d 100644 (file)
@@ -2899,7 +2899,7 @@ void lpfc_poll_timeout(unsigned long ptr)
  *   SCSI_MLQUEUE_HOST_BUSY - Block all devices served by this host temporarily.
  **/
 static int
-lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
        struct Scsi_Host  *shost = cmnd->device->host;
        struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
@@ -3060,6 +3060,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(lpfc_queuecommand)
+
 /**
  * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
  * @cmnd: Pointer to scsi_cmnd data structure.
index 3ddb4dc62d5d5eed49ecc1a1228ddbdfbecd1f47..6c42dff0f4d30d77e68dbfc445e961bfb55a786a 100644 (file)
@@ -66,7 +66,7 @@ static void cmd_done(struct fsc_state *, int result);
 static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *);
 
 
-static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct fsc_state *state;
 
@@ -99,6 +99,8 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
        return 0;
 }
 
+static DEF_SCSI_QCMD(mac53c94_queue)
+
 static int mac53c94_host_reset(struct scsi_cmnd *cmd)
 {
        struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
index 7ceb5cf12c6be3be77ccba93e4a1d550a9d80800..9aa048525eb2544b8159a9495f1a604695a79d26 100644 (file)
@@ -366,7 +366,7 @@ mega_runpendq(adapter_t *adapter)
  * The command queuing entry point for the mid-layer.
  */
 static int
-megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
+megaraid_queue_lck(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
 {
        adapter_t       *adapter;
        scb_t   *scb;
@@ -409,6 +409,8 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
        return busy;
 }
 
+static DEF_SCSI_QCMD(megaraid_queue)
+
 /**
  * mega_allocate_scb()
  * @adapter - pointer to our soft state
@@ -4456,7 +4458,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
 
        scb->idx = CMDID_INT_CMDS;
 
-       megaraid_queue(scmd, mega_internal_done);
+       megaraid_queue_lck(scmd, mega_internal_done);
 
        wait_for_completion(&adapter->int_waitq);
 
index 2b4a048cadf1b31d41a0659e1be55acb96815cd9..f5644745e24e1fe4980188d062d179753a5b024f 100644 (file)
@@ -987,7 +987,7 @@ static int mega_query_adapter(adapter_t *);
 static int issue_scb(adapter_t *, scb_t *);
 static int mega_setup_mailbox(adapter_t *);
 
-static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static int megaraid_queue (struct Scsi_Host *, struct scsi_cmnd *);
 static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
 static void __mega_runpendq(adapter_t *);
 static int issue_scb_block(adapter_t *, u_char *);
index a7810a106b37aed653e5183c192e60d1758d30bb..5708cb27d0783df3525fa1789dd10859a647f921 100644 (file)
@@ -113,8 +113,7 @@ static int megaraid_mbox_fire_sync_cmd(adapter_t *);
 static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
 static void megaraid_mbox_setup_device_map(adapter_t *);
 
-static int megaraid_queue_command(struct scsi_cmnd *,
-               void (*)(struct scsi_cmnd *));
+static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *);
 static void megaraid_mbox_runpendq(adapter_t *, scb_t *);
 static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *,
@@ -1484,7 +1483,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb)
  * Queue entry point for mailbox based controllers.
  */
 static int
-megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
        adapter_t       *adapter;
        scb_t           *scb;
@@ -1513,6 +1512,8 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
        return if_busy;
 }
 
+static DEF_SCSI_QCMD(megaraid_queue_command)
+
 /**
  * megaraid_mbox_build_cmd - transform the mid-layer scsi commands
  * @adapter    : controller's soft state
index eb29d508513148653fb492df24cee9ab0b14cb17..7451bc096a015db4ff38a42725387dabf3b0a58e 100644 (file)
@@ -1334,7 +1334,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
  * @done:                      Callback entry point
  */
 static int
-megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
 {
        u32 frame_count;
        struct megasas_cmd *cmd;
@@ -1417,6 +1417,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(megasas_queue_command)
+
 static struct megasas_instance *megasas_lookup_instance(u16 host_no)
 {
        int i;
index 1f784fde25109b53ef86f2b79fd975ed5cc2bf38..197aa1b3f0f31f111b7980310d05aa948880eb7c 100644 (file)
@@ -1627,7 +1627,7 @@ static void cmd_complete(struct mesh_state *ms)
  * Called by midlayer with host locked to queue a new
  * request
  */
-static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct mesh_state *ms;
 
@@ -1648,6 +1648,8 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(mesh_queue)
+
 /*
  * Called to handle interrupts, either call by the interrupt
  * handler (do_mesh_interrupt) or by other functions in
index 16e99b6863549ed0495cc283c884d9a162d34c01..1a96a00418a4faed68a77519a49d1bf81e02f6b2 100644 (file)
@@ -3315,7 +3315,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
  * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
  */
 static int
-_scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
+_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 {
        struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
        struct MPT2SAS_DEVICE *sas_device_priv_data;
@@ -3441,6 +3441,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
+static DEF_SCSI_QCMD(_scsih_qcmd)
+
 /**
  * _scsih_normalize_sense - normalize descriptor and fixed format sense data
  * @sense_buffer: sense data returned by target
index d013a2aa2fd54aac8e6d251f4aa2267ebe669922..46cc3825638d63fe50c6bd104214489b59c472ef 100644 (file)
@@ -8029,7 +8029,7 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device)
        return 0;
 }
 
-static int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+static int ncr53c8xx_queue_command_lck (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
      struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
      unsigned long flags;
@@ -8068,6 +8068,8 @@ printk("ncr53c8xx : command successfully queued\n");
      return sts;
 }
 
+static DEF_SCSI_QCMD(ncr53c8xx_queue_command)
+
 irqreturn_t ncr53c8xx_intr(int irq, void *dev_id)
 {
      unsigned long flags;
index 4c1e545452009c957baed7fa590018d93b4a3bfe..6b8b021400f848d9770684e4c1a5aebe4d2374e6 100644 (file)
@@ -196,8 +196,7 @@ static void __exit    exit_nsp32  (void);
 static int         nsp32_proc_info   (struct Scsi_Host *, char *, char **, off_t, int, int);
 
 static int         nsp32_detect      (struct pci_dev *pdev);
-static int         nsp32_queuecommand(struct scsi_cmnd *,
-               void (*done)(struct scsi_cmnd *));
+static int         nsp32_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static const char *nsp32_info        (struct Scsi_Host *);
 static int         nsp32_release     (struct Scsi_Host *);
 
@@ -909,7 +908,7 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
        return TRUE;
 }
 
-static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
        nsp32_target *target;
@@ -1050,6 +1049,8 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        return 0;
 }
 
+static DEF_SCSI_QCMD(nsp32_queuecommand)
+
 /* initialize asic */
 static int nsp32hw_init(nsp32_hw_data *data)
 {
index 8dc5b1a5f5da7ebacdbedbdbc9a8b5b9a135d42b..a04281cace2e318e8c1896f7d30b818e41e24000 100644 (file)
@@ -118,7 +118,7 @@ static int pas16_abort(Scsi_Cmnd *);
 static int pas16_biosparam(struct scsi_device *, struct block_device *,
                           sector_t, int*);
 static int pas16_detect(struct scsi_host_template *);
-static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int pas16_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int pas16_bus_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
index 9326c2c148803a6d1933faa0d183b6fad26be460..be3f33d31a99dc3e359190e233ae91b48e2066fe 100644 (file)
@@ -184,7 +184,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
        SCpnt->scsi_done(SCpnt);
 }
 
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
                            void (*done)(struct scsi_cmnd *))
 {
 #ifdef NSP_DEBUG
@@ -264,6 +264,8 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(nsp_queuecommand)
+
 /*
  * setup PIO FIFO transfer mode and enable/disable to data out
  */
index d68c9f267c5edc1aa285762d523e9ea58055bd29..7fc9a9d0a448b6a01c42461758ef118f5190ed93 100644 (file)
@@ -299,8 +299,7 @@ static        int        nsp_proc_info  (
                                         off_t   offset,
                                         int     length,
                                         int     inout);
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
-                           void (* done)(struct scsi_cmnd *SCpnt));
+static int nsp_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
 
 /* Error handler */
 /*static int nsp_eh_abort       (struct scsi_cmnd *SCpnt);*/
index 0ae27cb5cd6f30334d6e2dd19bae9c187729733d..8552296edaa1e8062504e4b8ee63d46cc19694e2 100644 (file)
@@ -547,7 +547,7 @@ SYM53C500_info(struct Scsi_Host *SChost)
 }
 
 static int 
-SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
        int i;
        int port_base = SCpnt->device->host->io_port;
@@ -583,6 +583,8 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(SYM53C500_queue)
+
 static int 
 SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
 {
index 8e38ca8cd1016461e9642d4032d579feb6fac6fc..7f064f9ca828d3ac1db449d352104899f31b84e8 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/sas_ata.h>
index cf89091e4c3d3befec59b89425792dcad23e2a87..5e76a624cb08a843d194e7102900dfac77c2aae4 100644 (file)
@@ -3478,7 +3478,7 @@ static int pmcraid_copy_sglist(
  *       SCSI_MLQUEUE_DEVICE_BUSY if device is busy
  *       SCSI_MLQUEUE_HOST_BUSY if host is busy
  */
-static int pmcraid_queuecommand(
+static int pmcraid_queuecommand_lck(
        struct scsi_cmnd *scsi_cmd,
        void (*done) (struct scsi_cmnd *)
 )
@@ -3584,6 +3584,8 @@ static int pmcraid_queuecommand(
        return rc;
 }
 
+static DEF_SCSI_QCMD(pmcraid_queuecommand)
+
 /**
  * pmcraid_open -char node "open" entry, allowed only users with admin access
  */
index 7bc2d796e4037712dd1113fe1e94d81f09782b85..d164c9639361c773fb41717509608587cb2ab9a6 100644 (file)
@@ -798,7 +798,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
        return 0;
 }
 
-static int ppa_queuecommand(struct scsi_cmnd *cmd,
+static int ppa_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done) (struct scsi_cmnd *))
 {
        ppa_struct *dev = ppa_dev(cmd->device->host);
@@ -821,6 +821,8 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ppa_queuecommand)
+
 /*
  * Apparently the disk->capacity attribute is off by 1 sector 
  * for all disk drives.  We add the one here, but it should really
index 92ffbb5104980dc98bde7d839dce1cd6548d385d..cd178b9e40cdde6d0266d103974357028a3e3807 100644 (file)
@@ -211,7 +211,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
        return 0;
 }
 
-static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
+static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd,
                               void (*done)(struct scsi_cmnd *))
 {
        struct ps3rom_private *priv = shost_priv(cmd->device->host);
@@ -260,6 +260,8 @@ static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(ps3rom_queuecommand)
+
 static int decode_lv1_status(u64 status, unsigned char *sense_key,
                             unsigned char *asc, unsigned char *ascq)
 {
index b8166ecfd0e35f17894a077679d5f5d2a29701cf..5dec684bf0103d5cb9fd244d5b3a706ab1109720 100644 (file)
@@ -727,7 +727,7 @@ qla1280_info(struct Scsi_Host *host)
  * context which is a big NO! NO!.
  **************************************************************************/
 static int
-qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+qla1280_queuecommand_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
@@ -756,6 +756,8 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
        return status;
 }
 
+static DEF_SCSI_QCMD(qla1280_queuecommand)
+
 enum action {
        ABORT_COMMAND,
        DEVICE_RESET,
index 1830e6e973155684234710e129e564f82176ce2d..1644eabaafeb58cb3130dccdb97b489bcd0c708e 100644 (file)
@@ -179,8 +179,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
 static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
 static void qla2xxx_scan_start(struct Scsi_Host *);
 static void qla2xxx_slave_destroy(struct scsi_device *);
-static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
-               void (*fn)(struct scsi_cmnd *));
+static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
@@ -535,7 +534,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
 }
 
 static int
-qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -609,6 +608,8 @@ qc24_fail_command:
        return 0;
 }
 
+static DEF_SCSI_QCMD(qla2xxx_queuecommand)
+
 
 /*
  * qla2x00_eh_wait_on_command
index f4cd846abf6dcf77dc7d6bd7a855437ba6a1868f..0d48fb4d1044480d8743ed355019891d1d03e907 100644 (file)
@@ -79,8 +79,7 @@ static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);
 /*
  * SCSI host template entry points
  */
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
-                               void (*done) (struct scsi_cmnd *));
+static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
@@ -464,7 +463,7 @@ void qla4xxx_srb_compl(struct kref *ref)
  * completion handling).   Unfortunely, it sometimes calls the scheduler
  * in interrupt context which is a big NO! NO!.
  **/
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd,
                                void (*done)(struct scsi_cmnd *))
 {
        struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
@@ -538,6 +537,8 @@ qc_fail_command:
        return 0;
 }
 
+static DEF_SCSI_QCMD(qla4xxx_queuecommand)
+
 /**
  * qla4xxx_mem_free - frees memory allocated to adapter
  * @ha: Pointer to host adapter structure.
index 1ad51552d6b188aba1e206d5dc8e2a2ae96622a9..c3a9151ca823cb64651390e940794262d9b7d989 100644 (file)
@@ -439,7 +439,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id)
  *     Queued command
  */
 
-int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
+static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
                              void (*done) (struct scsi_cmnd *))
 {
        struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
@@ -459,6 +459,8 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+DEF_SCSI_QCMD(qlogicfas408_queuecommand)
+
 /* 
  *     Return bios parameters 
  */
index 260626427a328f21ba57c40f86f05003e0b50ea2..2f6c0a166200fdea89aba2d8aee31281718a6be1 100644 (file)
@@ -103,8 +103,7 @@ struct qlogicfas408_priv {
 #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
 
 irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
-int qlogicfas408_queuecommand(struct scsi_cmnd * cmd,
-                             void (*done) (struct scsi_cmnd *));
+int qlogicfas408_queuecommand(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 int qlogicfas408_biosparam(struct scsi_device * disk,
                           struct block_device *dev,
                           sector_t capacity, int ip[]);
index f8c561cf751e46aa62e841a5e1d35920c3f6ecf1..664c9572d0c9a44b2540a05857c8710596d8b6c1 100644 (file)
@@ -1003,7 +1003,7 @@ static int qlogicpti_slave_configure(struct scsi_device *sdev)
  *
  * "This code must fly." -davem
  */
-static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
+static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = Cmnd->device->host;
        struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
@@ -1052,6 +1052,8 @@ toss_command:
        return 1;
 }
 
+static DEF_SCSI_QCMD(qlogicpti_queuecommand)
+
 static int qlogicpti_return_status(struct Status_Entry *sts, int id)
 {
        int host_status = DID_ERROR;
index 348fba0a8976467fa9724411699b918a9cd8b0ea..2aeb2e9c4d3bc708d5c12c7a117b021ffc160409 100644 (file)
@@ -634,12 +634,13 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
  * Description: a serial number identifies a request for error recovery
  * and debugging purposes.  Protected by the Host_Lock of host.
  */
-static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
        cmd->serial_number = host->cmd_serial_number++;
        if (cmd->serial_number == 0) 
                cmd->serial_number = host->cmd_serial_number++;
 }
+EXPORT_SYMBOL(scsi_cmd_get_serial);
 
 /**
  * scsi_dispatch_command - Dispatch a command to the low-level driver.
@@ -651,7 +652,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd
 int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 {
        struct Scsi_Host *host = cmd->device->host;
-       unsigned long flags = 0;
        unsigned long timeout;
        int rtn = 0;
 
@@ -737,23 +737,15 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
                goto out;
        }
 
-       spin_lock_irqsave(host->host_lock, flags);
-       /*
-        * AK: unlikely race here: for some reason the timer could
-        * expire before the serial number is set up below.
-        *
-        * TODO: kill serial or move to blk layer
-        */
-       scsi_cmd_get_serial(host, cmd); 
-
        if (unlikely(host->shost_state == SHOST_DEL)) {
                cmd->result = (DID_NO_CONNECT << 16);
                scsi_done(cmd);
        } else {
                trace_scsi_dispatch_cmd_start(cmd);
-               rtn = host->hostt->queuecommand(cmd, scsi_done);
+               cmd->scsi_done = scsi_done;
+               rtn = host->hostt->queuecommand(host, cmd);
        }
-       spin_unlock_irqrestore(host->host_lock, flags);
+
        if (rtn) {
                trace_scsi_dispatch_cmd_error(cmd, rtn);
                if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
index 2c36bae3bd4b7ea5c45f2c1c623d671e152a5bd3..2f1f9b079b1067fb078b74c471134bba9a7f55bb 100644 (file)
@@ -3538,7 +3538,7 @@ static void sdebug_remove_adapter(void)
 }
 
 static
-int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
+int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
 {
        unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
        int len, k;
@@ -3884,6 +3884,8 @@ write:
                             (delay_override ? 0 : scsi_debug_delay));
 }
 
+static DEF_SCSI_QCMD(scsi_debug_queuecommand)
+
 static struct scsi_host_template sdebug_driver_template = {
        .proc_info =            scsi_debug_proc_info,
        .proc_name =            sdebug_proc_name,
index f3cf924a2cd96f8c322e53d6012c8397c99f8a58..824b8fc03ce52f087dd3ca4d0fdadab15dfcac17 100644 (file)
@@ -773,17 +773,15 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
        struct Scsi_Host *shost = sdev->host;
        DECLARE_COMPLETION_ONSTACK(done);
        unsigned long timeleft;
-       unsigned long flags;
        struct scsi_eh_save ses;
        int rtn;
 
        scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes);
        shost->eh_action = &done;
 
-       spin_lock_irqsave(shost->host_lock, flags);
        scsi_log_send(scmd);
-       shost->hostt->queuecommand(scmd, scsi_eh_done);
-       spin_unlock_irqrestore(shost->host_lock, flags);
+       scmd->scsi_done = scsi_eh_done;
+       shost->hostt->queuecommand(shost, scmd);
 
        timeleft = wait_for_completion_timeout(&done, timeout);
 
index b9ab3a590e4b4fd891865a1f9d3d5f3cb55d9dc5..956496182c805d8dd7f0aa58cc3ddb7c12c91b8b 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/delay.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/string_helpers.h>
 #include <linux/async.h>
index 9c73dbda3bbb8d3137e8adaed717b61d83cf6551..606215e54b8896f38deeb51603a29f8e12cd5e40 100644 (file)
@@ -572,7 +572,7 @@ stex_slave_destroy(struct scsi_device *sdev)
 }
 
 static int
-stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct st_hba *hba;
        struct Scsi_Host *host;
@@ -698,6 +698,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(stex_queuecommand)
+
 static void stex_scsi_done(struct st_ccb *ccb)
 {
        struct scsi_cmnd *cmd = ccb->cmd;
index 713620ed70d96ef4a8f6111a689a118d2a6f962d..4f0e5485ffde4bf0b859a3786191861f83e0a62f 100644 (file)
@@ -908,7 +908,7 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
  */
 
 /* Only make static if a wrapper function is used */
-static int NCR5380_queue_command(struct scsi_cmnd *cmd,
+static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
                                 void (*done)(struct scsi_cmnd *))
 {
     SETUP_HOSTDATA(cmd->device->host);
@@ -1019,6 +1019,8 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
     return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
 /*
  * Function : NCR5380_main (void) 
  *
index b29a9d661ca41740b7e7a9693f4a04fb806ec64a..bcefd8458e653f086bf6387f6c80dbd82d0c3322 100644 (file)
@@ -51,8 +51,7 @@ static int sun3scsi_abort(struct scsi_cmnd *);
 static int sun3scsi_detect (struct scsi_host_template *);
 static const char *sun3scsi_info (struct Scsi_Host *);
 static int sun3scsi_bus_reset(struct scsi_cmnd *);
-static int sun3scsi_queue_command(struct scsi_cmnd *,
-                                 void (*done)(struct scsi_cmnd *));
+static int sun3scsi_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int sun3scsi_release (struct Scsi_Host *);
 
 #ifndef CMD_PER_LUN
index e5c369bb568f5d9ae5fd23b8bb8423c1be9c6ba1..190107ae120b5241d02864d94e6420cb826a3785 100644 (file)
@@ -734,7 +734,7 @@ const char *sym53c416_info(struct Scsi_Host *SChost)
        return info;
 }
 
-int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
        int base;
        unsigned long flags = 0;
@@ -761,6 +761,8 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        return 0;
 }
 
+DEF_SCSI_QCMD(sym53c416_queuecommand)
+
 static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
 {
        int base;
index 77860d0748ffc4d7c1eca48167f146427186524e..387de5d80a704373a3cbeeea42bbfb5d9ac08046 100644 (file)
@@ -25,7 +25,7 @@
 static int sym53c416_detect(struct scsi_host_template *);
 static const char *sym53c416_info(struct Scsi_Host *);
 static int sym53c416_release(struct Scsi_Host *);
-static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int sym53c416_host_reset(Scsi_Cmnd *);
 static int sym53c416_bios_param(struct scsi_device *, struct block_device *,
                sector_t, int *);
index 8b955b534a36f7ce836967b49978b2deb7bd8d64..6b97ded9d45de641770335a851d29761b9c9e66a 100644 (file)
@@ -505,7 +505,7 @@ void sym_log_bus_error(struct Scsi_Host *shost)
  * queuecommand method.  Entered with the host adapter lock held and
  * interrupts disabled.
  */
-static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
+static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd,
                                        void (*done)(struct scsi_cmnd *))
 {
        struct sym_hcb *np = SYM_SOFTC_PTR(cmd);
@@ -536,6 +536,8 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(sym53c8xx_queue_command)
+
 /*
  *  Linux entry point of the interrupt handler.
  */
index 76a069b7ac0bbd7ef2ae26a61a4c612b4f67b340..ada1115079c9e6890b00108e83f70f15061058a0 100644 (file)
@@ -96,8 +96,7 @@ static int t128_abort(struct scsi_cmnd *);
 static int t128_biosparam(struct scsi_device *, struct block_device *,
                          sector_t, int*);
 static int t128_detect(struct scsi_host_template *);
-static int t128_queue_command(struct scsi_cmnd *,
-                             void (*done)(struct scsi_cmnd *));
+static int t128_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
 static int t128_bus_reset(struct scsi_cmnd *);
 
 #ifndef CMD_PER_LUN
index 27866b0adfebd4901dbb1a38a4ebc752ecfd3d70..a124a28f2ccbf27f3e89981cc60eb57f0a305fc0 100644 (file)
@@ -1883,7 +1883,7 @@ dc390_ScsiRstDetect( struct dc390_acb* pACB )
     return;
 }
 
-static int DC390_queuecommand(struct scsi_cmnd *cmd,
+static int DC390_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *sdev = cmd->device;
@@ -1944,6 +1944,8 @@ static int DC390_queuecommand(struct scsi_cmnd *cmd,
        return SCSI_MLQUEUE_DEVICE_BUSY;
 }
 
+static DEF_SCSI_QCMD(DC390_queuecommand)
+
 static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
 {
     struct pci_dev *pdev;
index 5d9fdeeb2315cdd5e9958bf24ea56cd3669fca47..edfc5da8be4c05aa5bc729c7ee47fca531bf797f 100644 (file)
 
 static int u14_34f_detect(struct scsi_host_template *);
 static int u14_34f_release(struct Scsi_Host *);
-static int u14_34f_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+static int u14_34f_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int u14_34f_eh_abort(struct scsi_cmnd *);
 static int u14_34f_eh_host_reset(struct scsi_cmnd *);
 static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
@@ -1248,7 +1248,7 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
 
 }
 
-static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
+static int u14_34f_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
    unsigned int i, j, k;
    struct mscp *cpp;
 
@@ -1329,6 +1329,8 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
    return 0;
 }
 
+static DEF_SCSI_QCMD(u14_34f_queuecommand)
+
 static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
    unsigned int i, j;
 
index 27aa40f3980e56114ddb53847bda968a9e5d1a66..0571ef9639cbc15b6d5ace0384c03a895900ff7d 100644 (file)
@@ -700,7 +700,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
        mscp->transfer_data_length = transfer_length;
 }
 
-static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
+static int ultrastor_queuecommand_lck(struct scsi_cmnd *SCpnt,
                                void (*done) (struct scsi_cmnd *))
 {
     struct mscp *my_mscp;
@@ -825,6 +825,8 @@ retry:
     return 0;
 }
 
+static DEF_SCSI_QCMD(ultrastor_queuecommand)
+
 /* This code must deal with 2 cases:
 
    1. The command has not been written to the OGM.  In this case, set
index a692905f95f76c3d3935ddfbd9b6f38daa60c788..165c18b5cf5f70a96801d181376a60c55c761c85 100644 (file)
@@ -15,8 +15,7 @@
 
 static int ultrastor_detect(struct scsi_host_template *);
 static const char *ultrastor_info(struct Scsi_Host *shpnt);
-static int ultrastor_queuecommand(struct scsi_cmnd *,
-                               void (*done)(struct scsi_cmnd *));
+static int ultrastor_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int ultrastor_abort(struct scsi_cmnd *);
 static int ultrastor_host_reset(struct scsi_cmnd *);
 static int ultrastor_biosparam(struct scsi_device *, struct block_device *,
index 26894459c37fe375076464330ef7809345b57408..a18996d244664588ac1f7d2ea07cca0be3e29e7d 100644 (file)
@@ -690,7 +690,7 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
        return 0;
 }
 
-static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct Scsi_Host *host = cmd->device->host;
        struct pvscsi_adapter *adapter = shost_priv(host);
@@ -719,6 +719,8 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(pvscsi_queue)
+
 static int pvscsi_abort(struct scsi_cmnd *cmd)
 {
        struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
index b701bf2cc1873fb579b64d923f0950ce36d92c60..5f697e0bd0095c97f1c21326bc6c073a8fc61d40 100644 (file)
@@ -371,8 +371,8 @@ calc_sync_msg(unsigned int period, unsigned int offset, unsigned int fast,
        msg[1] = offset;
 }
 
-int
-wd33c93_queuecommand(struct scsi_cmnd *cmd,
+static int
+wd33c93_queuecommand_lck(struct scsi_cmnd *cmd,
                void (*done)(struct scsi_cmnd *))
 {
        struct WD33C93_hostdata *hostdata;
@@ -468,6 +468,8 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
        return 0;
 }
 
+DEF_SCSI_QCMD(wd33c93_queuecommand)
+
 /*
  * This routine attempts to start a scsi command. If the host_card is
  * already connected, we give up immediately. Otherwise, look through
index 1ed5f3bf388eeea541ac6a097c3103d69528a5c8..3b463d7304dca635cf3f4360c7aa6d9430127f63 100644 (file)
@@ -343,8 +343,7 @@ struct WD33C93_hostdata {
 void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs,
          dma_setup_t setup, dma_stop_t stop, int clock_freq);
 int wd33c93_abort (struct scsi_cmnd *cmd);
-int wd33c93_queuecommand (struct scsi_cmnd *cmd,
-               void (*done)(struct scsi_cmnd *));
+int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd);
 void wd33c93_intr (struct Scsi_Host *instance);
 int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 int wd33c93_host_reset (struct scsi_cmnd *);
index 333580bf37c5a7d6cbccf6587d55ad7a2b3b3b2b..db451ae0a36811427165b9d0431d3b38d356ec8e 100644 (file)
@@ -1082,7 +1082,7 @@ static irqreturn_t wd7000_intr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
+static int wd7000_queuecommand_lck(struct scsi_cmnd *SCpnt,
                void (*done)(struct scsi_cmnd *))
 {
        Scb *scb;
@@ -1139,6 +1139,8 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
        return 0;
 }
 
+static DEF_SCSI_QCMD(wd7000_queuecommand)
+
 static int wd7000_diagnostics(Adapter * host, int code)
 {
        static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
index 4d8e14b7aa931bcf3de11c6e5805005e0bf413ca..09a550860dcf7acc702523319332972ed02f7249 100644 (file)
@@ -2872,7 +2872,7 @@ static struct console serial8250_console = {
        .device         = uart_console_device,
        .setup          = serial8250_console_setup,
        .early_setup    = serial8250_console_early_setup,
-       .flags          = CON_PRINTBUFFER,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
        .index          = -1,
        .data           = &serial8250_reg,
 };
index fa62578fcd20f572dbd391b614e47f246250b978..bcc31f2140ac7528811d607fd0e3e1f1f6cd66d4 100644 (file)
@@ -18,7 +18,6 @@ static char *serial_version = "$Revision: 1.25 $";
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/mm.h>
index 5fc699e929dc50dff6601c3b00a2762c1f673a1f..d40010a22ecd788e6d90c69337333c7bed0bfc7b 100644 (file)
@@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
-       u32 mul = 0x3600;
-       u32 ps = 0x10;
+       u32 ps, mul;
 
        switch (termios->c_cflag & CSIZE) {
        case CS5:
@@ -943,31 +942,24 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
 
        quot = 1;
+       ps = 0x10;
+       mul = 0x3600;
        switch (baud) {
        case 3500000:
                mul = 0x3345;
                ps = 0xC;
                break;
-       case 3000000:
-               mul = 0x2EE0;
-               break;
-       case 2500000:
-               mul = 0x2710;
-               break;
-       case 2000000:
-               mul = 0x1F40;
-               break;
        case 1843200:
                mul = 0x2400;
                break;
+       case 3000000:
+       case 2500000:
+       case 2000000:
        case 1500000:
-               mul = 0x1770;
-               break;
        case 1000000:
-               mul = 0xFA0;
-               break;
        case 500000:
-               mul = 0x7D0;
+               /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
+               mul = baud / 500000 * 0x9C4;
                break;
        default:
                /* Use uart_get_divisor to get quot for other baud rates */
index c4ea14670d4486fc142df31d806c528d2752c238..9ffa5bee44ab17b852f9bbaa5b9a5a8f3853286d 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/console.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
 #include <linux/serial_core.h>
index cb12a8e1466b3d8cfe2ad13833d150eaaca90bc3..3f5e387ed56486ba5c454f4a809a9a57d84d80d5 100644 (file)
@@ -418,8 +418,11 @@ int clk_register(struct clk *clk)
                list_add(&clk->sibling, &root_clks);
 
        list_add(&clk->node, &clock_list);
+
+#ifdef CONFIG_SH_CLK_CPG_LEGACY
        if (clk->ops && clk->ops->init)
                clk->ops->init(clk);
+#endif
 
 out_unlock:
        mutex_unlock(&clock_list_sem);
@@ -454,12 +457,6 @@ unsigned long clk_get_rate(struct clk *clk)
 EXPORT_SYMBOL_GPL(clk_get_rate);
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       return clk_set_rate_ex(clk, rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
 {
        int ret = -EOPNOTSUPP;
        unsigned long flags;
@@ -467,7 +464,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
        spin_lock_irqsave(&clock_lock, flags);
 
        if (likely(clk->ops && clk->ops->set_rate)) {
-               ret = clk->ops->set_rate(clk, rate, algo_id);
+               ret = clk->ops->set_rate(clk, rate);
                if (ret != 0)
                        goto out_unlock;
        } else {
@@ -485,7 +482,7 @@ out_unlock:
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+EXPORT_SYMBOL_GPL(clk_set_rate);
 
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
@@ -653,8 +650,7 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
                                        clkp->ops->set_parent(clkp,
                                                clkp->parent);
                                if (likely(clkp->ops->set_rate))
-                                       clkp->ops->set_rate(clkp,
-                                               rate, NO_CHANGE);
+                                       clkp->ops->set_rate(clkp, rate);
                                else if (likely(clkp->ops->recalc))
                                        clkp->rate = clkp->ops->recalc(clkp);
                        }
index 3aea5f0ceb09ebd3f5e3b59ae5b04128862afc9c..6172335ae3234b11d2bd37e4b57dad3c9061278c 100644 (file)
@@ -110,8 +110,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
-static int sh_clk_div6_set_rate(struct clk *clk,
-                               unsigned long rate, int algo_id)
+static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
 {
        unsigned long value;
        int idx;
@@ -132,7 +131,7 @@ static int sh_clk_div6_enable(struct clk *clk)
        unsigned long value;
        int ret;
 
-       ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
+       ret = sh_clk_div6_set_rate(clk, clk->rate);
        if (ret == 0) {
                value = __raw_readl(clk->enable_reg);
                value &= ~0x100; /* clear stop bit to enable clock */
@@ -253,7 +252,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
-static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
 {
        struct clk_div4_table *d4t = clk->priv;
        unsigned long value;
index 154529aacc037e332b005c418659089d80d5c9c5..a067046c9da288b368fecc1aee31aa4cef32c2b7 100644 (file)
@@ -352,8 +352,12 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer)
 
        xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS;
        if (xfer->tx_buf) {
+               /* tx_buf is a const void* where we need a void * for the dma
+                * mapping */
+               void *nonconst_tx = (void *)xfer->tx_buf;
+
                xfer->tx_dma = dma_map_single(dev,
-                               (void *) xfer->tx_buf, xfer->len,
+                               nonconst_tx, xfer->len,
                                DMA_TO_DEVICE);
                if (dma_mapping_error(dev, xfer->tx_dma))
                        return -ENOMEM;
index ef9c6a04ad8f01af0d402f9f0f03a08175c04524..744d3f6e470987c773f72a733dbbc146fa358706 100644 (file)
@@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC,  0x4318) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
index 8c95d8c2a4f4992e51f8b147a2238ce7b2e02430..016c6f7f8630ac551631660f9c27dd529bb1cbd5 100644 (file)
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
 
 #define ASUS_OLED_DEVICE_ATTR(_file)           dev_attr_asus_oled_##_file
 
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO,
                   get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture);
 
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO,
                   class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture);
 
 static int asus_oled_probe(struct usb_interface *interface,
                           const struct usb_device_id *id)
index b68a7e5173be9279b44fbe5ce4f574b847c832b3..d85de82f941a4a8b302b5c4dd02eea8b0de79bcc 100644 (file)
@@ -463,9 +463,6 @@ static void hardif_remove_interface(struct batman_if *batman_if)
                return;
 
        batman_if->if_status = IF_TO_BE_REMOVED;
-
-       /* caller must take if_list_lock */
-       list_del_rcu(&batman_if->list);
        synchronize_rcu();
        sysfs_del_hardif(&batman_if->hardif_obj);
        hardif_put(batman_if);
@@ -474,13 +471,21 @@ static void hardif_remove_interface(struct batman_if *batman_if)
 void hardif_remove_interfaces(void)
 {
        struct batman_if *batman_if, *batman_if_tmp;
+       struct list_head if_queue;
+
+       INIT_LIST_HEAD(&if_queue);
 
-       rtnl_lock();
        spin_lock(&if_list_lock);
        list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
-               hardif_remove_interface(batman_if);
+               list_del_rcu(&batman_if->list);
+               list_add_tail(&batman_if->list, &if_queue);
        }
        spin_unlock(&if_list_lock);
+
+       rtnl_lock();
+       list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
+               hardif_remove_interface(batman_if);
+       }
        rtnl_unlock();
 }
 
@@ -507,8 +512,10 @@ static int hard_if_event(struct notifier_block *this,
                break;
        case NETDEV_UNREGISTER:
                spin_lock(&if_list_lock);
-               hardif_remove_interface(batman_if);
+               list_del_rcu(&batman_if->list);
                spin_unlock(&if_list_lock);
+
+               hardif_remove_interface(batman_if);
                break;
        case NETDEV_CHANGEMTU:
                if (batman_if->soft_iface)
index 3904db9ce7b1f00909ecf2f07df7b561da28ec56..0e996181daf764b81965700b8b0dd90a0e39316d 100644 (file)
@@ -194,14 +194,15 @@ void interface_rx(struct net_device *soft_iface,
        struct bat_priv *priv = netdev_priv(soft_iface);
 
        /* check if enough space is available for pulling, and pull */
-       if (!pskb_may_pull(skb, hdr_size)) {
-               kfree_skb(skb);
-               return;
-       }
+       if (!pskb_may_pull(skb, hdr_size))
+               goto dropped;
+
        skb_pull_rcsum(skb, hdr_size);
 /*     skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
 
        /* skb->dev & skb->pkt_type are set here */
+       if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+               goto dropped;
        skb->protocol = eth_type_trans(skb, soft_iface);
 
        /* should not be neccesary anymore as we use skb_pull_rcsum()
@@ -216,6 +217,11 @@ void interface_rx(struct net_device *soft_iface,
        soft_iface->last_rx = jiffies;
 
        netif_rx(skb);
+       return;
+
+dropped:
+       kfree_skb(skb);
+       return;
 }
 
 #ifdef HAVE_NET_DEVICE_OPS
index c8f1cf1b440963280241229906452d227b3e9ad4..a27bb0b4f58126f24bb17a2d1448517948e5b917 100644 (file)
@@ -88,7 +88,9 @@ with the driver.
 
 Contact Info:
 =============
-Brett Rudley   brudley@broadcom.com
-Henry Ptasinski henryp@broadcom.com
-Dowan Kim      dowan@broadcom.com
+Brett Rudley           brudley@broadcom.com
+Henry Ptasinski                henryp@broadcom.com
+Dowan Kim                      dowan@broadcom.com
+Roland Vossen          rvossen@broadcom.com
+Arend van Spriel       arend@broadcom.com
 
index dbf904184899884c825dab5e1e290c962e5dad25..24ebadbe4241f1ffd5178178d7d07b4eb6451fa5 100644 (file)
@@ -46,4 +46,6 @@ Contact
 Brett Rudley <brudley@broadcom.com>
 Henry Ptasinski <henryp@broadcom.com>
 Dowan Kim <dowan@broadcom.com>
+Roland Vossen <rvossen@broadcom.com>
+Arend van Spriel <arend@broadcom.com>
 
index 1f177a67ff114f9098f3bcdb282068978c6567e3..de784ff08caaef9665e63a66d107a888400301cc 100644 (file)
@@ -2295,8 +2295,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
        usbduxsub_tmp->inBuffer = NULL;
        kfree(usbduxsub_tmp->insnBuffer);
        usbduxsub_tmp->insnBuffer = NULL;
-       kfree(usbduxsub_tmp->inBuffer);
-       usbduxsub_tmp->inBuffer = NULL;
+       kfree(usbduxsub_tmp->outBuffer);
+       usbduxsub_tmp->outBuffer = NULL;
        kfree(usbduxsub_tmp->dac_commands);
        usbduxsub_tmp->dac_commands = NULL;
        kfree(usbduxsub_tmp->dux_commands);
index f3c827eb0abe066bac548b0173cd86b01fb251d8..884263b2775d76a5d0840b59d25cf04453b5a9a2 100644 (file)
@@ -75,9 +75,9 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/module.h>
 #include <linux/kref.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <linux/uaccess.h>
 
index a145a15cfdb39d865a62200a83298192f2670098..8894ab14f167755a242eda73b5465bb16aaa7b8c 100644 (file)
@@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
                t->value = temp;        \
                return count;   \
        }       \
-       static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+       static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
 
 show_int(enable);
 show_int(offline);
index b3f42f37a31381f3bc17d1e5f3bdf1c55ec94c95..48d4e483d8a40b3d2f99ab24b5e69cb3f119bde7 100644 (file)
@@ -199,7 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
        struct go7007 *go = i2c_get_adapdata(adapter);
        struct v4l2_device *v4l2_dev = &go->v4l2_dev;
 
-       if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL))
+       if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
                return 0;
 
        printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
index 41d9acf4cd6119c1d52254df01faaf793e47e622..6f8d67d0d64fd20b77b515b696d9e92c485ed5e4 100644 (file)
@@ -72,8 +72,7 @@ struct storvsc_driver_context {
 
 /* Static decl */
 static int storvsc_probe(struct device *dev);
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
-                               void (*done)(struct scsi_cmnd *));
+static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd);
 static int storvsc_device_alloc(struct scsi_device *);
 static int storvsc_device_configure(struct scsi_device *);
 static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
@@ -595,7 +594,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
 /*
  * storvsc_queuecommand - Initiate command processing
  */
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
+static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
                                void (*done)(struct scsi_cmnd *))
 {
        int ret;
@@ -783,6 +782,8 @@ retry_request:
        return ret;
 }
 
+static DEF_SCSI_QCMD(storvsc_queuecommand)
+
 static int storvsc_merge_bvec(struct request_queue *q,
                              struct bvec_merge_data *bmd, struct bio_vec *bvec)
 {
index c86d1498737d0cbe7db91914f7865969662643a7..1c1e98aee2d9fdd78aeabeab1d604f344a092367 100644 (file)
@@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
                adis16220_write_reset, 0);
 
 #define IIO_DEV_ATTR_CAPTURE(_store)                           \
-       IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0)
+       IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
 
 static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
 
index 9618c79974611f682a8d4dd575f704cf00f92443..991440015e9263e415a9449eb9fa7f34dae07f41 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/uaccess.h>
 #include <linux/firmware.h>
 #include <linux/ioctl.h>
-#include <linux/smp_lock.h>
 #ifdef CONFIG_MRST_RAR_HANDLER
 #include <linux/rar_register.h>
 #include "../../../drivers/staging/memrar/memrar.h"
index fbae39fda5c0307151024edd92bc7c65523bb9f0..5c455608b02451ff83708ce847ee4df68d7617a8 100644 (file)
@@ -1269,7 +1269,7 @@ finish:
        dbufs->output_bytes_produced = total_output;
        str_info->status = str_info->prev;
        str_info->prev = STREAM_DECODE;
-       str_info->decode_ibuf = NULL;
        kfree(str_info->decode_ibuf);
+       str_info->decode_ibuf = NULL;
        return retval;
 }
index a2671404f7ac244c39f51c44303fae0df16fceaf..da4f42af3838eb209e7545128b74d0aaedcebe7b 100644 (file)
@@ -87,7 +87,7 @@ static int slave_configure(struct scsi_device *sdev)
 
 /* This is always called with scsi_lock(host) held */
 //----- queuecommand() ---------------------
-static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
+static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
 {
        struct us_data *us = host_to_us(srb->device->host);
 
@@ -117,6 +117,8 @@ static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(queuecommand)
+
 /***********************************************************************
  * Error handling functions
  ***********************************************************************/
index 040e25ca6d33ef3f4863cac1718ea08a69a09d31..67e23b6e2d3593b22566d54abc8fe9bcda1e41a7 100644 (file)
@@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2);
 VARIAX_PARAM_R(float, mix1);
 VARIAX_PARAM_R(int, pickup_wiring);
 
-static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
                   pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
                   pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
                   pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
                   pod_get_compression_threshold,
                   pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
                   pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
                   pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
                   pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
                   pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
                   pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
                   pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
                   pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
                    pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
                   pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
                   pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
                   pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
                   pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
                   pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
                   pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
                   pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
                   pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
                   pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_delay_param_1_note_value,
                   pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_2_frequency__bass,
                    pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
                   pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
                   pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
                   pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
                   pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
                   pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
                   pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
                   pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
                   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
                   pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_3_frequency__bass,
                    pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
                   pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
                   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
                   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
                   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
                   pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
                   pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
                   pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
                   pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
                   pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_mod_param_1_note_value,
                   pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
                   pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
                   pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
                   pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
                   pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
                   pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
                   pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
                   pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
                    pod_get_band_4_frequency__bass,
                    pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
                   pod_get_mod_param_1_double_precision,
                   pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
                   pod_get_delay_param_1_double_precision,
                   pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
                   pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
                   pod_get_volume_tweak_pedal_assign,
                   pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
                   pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
                   pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
                   pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
                   pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
                   pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
                   pod_get_stomp_param_1_note_value,
                   pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
                   pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
                   pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
                   pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
                   pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
                   pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
                   pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
                   pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
                   pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
                   pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
                   pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
                   pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
                   pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
                   pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
                   pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
                   pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
                   pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
                   pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
                   pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
                   pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
                   pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
                   pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
                   pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
                    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
 static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
 static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
index 4304dfe6c16608debc95f34b7d2cf1dd3a49d681..ab67e889d2c4b53f14f0488d96e3749de08565c7 100644 (file)
@@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO,
                   midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO,
                   midi_get_midi_mask_receive, midi_set_midi_mask_receive);
 
 /* MIDI device destructor */
index e54770e34d2e79440c62e08460c401e5c484ef23..b9c55f9eb501185bb63ad142ca2ea7f1f2bca950 100644 (file)
@@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
+static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume,
                   pcm_set_impulse_volume);
-static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
+static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period,
                   pcm_set_impulse_period);
 
 #endif
index 22e2cedcacf79f027c6b0505c99d66641ec03223..d9b30212585c6851c428a7c525976feb05e7b85d 100644 (file)
@@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
 #undef GET_SYSTEM_PARAM
 
 /* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
+static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel,
                   pod_set_channel);
 static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
 static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
+static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf,
                   pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
                   line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
                   pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
+static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level,
                   pod_set_monitor_level);
 static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
 static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
                   pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
+static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
                   pod_set_routing);
 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
                   line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
                   pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
                   pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
                   pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
+static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
                   pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
+static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
                   pod_set_tuner_mute);
 static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
 static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
 
 #ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
 #endif
 
 /* control info callback */
index 6a10b0f9749a4cee25e54a717072b734a67e5baf..879e6992bbc6f8976c8fbea0c450db15428dda8e 100644 (file)
@@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
                   toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
                   toneport_set_led_green);
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
index 894eee7f2317b62c392dc426be44dee4479fb89c..81241cdf1be97ec60888550c128f3827f23713a2 100644 (file)
@@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev,
 #endif
 
 /* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
+static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
                   variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
                   variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
+static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
                   variax_set_active);
 static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
 
 #ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
 #endif
 
 /*
index d746715d3d894cbc10e02aa0e2c117442b30ddbf..d83bec876d2e3a1daf4e71dd4969df36e352ee78 100644 (file)
@@ -355,7 +355,6 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type)
 static void quickstart_exit(void)
 {
        input_unregister_device(quickstart_input);
-       input_free_device(quickstart_input);
 
        device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
        device_remove_file(&pf_device->dev, &dev_attr_buttons);
@@ -375,6 +374,7 @@ static int __init quickstart_init_input(void)
 {
        struct quickstart_btn **ptr = &quickstart_data.btn_lst;
        int count;
+       int ret;
 
        quickstart_input = input_allocate_device();
 
@@ -391,7 +391,13 @@ static int __init quickstart_init_input(void)
                ptr = &((*ptr)->next);
        }
 
-       return input_register_device(quickstart_input);
+       ret = input_register_device(quickstart_input);
+       if (ret) {
+               input_free_device(quickstart_input);
+               return ret;
+       }
+
+       return 0;
 }
 
 static int __init quickstart_init(void)
index ddacfc6c486179274394b330153c901dfc7c63b7..cd15daae5412f52339508db53d7353653175ffe0 100644 (file)
@@ -182,6 +182,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x2001, 0x3C09)},   /* D-Link */
        {USB_DEVICE(0x2001, 0x3C0A)},   /* D-Link 3072 */
        {USB_DEVICE(0x2019, 0xED14)},   /* Planex Communications, Inc. */
+       {USB_DEVICE(0x0411, 0x015D)},   /* Buffalo Airstation WLI-UC-GN */
        {}                      /* Terminating entry */
 };
 
index 46000d72f4c419b51f1dd090e3f1fbac17f6c22a..3bdf9b31cc4e2f4565d85a2e530effd56c0154ee 100644 (file)
@@ -264,8 +264,12 @@ HwHSSIThreeWire(
 
                        udelay(10);
                }
-               if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
-                       panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
+               if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+                       printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
+                              " %#X RE|WE bits are not clear!!\n", u1bTmp);
+                       dump_stack();
+                       return 0;
+               }
 
                /* RTL8187S HSSI Read/Write Function */
                u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
@@ -298,13 +302,23 @@ HwHSSIThreeWire(
                                int idx;
                                int ByteCnt = nDataBufBitCnt / 8;
                                                                /* printk("%d\n",nDataBufBitCnt); */
-                               if ((nDataBufBitCnt % 8) != 0)
-                               panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
-                               nDataBufBitCnt);
+                               if ((nDataBufBitCnt % 8) != 0) {
+                                       printk(KERN_ERR "rtl8187se: "
+                                              "HwThreeWire(): nDataBufBitCnt(%d)"
+                                              " should be multiple of 8!!!\n",
+                                              nDataBufBitCnt);
+                                       dump_stack();
+                                       nDataBufBitCnt += 8;
+                                       nDataBufBitCnt &= ~7;
+                               }
 
-                              if (nDataBufBitCnt > 64)
-                               panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
-                               nDataBufBitCnt);
+                              if (nDataBufBitCnt > 64) {
+                                       printk(KERN_ERR "rtl8187se: HwThreeWire():"
+                                              " nDataBufBitCnt(%d) should <= 64!!!\n",
+                                              nDataBufBitCnt);
+                                       dump_stack();
+                                       nDataBufBitCnt = 64;
+                               }
 
                                for (idx = 0; idx < ByteCnt; idx++)
                                        write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
index d1674cd282dcd7deb370cca6b75c8f0f69b3ed73..831d81e0e429b81924a53f8cad76aebd02d8be4d 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kref.h>
-#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/usb.h>
index f6569dce30127c7c5b033f4a2e2b01e17c219938..0e9483bbabe17fb7cab00fc6e2c757a68190c814 100644 (file)
@@ -37,7 +37,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
 {
        u8 val8 = 0;
        u8 ret = _SUCCESS;
-       u8 PollingCnt = 20;
+       int PollingCnt = 20;
        struct registry_priv *pregistrypriv = &padapter->registrypriv;
 
        if (pregistrypriv->chip_version == RTL8712_FPGA) {
index eb44b60e1eb542d735cb0cbabbff1e55109008c9..ac2bf11e1119904e76a6dace0ec2fb63ed33db56 100644 (file)
@@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev,
        }
        return count;
 }
-static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO,
                   get_silent_state, set_silent_state);
 
 
index b7b60d5e866023d461a8661a2fa278330ff8a5de..a2db956edd54db0f81979bd038bcfc5d348a7232 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/console.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/wait.h>
 
index adb93f21c0d6c844b345d6c8fb9cec77d26c8efe..65b231178f0580d30a4233e17bf31eb73c7df6f7 100644 (file)
@@ -62,7 +62,6 @@ void speakup_remove_virtual_keyboard(void)
 {
        if (virt_keyboard != NULL) {
                input_unregister_device(virt_keyboard);
-               input_free_device(virt_keyboard);
                virt_keyboard = NULL;
        }
 }
index c7932da03c56df5d40182e24c039b28762fe8ba4..63a9d0adf32d1c12f04708c971162a480e3f8e33 100644 (file)
@@ -656,7 +656,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
        /* Here we force report 512 byte hardware sector size to Kernel */
        blk_queue_logical_block_size(dev->queue, 512);
 
-       blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
+       blk_queue_flush(dev->queue, REQ_FLUSH);
 
        dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
        if (IS_ERR(dev->thread)) {
index 92e8911418962d19796e6dadf7db52d43ea745b7..02f0fc504cf5ef13595ad67b7668c28a54534ce7 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_STRADIS
         tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)"
-        depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS
+        depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS && BKL
         help
           Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
           driver for PCI.  There is a product page at
index 664e6038090dbf447aa78eca713d904c145fd54b..b143258f094a34d7cacdced5b5b0c3c0289313ad 100644 (file)
@@ -545,7 +545,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
 
        /* Load tuner module */
        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-               NULL, "tuner", dev->tuner_addr, NULL);
+               "tuner", dev->tuner_addr, NULL);
 
        memset(&tun_setup, 0, sizeof(tun_setup));
        tun_setup.type = dev->tuner_type;
@@ -683,7 +683,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
 
        if (dev->caps.has_tda9874)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-                       NULL, "tvaudio", I2C_ADDR_TDA9874, NULL);
+                       "tvaudio", I2C_ADDR_TDA9874, NULL);
 
        /* register and initialize V4L2 */
        rc = tm6000_v4l2_register(dev);
index fed25105970a94d06ca185fa81603f79968d67f8..b7ac16005265ede845b8b5debfb03f601fe66992 100644 (file)
@@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = {
        __ATTR_RO(metrics_bytes_identical),
        __ATTR_RO(metrics_bytes_sent),
        __ATTR_RO(metrics_cpu_kcycles_used),
-       __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+       __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store),
 };
 
 /*
index 9195adf98e142dd34476dc229d4aa8f67ab236b6..d0d71f69bc8ccad684eae2712370679a1a1d752c 100644 (file)
@@ -2,6 +2,9 @@
 
 #ifndef SYS_DEF_H
 #define SYS_DEF_H
+
+#include <linux/delay.h>
+
 #define WB_LINUX
 #define WB_LINUX_WPA_PSK
 
index 6c574a994d11a23e2a0c0b4fc052769c8b0a9ccc..6b3cf00b0ff42aa83069bd1649b090c5e6e1b522 100644 (file)
@@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev,
        return sprintf(buf, "%llu\n", val);
 }
 
-static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
                disksize_show, disksize_store);
 static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
-static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store);
+static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
 static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
 static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
 static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
index eaa5d3efa79da4cb061b4fbaf9d6acb6f21afd5e..c556ed9db13d82a4bd7dcff1bb599dce6abd8341 100644 (file)
@@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq);
 #ifdef CONFIG_INPUT
 
 /* Simple translation table for the SysRq keys */
-static const unsigned char sysrq_xlate[KEY_MAX + 1] =
+static const unsigned char sysrq_xlate[KEY_CNT] =
         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
@@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
         "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
         "\r\000/";                                      /* 0x60 - 0x6f */
 
-static bool sysrq_down;
-static int sysrq_alt_use;
-static int sysrq_alt;
-static DEFINE_SPINLOCK(sysrq_event_lock);
+struct sysrq_state {
+       struct input_handle handle;
+       struct work_struct reinject_work;
+       unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
+       unsigned int alt;
+       unsigned int alt_use;
+       bool active;
+       bool need_reinject;
+};
+
+static void sysrq_reinject_alt_sysrq(struct work_struct *work)
+{
+       struct sysrq_state *sysrq =
+                       container_of(work, struct sysrq_state, reinject_work);
+       struct input_handle *handle = &sysrq->handle;
+       unsigned int alt_code = sysrq->alt_use;
+
+       if (sysrq->need_reinject) {
+               /* Simulate press and release of Alt + SysRq */
+               input_inject_event(handle, EV_KEY, alt_code, 1);
+               input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+               input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
+               input_inject_event(handle, EV_KEY, alt_code, 0);
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+       }
+}
 
-static bool sysrq_filter(struct input_handle *handle, unsigned int type,
-                        unsigned int code, int value)
+static bool sysrq_filter(struct input_handle *handle,
+                        unsigned int type, unsigned int code, int value)
 {
+       struct sysrq_state *sysrq = handle->private;
+       bool was_active = sysrq->active;
        bool suppress;
 
-       /* We are called with interrupts disabled, just take the lock */
-       spin_lock(&sysrq_event_lock);
+       switch (type) {
 
-       if (type != EV_KEY)
-               goto out;
+       case EV_SYN:
+               suppress = false;
+               break;
 
-       switch (code) {
+       case EV_KEY:
+               switch (code) {
 
-       case KEY_LEFTALT:
-       case KEY_RIGHTALT:
-               if (value)
-                       sysrq_alt = code;
-               else {
-                       if (sysrq_down && code == sysrq_alt_use)
-                               sysrq_down = false;
+               case KEY_LEFTALT:
+               case KEY_RIGHTALT:
+                       if (!value) {
+                               /* One of ALTs is being released */
+                               if (sysrq->active && code == sysrq->alt_use)
+                                       sysrq->active = false;
 
-                       sysrq_alt = 0;
+                               sysrq->alt = KEY_RESERVED;
+
+                       } else if (value != 2) {
+                               sysrq->alt = code;
+                               sysrq->need_reinject = false;
+                       }
+                       break;
+
+               case KEY_SYSRQ:
+                       if (value == 1 && sysrq->alt != KEY_RESERVED) {
+                               sysrq->active = true;
+                               sysrq->alt_use = sysrq->alt;
+                               /*
+                                * If nothing else will be pressed we'll need
+                                * to * re-inject Alt-SysRq keysroke.
+                                */
+                               sysrq->need_reinject = true;
+                       }
+
+                       /*
+                        * Pretend that sysrq was never pressed at all. This
+                        * is needed to properly handle KGDB which will try
+                        * to release all keys after exiting debugger. If we
+                        * do not clear key bit it KGDB will end up sending
+                        * release events for Alt and SysRq, potentially
+                        * triggering print screen function.
+                        */
+                       if (sysrq->active)
+                               clear_bit(KEY_SYSRQ, handle->dev->key);
+
+                       break;
+
+               default:
+                       if (sysrq->active && value && value != 2) {
+                               sysrq->need_reinject = false;
+                               __handle_sysrq(sysrq_xlate[code], true);
+                       }
+                       break;
                }
-               break;
 
-       case KEY_SYSRQ:
-               if (value == 1 && sysrq_alt) {
-                       sysrq_down = true;
-                       sysrq_alt_use = sysrq_alt;
+               suppress = sysrq->active;
+
+               if (!sysrq->active) {
+                       /*
+                        * If we are not suppressing key presses keep track of
+                        * keyboard state so we can release keys that have been
+                        * pressed before entering SysRq mode.
+                        */
+                       if (value)
+                               set_bit(code, sysrq->key_down);
+                       else
+                               clear_bit(code, sysrq->key_down);
+
+                       if (was_active)
+                               schedule_work(&sysrq->reinject_work);
+
+               } else if (value == 0 &&
+                          test_and_clear_bit(code, sysrq->key_down)) {
+                       /*
+                        * Pass on release events for keys that was pressed before
+                        * entering SysRq mode.
+                        */
+                       suppress = false;
                }
                break;
 
        default:
-               if (sysrq_down && value && value != 2)
-                       __handle_sysrq(sysrq_xlate[code], true);
+               suppress = sysrq->active;
                break;
        }
 
-out:
-       suppress = sysrq_down;
-       spin_unlock(&sysrq_event_lock);
-
        return suppress;
 }
 
@@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler,
                         struct input_dev *dev,
                         const struct input_device_id *id)
 {
-       struct input_handle *handle;
+       struct sysrq_state *sysrq;
        int error;
 
-       sysrq_down = false;
-       sysrq_alt = 0;
-
-       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
-       if (!handle)
+       sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL);
+       if (!sysrq)
                return -ENOMEM;
 
-       handle->dev = dev;
-       handle->handler = handler;
-       handle->name = "sysrq";
+       INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq);
+
+       sysrq->handle.dev = dev;
+       sysrq->handle.handler = handler;
+       sysrq->handle.name = "sysrq";
+       sysrq->handle.private = sysrq;
 
-       error = input_register_handle(handle);
+       error = input_register_handle(&sysrq->handle);
        if (error) {
                pr_err("Failed to register input sysrq handler, error %d\n",
                        error);
                goto err_free;
        }
 
-       error = input_open_device(handle);
+       error = input_open_device(&sysrq->handle);
        if (error) {
                pr_err("Failed to open input device, error %d\n", error);
                goto err_unregister;
@@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler,
        return 0;
 
  err_unregister:
-       input_unregister_handle(handle);
+       input_unregister_handle(&sysrq->handle);
  err_free:
-       kfree(handle);
+       kfree(sysrq);
        return error;
 }
 
 static void sysrq_disconnect(struct input_handle *handle)
 {
+       struct sysrq_state *sysrq = handle->private;
+
        input_close_device(handle);
+       cancel_work_sync(&sysrq->reinject_work);
        input_unregister_handle(handle);
-       kfree(handle);
+       kfree(sysrq);
 }
 
 /*
index c05c5af5aa044029561e38de9683e12a26c0c0c4..35480dd57a307e72b2893d484a86783659c6a45d 100644 (file)
@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
 
        tty_lock();
 
+       /* some functions below drop BTM, so we need this bit */
+       set_bit(TTY_HUPPING, &tty->flags);
+
        /* inuse_filps is protected by the single tty lock,
           this really needs to change if we want to flush the
           workqueue with the lock held */
@@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
        }
        spin_unlock(&tty_files_lock);
 
+       /*
+        * it drops BTM and thus races with reopen
+        * we protect the race by TTY_HUPPING
+        */
        tty_ldisc_hangup(tty);
 
        read_lock(&tasklist_lock);
@@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
        tty->session = NULL;
        tty->pgrp = NULL;
        tty->ctrl_status = 0;
-       set_bit(TTY_HUPPED, &tty->flags);
        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 
        /* Account for the p->signal references we killed */
@@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
         * can't yet guarantee all that.
         */
        set_bit(TTY_HUPPED, &tty->flags);
+       clear_bit(TTY_HUPPING, &tty->flags);
        tty_ldisc_enable(tty);
 
        tty_unlock();
@@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
 {
        struct tty_driver *driver = tty->driver;
 
-       if (test_bit(TTY_CLOSING, &tty->flags))
+       if (test_bit(TTY_CLOSING, &tty->flags) ||
+                       test_bit(TTY_HUPPING, &tty->flags) ||
+                       test_bit(TTY_LDISC_CHANGING, &tty->flags))
                return -EIO;
 
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
index d8e96b005023ad21ff22d143203ab0d59fb09611..4214d58276f709a8743c03f431cef5b6360c2b46 100644 (file)
@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
                 /* BTM here locks versus a hangup event */
                WARN_ON(!tty_locked());
                ret = ld->ops->open(tty);
+               if (ret)
+                       clear_bit(TTY_LDISC_OPEN, &tty->flags);
                return ret;
        }
        return 0;
index a858d2b87b942e13840b005e54079ab0d296354b..51fe1795d5a8197678a5a00763f62e8a9fe59183 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
  * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
  * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
  *
  * Userspace IO
index a8ea2f19a0ccfb3a62b1649c28b54e810703d624..a84a451159edb2677ea0cad2ef2e7dd24211833f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * UIO Hilscher CIF card driver
  *
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
  * Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
  *
  * Licensed under GPL version 2 only.
index 5a18e9f7b8362787dbf60c0dc09fe48c23d627be..5ffdb483b0157a0c3998ae5cb8c1c0a316bb627a 100644 (file)
@@ -2,7 +2,7 @@
  * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
  * See http://www.hilscher.com for details.
  *
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
  * (C) 2008 Manuel Traut <manut@linutronix.de>
  *
  * Licensed under GPL version 2 only.
index ea071a5b6eee6aa929827851966dec80dfe070a0..44447f54942f6d6e1c7c7e2a777b4c882f6b546d 100644 (file)
@@ -2301,7 +2301,7 @@ out:
        return ret;
 }
 
-static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot);
 
 static ssize_t read_human_status(struct device *dev,
                        struct device_attribute *attr, char *buf)
@@ -2364,8 +2364,7 @@ out:
        return ret;
 }
 
-static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO,
-                               read_human_status, NULL);
+static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL);
 
 static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
                char *buf)
@@ -2397,7 +2396,7 @@ out:
        return ret;
 }
 
-static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL);
 
 #define UEA_ATTR(name, reset)                                  \
                                                                \
index ddb4dc980923e443e9cc2f3e0da30855ca59ff5b..a3d2e2399655b84a348561e8aa27521212f21831 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/gfp.h>
 #include <linux/poll.h>
 #include <linux/usb.h>
-#include <linux/smp_lock.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/usb/hcd.h>
 #include <linux/mutex.h>
index 045bb4b823e175fa2d16e228071e138a2c8a44e8..a7131ad630f9ad54535205017352ee10175df384 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/signal.h>
 #include <linux/poll.h>
 #include <linux/module.h>
index 9fe34fb78ef11c4d0dd88065502c6e92cd4398f3..cf6a5423de0997b424fe06c051acd1e7d305519f 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/usb.h>
 
 #include "usb.h"
index 61800f77dac80f0064cd7184f858241a35e2fc8c..ced846ac4141e6f4540e0012f73afb9931b5de63 100644 (file)
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
         */
 
        if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+               if (hcd->self.uses_pio_for_control)
+                       return ret;
                if (hcd->self.uses_dma) {
                        urb->setup_dma = dma_map_single(
                                        hcd->self.controller,
index 9819a4cc3b264d48111a08a8d51e242b0b1329d8..b690aa35df9a35117394c4177213e3f5ad286162 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/parser.h>
 #include <linux/notifier.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/usb/hcd.h>
 #include <asm/byteorder.h>
 #include "usb.h"
index b5e20e873cbad09bbebb7134929cf97880532bea..717ff653fa2330a9e5b78774b1a084f80186faf0 100644 (file)
@@ -2017,7 +2017,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
                        }
                } else {
                        /* gpio_request fail so use -EINVAL for gpio_is_valid */
-                       ubc->vbus_pin = -EINVAL;
+                       udc->vbus_pin = -EINVAL;
                }
        }
 
index 4a830df4fc31a1a58692f6b1b5adc29a7a9895c4..484c5ba5450ebfc254613ca04cd9c8ac9227aaf6 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/blkdev.h>
 #include <linux/pagemap.h>
 #include <asm/unaligned.h>
-#include <linux/smp_lock.h>
 
 #include <linux/usb/composite.h>
 #include <linux/usb/functionfs.h>
index 4f891eddd06041886b664d54f7488d9b00fcf781..598e7e2ab80c666f1395f1db6c30aaa44f34d646 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/cdev.h>
 #include <linux/mutex.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/uaccess.h>
 #include <linux/wait.h>
 #include <linux/usb/g_hid.h>
index 86afdc73322f21787bf0d1e003acbe563f8f316e..6e2599661b5bdcad9323185bd992dbdb7df45b21 100644 (file)
@@ -1067,7 +1067,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
                                                    &debug_registers_fops))
                goto file_error;
 
-       if (!debugfs_create_file("lpm", S_IRUGO|S_IWUGO, ehci->debug_dir, bus,
+       if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus,
                                                    &debug_lpm_fops))
                goto file_error;
 
index 502a7e6fef42a5a5c9ddbfa0ca26b4b971b043e1..e9062806d4a24898286240f139a2f28dadd8522c 100644 (file)
@@ -1063,10 +1063,11 @@ rescan:
                                tmp && tmp != qh;
                                tmp = tmp->qh_next.qh)
                        continue;
-               /* periodic qh self-unlinks on empty */
-               if (!tmp)
-                       goto nogood;
-               unlink_async (ehci, qh);
+               /* periodic qh self-unlinks on empty, and a COMPLETING qh
+                * may already be unlinked.
+                */
+               if (tmp)
+                       unlink_async(ehci, qh);
                /* FALL THROUGH */
        case QH_STATE_UNLINK:           /* wait for hw to finish? */
        case QH_STATE_UNLINK_WAIT:
@@ -1083,7 +1084,6 @@ idle_timeout:
                }
                /* else FALL THROUGH */
        default:
-nogood:
                /* caller was supposed to have unlinked any requests;
                 * that's not our job.  just leak this memory.
                 */
index d36e4e75e08d4e476249a71259d8d760d5158a7b..12f70c302b0b73089451e8e93dbeb66f3c068723 100644 (file)
@@ -141,6 +141,10 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci)
                qh_put (ehci->async);
        ehci->async = NULL;
 
+       if (ehci->dummy)
+               qh_put(ehci->dummy);
+       ehci->dummy = NULL;
+
        /* DMA consistent memory and pools */
        if (ehci->qtd_pool)
                dma_pool_destroy (ehci->qtd_pool);
@@ -227,8 +231,26 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
        if (ehci->periodic == NULL) {
                goto fail;
        }
-       for (i = 0; i < ehci->periodic_size; i++)
-               ehci->periodic [i] = EHCI_LIST_END(ehci);
+
+       if (ehci->use_dummy_qh) {
+               struct ehci_qh_hw       *hw;
+               ehci->dummy = ehci_qh_alloc(ehci, flags);
+               if (!ehci->dummy)
+                       goto fail;
+
+               hw = ehci->dummy->hw;
+               hw->hw_next = EHCI_LIST_END(ehci);
+               hw->hw_qtd_next = EHCI_LIST_END(ehci);
+               hw->hw_alt_next = EHCI_LIST_END(ehci);
+               hw->hw_token &= ~QTD_STS_ACTIVE;
+               ehci->dummy->hw = hw;
+
+               for (i = 0; i < ehci->periodic_size; i++)
+                       ehci->periodic[i] = ehci->dummy->qh_dma;
+       } else {
+               for (i = 0; i < ehci->periodic_size; i++)
+                       ehci->periodic[i] = EHCI_LIST_END(ehci);
+       }
 
        /* software shadow of hardware table */
        ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);
index a1e8d273103f77b2d237a5f68438b289b51bb92a..655f3c9f88bfbb6740e0ac5cc377b45c1af8adae 100644 (file)
@@ -103,6 +103,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
        if (retval)
                return retval;
 
+       if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) ||
+           (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) {
+               /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may
+                * read/write memory space which does not belong to it when
+                * there is NULL pointer with T-bit set to 1 in the frame list
+                * table. To avoid the issue, the frame list link pointer
+                * should always contain a valid pointer to a inactive qh.
+                */
+               ehci->use_dummy_qh = 1;
+               ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI "
+                               "dummy qh workaround\n");
+       }
+
        /* data structure init */
        retval = ehci_init(hcd);
        if (retval)
@@ -148,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                        if (pdev->revision < 0xa4)
                                ehci->no_selective_suspend = 1;
                        break;
+
+               /* MCP89 chips on the MacBookAir3,1 give EPROTO when
+                * fetching device descriptors unless LPM is disabled.
+                * There are also intermittent problems enumerating
+                * devices with PPCD enabled.
+                */
+               case 0x0d9d:
+                       ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
+                       ehci->has_lpm = 0;
+                       ehci->has_ppcd = 0;
+                       ehci->command &= ~CMD_PPCEE;
+                       break;
                }
                break;
        case PCI_VENDOR_ID_VIA:
index a92526d6e5aeb4a306442df77d27b702e00c0d0c..d9f78eb265721bb065f23482e482b50d2bc8430a 100644 (file)
@@ -98,7 +98,14 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
         */
        *prev_p = *periodic_next_shadow(ehci, &here,
                        Q_NEXT_TYPE(ehci, *hw_p));
-       *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p));
+
+       if (!ehci->use_dummy_qh ||
+           *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p))
+                       != EHCI_LIST_END(ehci))
+               *hw_p = *shadow_next_periodic(ehci, &here,
+                               Q_NEXT_TYPE(ehci, *hw_p));
+       else
+               *hw_p = ehci->dummy->qh_dma;
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
@@ -2335,7 +2342,11 @@ restart:
                                 * pointer for much longer, if at all.
                                 */
                                *q_p = q.itd->itd_next;
-                               *hw_p = q.itd->hw_next;
+                               if (!ehci->use_dummy_qh ||
+                                   q.itd->hw_next != EHCI_LIST_END(ehci))
+                                       *hw_p = q.itd->hw_next;
+                               else
+                                       *hw_p = ehci->dummy->qh_dma;
                                type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
                                wmb();
                                modified = itd_complete (ehci, q.itd);
@@ -2368,7 +2379,11 @@ restart:
                                 * URB completion.
                                 */
                                *q_p = q.sitd->sitd_next;
-                               *hw_p = q.sitd->hw_next;
+                               if (!ehci->use_dummy_qh ||
+                                   q.sitd->hw_next != EHCI_LIST_END(ehci))
+                                       *hw_p = q.sitd->hw_next;
+                               else
+                                       *hw_p = ehci->dummy->qh_dma;
                                type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
                                wmb();
                                modified = sitd_complete (ehci, q.sitd);
index bde823f704e9a6d496cf735f08658fa7f2f6397b..ba8eab366b823fd7153879a801ce7a60c915af08 100644 (file)
@@ -73,6 +73,7 @@ struct ehci_hcd {                     /* one per controller */
 
        /* async schedule support */
        struct ehci_qh          *async;
+       struct ehci_qh          *dummy;         /* For AMD quirk use */
        struct ehci_qh          *reclaim;
        unsigned                scanning : 1;
 
@@ -131,6 +132,7 @@ struct ehci_hcd {                   /* one per controller */
        unsigned                need_io_watchdog:1;
        unsigned                broken_periodic:1;
        unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
+       unsigned                use_dummy_qh:1; /* AMD Frame List table quirk*/
 
        /* required for usb32 quirk */
        #define OHCI_CTRL_HCFS          (3 << 6)
index 8196fa11fec43678cb96b4c3241fd63b7fc1b35f..43a39eb56cc6ea77af2cc7ae930392f1cd70325a 100644 (file)
@@ -70,7 +70,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
@@ -2684,7 +2683,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int __init isp1362_probe(struct platform_device *pdev)
+static int __devinit isp1362_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
        struct isp1362_hcd *isp1362_hcd;
index 6e7fb5f38db6379f0318f223f31054798e4640f0..ee60cd3ea64201dc4e86d534651c0699d7e8f1ef 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
-#include <linux/smp_lock.h>
 #include <asm/io.h>
 
 #include "uhci-hcd.h"
index fef5a1f9d483ac99a49f9c904ea2c7f692442ace..5d963e350494ee44983e6ac72428899e32db9a04 100644 (file)
@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
 static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
                u32 __iomem *addr, u32 port_status)
 {
+       /* Don't allow the USB core to disable SuperSpeed ports. */
+       if (xhci->port_array[wIndex] == 0x03) {
+               xhci_dbg(xhci, "Ignoring request to disable "
+                               "SuperSpeed port.\n");
+               return;
+       }
+
        /* Write 1 to disable the port */
        xhci_writel(xhci, port_status | PORT_PE, addr);
        port_status = xhci_readl(xhci, addr);
index 202770676da30c409652dc1aca0b4d33a857d366..0fae58ef8afe7c43b145074fd8cbb1fe7b30e248 100644 (file)
@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
        if (udev->speed == USB_SPEED_SUPER)
                return ep->ss_ep_comp.wBytesPerInterval;
 
-       max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+       max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
        max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
        /* A 0 in max burst means 1 transfer per ESIT */
        return max_packet * (max_burst + 1);
@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                /* Fall through */
        case USB_SPEED_FULL:
        case USB_SPEED_LOW:
-               max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+               max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
                ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
                break;
        default:
@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->dcbaa = NULL;
 
        scratchpad_free(xhci);
+
+       xhci->num_usb2_ports = 0;
+       xhci->num_usb3_ports = 0;
+       kfree(xhci->usb2_ports);
+       kfree(xhci->usb3_ports);
+       kfree(xhci->port_array);
+
        xhci->page_size = 0;
        xhci->page_shift = 0;
        xhci->bus_suspended = 0;
@@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
                        &xhci->ir_set->erst_dequeue);
 }
 
+static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+               u32 __iomem *addr, u8 major_revision)
+{
+       u32 temp, port_offset, port_count;
+       int i;
+
+       if (major_revision > 0x03) {
+               xhci_warn(xhci, "Ignoring unknown port speed, "
+                               "Ext Cap %p, revision = 0x%x\n",
+                               addr, major_revision);
+               /* Ignoring port protocol we can't understand. FIXME */
+               return;
+       }
+
+       /* Port offset and count in the third dword, see section 7.2 */
+       temp = xhci_readl(xhci, addr + 2);
+       port_offset = XHCI_EXT_PORT_OFF(temp);
+       port_count = XHCI_EXT_PORT_COUNT(temp);
+       xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
+                       "count = %u, revision = 0x%x\n",
+                       addr, port_offset, port_count, major_revision);
+       /* Port count includes the current port offset */
+       if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
+               /* WTF? "Valid values are â€˜1’ to MaxPorts" */
+               return;
+       port_offset--;
+       for (i = port_offset; i < (port_offset + port_count); i++) {
+               /* Duplicate entry.  Ignore the port if the revisions differ. */
+               if (xhci->port_array[i] != 0) {
+                       xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+                                       " port %u\n", addr, i);
+                       xhci_warn(xhci, "Port was marked as USB %u, "
+                                       "duplicated as USB %u\n",
+                                       xhci->port_array[i], major_revision);
+                       /* Only adjust the roothub port counts if we haven't
+                        * found a similar duplicate.
+                        */
+                       if (xhci->port_array[i] != major_revision &&
+                               xhci->port_array[i] != (u8) -1) {
+                               if (xhci->port_array[i] == 0x03)
+                                       xhci->num_usb3_ports--;
+                               else
+                                       xhci->num_usb2_ports--;
+                               xhci->port_array[i] = (u8) -1;
+                       }
+                       /* FIXME: Should we disable the port? */
+               }
+               xhci->port_array[i] = major_revision;
+               if (major_revision == 0x03)
+                       xhci->num_usb3_ports++;
+               else
+                       xhci->num_usb2_ports++;
+       }
+       /* FIXME: Should we disable ports not in the Extended Capabilities? */
+}
+
+/*
+ * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
+ * specify what speeds each port is supposed to be.  We can't count on the port
+ * speed bits in the PORTSC register being correct until a device is connected,
+ * but we need to set up the two fake roothubs with the correct number of USB
+ * 3.0 and USB 2.0 ports at host controller initialization time.
+ */
+static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
+{
+       u32 __iomem *addr;
+       u32 offset;
+       unsigned int num_ports;
+       int i, port_index;
+
+       addr = &xhci->cap_regs->hcc_params;
+       offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
+       if (offset == 0) {
+               xhci_err(xhci, "No Extended Capability registers, "
+                               "unable to set up roothub.\n");
+               return -ENODEV;
+       }
+
+       num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+       xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
+       if (!xhci->port_array)
+               return -ENOMEM;
+
+       /*
+        * For whatever reason, the first capability offset is from the
+        * capability register base, not from the HCCPARAMS register.
+        * See section 5.3.6 for offset calculation.
+        */
+       addr = &xhci->cap_regs->hc_capbase + offset;
+       while (1) {
+               u32 cap_id;
+
+               cap_id = xhci_readl(xhci, addr);
+               if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
+                       xhci_add_in_port(xhci, num_ports, addr,
+                                       (u8) XHCI_EXT_PORT_MAJOR(cap_id));
+               offset = XHCI_EXT_CAPS_NEXT(cap_id);
+               if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
+                               == num_ports)
+                       break;
+               /*
+                * Once you're into the Extended Capabilities, the offset is
+                * always relative to the register holding the offset.
+                */
+               addr += offset;
+       }
+
+       if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
+               xhci_warn(xhci, "No ports on the roothubs?\n");
+               return -ENODEV;
+       }
+       xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
+                       xhci->num_usb2_ports, xhci->num_usb3_ports);
+       /*
+        * Note we could have all USB 3.0 ports, or all USB 2.0 ports.
+        * Not sure how the USB core will handle a hub with no ports...
+        */
+       if (xhci->num_usb2_ports) {
+               xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
+                               xhci->num_usb2_ports, flags);
+               if (!xhci->usb2_ports)
+                       return -ENOMEM;
+
+               port_index = 0;
+               for (i = 0; i < num_ports; i++)
+                       if (xhci->port_array[i] != 0x03) {
+                               xhci->usb2_ports[port_index] =
+                                       &xhci->op_regs->port_status_base +
+                                       NUM_PORT_REGS*i;
+                               xhci_dbg(xhci, "USB 2.0 port at index %u, "
+                                               "addr = %p\n", i,
+                                               xhci->usb2_ports[port_index]);
+                               port_index++;
+                       }
+       }
+       if (xhci->num_usb3_ports) {
+               xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
+                               xhci->num_usb3_ports, flags);
+               if (!xhci->usb3_ports)
+                       return -ENOMEM;
+
+               port_index = 0;
+               for (i = 0; i < num_ports; i++)
+                       if (xhci->port_array[i] == 0x03) {
+                               xhci->usb3_ports[port_index] =
+                                       &xhci->op_regs->port_status_base +
+                                       NUM_PORT_REGS*i;
+                               xhci_dbg(xhci, "USB 3.0 port at index %u, "
+                                               "addr = %p\n", i,
+                                               xhci->usb3_ports[port_index]);
+                               port_index++;
+                       }
+       }
+       return 0;
+}
 
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
@@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
        if (scratchpad_alloc(xhci, flags))
                goto fail;
+       if (xhci_setup_port_arrays(xhci, flags))
+               goto fail;
 
        return 0;
 
index 9f3115e729b173605cb36c278509b7befb68f825..df558f6f84e30eff6d6df0fc61c3bd67fb183387 100644 (file)
@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
 
        if (!(status & STS_EINT)) {
                spin_unlock(&xhci->lock);
-               xhci_warn(xhci, "Spurious interrupt.\n");
                return IRQ_NONE;
        }
        xhci_dbg(xhci, "op reg status = %08x\n", status);
index 5d7d4e951ea4bc951c4783729472467a383ec1c2..45e4a3108cc31285fcb41c7a83972a621a72a68b 100644 (file)
@@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
        xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
 }
 
+static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
+{
+       u64     val_64;
+
+       /* step 2: initialize command ring buffer */
+       val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
+               (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
+                                     xhci->cmd_ring->dequeue) &
+                (u64) ~CMD_RING_RSVD_BITS) |
+               xhci->cmd_ring->cycle_state;
+       xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
+                       (long unsigned long) val_64);
+       xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
+}
+
+/*
+ * The whole command ring must be cleared to zero when we suspend the host.
+ *
+ * The host doesn't save the command ring pointer in the suspend well, so we
+ * need to re-program it on resume.  Unfortunately, the pointer must be 64-byte
+ * aligned, because of the reserved bits in the command ring dequeue pointer
+ * register.  Therefore, we can't just set the dequeue pointer back in the
+ * middle of the ring (TRBs are 16-byte aligned).
+ */
+static void xhci_clear_command_ring(struct xhci_hcd *xhci)
+{
+       struct xhci_ring *ring;
+       struct xhci_segment *seg;
+
+       ring = xhci->cmd_ring;
+       seg = ring->deq_seg;
+       do {
+               memset(seg->trbs, 0, SEGMENT_SIZE);
+               seg = seg->next;
+       } while (seg != ring->deq_seg);
+
+       /* Reset the software enqueue and dequeue pointers */
+       ring->deq_seg = ring->first_seg;
+       ring->dequeue = ring->first_seg->trbs;
+       ring->enq_seg = ring->deq_seg;
+       ring->enqueue = ring->dequeue;
+
+       /*
+        * Ring is now zeroed, so the HW should look for change of ownership
+        * when the cycle bit is set to 1.
+        */
+       ring->cycle_state = 1;
+
+       /*
+        * Reset the hardware dequeue pointer.
+        * Yes, this will need to be re-written after resume, but we're paranoid
+        * and want to make sure the hardware doesn't access bogus memory
+        * because, say, the BIOS or an SMI started the host without changing
+        * the command ring pointers.
+        */
+       xhci_set_cmd_ring_deq(xhci);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
                spin_unlock_irq(&xhci->lock);
                return -ETIMEDOUT;
        }
+       xhci_clear_command_ring(xhci);
 
        /* step 3: save registers */
        xhci_save_registers(xhci);
@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        u32                     command, temp = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
-       u64     val_64;
        int     old_state, retval;
 
        old_state = hcd->state;
@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                /* step 1: restore register */
                xhci_restore_registers(xhci);
                /* step 2: initialize command ring buffer */
-               val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
-               val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
-                        (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
-                                              xhci->cmd_ring->dequeue) &
-                        (u64) ~CMD_RING_RSVD_BITS) |
-                        xhci->cmd_ring->cycle_state;
-               xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
-                               (long unsigned long) val_64);
-               xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
+               xhci_set_cmd_ring_deq(xhci);
                /* step 3: restore state and start state*/
                /* step 3: set CRS flag */
                command = xhci_readl(xhci, &xhci->op_regs->command);
@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                return retval;
        }
 
+       spin_unlock_irq(&xhci->lock);
        /* Re-setup MSI-X */
        if (hcd->irq)
                free_irq(hcd->irq, hcd);
@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                hcd->irq = pdev->irq;
        }
 
+       spin_lock_irq(&xhci->lock);
        /* step 4: set Run/Stop bit */
        command = xhci_readl(xhci, &xhci->op_regs->command);
        command |= CMD_RUN;
@@ -1496,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
                cmd_completion = command->completion;
                cmd_status = &command->status;
                command->command_trb = xhci->cmd_ring->enqueue;
+
+               /* Enqueue pointer can be left pointing to the link TRB,
+                * we must handle that
+                */
+               if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
+                               == TRB_TYPE(TRB_LINK))
+                       command->command_trb =
+                               xhci->cmd_ring->enq_seg->next->trbs;
+
                list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
        } else {
                in_ctx = virt_dev->in_ctx;
@@ -2219,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
        /* Attempt to submit the Reset Device command to the command ring */
        spin_lock_irqsave(&xhci->lock, flags);
        reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+
+       /* Enqueue pointer can be left pointing to the link TRB,
+        * we must handle that
+        */
+       if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
+                       == TRB_TYPE(TRB_LINK))
+               reset_device_cmd->command_trb =
+                       xhci->cmd_ring->enq_seg->next->trbs;
+
        list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
        ret = xhci_queue_reset_device(xhci, slot_id);
        if (ret) {
index 93d3bf4d213c76dbacc8d964f72bda2a4c2c32c5..170c367112d2e8046f39ec596703c126f2050f84 100644 (file)
@@ -453,6 +453,24 @@ struct xhci_doorbell_array {
 #define STREAM_ID_TO_DB(p)     (((p) & 0xffff) << 16)
 
 
+/**
+ * struct xhci_protocol_caps
+ * @revision:          major revision, minor revision, capability ID,
+ *                     and next capability pointer.
+ * @name_string:       Four ASCII characters to say which spec this xHC
+ *                     follows, typically "USB ".
+ * @port_info:         Port offset, count, and protocol-defined information.
+ */
+struct xhci_protocol_caps {
+       u32     revision;
+       u32     name_string;
+       u32     port_info;
+};
+
+#define        XHCI_EXT_PORT_MAJOR(x)  (((x) >> 24) & 0xff)
+#define        XHCI_EXT_PORT_OFF(x)    ((x) & 0xff)
+#define        XHCI_EXT_PORT_COUNT(x)  (((x) >> 8) & 0xff)
+
 /**
  * struct xhci_container_ctx
  * @type: Type of context.  Used to calculated offsets to contained contexts.
@@ -621,6 +639,11 @@ struct xhci_ep_ctx {
 #define MAX_PACKET_MASK                (0xffff << 16)
 #define MAX_PACKET_DECODED(p)  (((p) >> 16) & 0xffff)
 
+/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
+ * USB2.0 spec 9.6.6.
+ */
+#define GET_MAX_PACKET(p)      ((p) & 0x7ff)
+
 /* tx_info bitmasks */
 #define AVG_TRB_LENGTH_FOR_EP(p)       ((p) & 0xffff)
 #define MAX_ESIT_PAYLOAD_FOR_EP(p)     (((p) & 0xffff) << 16)
@@ -1235,6 +1258,14 @@ struct xhci_hcd {
        u32                     suspended_ports[8];     /* which ports are
                                                           suspended */
        unsigned long           resume_done[MAX_HC_PORTS];
+       /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
+       u8                      *port_array;
+       /* Array of pointers to USB 3.0 PORTSC registers */
+       u32 __iomem             **usb3_ports;
+       unsigned int            num_usb3_ports;
+       /* Array of pointers to USB 2.0 PORTSC registers */
+       u32 __iomem             **usb2_ports;
+       unsigned int            num_usb2_ports;
 };
 
 /* For testing purposes */
index 5a47805d9580740c7ef33f75bb0fafd0a2c73dad..c90c89dc00035c1e3c2da06fb177f11c82ed28dd 100644 (file)
@@ -364,7 +364,7 @@ static int mts_scsi_host_reset(struct scsi_cmnd *srb)
 }
 
 static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback);
+mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb);
 
 static void mts_transfer_cleanup( struct urb *transfer );
 static void mts_do_sg(struct urb * transfer);
@@ -573,7 +573,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 
 
 static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
+mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 {
        struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
        int err = 0;
@@ -626,6 +626,8 @@ out:
        return err;
 }
 
+static DEF_SCSI_QCMD(mts_scsi_queuecommand)
+
 static struct scsi_host_template mts_scsi_host_template = {
        .module                 = THIS_MODULE,
        .name                   = "microtekX6",
index 2f43c57743c9c905b26e8e06dc517df6b5bb7c26..9251773ecef4ffae6102a29f356bad68cf7dd574 100644 (file)
@@ -196,11 +196,9 @@ static ssize_t get_port1_handler(struct device *dev,
        return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
 }
 
-static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
-                  get_port0_handler, set_port0_handler);
+static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler);
 
-static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
-                  get_port1_handler, set_port1_handler);
+static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler);
 
 
 static int cypress_probe(struct usb_interface *interface,
index d77aba46ae85675e58afb532078458b74b7b29a7..f63776a48e2a8717f37d5ebf68cb6b408a5d895a 100644 (file)
@@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
+static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed);
 
 static int tv_probe(struct usb_interface *interface,
                    const struct usb_device_id *id)
index 63da2c3c838fd0b6495d0429a870e3b1e035e9dd..c96f51de1696581faba425fb29db3a18f9ef1458 100644 (file)
@@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
        change_color(led);                                              \
        return count;                                                   \
 }                                                                      \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value);
 show_set(blue);
 show_set(red);
 show_set(green);
index de8ef945b536d07a277c56bff506798bd90620e3..417b8f207e8b126ac5b2ee33bab0dc5fdaa232b0 100644 (file)
@@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev,          \
                                                                \
        return count;                                           \
 }                                                              \
-static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name);
+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name);
 
 static ssize_t show_attr_text(struct device *dev,
        struct device_attribute *attr, char *buf)
@@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text);
+static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text);
 
 static ssize_t show_attr_decimals(struct device *dev,
        struct device_attribute *attr, char *buf)
@@ -272,8 +272,7 @@ static ssize_t set_attr_decimals(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO,
-       show_attr_decimals, set_attr_decimals);
+static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals);
 
 static ssize_t show_attr_textmode(struct device *dev,
        struct device_attribute *attr, char *buf)
@@ -319,8 +318,7 @@ static ssize_t set_attr_textmode(struct device *dev,
        return -EINVAL;
 }
 
-static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO,
-       show_attr_textmode, set_attr_textmode);
+static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode);
 
 
 MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered);
index 719c6180b31ff1b94815737c5d129dd3aac8a408..ac5bfd619e62ab4dad5d05772ece6fcc13744159 100644 (file)
@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = {
        .open =         yurex_open,
        .release =      yurex_release,
        .fasync =       yurex_fasync,
+       .llseek =       default_llseek,
 };
 
 
index 44cb37b5a4dc1f9b27075e3db5346b9ebe307b22..c436e1e2c3b6274f0fdcdb699ec1fd10a9b2273f 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/poll.h>
 #include <linux/compat.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 
index 8ec94f15a73820ce5a1b26b8ed5d86fa04b6bba4..e5ce42bd316e5c68d29a72ffdc2d805b6a575f37 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
index e6669fc3b8048c3dfdbbbf5ee1e1a2048561cfaf..99beebce85506128cf40d9556465900aebbd1ad4 100644 (file)
@@ -2116,12 +2116,15 @@ bad_config:
         * Otherwise, wait till the gadget driver hooks up.
         */
        if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
+
                MUSB_HST_MODE(musb);
                musb->xceiv->default_a = 1;
                musb->xceiv->state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
 
+               hcd->self.uses_pio_for_control = 1;
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
                        musb_readb(musb->mregs, MUSB_DEVCTL),
index 36cfd060dbe55bffb7707293f3c1182ed7cbff6e..9d6ade82b9f2906b632cacaadbebdf34294dab83 100644 (file)
 
 /* ----------------------------------------------------------------------- */
 
+/* Maps the buffer to dma  */
+
+static inline void map_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               request->request.dma = dma_map_single(
+                               musb->controller,
+                               request->request.buf,
+                               request->request.length,
+                               request->tx
+                                       ? DMA_TO_DEVICE
+                                       : DMA_FROM_DEVICE);
+               request->mapped = 1;
+       } else {
+               dma_sync_single_for_device(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->mapped = 0;
+       }
+}
+
+/* Unmap the buffer from dma and maps it back to cpu */
+static inline void unmap_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               DBG(20, "not unmapping a never mapped buffer\n");
+               return;
+       }
+       if (request->mapped) {
+               dma_unmap_single(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->request.dma = DMA_ADDR_INVALID;
+               request->mapped = 0;
+       } else {
+               dma_sync_single_for_cpu(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+
+       }
+}
+
 /*
  * Immediately complete a request.
  *
@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)
 
        ep->busy = 1;
        spin_unlock(&musb->lock);
-       if (is_dma_capable()) {
-               if (req->mapped) {
-                       dma_unmap_single(musb->controller,
-                                       req->request.dma,
-                                       req->request.length,
-                                       req->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       req->request.dma = DMA_ADDR_INVALID;
-                       req->mapped = 0;
-               } else if (req->request.dma != DMA_ADDR_INVALID)
-                       dma_sync_single_for_cpu(musb->controller,
-                                       req->request.dma,
-                                       req->request.length,
-                                       req->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-       }
+       if (is_dma_capable() && ep->dma)
+               unmap_dma_buffer(req, musb);
        if (request->status == 0)
                DBG(5, "%s done request %p,  %d/%d\n",
                                ep->end_point.name, request,
@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
 #endif
 
        if (!use_dma) {
+               /*
+                * Unmap the dma buffer back to cpu if dma channel
+                * programming fails
+                */
+               if (is_dma_capable() && musb_ep->dma)
+                       unmap_dma_buffer(req, musb);
+
                musb_write_fifo(musb_ep->hw_ep, fifo_count,
                                (u8 *) (request->buf + request->actual));
                request->actual += fifo_count;
@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                        return;
                        }
 #endif
+                       /*
+                        * Unmap the dma buffer back to cpu if dma channel
+                        * programming fails. This buffer is mapped if the
+                        * channel allocation is successful
+                        */
+                        if (is_dma_capable() && musb_ep->dma) {
+                               unmap_dma_buffer(req, musb);
+
+                               /*
+                                * Clear DMAENAB and AUTOCLEAR for the
+                                * PIO mode transfer
+                                */
+                               csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
+                               musb_writew(epio, MUSB_RXCSR, csr);
+                       }
 
                        musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
                                        (request->buf + request->actual));
@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                if (!request)
                        return;
        }
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
 exit:
+#endif
        /* Analyze request */
        rxstate(musb, to_musb_request(request));
 }
@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
        request->epnum = musb_ep->current_epnum;
        request->tx = musb_ep->is_in;
 
-       if (is_dma_capable() && musb_ep->dma) {
-               if (request->request.dma == DMA_ADDR_INVALID) {
-                       request->request.dma = dma_map_single(
-                                       musb->controller,
-                                       request->request.buf,
-                                       request->request.length,
-                                       request->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       request->mapped = 1;
-               } else {
-                       dma_sync_single_for_device(musb->controller,
-                                       request->request.dma,
-                                       request->request.length,
-                                       request->tx
-                                               ? DMA_TO_DEVICE
-                                               : DMA_FROM_DEVICE);
-                       request->mapped = 0;
-               }
-       } else
+       if (is_dma_capable() && musb_ep->dma)
+               map_dma_buffer(request, musb);
+       else
                request->mapped = 0;
 
        spin_lock_irqsave(&musb->lock, lockflags);
@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                spin_unlock_irqrestore(&musb->lock, flags);
 
                if (is_otg_enabled(musb)) {
+                       struct usb_hcd  *hcd = musb_to_hcd(musb);
+
                        DBG(3, "OTG startup...\n");
 
                        /* REVISIT:  funcall to other code, which also
@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                                musb->gadget_driver = NULL;
                                musb->g.dev.driver = NULL;
                                spin_unlock_irqrestore(&musb->lock, flags);
+                       } else {
+                               hcd->self.uses_pio_for_control = 1;
                        }
                }
        }
index bdc3ea66be692dd1155828d97971cb11970a77f5..9fea48264fa2049fe7eefd18cada2013a180a5e0 100644 (file)
@@ -1896,7 +1896,7 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr,
        }
        return count;
 }
-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
+static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req);
 
 static ssize_t
 get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1942,8 +1942,7 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr,
        }
        return count;
 }
-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
-       get_a_bus_drop, set_a_bus_drop);
+static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop);
 
 static ssize_t
 get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1988,7 +1987,7 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr,
        }
        return count;
 }
-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
+static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req);
 
 static ssize_t
 set_a_clr_err(struct device *dev, struct device_attribute *attr,
@@ -2012,7 +2011,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr,
        }
        return count;
 }
-static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
+static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err);
 
 static struct attribute *inputs_attrs[] = {
        &dev_attr_a_bus_req.attr,
index 76f8b3556672307452c991d6144d6395c7395c65..6a50965e23f29498b2055f4ecbf1912eb3628759 100644 (file)
@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+       { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
        { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+       { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
        { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
index 263f625511972137585c8cdcee3f1fe7a0a74ab9..1286f1e23d8c1505de15be5e1c223128d854055c 100644 (file)
 /* Lenz LI-USB Computer Interface. */
 #define FTDI_LENZ_LIUSB_PID    0xD780
 
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID       0xF070
+
 /*
  * Xsens Technologies BV products (http://www.xsens.com).
  */
  */
 #define RTSYSTEMS_VID                  0x2100  /* Vendor ID */
 #define RTSYSTEMS_SERIAL_VX7_PID       0x9e52  /* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID            0x9e54  /* CT29B Radio Cable */
 
 /*
  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
index e64da74bdcc5d112ff20cf46e0c074115ca3ee67..6954de50c0ffe5e22cc85ad909af0ceef1dde4fd 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
@@ -52,6 +51,7 @@ static struct usb_driver usb_serial_driver = {
        .suspend =      usb_serial_suspend,
        .resume =       usb_serial_resume,
        .no_dynamic_id =        1,
+       .supports_autosuspend = 1,
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -1344,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver)
                return -ENODEV;
 
        fixup_generic(driver);
+       if (driver->usb_driver)
+               driver->usb_driver->supports_autosuspend = 1;
 
        if (!driver->description)
                driver->description = driver->driver.name;
index a688b1e686eae326d26da45bf37fa378524e6624..689ee1fb702a4351a7fdb2a0e0a400a682eabd4f 100644 (file)
@@ -285,7 +285,7 @@ static int slave_configure(struct scsi_device *sdev)
 
 /* queue a command */
 /* This is always called with scsi_lock(host) held */
-static int queuecommand(struct scsi_cmnd *srb,
+static int queuecommand_lck(struct scsi_cmnd *srb,
                        void (*done)(struct scsi_cmnd *))
 {
        struct us_data *us = host_to_us(srb->device->host);
@@ -315,6 +315,8 @@ static int queuecommand(struct scsi_cmnd *srb,
        return 0;
 }
 
+static DEF_SCSI_QCMD(queuecommand)
+
 /***********************************************************************
  * Error handling functions
  ***********************************************************************/
index 57fc2f532cabe985b9b10fdd57c7042b6d0fd4be..ceba512f84d0eeeb2f3170a14df915528304dbe2 100644 (file)
@@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr,
        }
        return result;
 }
-static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL);
+static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL);
 
 int sierra_ms_init(struct us_data *us)
 {
index d1268191acbde5ead493c660558fce8a23e833a8..339fac3949df870bd838c08fe652386ddfdde172 100644 (file)
@@ -430,7 +430,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
        return 0;
 }
 
-static int uas_queuecommand(struct scsi_cmnd *cmnd,
+static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
                                        void (*done)(struct scsi_cmnd *))
 {
        struct scsi_device *sdev = cmnd->device;
@@ -488,6 +488,8 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
        return 0;
 }
 
+static DEF_SCSI_QCMD(uas_queuecommand)
+
 static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
 {
        struct scsi_device *sdev = cmnd->device;
index 4b4da5b86ff99337fc0d81afeb48363918df65c3..f442668a1e52e137b347419f9938d386f638b16b 100644 (file)
@@ -129,8 +129,9 @@ static void handle_tx(struct vhost_net *net)
        size_t hdr_size;
        struct socket *sock;
 
-       sock = rcu_dereference_check(vq->private_data,
-                                    lockdep_is_held(&vq->mutex));
+       /* TODO: check that we are running from vhost_worker?
+        * Not sure it's worth it, it's straight-forward enough. */
+       sock = rcu_dereference_check(vq->private_data, 1);
        if (!sock)
                return;
 
index e207810bba3cfe9e0042f02bc447ad5b01564ff0..08703299ef61184bf3e0cd212601f2817e9e8e63 100644 (file)
@@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state)
 {
        struct backlight_device *bd = to_backlight_device(dev);
 
-       if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-               mutex_lock(&bd->ops_lock);
+       mutex_lock(&bd->ops_lock);
+       if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
                bd->props.state |= BL_CORE_SUSPENDED;
                backlight_update_status(bd);
-               mutex_unlock(&bd->ops_lock);
        }
+       mutex_unlock(&bd->ops_lock);
 
        return 0;
 }
@@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev)
 {
        struct backlight_device *bd = to_backlight_device(dev);
 
-       if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-               mutex_lock(&bd->ops_lock);
+       mutex_lock(&bd->ops_lock);
+       if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
                bd->props.state &= ~BL_CORE_SUSPENDED;
                backlight_update_status(bd);
-               mutex_unlock(&bd->ops_lock);
        }
+       mutex_unlock(&bd->ops_lock);
 
        return 0;
 }
index 54e32c513610f8164839c2c167e3eccc09bbdb8b..915448ec75bf2fd33617eb73517876da74c68137 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/screen_info.h>
-#include <linux/smp_lock.h>
 #include <video/vga.h>
 #include <asm/io.h>
 
index cad7d45c8bac2b94a1e3f06b57a241d26ed4570c..c265aed09e04a2061ca224dd4354ffd178d9ccdc 100644 (file)
@@ -1029,10 +1029,6 @@ static int __init fb_probe(struct platform_device *device)
                goto err_release_pl_mem;
        }
 
-       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
-       if (ret)
-               goto err_release_pl_mem;
-
        /* Initialize par */
        da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
 
@@ -1060,7 +1056,7 @@ static int __init fb_probe(struct platform_device *device)
 
        ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
        if (ret)
-               goto err_free_irq;
+               goto err_release_pl_mem;
        da8xx_fb_info->cmap.len = par->palette_sz;
 
        /* initialize var_screeninfo */
@@ -1088,8 +1084,13 @@ static int __init fb_probe(struct platform_device *device)
                goto err_cpu_freq;
        }
 #endif
+
+       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+       if (ret)
+               goto irq_freq;
        return 0;
 
+irq_freq:
 #ifdef CONFIG_CPU_FREQ
 err_cpu_freq:
        unregister_framebuffer(da8xx_fb_info);
@@ -1098,9 +1099,6 @@ err_cpu_freq:
 err_dealloc_cmap:
        fb_dealloc_cmap(&da8xx_fb_info->cmap);
 
-err_free_irq:
-       free_irq(par->irq, par);
-
 err_release_pl_mem:
        dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
                          par->p_palette_base);
index f53b9f1d6aba23830d3b5c1a551054cf9f8b4538..5c3960da755aa52eefe1069442e9a43341e43e8c 100644 (file)
@@ -80,6 +80,7 @@ static const struct fb_cmap default_16_colors = {
  *     @cmap: frame buffer colormap structure
  *     @len: length of @cmap
  *     @transp: boolean, 1 if there is transparency, 0 otherwise
+ *     @flags: flags for kmalloc memory allocation
  *
  *     Allocates memory for a colormap @cmap.  @len is the
  *     number of entries in the palette.
@@ -88,34 +89,48 @@ static const struct fb_cmap default_16_colors = {
  *
  */
 
-int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
 {
-    int size = len*sizeof(u16);
-
-    if (cmap->len != len) {
-       fb_dealloc_cmap(cmap);
-       if (!len)
-           return 0;
-       if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-           goto fail;
-       if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-           goto fail;
-       if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-           goto fail;
-       if (transp) {
-           if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+       int size = len * sizeof(u16);
+       int ret = -ENOMEM;
+
+       if (cmap->len != len) {
+               fb_dealloc_cmap(cmap);
+               if (!len)
+                       return 0;
+
+               cmap->red = kmalloc(size, flags);
+               if (!cmap->red)
+                       goto fail;
+               cmap->green = kmalloc(size, flags);
+               if (!cmap->green)
+                       goto fail;
+               cmap->blue = kmalloc(size, flags);
+               if (!cmap->blue)
+                       goto fail;
+               if (transp) {
+                       cmap->transp = kmalloc(size, flags);
+                       if (!cmap->transp)
+                               goto fail;
+               } else {
+                       cmap->transp = NULL;
+               }
+       }
+       cmap->start = 0;
+       cmap->len = len;
+       ret = fb_copy_cmap(fb_default_cmap(len), cmap);
+       if (ret)
                goto fail;
-       } else
-           cmap->transp = NULL;
-    }
-    cmap->start = 0;
-    cmap->len = len;
-    fb_copy_cmap(fb_default_cmap(len), cmap);
-    return 0;
+       return 0;
 
 fail:
-    fb_dealloc_cmap(cmap);
-    return -ENOMEM;
+       fb_dealloc_cmap(cmap);
+       return ret;
+}
+
+int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+       return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC);
 }
 
 /**
@@ -250,8 +265,12 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
        int rc, size = cmap->len * sizeof(u16);
        struct fb_cmap umap;
 
+       if (size < 0 || size < cmap->len)
+               return -E2BIG;
+
        memset(&umap, 0, sizeof(struct fb_cmap));
-       rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
+       rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL,
+                               GFP_KERNEL);
        if (rc)
                return rc;
        if (copy_from_user(umap.red, cmap->red, size) ||
index e4c4d89b786034c33aaf687b9616feddd3c76bbd..be8ccb47ebe039e11a84c32892ddfa046a000df8 100644 (file)
@@ -22,6 +22,7 @@
 #define DC_HFILT_COUNT 0x100
 #define DC_VFILT_COUNT 0x100
 #define VP_COEFF_SIZE  0x1000
+#define VP_PAL_COUNT   0x100
 
 #define OUTPUT_CRT   0x01
 #define OUTPUT_PANEL 0x02
@@ -48,7 +49,8 @@ struct lxfb_par {
        uint64_t vp[VP_REG_COUNT];
        uint64_t fp[FP_REG_COUNT];
 
-       uint32_t pal[DC_PAL_COUNT];
+       uint32_t dc_pal[DC_PAL_COUNT];
+       uint32_t vp_pal[VP_PAL_COUNT];
        uint32_t hcoeff[DC_HFILT_COUNT * 2];
        uint32_t vcoeff[DC_VFILT_COUNT];
        uint32_t vp_coeff[VP_COEFF_SIZE / 4];
index bc35a95e59d417ef85df900e26824f5de67eaa35..79e9abc72b836ea0c8cbd3c28e5db87284a9e118 100644 (file)
@@ -276,10 +276,10 @@ static void lx_graphics_enable(struct fb_info *info)
                write_fp(par, FP_PT1, 0);
                temp = FP_PT2_SCRC;
 
-               if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+               if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
                        temp |= FP_PT2_HSP;
 
-               if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+               if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
                        temp |= FP_PT2_VSP;
 
                write_fp(par, FP_PT2, temp);
@@ -610,10 +610,15 @@ static void lx_save_regs(struct lxfb_par *par)
        memcpy(par->vp, par->vp_regs, sizeof(par->vp));
        memcpy(par->fp, par->vp_regs + VP_FP_START, sizeof(par->fp));
 
-       /* save the palette */
+       /* save the display controller palette */
        write_dc(par, DC_PAL_ADDRESS, 0);
-       for (i = 0; i < ARRAY_SIZE(par->pal); i++)
-               par->pal[i] = read_dc(par, DC_PAL_DATA);
+       for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+               par->dc_pal[i] = read_dc(par, DC_PAL_DATA);
+
+       /* save the video processor palette */
+       write_vp(par, VP_PAR, 0);
+       for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+               par->vp_pal[i] = read_vp(par, VP_PDR);
 
        /* save the horizontal filter coefficients */
        filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -706,8 +711,8 @@ static void lx_restore_display_ctlr(struct lxfb_par *par)
 
        /* restore the palette */
        write_dc(par, DC_PAL_ADDRESS, 0);
-       for (i = 0; i < ARRAY_SIZE(par->pal); i++)
-               write_dc(par, DC_PAL_DATA, par->pal[i]);
+       for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+               write_dc(par, DC_PAL_DATA, par->dc_pal[i]);
 
        /* restore the horizontal filter coefficients */
        filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -751,6 +756,11 @@ static void lx_restore_video_proc(struct lxfb_par *par)
                }
        }
 
+       /* restore video processor palette */
+       write_vp(par, VP_PAR, 0);
+       for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+               write_vp(par, VP_PDR, par->vp_pal[i]);
+
        /* restore video coeff ram */
        memcpy(par->vp_regs + VP_VCR, par->vp_coeff, sizeof(par->vp_coeff));
 }
index 7cfc170bce196d28492fd4f4bbc5d9aace16ce31..ca0f6be9d12ebcc91f2689fafd3ac6d4cf535da7 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 
+#include <mach/dma.h>
 #include <mach/hardware.h>
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
@@ -1420,6 +1421,9 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
        struct device *dev;
        struct mx3fb_platform_data *mx3fb_pdata;
 
+       if (!imx_dma_is_ipu(chan))
+               return false;
+
        if (!rq)
                return false;
 
index 9b1364723c65e2fcff4dcec661d59ab50b960ee1..b02d97a879d67256992a3941536fcd7e88626f63 100644 (file)
@@ -860,7 +860,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
                /* Couldn't reconfigure, hopefully, can continue as before */
                return;
 
-       info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8);
+       info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
 
        /*
         * fb_set_var() calls the notifier change internally, only if
@@ -868,7 +868,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
         * user event, we have to call the chain ourselves.
         */
        event.info = info;
-       event.data = &mode2;
+       event.data = &mode1;
        fb_notifier_call_chain(evnt, &event);
 }
 
index c311ad3c3687c739a558fc9baea8d9393aef756a..31137adc8fba5245596d378bf785345957cc6597 100644 (file)
 
 #include "init.h"
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 #include "300vtbl.h"
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 #include "310vtbl.h"
 #endif
 
@@ -78,7 +78,7 @@
 /*         POINTER INITIALIZATION            */
 /*********************************************/
 
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 static void
 InitCommonPointer(struct SiS_Private *SiS_Pr)
 {
@@ -160,7 +160,7 @@ InitCommonPointer(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static void
 InitTo300Pointer(struct SiS_Private *SiS_Pr)
 {
@@ -237,7 +237,7 @@ InitTo300Pointer(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 InitTo310Pointer(struct SiS_Private *SiS_Pr)
 {
@@ -321,13 +321,13 @@ bool
 SiSInitPtr(struct SiS_Private *SiS_Pr)
 {
    if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       InitTo300Pointer(SiS_Pr);
 #else
       return false;
 #endif
    } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       InitTo310Pointer(SiS_Pr);
 #else
       return false;
@@ -340,9 +340,7 @@ SiSInitPtr(struct SiS_Private *SiS_Pr)
 /*            HELPER: Get ModeID             */
 /*********************************************/
 
-#ifndef SIS_XORG_XF86
 static
-#endif
 unsigned short
 SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
                int Depth, bool FSTN, int LCDwidth, int LCDheight)
@@ -884,51 +882,51 @@ SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispl
 void
 SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
 {
-   OutPortByte(port, index);
-   OutPortByte(port + 1, data);
+       outb((u8)index, port);
+       outb((u8)data, port + 1);
 }
 
 void
 SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
 {
-   OutPortByte(port, data);
+       outb((u8)data, port);
 }
 
 void
 SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
 {
-   OutPortWord(port, data);
+       outw((u16)data, port);
 }
 
 void
 SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
 {
-   OutPortLong(port, data);
+       outl((u32)data, port);
 }
 
 unsigned char
 SiS_GetReg(SISIOADDRESS port, unsigned short index)
 {
-   OutPortByte(port, index);
-   return(InPortByte(port + 1));
+       outb((u8)index, port);
+       return inb(port + 1);
 }
 
 unsigned char
 SiS_GetRegByte(SISIOADDRESS port)
 {
-   return(InPortByte(port));
+       return inb(port);
 }
 
 unsigned short
 SiS_GetRegShort(SISIOADDRESS port)
 {
-   return(InPortWord(port));
+       return inw(port);
 }
 
 unsigned int
 SiS_GetRegLong(SISIOADDRESS port)
 {
-   return(InPortLong(port));
+       return inl(port);
 }
 
 void
@@ -1089,7 +1087,7 @@ static void
 SiSInitPCIetc(struct SiS_Private *SiS_Pr)
 {
    switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    case SIS_300:
    case SIS_540:
    case SIS_630:
@@ -1108,7 +1106,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
       break;
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    case SIS_315H:
    case SIS_315:
    case SIS_315PRO:
@@ -1152,9 +1150,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
 /*             HELPER: SetLVDSetc            */
 /*********************************************/
 
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 void
 SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
 {
@@ -1174,7 +1170,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
    if((temp == 1) || (temp == 2)) return;
 
    switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    case SIS_540:
    case SIS_630:
    case SIS_730:
@@ -1188,7 +1184,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
        }
        break;
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    case SIS_550:
    case SIS_650:
    case SIS_740:
@@ -1420,9 +1416,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
 /*             HELPER: GetVBType             */
 /*********************************************/
 
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 void
 SiS_GetVBType(struct SiS_Private *SiS_Pr)
 {
@@ -1487,7 +1481,6 @@ SiS_GetVBType(struct SiS_Private *SiS_Pr)
 /*           HELPER: Check RAM size          */
 /*********************************************/
 
-#ifdef SIS_LINUX_KERNEL
 static bool
 SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
                unsigned short ModeIdIndex)
@@ -1501,13 +1494,12 @@ SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    if(AdapterMemSize < memorysize) return false;
    return true;
 }
-#endif
 
 /*********************************************/
 /*           HELPER: Get DRAM type           */
 /*********************************************/
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static unsigned char
 SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
 {
@@ -1574,7 +1566,6 @@ SiS_GetMCLK(struct SiS_Private *SiS_Pr)
 /*           HELPER: ClearBuffer             */
 /*********************************************/
 
-#ifdef SIS_LINUX_KERNEL
 static void
 SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
@@ -1587,7 +1578,7 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 
    if(SiS_Pr->SiS_ModeType >= ModeEGA) {
       if(ModeNo > 0x13) {
-        SiS_SetMemory(memaddr, memsize, 0);
+        memset_io(memaddr, 0, memsize);
       } else {
         pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
         for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
@@ -1596,10 +1587,9 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
       pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
       for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
    } else {
-      SiS_SetMemory(memaddr, 0x8000, 0);
+      memset_io(memaddr, 0, 0x8000);
    }
 }
-#endif
 
 /*********************************************/
 /*           HELPER: SearchModeID            */
@@ -2132,7 +2122,7 @@ SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
    }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType == XGI_20) {
       SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
       if(!(temp = crt1data[5] & 0x1f)) {
@@ -2215,7 +2205,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
 
    if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
       if(SiS_Pr->ChipType == XGI_20) {
          unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
@@ -2236,7 +2226,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 /*                  FIFO                     */
 /*********************************************/
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 void
 SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
                unsigned short *idx2)
@@ -2506,11 +2496,7 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
 
   /* Write foreground and background queue */
-#ifdef SIS_LINUX_KERNEL
    templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
-#else
-   templ = pciReadLong(0x00000000, 0x50);
-#endif
 
    if(SiS_Pr->ChipType == SIS_730) {
 
@@ -2530,13 +2516,8 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 
    }
 
-#ifdef SIS_LINUX_KERNEL
    sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
    templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
-#else
-   pciWriteLong(0x00000000, 0x50, templ);
-   templ = pciReadLong(0x00000000, 0xA0);
-#endif
 
    /* GUI grant timer (PCI config 0xA3) */
    if(SiS_Pr->ChipType == SIS_730) {
@@ -2552,15 +2533,11 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 
    }
 
-#ifdef SIS_LINUX_KERNEL
    sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
-#else
-   pciWriteLong(0x00000000, 0xA0, templ);
-#endif
 }
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
 {
@@ -2612,7 +2589,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    }
 
    if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       if(VCLK > 150) data |= 0x80;
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
 
@@ -2621,7 +2598,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
 #endif
    } else if(SiS_Pr->ChipType < XGI_20) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       if(VCLK >= 166) data |= 0x0c;
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
 
@@ -2630,7 +2607,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       }
 #endif
    } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       if(VCLK >= 200) data |= 0x0c;
       if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
@@ -2675,7 +2652,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
                unsigned short ModeIdIndex, unsigned short RRTI)
 {
    unsigned short data, infoflag = 0, modeflag, resindex;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
    unsigned short data2, data3;
 #endif
@@ -2736,7 +2713,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
    }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType >= SIS_315H) {
       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
    }
@@ -2826,7 +2803,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 
    SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
        (SiS_Pr->ChipType == XGI_40)) {
       if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
@@ -2845,7 +2822,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 #endif
 }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
 {
@@ -2999,11 +2976,6 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
    SiS_Pr->SiS_SelectCRT2Rate = 0;
    SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
 
-#ifdef SIS_XORG_XF86
-   xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
-                    SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
-#endif
-
    if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
          SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
@@ -3028,7 +3000,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
    }
 
    switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    case SIS_300:
       SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
       break;
@@ -3039,7 +3011,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
       break;
 #endif
    default:
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       if(SiS_Pr->ChipType == XGI_20) {
          unsigned char sr2b = 0, sr2c = 0;
          switch(ModeNo) {
@@ -3062,7 +3034,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
 
    SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType == XGI_40) {
       SiS_SetupDualChip(SiS_Pr);
    }
@@ -3070,11 +3042,9 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
 
    SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
 
-#ifdef SIS_LINUX_KERNEL
    if(SiS_Pr->SiS_flag_clearbuffer) {
       SiS_ClearBuffer(SiS_Pr, ModeNo);
    }
-#endif
 
    if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
       SiS_WaitRetrace1(SiS_Pr);
@@ -3104,7 +3074,7 @@ SiS_InitVB(struct SiS_Private *SiS_Pr)
 static void
 SiS_ResetVB(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    unsigned short temp;
 
@@ -3139,7 +3109,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
     * which locks CRT2 in some way to CRT1 timing. Disable
     * this here.
     */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if((IS_SIS651) || (IS_SISM650) ||
       SiS_Pr->ChipType == SIS_340 ||
       SiS_Pr->ChipType == XGI_40) {
@@ -3160,7 +3130,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
 static void
 SiS_Handle760(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    unsigned int somebase;
    unsigned char temp1, temp2, temp3;
 
@@ -3170,11 +3140,7 @@ SiS_Handle760(struct SiS_Private *SiS_Pr)
        (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
       return;
 
-#ifdef SIS_LINUX_KERNEL
    somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
-#else
-   somebase = pciReadWord(0x00001000, 0x74);
-#endif
    somebase &= 0xffff;
 
    if(somebase == 0) return;
@@ -3190,105 +3156,34 @@ SiS_Handle760(struct SiS_Private *SiS_Pr)
       temp2 = 0x0b;
    }
 
-#ifdef SIS_LINUX_KERNEL
    sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
    sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
-#else
-   pciWriteByte(0x00000000, 0x7e, temp1);
-   pciWriteByte(0x00000000, 0x8d, temp2);
-#endif
 
    SiS_SetRegByte((somebase + 0x85), temp3);
 #endif
 }
 
-/*********************************************/
-/*      X.org/XFree86: SET SCREEN PITCH      */
-/*********************************************/
-
-#ifdef SIS_XORG_XF86
-static void
-SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
-   SISPtr pSiS = SISPTR(pScrn);
-   unsigned short HDisplay = pSiS->scrnPitch >> 3;
-
-   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
-}
-
-static void
-SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
-   SISPtr pSiS = SISPTR(pScrn);
-   unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
-
-    /* Unlock CRT2 */
-   if(pSiS->VGAEngine == SIS_315_VGA)
-      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
-   else
-      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
-
-   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
-   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
-}
-
-static void
-SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
-   SISPtr pSiS = SISPTR(pScrn);
-   bool isslavemode = false;
-
-   if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
-       ( ((pSiS->VGAEngine == SIS_300_VGA) &&
-         (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-        ((pSiS->VGAEngine == SIS_315_VGA) &&
-         (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
-      isslavemode = true;
-   }
-
-   /* We need to set pitch for CRT1 if bridge is in slave mode, too */
-   if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) {
-      SiS_SetPitchCRT1(SiS_Pr, pScrn);
-   }
-   /* We must not set the pitch for CRT2 if bridge is in slave mode */
-   if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) {
-      SiS_SetPitchCRT2(SiS_Pr, pScrn);
-   }
-}
-#endif
-
 /*********************************************/
 /*                 SiSSetMode()              */
 /*********************************************/
 
-#ifdef SIS_XORG_XF86
-/* We need pScrn for setting the pitch correctly */
-bool
-SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch)
-#else
 bool
 SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
-#endif
 {
    SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
    unsigned short RealModeNo, ModeIdIndex;
    unsigned char  backupreg = 0;
-#ifdef SIS_LINUX_KERNEL
    unsigned short KeepLockReg;
 
    SiS_Pr->UseCustomMode = false;
    SiS_Pr->CRT1UsesCustomMode = false;
-#endif
 
    SiS_Pr->SiS_flag_clearbuffer = 0;
 
    if(SiS_Pr->UseCustomMode) {
       ModeNo = 0xfe;
    } else {
-#ifdef SIS_LINUX_KERNEL
       if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
-#endif
       ModeNo &= 0x7f;
    }
 
@@ -3301,13 +3196,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
    SiS_GetSysFlags(SiS_Pr);
 
    SiS_Pr->SiS_VGAINFO = 0x11;
-#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
-   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#endif
 
-#ifdef SIS_LINUX_KERNEL
    KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
-#endif
    SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
    SiSInitPCIetc(SiS_Pr);
@@ -3344,12 +3234,10 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
    SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
    SiS_SetLowModeTest(SiS_Pr, ModeNo);
 
-#ifdef SIS_LINUX_KERNEL
    /* Check memory size (kernel framebuffer driver only) */
    if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
       return false;
    }
-#endif
 
    SiS_OpenCRTC(SiS_Pr);
 
@@ -3384,7 +3272,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
    SiS_DisplayOn(SiS_Pr);
    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType >= SIS_315H) {
       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
         if(!(SiS_IsDualEdge(SiS_Pr))) {
@@ -3396,7 +3284,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 
    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
       if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
         if(!SiS_Pr->SiS_ROMNew) {
            if(SiS_IsVAMode(SiS_Pr)) {
               SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
@@ -3424,424 +3312,16 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
       }
    }
 
-#ifdef SIS_XORG_XF86
-   if(pScrn) {
-      /* SetPitch: Adapt to virtual size & position */
-      if((ModeNo > 0x13) && (dosetpitch)) {
-        SiS_SetPitch(SiS_Pr, pScrn);
-      }
-
-      /* Backup/Set ModeNo in BIOS scratch area */
-      SiS_GetSetModeID(pScrn, ModeNo);
-   }
-#endif
-
    SiS_CloseCRTC(SiS_Pr);
 
    SiS_Handle760(SiS_Pr);
 
-#ifdef SIS_LINUX_KERNEL
    /* We never lock registers in XF86 */
    if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
-#endif
 
    return true;
 }
 
-/*********************************************/
-/*       X.org/XFree86: SiSBIOSSetMode()     */
-/*           for non-Dual-Head mode          */
-/*********************************************/
-
-#ifdef SIS_XORG_XF86
-bool
-SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, bool IsCustom)
-{
-   SISPtr pSiS = SISPTR(pScrn);
-   unsigned short ModeNo = 0;
-
-   SiS_Pr->UseCustomMode = false;
-
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
-               SiS_Pr->CHDisplay,
-               (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
-                  (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
-                     SiS_Pr->CVDisplay)));
-
-   } else {
-
-      /* Don't need vbflags here; checks done earlier */
-      ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
-      if(!ModeNo) return false;
-
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
-
-   }
-
-   return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true));
-}
-
-/*********************************************/
-/*    X.org/XFree86: SiSBIOSSetModeCRT2()    */
-/*           for Dual-Head modes             */
-/*********************************************/
-
-bool
-SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, bool IsCustom)
-{
-   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
-   SISPtr  pSiS = SISPTR(pScrn);
-#ifdef SISDUALHEAD
-   SISEntPtr pSiSEnt = pSiS->entityPrivate;
-#endif
-   unsigned short ModeIdIndex;
-   unsigned short ModeNo = 0;
-   unsigned char  backupreg = 0;
-
-   SiS_Pr->UseCustomMode = false;
-
-   /* Remember: Custom modes for CRT2 are ONLY supported
-    *     -) on the 30x/B/C, and
-    *     -) if CRT2 is LCD or VGA, or CRT1 is LCDA
-    */
-
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
-        ModeNo = 0xfe;
-
-   } else {
-
-        ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
-        if(!ModeNo) return false;
-
-   }
-
-   SiSRegInit(SiS_Pr, BaseAddr);
-   SiSInitPtr(SiS_Pr);
-   SiS_GetSysFlags(SiS_Pr);
-#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#else
-   SiS_Pr->SiS_VGAINFO = 0x11;
-#endif
-
-   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
-   SiSInitPCIetc(SiS_Pr);
-   SiSSetLVDSetc(SiS_Pr);
-   SiSDetermineROMUsage(SiS_Pr);
-
-   /* Save mode info so we can set it from within SetMode for CRT1 */
-#ifdef SISDUALHEAD
-   if(pSiS->DualHeadMode) {
-      pSiSEnt->CRT2ModeNo = ModeNo;
-      pSiSEnt->CRT2DMode = mode;
-      pSiSEnt->CRT2IsCustom = IsCustom;
-      pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-      pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
-      pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-      pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-#if 0
-      /* We can't set CRT2 mode before CRT1 mode is set - says who...? */
-      if(pSiSEnt->CRT1ModeNo == -1) {
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-               "Setting CRT2 mode delayed until after setting CRT1 mode\n");
-        return true;
-      }
-#endif
-      pSiSEnt->CRT2ModeSet = true;
-   }
-#endif
-
-   if(SiS_Pr->UseCustomMode) {
-
-      unsigned short temptemp = SiS_Pr->CVDisplay;
-
-      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-         "Setting custom mode %dx%d on CRT2\n",
-         SiS_Pr->CHDisplay, temptemp);
-
-   } else {
-
-      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-         "Setting standard mode 0x%x on CRT2\n", ModeNo);
-
-   }
-
-   SiS_UnLockCRT2(SiS_Pr);
-
-   if(!SiS_Pr->UseCustomMode) {
-      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
-   } else {
-      ModeIdIndex = 0;
-   }
-
-   SiS_GetVBType(SiS_Pr);
-
-   SiS_InitVB(SiS_Pr);
-   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
-      if(SiS_Pr->ChipType >= SIS_315H) {
-        SiS_ResetVB(SiS_Pr);
-        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-        SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-        backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-      } else {
-        backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-      }
-   }
-
-   /* Get VB information (connectors, connected devices) */
-   if(!SiS_Pr->UseCustomMode) {
-      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
-   } else {
-      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
-      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
-   }
-   SiS_SetYPbPr(SiS_Pr);
-   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
-   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
-   SiS_SetLowModeTest(SiS_Pr, ModeNo);
-
-   SiS_ResetSegmentRegisters(SiS_Pr);
-
-   /* Set mode on CRT2 */
-   if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
-       (SiS_Pr->SiS_IF_DEF_LVDS     == 1) ||
-       (SiS_Pr->SiS_IF_DEF_CH70xx   != 0) ||
-       (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
-      SiS_SetCRT2Group(SiS_Pr, ModeNo);
-   }
-
-   SiS_StrangeStuff(SiS_Pr);
-
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
-
-   if(SiS_Pr->ChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(!(SiS_IsDualEdge(SiS_Pr))) {
-           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
-        }
-      }
-   }
-
-   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
-      if(SiS_Pr->ChipType >= SIS_315H) {
-        if(!SiS_Pr->SiS_ROMNew) {
-           if(SiS_IsVAMode(SiS_Pr)) {
-              SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-           } else {
-              SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
-           }
-        }
-
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
-
-        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
-           SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
-        }
-      } else if((SiS_Pr->ChipType == SIS_630) ||
-               (SiS_Pr->ChipType == SIS_730)) {
-         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
-      }
-   }
-
-   /* SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT2(SiS_Pr, pScrn);
-
-   SiS_Handle760(SiS_Pr);
-
-   return true;
-}
-
-/*********************************************/
-/*    X.org/XFree86: SiSBIOSSetModeCRT1()    */
-/*           for Dual-Head modes             */
-/*********************************************/
-
-bool
-SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-                   DisplayModePtr mode, bool IsCustom)
-{
-   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
-   SISPtr  pSiS = SISPTR(pScrn);
-   unsigned short ModeIdIndex, ModeNo = 0;
-   unsigned char  backupreg = 0;
-#ifdef SISDUALHEAD
-   SISEntPtr pSiSEnt = pSiS->entityPrivate;
-   unsigned char  backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
-   bool backupcustom;
-#endif
-
-   SiS_Pr->UseCustomMode = false;
-
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
-        unsigned short temptemp = SiS_Pr->CVDisplay;
-
-        if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
-        else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-               "Setting custom mode %dx%d on CRT1\n",
-               SiS_Pr->CHDisplay, temptemp);
-        ModeNo = 0xfe;
-
-   } else {
-
-        ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
-        if(!ModeNo) return false;
-
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-               "Setting standard mode 0x%x on CRT1\n", ModeNo);
-   }
-
-   SiSInitPtr(SiS_Pr);
-   SiSRegInit(SiS_Pr, BaseAddr);
-   SiS_GetSysFlags(SiS_Pr);
-#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#else
-   SiS_Pr->SiS_VGAINFO = 0x11;
-#endif
-
-   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
-   SiSInitPCIetc(SiS_Pr);
-   SiSSetLVDSetc(SiS_Pr);
-   SiSDetermineROMUsage(SiS_Pr);
-
-   SiS_UnLockCRT2(SiS_Pr);
-
-   if(!SiS_Pr->UseCustomMode) {
-      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
-   } else {
-      ModeIdIndex = 0;
-   }
-
-   /* Determine VBType */
-   SiS_GetVBType(SiS_Pr);
-
-   SiS_InitVB(SiS_Pr);
-   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
-      if(SiS_Pr->ChipType >= SIS_315H) {
-         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-      } else {
-         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-      }
-   }
-
-   /* Get VB information (connectors, connected devices) */
-   /* (We don't care if the current mode is a CRT2 mode) */
-   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
-   SiS_SetYPbPr(SiS_Pr);
-   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
-   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
-   SiS_SetLowModeTest(SiS_Pr, ModeNo);
-
-   SiS_OpenCRTC(SiS_Pr);
-
-   /* Set mode on CRT1 */
-   SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      SiS_SetCRT2Group(SiS_Pr, ModeNo);
-   }
-
-   /* SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT1(SiS_Pr, pScrn);
-
-   SiS_HandleCRT1(SiS_Pr);
-
-   SiS_StrangeStuff(SiS_Pr);
-
-   SiS_CloseCRTC(SiS_Pr);
-
-#ifdef SISDUALHEAD
-   if(pSiS->DualHeadMode) {
-      pSiSEnt->CRT1ModeNo = ModeNo;
-      pSiSEnt->CRT1DMode = mode;
-   }
-#endif
-
-   if(SiS_Pr->UseCustomMode) {
-      SiS_Pr->CRT1UsesCustomMode = true;
-      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
-      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
-   } else {
-      SiS_Pr->CRT1UsesCustomMode = false;
-   }
-
-   /* Reset CRT2 if changing mode on CRT1 */
-#ifdef SISDUALHEAD
-   if(pSiS->DualHeadMode) {
-      if(pSiSEnt->CRT2ModeNo != -1) {
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-                               "(Re-)Setting mode for CRT2\n");
-        backupcustom = SiS_Pr->UseCustomMode;
-        backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-        backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
-        backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
-        backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-        if(SiS_Pr->SiS_VBType & VB_SISVB) {
-           /* Backup LUT-enable */
-           if(pSiSEnt->CRT2ModeSet) {
-              backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08;
-           }
-        }
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-           SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30);
-           SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31);
-           SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
-           SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
-        }
-
-        SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
-                           pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
-
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
-        if(SiS_Pr->SiS_VBType & VB_SISVB) {
-           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d);
-        }
-        SiS_Pr->UseCustomMode = backupcustom;
-      }
-   }
-#endif
-
-   /* Warning: From here, the custom mode entries in SiS_Pr are
-    * possibly overwritten
-    */
-
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
-
-   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
-      if(SiS_Pr->ChipType >= SIS_315H) {
-        SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
-      } else if((SiS_Pr->ChipType == SIS_630) ||
-                (SiS_Pr->ChipType == SIS_730)) {
-         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
-      }
-   }
-
-   SiS_Handle760(SiS_Pr);
-
-   /* Backup/Set ModeNo in BIOS scratch area */
-   SiS_GetSetModeID(pScrn,ModeNo);
-
-   return true;
-}
-#endif /* Linux_XF86 */
-
 #ifndef GETBITSTR
 #define BITMASK(h,l)           (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
 #define GENMASK(mask)          BITMASK(1?mask,0?mask)
@@ -3927,7 +3407,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
 
    if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       tempbx = SiS_Pr->SiS_VGAHT;
       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
          tempbx = SiS_Pr->PanelHT;
@@ -3936,7 +3416,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       remaining = tempbx % 8;
 #endif
    } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       /* OK for LCDA, LVDS */
       tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
       tempax = SiS_Pr->SiS_VGAHDE;  /* not /2 ! */
@@ -3950,7 +3430,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
 
    if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
         SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
         SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
@@ -3982,7 +3462,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
       }
 #endif
    } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       tempax = VGAHDE;
       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
         tempbx = SiS_Pr->PanelXRes;
@@ -4001,7 +3481,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
       tempax = SiS_Pr->PanelYRes;
    } else if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       /* Stupid hack for 640x400/320x200 */
       if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
         if((tempax + tempbx) == 438) tempbx += 16;
@@ -4054,36 +3534,12 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
    if(modeflag & DoubleScanMode) tempax |= 0x80;
    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
-       SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
-       SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
-       SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
-   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
-       SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
-       SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
-       SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
-   xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
-       SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
-       SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
-       SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
-   xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
-#endif
-#endif
 }
 
 void
 SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
                        int xres, int yres,
-#ifdef SIS_XORG_XF86
-                       DisplayModePtr current
-#endif
-#ifdef SIS_LINUX_KERNEL
                        struct fb_var_screeninfo *var, bool writeres
-#endif
 )
 {
    unsigned short HRE, HBE, HRS, HBS, HDE, HT;
@@ -4127,25 +3583,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
 
    D = B - F - C;
 
-#ifdef SIS_XORG_XF86
-   current->HDisplay   = (E * 8);
-   current->HSyncStart = (E * 8) + (F * 8);
-   current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
-   current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO,
-               "H: A %d B %d C %d D %d E %d F %d  HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
-               A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
-#else
-   (void)VBS;  (void)HBS;  (void)A;
-#endif
-#endif
-#ifdef SIS_LINUX_KERNEL
    if(writeres) var->xres = xres = E * 8;
    var->left_margin = D * 8;
    var->right_margin = F * 8;
    var->hsync_len = C * 8;
-#endif
 
    /* Vertical */
    sr_data = crdata[13];
@@ -4192,30 +3633,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
 
    D = B - F - C;
 
-#ifdef SIS_XORG_XF86
-   current->VDisplay   = VDE + 1;
-   current->VSyncStart = VRS + 1;
-   current->VSyncEnd   = ((VRS & ~0x1f) | VRE) + 1;
-   if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
-   current->VTotal     = E + D + C + F;
-#if 0
-   current->VDisplay   = E;
-   current->VSyncStart = E + D;
-   current->VSyncEnd   = E + D + C;
-   current->VTotal     = E + D + C + F;
-#endif
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO,
-       "V: A %d B %d C %d D %d E %d F %d  VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
-       A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
-#endif
-#endif
-#ifdef SIS_LINUX_KERNEL
    if(writeres) var->yres = yres = E;
    var->upper_margin = D;
    var->lower_margin = F;
    var->vsync_len = C;
-#endif
 
    if((xres == 320) && ((yres == 200) || (yres == 240))) {
        /* Terrible hack, but correct CRTC data for
@@ -4224,17 +3645,9 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
         * a negative D. The CRT controller does not
         * seem to like correcting HRE to 50)
         */
-#ifdef SIS_XORG_XF86
-      current->HDisplay   = 320;
-      current->HSyncStart = 328;
-      current->HSyncEnd   = 376;
-      current->HTotal     = 400;
-#endif
-#ifdef SIS_LINUX_KERNEL
       var->left_margin = (400 - 376);
       var->right_margin = (328 - 320);
       var->hsync_len = (376 - 328);
-#endif
 
    }
 
index b96005c39c67fdbe4d63e034123a328e53282cd0..ee8ed3c203daa4a3f7a1fb346c2d4105ac93a0e5 100644 (file)
 #ifndef _INIT_H_
 #define _INIT_H_
 
-#include "osdef.h"
 #include "initdef.h"
 
-#ifdef SIS_XORG_XF86
-#include "sis.h"
-#define SIS_NEED_inSISREG
-#define SIS_NEED_inSISREGW
-#define SIS_NEED_inSISREGL
-#define SIS_NEED_outSISREG
-#define SIS_NEED_outSISREGW
-#define SIS_NEED_outSISREGL
-#include "sis_regs.h"
-#endif
-
-#ifdef SIS_LINUX_KERNEL
 #include "vgatypes.h"
 #include "vstruct.h"
 #ifdef SIS_CP
@@ -78,7 +65,6 @@
 #include <linux/fb.h>
 #include "sis.h"
 #include <video/sisfb.h>
-#endif
 
 /* Mode numbers */
 static const unsigned short ModeIndex_320x200[]      = {0x59, 0x41, 0x00, 0x4f};
@@ -286,7 +272,7 @@ static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
        { 1280, 854, 8,16}    /* 0x22 */
 };
 
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 static const struct SiS_StandTable_S SiS_StandTable[]=
 {
 /* 0x00: MD_0_200 */
@@ -1521,10 +1507,6 @@ static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
 };
 
 bool           SiSInitPtr(struct SiS_Private *SiS_Pr);
-#ifdef SIS_XORG_XF86
-unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
-                               int Depth, bool FSTN, int LCDwith, int LCDheight);
-#endif
 unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
                                int VDisplay, int Depth, bool FSTN,
                                unsigned short CustomT, int LCDwith, int LCDheight,
@@ -1550,17 +1532,11 @@ void            SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR
 void           SiS_DisplayOn(struct SiS_Private *SiS_Pr);
 void           SiS_DisplayOff(struct SiS_Private *SiS_Pr);
 void           SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-#ifndef SIS_LINUX_KERNEL
-void           SiSSetLVDSetc(struct SiS_Private *SiS_Pr);
-#endif
 void           SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
 void           SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
 unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
                                unsigned short ModeIdIndex);
 bool           SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void           SiS_GetVBType(struct SiS_Private *SiS_Pr);
-#endif
 
 bool           SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
                                unsigned short *ModeIdIndex);
@@ -1572,37 +1548,19 @@ unsigned short  SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short Mode
                                unsigned short ModeIdIndex);
 unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
                                unsigned short ModeIdIndex, unsigned short RRTI);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 void           SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
                                unsigned short *idx2);
 unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
 unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
 #endif
 void           SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
-#ifdef SIS_XORG_XF86
-bool           SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
-                               bool dosetpitch);
-bool           SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-                               DisplayModePtr mode, bool IsCustom);
-bool           SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-                               DisplayModePtr mode, bool IsCustom);
-bool           SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
-                               DisplayModePtr mode, bool IsCustom);
-#endif
-#ifdef SIS_LINUX_KERNEL
 bool           SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
-#endif
 void           SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
 void           SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
                                unsigned short ModeIdIndex);
-#ifdef SIS_XORG_XF86
-void           SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
-                               int yres, DisplayModePtr current);
-#endif
-#ifdef SIS_LINUX_KERNEL
 void           SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
                                int yres, struct fb_var_screeninfo *var, bool writeres);
-#endif
 
 /* From init301.c: */
 extern void            SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
@@ -1626,29 +1584,16 @@ extern unsigned short   SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short
 extern bool            SiS_IsVAMode(struct SiS_Private *);
 extern bool            SiS_IsDualEdge(struct SiS_Private *);
 
-#ifdef SIS_XORG_XF86
-/* From other modules: */
-extern unsigned short  SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
-                               unsigned int VBFlags);
-extern unsigned char   SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset,
-                               unsigned char value);
-extern unsigned char   SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
-extern unsigned short  SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
-                               unsigned int VBFlags);
-#endif
-
-#ifdef SIS_LINUX_KERNEL
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 extern unsigned int    sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
 extern void            sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
                                unsigned int val);
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 extern void            sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
                                unsigned char val);
 extern unsigned int    sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
 #endif
-#endif
 
 #endif
 
index da33d801c22e0c114147335701535c2c69e45d88..9fa66fd4052acfaf5833a2e12e6c88f97aa9e72e 100644 (file)
 
 #include "init301.h"
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 #include "oem300.h"
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 #include "oem310.h"
 #endif
 
@@ -87,9 +87,7 @@
 #define SiS_I2CDELAYSHORT  150
 
 static unsigned short  SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
-#ifdef SIS_LINUX_KERNEL
 static void            SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
-#endif
 
 /*********************************************/
 /*         HELPER: Lock/Unlock CRT2          */
@@ -106,9 +104,7 @@ SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 void
 SiS_LockCRT2(struct SiS_Private *SiS_Pr)
 {
@@ -138,7 +134,7 @@ SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned
 /*    HELPER: Get Pointer to LCD structure   */
 /*********************************************/
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static unsigned char *
 GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
 {
@@ -404,7 +400,7 @@ SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 /*    HELPER: GET SOME DATA FROM BIOS ROM    */
 /*********************************************/
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static bool
 SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
 {
@@ -449,7 +445,7 @@ SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
       SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
 }
 
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 static void
 SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
@@ -457,7 +453,7 @@ SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
@@ -467,7 +463,7 @@ SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 }
 #endif
 
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 static void
 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 {
@@ -480,14 +476,14 @@ SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
 static void
 SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
 {
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
    unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    unsigned short PanelID, DelayIndex, Delay=0;
 #endif
 
    if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 
       PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
       if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -513,11 +509,11 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
       }
       SiS_ShortDelay(SiS_Pr, Delay);
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
    } else {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 
       if((SiS_Pr->ChipType >= SIS_661)    ||
         (SiS_Pr->ChipType <= SIS_315PRO) ||
@@ -579,12 +575,12 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
 
       }
 
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
 
    }
 }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
 {
@@ -613,7 +609,7 @@ SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
    while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
 }
 
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
 static void
 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
 {
@@ -630,7 +626,7 @@ static void
 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
 {
    if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
         if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
       }
@@ -641,7 +637,7 @@ SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
       }
 #endif
    } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
         SiS_WaitRetrace1(SiS_Pr);
       } else {
@@ -686,7 +682,7 @@ SiS_VBLongWait(struct SiS_Private *SiS_Pr)
 /*               HELPER: MISC                */
 /*********************************************/
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static bool
 SiS_Is301B(struct SiS_Private *SiS_Pr)
 {
@@ -708,7 +704,7 @@ SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
 bool
 SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType >= SIS_315H) {
       if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
         if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
@@ -721,7 +717,7 @@ SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
 bool
 SiS_IsVAMode(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    unsigned short flag;
 
    if(SiS_Pr->ChipType >= SIS_315H) {
@@ -732,7 +728,7 @@ SiS_IsVAMode(struct SiS_Private *SiS_Pr)
    return false;
 }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
 {
@@ -745,7 +741,7 @@ SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
 static bool
 SiS_IsDualLink(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType >= SIS_315H) {
       if((SiS_CRT2IsLCD(SiS_Pr)) ||
          (SiS_IsVAMode(SiS_Pr))) {
@@ -756,7 +752,7 @@ SiS_IsDualLink(struct SiS_Private *SiS_Pr)
    return false;
 }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_TVEnabled(struct SiS_Private *SiS_Pr)
 {
@@ -768,7 +764,7 @@ SiS_TVEnabled(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
 {
@@ -777,7 +773,7 @@ SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
 {
@@ -788,7 +784,7 @@ SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
 {
@@ -804,7 +800,7 @@ SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
 {
@@ -816,7 +812,7 @@ SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsChScart(struct SiS_Private *SiS_Pr)
 {
@@ -828,7 +824,7 @@ SiS_IsChScart(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
 {
@@ -848,7 +844,7 @@ SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
 }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static bool
 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
 {
@@ -914,7 +910,7 @@ SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
 /*********************************************/
 
 /* Setup general purpose IO for Chrontel communication */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 void
 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
 {
@@ -923,11 +919,7 @@ SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
 
    if(!(SiS_Pr->SiS_ChSW)) return;
 
-#ifdef SIS_LINUX_KERNEL
    acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
-#else
-   acpibase = pciReadLong(0x00000800, 0x74);
-#endif
    acpibase &= 0xFFFF;
    if(!acpibase) return;
    temp = SiS_GetRegShort((acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
@@ -969,7 +961,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
        tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
        tempbx |= tempax;
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
        if(SiS_Pr->ChipType >= SIS_315H) {
           if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
              if(ModeNo == 0x03) {
@@ -1019,7 +1011,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
           }
        }
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
         if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
           tempbx &= ~(SetCRT2ToRAMDAC);
@@ -1154,24 +1146,16 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
 
    SiS_Pr->SiS_VBInfo = tempbx;
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    if(SiS_Pr->ChipType == SIS_630) {
       SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
    }
 #endif
 
-#ifdef SIS_LINUX_KERNEL
 #if 0
    printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
       SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
 #endif
-#endif
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
-      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
-#endif
-#endif
 }
 
 /*********************************************/
@@ -1415,12 +1399,6 @@ SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
    }
 
    SiS_Pr->SiS_VBInfo &= ~SetPALTV;
-
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
-#endif
-#endif
 }
 
 /*********************************************/
@@ -1443,22 +1421,10 @@ SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
 static void
 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    unsigned char  *ROMAddr;
    unsigned short temp;
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
-       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
-       SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
-       SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
-#endif
-#endif
-
    if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
       if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
         SiS_Pr->SiS_NeedRomModeData = true;
@@ -1480,18 +1446,6 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
       SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
         SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-      xf86DrvMsg(0, X_INFO, "Paneldata BIOS:  [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
-       SiS_Pr->PanelHT, SiS_Pr->PanelVT,
-       SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
-       SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
-       SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
-#endif
-#endif
-
    }
 #endif
 }
@@ -1517,13 +1471,13 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
 {
   unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
   bool panelcanscale = false;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
   static const unsigned char SiS300SeriesLCDRes[] =
           { 0,  1,  2,  3,  7,  4,  5,  8,
            0,  0, 10,  0,  0,  0,  0, 15 };
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned char   *myptr = NULL;
 #endif
 
@@ -1562,7 +1516,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
      SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
   temp &= 0x0f;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->ChipType < SIS_315H) {
      /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
      if(SiS_Pr->SiS_VBType & VB_SIS301) {
@@ -1574,7 +1528,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
 #endif
 
   /* Translate to our internal types */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->ChipType == SIS_550) {
      if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
      else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
@@ -1597,7 +1551,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
 
   SiS_Pr->SiS_LCDResInfo = temp;
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
        SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
@@ -1639,7 +1593,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
   else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 
   /* Dual link, Pass 1:1 BIOS default, etc. */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->ChipType >= SIS_661) {
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
        if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
@@ -2076,7 +2030,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
      }
   }
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
@@ -2186,17 +2140,10 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
      SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   }
 
-#ifdef SIS_LINUX_KERNEL
 #if 0
   printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
        SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
 #endif
-#endif
-#ifdef SIS_XORG_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 4,
-       "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
-       SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
-#endif
 }
 
 /*********************************************/
@@ -2359,7 +2306,7 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
              VCLKIndex = SiS_Pr->PanelVCLKIdx315;
           }
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
           /* Special Timing: Barco iQ Pro R series */
           if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
 
@@ -2410,12 +2357,6 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
 
   }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
-#endif
-#endif
-
   return VCLKIndex;
 }
 
@@ -2428,10 +2369,10 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 {
   unsigned short i, j, modeflag, tempah=0;
   short tempcl;
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
   unsigned short tempbl;
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short tempah2, tempbl2;
 #endif
@@ -2454,7 +2395,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
      if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300    /* ---- 300 series ---- */
+#ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
 
        /* For 301BDH: (with LCD via LVDS) */
        if(SiS_Pr->SiS_VBType & VB_NoLCD) {
@@ -2477,11 +2418,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
      } else {
 
-#ifdef SIS315H    /* ------- 315/330 series ------ */
+#ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
 
        if(ModeNo > 0x13) {
           tempcl -= ModeVGA;
@@ -2494,7 +2435,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
      }
 
@@ -2503,7 +2444,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
      if(SiS_Pr->ChipType < SIS_315H) {
        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
      } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -2584,7 +2525,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
        if(SiS_Pr->ChipType >= SIS_315H) {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
           /* LVDS can only be slave in 8bpp modes */
           tempah = 0x80;
           if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
@@ -2604,7 +2545,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
        } else {
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
           tempah = 0;
           if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
              tempah |= 0x02;
@@ -2626,7 +2567,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
      if(SiS_Pr->ChipType >= SIS_315H) {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
        /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
 
        /* The following is nearly unpreditable and varies from machine
@@ -2718,11 +2659,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
        }
 
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
 
      } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
        if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
@@ -2745,7 +2686,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
   } else {  /* LVDS */
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
      if(SiS_Pr->ChipType >= SIS_315H) {
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
@@ -2931,7 +2872,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
           }
        }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
        if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
           if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
              if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
@@ -3036,7 +2977,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        case Panel_1280x1024: tempbx = 24; break;
        case Panel_1400x1050: tempbx = 26; break;
        case Panel_1600x1200: tempbx = 28; break;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
        case Panel_Barco1366: tempbx = 80; break;
 #endif
        }
@@ -3053,7 +2994,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
        if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
        if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
           tempbx = 82;
           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
@@ -3189,7 +3130,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
 
    if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
       SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
       SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
 #endif
@@ -3214,7 +3155,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
         case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
         case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
         case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
         case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
         case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
         case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
@@ -3248,7 +3189,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
             (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
            SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
             SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
            if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
               if(ResIndex < 0x08) {
                  SiS_Pr->SiS_HDE = 1280;
@@ -3270,7 +3211,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   unsigned short resinfo, CRT2Index, ResIndex;
   const struct SiS_LCDData *LCDPtr = NULL;
   const struct SiS_TVData  *TVPtr  = NULL;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   short resinfo661;
 #endif
 
@@ -3283,7 +3224,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
      resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
         (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
@@ -3460,7 +3401,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
 
        } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
           SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
           SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
           SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
@@ -3520,19 +3461,13 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
              case Panel_1680x1050     :
              case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
              case 100                 : LCDPtr = SiS_Pr->SiS_NoScaleData;          break;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
              case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
              case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
 #endif
              default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
           }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-          xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
-#endif
-#endif
-
           SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
           SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
           SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
@@ -3624,7 +3559,7 @@ SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
 {
    const struct SiS_LVDSDes *PanelDesPtr = NULL;
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
       if(SiS_Pr->ChipType < SIS_315H) {
@@ -3696,7 +3631,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
 
   if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
        /* non-pass 1:1 only, see above */
        if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
@@ -3771,7 +3706,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
      } else {
 
         if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
           switch(SiS_Pr->SiS_LCDResInfo) {
           case Panel_800x600:
              if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
@@ -3816,7 +3751,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
           }
 #endif
         } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
           switch(SiS_Pr->SiS_LCDResInfo) {
           case Panel_1024x768:
           case Panel_1280x1024:
@@ -3844,7 +3779,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
                 if(SiS_Pr->ChipType < SIS_315H) {
                    if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
                 } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
                    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
                    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
                    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
@@ -3866,7 +3801,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
 /*           DISABLE VIDEO BRIDGE            */
 /*********************************************/
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static int
 SiS_HandlePWD(struct SiS_Private *SiS_Pr)
 {
@@ -3891,11 +3826,6 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr)
         ret = 1;
       }
       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-      xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
-#endif
-#endif
    }
 #endif
    return ret;
@@ -3909,7 +3839,7 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr)
 void
 SiS_DisableBridge(struct SiS_Private *SiS_Pr)
 {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned short tempah, pushax=0, modenum;
 #endif
   unsigned short temp=0;
@@ -3920,7 +3850,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
 
        if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300     /* 300 series */
+#ifdef CONFIG_FB_SIS_300          /* 300 series */
 
           if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
              if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
@@ -3953,11 +3883,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
              }
           }
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
         } else {
 
-#ifdef SIS315H    /* 315 series */
+#ifdef CONFIG_FB_SIS_315          /* 315 series */
 
           int didpwd = 0;
           bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
@@ -4081,14 +4011,14 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
 
           }
 
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
 
        }
 
      } else {     /* ============ For 301 ================ */
 
         if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
           if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
              SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
              SiS_PanelDelay(SiS_Pr, 3);
@@ -4111,7 +4041,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
            SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
            SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
        } else {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
            if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
                (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
@@ -4127,7 +4057,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
 
     if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300  /* 300 series */
+#ifdef CONFIG_FB_SIS_300       /* 300 series */
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
           SiS_SetCH700x(SiS_Pr,0x0E,0x09);
@@ -4171,11 +4101,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
           SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
        }
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
     } else {
 
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315       /* 315 series */
 
        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
           /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
@@ -4288,7 +4218,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
           }
         }
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
     }  /* 315 series */
 
@@ -4304,14 +4234,12 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
  * from outside the context of a mode switch!
  * MUST call getVBType before calling this
  */
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 void
 SiS_EnableBridge(struct SiS_Private *SiS_Pr)
 {
   unsigned short temp=0, tempah;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned short temp1, pushax=0;
   bool delaylong = false;
 #endif
@@ -4322,7 +4250,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
 
       if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300     /* 300 series */
+#ifdef CONFIG_FB_SIS_300     /* 300 series */
 
         if(SiS_CRT2IsLCD(SiS_Pr)) {
            if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
@@ -4385,11 +4313,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
         }
 
 
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
 
       } else {
 
-#ifdef SIS315H    /* 315 series */
+#ifdef CONFIG_FB_SIS_315    /* 315 series */
 
 #ifdef SET_EMI
         unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
@@ -4688,7 +4616,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
         }
 
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
 
       }
 
@@ -4739,7 +4667,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
 
     if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300    /* 300 series */
+#ifdef CONFIG_FB_SIS_300    /* 300 series */
 
        if(SiS_CRT2IsLCD(SiS_Pr)) {
          if(SiS_Pr->ChipType == SIS_730) {
@@ -4783,11 +4711,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
          }
        }
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
     } else {
 
-#ifdef SIS315H    /* 315 series */
+#ifdef CONFIG_FB_SIS_315    /* 315 series */
 
        if(!(SiS_IsNotM650orLater(SiS_Pr))) {
          /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
@@ -4881,7 +4809,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
          }
        }
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
     } /* 310 series */
 
@@ -4971,7 +4899,7 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
 
       if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300  /* ---- 300 series --- */
+#ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
 
         if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {                        /* 630 - 301B(-DH) */
 
@@ -5000,11 +4928,11 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
 
         }
 
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
 
       } else {
 
-#ifdef SIS315H  /* ------- 315 series ------ */
+#ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
 
         if(SiS_Pr->SiS_VBType & VB_SISLVDS) {                  /* 315 - LVDS */
 
@@ -5076,13 +5004,13 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
            }
 
          }
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
       }
    }
 }
 
 /* Set CRT2 FIFO on 300/540/630/730 */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static void
 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
 {
@@ -5154,13 +5082,8 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
 
      } else {
 
-#ifdef SIS_LINUX_KERNEL
        pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
        pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
-#else
-       pci50 = pciReadLong(0x00000000, 0x50);
-       pciA0 = pciReadLong(0x00000000, 0xA0);
-#endif
 
         if(SiS_Pr->ChipType == SIS_730) {
 
@@ -5262,7 +5185,7 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
 #endif
 
 /* Set CRT2 FIFO on 315/330 series */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void
 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
 {
@@ -5420,27 +5343,6 @@ SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned sho
 
   temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);                 /* ? */
-
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "%d %d %d %d  %d %d %d %d  (%d %d %d %d)\n",
-       SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
-       SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
-       SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
-
-   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
-       SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
-       SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
-       SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
-   xf86DrvMsg(0, X_INFO, "   0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
-       SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
-       SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
-       SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
-       SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
-   xf86DrvMsg(0, X_INFO, "   0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
-#endif
-#endif
 }
 
 /* Setup panel link
@@ -5455,17 +5357,17 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   unsigned short push2, tempax, tempbx, tempcx, temp;
   unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
   bool islvds = false, issis  = false, chkdclkfirst = false;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   unsigned short crt2crtc = 0;
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned short pushcx;
 #endif
 
   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
      crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 #endif
   } else if(SiS_Pr->UseCustomMode) {
@@ -5473,7 +5375,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
      crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 #endif
   }
@@ -5494,7 +5396,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
      }
   }
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
      if(IS_SIS330) {
         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
@@ -5744,7 +5646,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
 
   if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300      /* 300 series */
+#ifdef CONFIG_FB_SIS_300      /* 300 series */
      tempeax = SiS_Pr->SiS_VGAVDE << 6;
      temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
      tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
@@ -5755,11 +5657,11 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
      temp = (unsigned short)(tempeax & 0x00FF);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);              /* BPLVCFACT */
      tempvcfact = temp;
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
 
   } else {
 
-#ifdef SIS315H  /* 315 series */
+#ifdef CONFIG_FB_SIS_315  /* 315 series */
      tempeax = SiS_Pr->SiS_VGAVDE << 18;
      tempebx = SiS_Pr->SiS_VDE;
      temp = (tempeax % tempebx);
@@ -5845,7 +5747,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   temp = (unsigned short)(tempecx & 0x00FF);
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->ChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
@@ -5863,7 +5765,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   }
 #endif
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
      unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
      unsigned char *trumpdata;
@@ -5899,7 +5801,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
   }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
@@ -5999,7 +5901,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
      }
   }
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 }
 
 /* Set Part 1 */
@@ -6007,12 +5909,12 @@ static void
 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
                unsigned short RefreshRateTableIndex)
 {
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
   unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
 #endif
   unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
   unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned short  tempbl=0;
 #endif
 
@@ -6038,11 +5940,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
          (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
 
      if(SiS_Pr->ChipType < SIS_315H ) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
        SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
 #endif
      } else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
        SiS_SetCRT2FIFO_310(SiS_Pr);
 #endif
      }
@@ -6051,7 +5953,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
      if(SiS_Pr->ChipType < SIS_315H ) {
 
-#ifdef SIS300   /* ------------- 300 series --------------*/
+#ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
 
        temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;                   /* BTVGA2HT 0x08,0x09 */
        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
@@ -6070,11 +5972,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
        bridgeadd = 12;
 
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
 
      } else {
 
-#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
+#ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
 
        tempcx = SiS_Pr->SiS_VGAHT;                               /* BTVGA2HT 0x08,0x09 */
        if(modeflag & HalfDCLK) {
@@ -6125,7 +6027,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
           }
         }
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
      }  /* 315/330 series */
 
@@ -6256,7 +6158,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
      if(SiS_Pr->ChipType < SIS_315H) {
 
-#ifdef SIS300  /* ---------- 300 series -------------- */
+#ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
 
        if(SiS_Pr->SiS_VBType & VB_SISVB) {
           temp = 0x20;
@@ -6310,11 +6212,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
 
-#endif  /* SIS300 */
+#endif  /* CONFIG_FB_SIS_300 */
 
      } else {
 
-#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
+#ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
 
        if(SiS_Pr->ChipType < SIS_661) {
 
@@ -6349,7 +6251,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        if(modeflag & HalfDCLK)       tempax |= 0x40;
        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
 
-#endif  /* SIS315H */
+#endif  /* CONFIG_FB_SIS_315 */
 
      }
 
@@ -6381,7 +6283,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 /*         SET PART 2 REGISTER GROUP         */
 /*********************************************/
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static unsigned char *
 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
 {
@@ -6478,7 +6380,7 @@ SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned sh
 }
 #endif
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static void
 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
 {
@@ -6690,7 +6592,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
   unsigned int   longtemp, PhaseIndex;
   bool           newtvphase;
   const unsigned char *TimingPoint;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   unsigned short resindex, CRT2Index;
   const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
 
@@ -7069,7 +6971,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
                                                &CRT2Index, &resindex)) {
       switch(CRT2Index) {
@@ -7130,12 +7032,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
     /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
-#endif
-#endif
-
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);     /* lcdvdes  */
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);     /* lcdvdee  */
 
@@ -7184,12 +7080,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        tempbx = SiS_Pr->CVSyncStart;
     }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
-#endif
-#endif
-
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);         /* lcdvrs */
 
     temp = (tempbx >> 4) & 0xF0;
@@ -7201,15 +7091,9 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        temp |= (SiS_Pr->CVSyncEnd & 0x0f);
     }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
-#endif
-#endif
-
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
     SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
 #endif
 
@@ -7245,12 +7129,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        tempax >>= 1;
     }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
-#endif
-#endif
-
     tempbx += bridgeoffset;
 
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);         /* lcdhdee */
@@ -7276,12 +7154,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        tempbx += bridgeoffset;
     }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
-#endif
-#endif
-
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);         /* lcdhrs */
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
 
@@ -7300,20 +7172,14 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
        tempbx += bridgeoffset;
     }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
-#endif
-#endif
-
     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);         /* lcdhre */
 
     SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
     SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
   } /* CRT2-LCD from table */
 #endif
 }
@@ -7382,7 +7248,7 @@ SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 /*         SET PART 4 REGISTER GROUP         */
 /*********************************************/
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 #if 0
 static void
 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
@@ -8011,7 +7877,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 
       /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
 
@@ -8124,7 +7990,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
       /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 
       unsigned short temp;
 
@@ -8175,7 +8041,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 
 }
 
-#ifdef SIS315H  /* ----------- 315 series only ---------- */
+#ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
 
 void
 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
@@ -8657,7 +8523,7 @@ SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
 bool
 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
 #endif
    unsigned short ModeIdIndex, RefreshRateTableIndex;
@@ -8703,16 +8569,6 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
       SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
    }
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
-  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
-  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
-#endif
-#endif
-
    if(SiS_Pr->SiS_SetFlag & LowModeTests) {
       SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
    }
@@ -8722,12 +8578,12 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
 
         SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
         SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 #endif
         SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
         SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
         SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
 #endif
         SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
@@ -8758,7 +8614,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
            if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
               if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
                  SiS_SetCH701xForLCD(SiS_Pr);
 #endif
               }
@@ -8771,7 +8627,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 
    }
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
    if(SiS_Pr->ChipType < SIS_315H) {
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         if(SiS_Pr->SiS_UseOEM) {
@@ -8794,7 +8650,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
    }
 #endif
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
    if(SiS_Pr->ChipType >= SIS_315H) {
       if(SiS_Pr->SiS_SetFlag & LowModeTests) {
         if(SiS_Pr->ChipType < SIS_661) {
@@ -8873,7 +8729,7 @@ SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
   }
 }
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static unsigned char *
 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
 {
@@ -8923,11 +8779,6 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
      dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
      if(!dataptr) return false;
   }
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
-#endif
-#endif
   return true;
 }
 #endif
@@ -9002,9 +8853,7 @@ SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
   SiS_SetChReg(SiS_Pr, reg, val, 0);
 }
 
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 void
 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
 {
@@ -9091,9 +8940,7 @@ SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
 
 /* Read from Chrontel 70xx */
 /* Parameter is [Register no (S7-S0)] */
-#ifdef SIS_LINUX_KERNEL
 static
-#endif
 unsigned short
 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
 {
@@ -9114,9 +8961,7 @@ SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
 }
 
 /* Our own DDC functions */
-#ifndef SIS_XORG_XF86
 static
-#endif
 unsigned short
 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
                 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
@@ -9224,12 +9069,6 @@ SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
 
     SiS_SetupDDCN(SiS_Pr);
 
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
-               SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
-#endif
-#endif
     return 0;
 }
 
@@ -9292,11 +9131,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
     SiS_SetSwitchDDC2(SiS_Pr);
     if(SiS_PrepareDDC(SiS_Pr)) {
          SiS_SetStop(SiS_Pr);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-         xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
-#endif
-#endif
          return 0xFFFF;
     }
     mask = 0xf0;
@@ -9310,11 +9144,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
        } else {
            failed = true;
           ret = 0xFFFF;
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-           xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
-#endif
-#endif
        }
     }
     if(!failed) {
@@ -9324,11 +9153,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
        if(temp == value) ret = 0;
        else {
           ret = 0xFFFF;
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-          xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
-#endif
-#endif
           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
              if(temp == 0x30) ret = 0;
           }
@@ -9338,9 +9162,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
     return ret;
 }
 
-#ifndef SIS_XORG_XF86
 static
-#endif
 unsigned short
 SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
 {
@@ -9357,9 +9179,7 @@ SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
    return flag;
 }
 
-#ifndef SIS_XORG_XF86
 static
-#endif
 unsigned short
 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
 {
@@ -9606,11 +9426,6 @@ SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
     temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
   if (!watchdog) {
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
-#endif
-#endif
        return 0xFFFF;
   }
   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
@@ -9641,7 +9456,7 @@ SiS_CheckACK(struct SiS_Private *SiS_Pr)
 
 /* =============== SiS 315/330 O.E.M. ================= */
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 
 static unsigned short
 GetRAMDACromptr(struct SiS_Private *SiS_Pr)
@@ -10829,7 +10644,7 @@ SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
 
 /*  =================  SiS 300 O.E.M. ================== */
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 
 static void
 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
index 51d99222375dd9034c94c5a66eba731f60299e05..e1fd31d0fddff00eb5a08fac8f7850c3de47d249 100644 (file)
 #ifndef  _INIT301_H_
 #define  _INIT301_H_
 
-#include "osdef.h"
 #include "initdef.h"
 
-#ifdef SIS_XORG_XF86
-#include "sis.h"
-#include "sis_regs.h"
-#endif
-
-#ifdef SIS_LINUX_KERNEL
 #include "vgatypes.h"
 #include "vstruct.h"
 #ifdef SIS_CP
@@ -72,7 +65,6 @@
 #include <linux/fb.h>
 #include "sis.h"
 #include <video/sisfb.h>
-#endif
 
 static const unsigned char SiS_YPbPrTable[3][64] = {
   {
@@ -237,7 +229,7 @@ static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */
     0xFF,0xFF,
 };
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 /* 661 et al LCD data structure (2.03.00) */
 static const unsigned char SiS_LCDStruct661[] = {
     /* 1024x768 */
@@ -279,7 +271,7 @@ static const unsigned char SiS_LCDStruct661[] = {
 };
 #endif
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static unsigned char SiS300_TrumpionData[14][80] = {
   { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
     0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
@@ -356,9 +348,6 @@ static unsigned char SiS300_TrumpionData[14][80] = {
 #endif
 
 void           SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void           SiS_LockCRT2(struct SiS_Private *SiS_Pr);
-#endif
 void           SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
 unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
 void           SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
@@ -375,9 +364,6 @@ unsigned short      SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo
                        unsigned short RefreshRateTableIndex);
 unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
 void           SiS_DisableBridge(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void           SiS_EnableBridge(struct SiS_Private *SiS_Pr);
-#endif
 bool           SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
 void           SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
 void           SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
@@ -386,13 +372,9 @@ void               SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned cha
 unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
 void           SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
 unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
-#ifndef SIS_LINUX_KERNEL
-void           SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
-unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax);
-#endif
 void           SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
                        unsigned char orval,unsigned short andval);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void    SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
 static void    SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
 static void    SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
@@ -401,7 +383,7 @@ void                SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
 void           SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
 #endif /* 315 */
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static  bool   SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
 void           SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
 #endif
@@ -412,21 +394,12 @@ unsigned short    SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, i
                        unsigned short adaptnum, unsigned short DDCdatatype,
                        unsigned char *buffer, unsigned int VBFlags2);
 
-#ifdef SIS_XORG_XF86
-unsigned short         SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
-                               int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
-                               bool checkcr32, unsigned int VBFlags2);
-unsigned short         SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
-unsigned short         SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
-                               unsigned char *buffer);
-#else
 static unsigned short  SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
                                int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
                                bool checkcr32, unsigned int VBFlags2);
 static unsigned short  SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
 static unsigned short  SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
                                unsigned char *buffer);
-#endif
 static void            SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
 static unsigned short  SiS_SetStart(struct SiS_Private *SiS_Pr);
 static unsigned short  SiS_SetStop(struct SiS_Private *SiS_Pr);
@@ -441,13 +414,13 @@ static unsigned short     SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
 static void            SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
 static unsigned short  SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
 
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 static void            SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
                                unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
 static void            SetOEMLCDData2(struct SiS_Private *SiS_Pr,
                                unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
 #endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
 static void            SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
                                unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
 static void            SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
@@ -482,15 +455,13 @@ extern void               SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short M
 extern void            SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
 extern unsigned short  SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
 extern unsigned short  SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
 extern void            SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
                                unsigned short *tempcl);
 extern unsigned short  SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
 extern unsigned short  SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
-#ifdef SIS_LINUX_KERNEL
 extern unsigned int    sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
 extern unsigned int    sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
 #endif
-#endif
 
 #endif
index 99c04a4855d13671925301f1f219a2d991160f86..9dec64da401593097b4432e6bf846187ca864ddc 100644 (file)
@@ -25,7 +25,6 @@
  * Author:     Thomas Winischhofer <thomas@winischhofer.net>
  */
 
-#include "osdef.h"
 #include "initdef.h"
 #include "vgatypes.h"
 #include "vstruct.h"
@@ -59,7 +58,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
 
     if(rateindex > 0) rateindex--;
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
     switch(ModeNo) {
     case 0x5a: ModeNo = 0x50; break;
     case 0x5b: ModeNo = 0x56;
@@ -103,7 +102,7 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
 
     if(rateindex > 0) rateindex--;
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
     switch(ModeNo) {
        case 0x5a: ModeNo = 0x50; break;
        case 0x5b: ModeNo = 0x56;
@@ -187,7 +186,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht
 
     if(rateindex > 0) rateindex--;
 
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
     switch(ModeNo) {
        case 0x5a: ModeNo = 0x50; break;
        case 0x5b: ModeNo = 0x56;
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
deleted file mode 100644 (file)
index 6ff8f98..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $XFree86$ */
-/* $XdotOrg$ */
-/*
- * OS depending defines
- *
- * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
- *
- * If distributed as part of the Linux kernel, the following license terms
- * apply:
- *
- * * 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 named License,
- * * or any later version.
- * *
- * * This program is distributed in the hope that it will be useful,
- * * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * * GNU General Public License for more details.
- * *
- * * You should have received a copy of the GNU General Public License
- * * along with this program; if not, write to the Free Software
- * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
- *
- * Otherwise, the following license terms apply:
- *
- * * Redistribution and use in source and binary forms, with or without
- * * modification, are permitted provided that the following conditions
- * * are met:
- * * 1) Redistributions of source code must retain the above copyright
- * *    notice, this list of conditions and the following disclaimer.
- * * 2) Redistributions in binary form must reproduce the above copyright
- * *    notice, this list of conditions and the following disclaimer in the
- * *    documentation and/or other materials provided with the distribution.
- * * 3) The name of the author may not be used to endorse or promote products
- * *    derived from this software without specific prior written permission.
- * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author:     Thomas Winischhofer <thomas@winischhofer.net>
- *             Silicon Integrated Systems, Inc. (used by permission)
- *
- */
-
-#ifndef _SIS_OSDEF_H_
-#define _SIS_OSDEF_H_
-
-/* The choices are: */
-#define SIS_LINUX_KERNEL               /* Linux kernel framebuffer */
-#undef  SIS_XORG_XF86                  /* XFree86/X.org */
-
-#ifdef OutPortByte
-#undef OutPortByte
-#endif
-
-#ifdef OutPortWord
-#undef OutPortWord
-#endif
-
-#ifdef OutPortLong
-#undef OutPortLong
-#endif
-
-#ifdef InPortByte
-#undef InPortByte
-#endif
-
-#ifdef InPortWord
-#undef InPortWord
-#endif
-
-#ifdef InPortLong
-#undef InPortLong
-#endif
-
-/**********************************************************************/
-/*  LINUX KERNEL                                                      */
-/**********************************************************************/
-
-#ifdef SIS_LINUX_KERNEL
-
-#ifdef CONFIG_FB_SIS_300
-#define SIS300
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-#define SIS315H
-#endif
-
-#if !defined(SIS300) && !defined(SIS315H)
-#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
-#warning sisfb will not work!
-#endif
-
-#define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p))
-#define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p))
-#define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p))
-#define InPortByte(p)    inb((SISIOADDRESS)(p))
-#define InPortWord(p)    inw((SISIOADDRESS)(p))
-#define InPortLong(p)    inl((SISIOADDRESS)(p))
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
-
-#endif /* LINUX_KERNEL */
-
-/**********************************************************************/
-/*  XFree86/X.org                                                    */
-/**********************************************************************/
-
-#ifdef SIS_XORG_XF86
-
-#define SIS300
-#define SIS315H
-
-#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
-#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
-#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
-#define InPortByte(p)    inSISREG((IOADDRESS)(p))
-#define InPortWord(p)    inSISREGW((IOADDRESS)(p))
-#define InPortLong(p)    inSISREGL((IOADDRESS)(p))
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-
-#endif /* XF86 */
-
-#endif  /* _OSDEF_H_ */
index 7c5710e3fb567272dc0952778bef930c8f2ba70b..80d89d37c414acbb52f38811cd134ade73a32fd2 100644 (file)
@@ -24,7 +24,6 @@
 #ifndef _SIS_H_
 #define _SIS_H_
 
-#include "osdef.h"
 #include <video/sisfb.h>
 
 #include "vgatypes.h"
index 3dde12b0ab06420c58b0e6a41fc5f23350b28a75..7e3370f115b6cdba3259b9a5bfd516cc10b3709f 100644 (file)
 #include "sis.h"
 #include "sis_main.h"
 
+#if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315)
+#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
+#warning sisfb will not work!
+#endif
+
 static void sisfb_handle_command(struct sis_video_info *ivideo,
                                 struct sisfb_cmd *sisfb_command);
 
@@ -4114,14 +4119,6 @@ sisfb_find_rom(struct pci_dev *pdev)
                        if(sisfb_check_rom(rom_base, ivideo)) {
 
                                if((myrombase = vmalloc(65536))) {
-
-                                       /* Work around bug in pci/rom.c: Folks forgot to check
-                                        * whether the size retrieved from the BIOS image eventually
-                                        * is larger than the mapped size
-                                        */
-                                       if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize)
-                                               romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-
                                        memcpy_fromio(myrombase, rom_base,
                                                        (romsize > 65536) ? 65536 : romsize);
                                }
@@ -4155,23 +4152,6 @@ sisfb_find_rom(struct pci_dev *pdev)
 
         }
 
-#else
-
-       pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp);
-       pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
-                       (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
-
-       rom_base = ioremap(ivideo->video_base, 65536);
-       if(rom_base) {
-               if(sisfb_check_rom(rom_base, ivideo)) {
-                       if((myrombase = vmalloc(65536)))
-                               memcpy_fromio(myrombase, rom_base, 65536);
-               }
-               iounmap(rom_base);
-       }
-
-       pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
-
 #endif
 
        return myrombase;
index 81a22eaabfde0f43abced33a8c4a0cd998acdc0d..12c0dfaf251876baf61b54ce5fe848e73151d371 100644 (file)
 
 #define SISIOMEMTYPE
 
-#ifdef SIS_LINUX_KERNEL
 typedef unsigned long SISIOADDRESS;
 #include <linux/types.h>  /* Need __iomem */
 #undef SISIOMEMTYPE
 #define SISIOMEMTYPE __iomem
-#endif
-
-#ifdef SIS_XORG_XF86
-#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
-typedef unsigned long IOADDRESS;
-typedef unsigned long SISIOADDRESS;
-#else
-typedef IOADDRESS SISIOADDRESS;
-#endif
-#endif
 
 typedef enum _SIS_CHIP_TYPE {
     SIS_VGALegacy = 0,
index bef4aae388d0fb98305c6dd2d9143cd7c862a491..ea94d214dcff575d4d1945518287c462852c5ac3 100644 (file)
@@ -233,24 +233,15 @@ struct SiS_Private
 {
        unsigned char                   ChipType;
        unsigned char                   ChipRevision;
-#ifdef SIS_XORG_XF86
-       PCITAG                          PciTag;
-#endif
-#ifdef SIS_LINUX_KERNEL
        void                            *ivideo;
-#endif
        unsigned char                   *VirtualRomBase;
        bool                            UseROM;
-#ifdef SIS_LINUX_KERNEL
        unsigned char SISIOMEMTYPE      *VideoMemoryAddress;
        unsigned int                    VideoMemorySize;
-#endif
        SISIOADDRESS                    IOAddress;
        SISIOADDRESS                    IOAddress2;  /* For dual chip XGI volari */
 
-#ifdef SIS_LINUX_KERNEL
        SISIOADDRESS                    RelIO;
-#endif
        SISIOADDRESS                    SiS_P3c4;
        SISIOADDRESS                    SiS_P3d4;
        SISIOADDRESS                    SiS_P3c0;
@@ -280,9 +271,6 @@ struct SiS_Private
        unsigned short                  SiS_IF_DEF_FSTN;
        unsigned short                  SiS_SysFlags;
        unsigned char                   SiS_VGAINFO;
-#ifdef SIS_XORG_XF86
-       unsigned short                  SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
-#endif
        bool                            SiS_UseROM;
        bool                            SiS_ROMNew;
        bool                            SiS_XGIROM;
index 3a43ebf83a49d6b869339e8f94da1f097141cb07..efb35aa8309abe0397bc8f1c7fd8f88da6ded96d 100644 (file)
@@ -9,19 +9,19 @@ static ssize_t device_show(struct device *_d,
                           struct device_attribute *attr, char *buf)
 {
        struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
-       return sprintf(buf, "%hu", dev->id.device);
+       return sprintf(buf, "0x%04x\n", dev->id.device);
 }
 static ssize_t vendor_show(struct device *_d,
                           struct device_attribute *attr, char *buf)
 {
        struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
-       return sprintf(buf, "%hu", dev->id.vendor);
+       return sprintf(buf, "0x%04x\n", dev->id.vendor);
 }
 static ssize_t status_show(struct device *_d,
                           struct device_attribute *attr, char *buf)
 {
        struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
-       return sprintf(buf, "0x%08x", dev->config->get_status(dev));
+       return sprintf(buf, "0x%08x\n", dev->config->get_status(dev));
 }
 static ssize_t modalias_show(struct device *_d,
                             struct device_attribute *attr, char *buf)
index 1475ed6b575fd7a9984380b9e0841ac5f019a306..cc2f73e03475b620053765b373c8b1a39fc08762 100644 (file)
@@ -230,9 +230,6 @@ add_head:
        pr_debug("Added buffer head %i to %p\n", head, vq);
        END_USE(vq);
 
-       /* If we're indirect, we can fit many (assuming not OOM). */
-       if (vq->indirect)
-               return vq->num_free ? vq->vring.num : 0;
        return vq->num_free;
 }
 EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
index 4a291045ebac16696cda5539a824a1207def3d33..a5ad77ef4266f22b166d8d86a5484aec5094178f 100644 (file)
@@ -558,6 +558,9 @@ config IT8712F_WDT
          This is the driver for the built-in watchdog timer on the IT8712F
          Super I/0 chipset used on many motherboards.
 
+         If the driver does not work, then make sure that the game port in
+         the BIOS is enabled.
+
          To compile this driver as a module, choose M here: the
          module will be called it8712f_wdt.
 
index a1debc89356b0c0c0f4d01b839b5bc0dfbfefb36..3c5045a206ddbded9e82fbb9db41fa5fa50c178d 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
@@ -220,14 +219,6 @@ static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
        }
 }
 
-static int bcm63xx_wdt_notify_sys(struct notifier_block *this,
-                               unsigned long code, void *unused)
-{
-       if (code == SYS_DOWN || code == SYS_HALT)
-               bcm63xx_wdt_pause();
-       return NOTIFY_DONE;
-}
-
 static const struct file_operations bcm63xx_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
@@ -243,12 +234,8 @@ static struct miscdevice bcm63xx_wdt_miscdev = {
        .fops   = &bcm63xx_wdt_fops,
 };
 
-static struct notifier_block bcm63xx_wdt_notifier = {
-       .notifier_call = bcm63xx_wdt_notify_sys,
-};
 
-
-static int bcm63xx_wdt_probe(struct platform_device *pdev)
+static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev)
 {
        int ret;
        struct resource *r;
@@ -280,16 +267,10 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
                        wdt_time);
        }
 
-       ret = register_reboot_notifier(&bcm63xx_wdt_notifier);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register reboot_notifier\n");
-               goto unregister_timer;
-       }
-
        ret = misc_register(&bcm63xx_wdt_miscdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to register watchdog device\n");
-               goto unregister_reboot_notifier;
+               goto unregister_timer;
        }
 
        dev_info(&pdev->dev, " started, timer margin: %d sec\n",
@@ -297,8 +278,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
 
        return 0;
 
-unregister_reboot_notifier:
-       unregister_reboot_notifier(&bcm63xx_wdt_notifier);
 unregister_timer:
        bcm63xx_timer_unregister(TIMER_WDT_ID);
 unmap:
@@ -306,25 +285,28 @@ unmap:
        return ret;
 }
 
-static int bcm63xx_wdt_remove(struct platform_device *pdev)
+static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev)
 {
        if (!nowayout)
                bcm63xx_wdt_pause();
 
        misc_deregister(&bcm63xx_wdt_miscdev);
-
-       iounmap(bcm63xx_wdt_device.regs);
-
-       unregister_reboot_notifier(&bcm63xx_wdt_notifier);
        bcm63xx_timer_unregister(TIMER_WDT_ID);
-
+       iounmap(bcm63xx_wdt_device.regs);
        return 0;
 }
 
+static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
+{
+       bcm63xx_wdt_pause();
+}
+
 static struct platform_driver bcm63xx_wdt = {
        .probe  = bcm63xx_wdt_probe,
-       .remove = bcm63xx_wdt_remove,
+       .remove = __devexit_p(bcm63xx_wdt_remove),
+       .shutdown = bcm63xx_wdt_shutdown,
        .driver = {
+               .owner = THIS_MODULE,
                .name = "bcm63xx-wdt",
        }
 };
index 9c21d19043a63980372d032ceee5d2933e3a591f..f6bd6f10fcece63c04aa106ca84b54f8684c7896 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
+#include <linux/fs.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
index f7e90fe47b71fb823620ed06496370cfcf6b3c30..b8838d2c67a63bae588a7a06edbe0fb4c796f822 100644 (file)
@@ -32,6 +32,7 @@
  *     document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
  *     document number 320066-003, 320257-008: EP80597 (IICH)
  *     document number TBD                   : Cougar Point (CPT)
+ *     document number TBD                   : Patsburg (PBG)
  */
 
 /*
@@ -146,7 +147,8 @@ enum iTCO_chipsets {
        TCO_CPT29,      /* Cougar Point */
        TCO_CPT30,      /* Cougar Point */
        TCO_CPT31,      /* Cougar Point */
-       TCO_PBG,        /* Patsburg */
+       TCO_PBG1,       /* Patsburg */
+       TCO_PBG2,       /* Patsburg */
 };
 
 static struct {
@@ -235,6 +237,7 @@ static struct {
        {"Cougar Point", 2},
        {"Cougar Point", 2},
        {"Patsburg", 2},
+       {"Patsburg", 2},
        {NULL, 0}
 };
 
@@ -350,7 +353,8 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
        { ITCO_PCI_DEVICE(0x1c5d,                               TCO_CPT29)},
        { ITCO_PCI_DEVICE(0x1c5e,                               TCO_CPT30)},
        { ITCO_PCI_DEVICE(0x1c5f,                               TCO_CPT31)},
-       { ITCO_PCI_DEVICE(0x1d40,                               TCO_PBG)},
+       { ITCO_PCI_DEVICE(0x1d40,                               TCO_PBG1)},
+       { ITCO_PCI_DEVICE(0x1d41,                               TCO_PBG2)},
        { 0, },                 /* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
index eb8a78d77d9d2a7fb70f81ac54ae902e6b29204d..533a199e7a3f94911ef9665ab5e1789c63bef6d2 100644 (file)
@@ -8,9 +8,12 @@ obj-$(CONFIG_BLOCK)            += biomerge.o
 obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
 obj-$(CONFIG_XEN_XENCOMM)      += xencomm.o
 obj-$(CONFIG_XEN_BALLOON)      += balloon.o
-obj-$(CONFIG_XEN_DEV_EVTCHN)   += evtchn.o
+obj-$(CONFIG_XEN_DEV_EVTCHN)   += xen-evtchn.o
 obj-$(CONFIG_XENFS)            += xenfs/
 obj-$(CONFIG_XEN_SYS_HYPERVISOR)       += sys-hypervisor.o
 obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
 obj-$(CONFIG_SWIOTLB_XEN)      += swiotlb-xen.o
 obj-$(CONFIG_XEN_DOM0)         += pci.o
+
+xen-evtchn-y                   := evtchn.o
+
index 500290b150bb526cf27b9f5e82d9a08b160a2d91..43f9f02c7db0671668343fc19bed043fbbe61fad 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
+#include <asm/e820.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
@@ -119,7 +120,7 @@ static void scrub_page(struct page *page)
 }
 
 /* balloon_append: add the given page to the balloon. */
-static void balloon_append(struct page *page)
+static void __balloon_append(struct page *page)
 {
        /* Lowmem is re-populated first, so highmem pages go at list tail. */
        if (PageHighMem(page)) {
@@ -130,7 +131,11 @@ static void balloon_append(struct page *page)
                list_add(&page->lru, &ballooned_pages);
                balloon_stats.balloon_low++;
        }
+}
 
+static void balloon_append(struct page *page)
+{
+       __balloon_append(page);
        totalram_pages--;
 }
 
@@ -191,7 +196,7 @@ static unsigned long current_target(void)
 
 static int increase_reservation(unsigned long nr_pages)
 {
-       unsigned long  pfn, i, flags;
+       unsigned long  pfn, i;
        struct page   *page;
        long           rc;
        struct xen_memory_reservation reservation = {
@@ -203,8 +208,6 @@ static int increase_reservation(unsigned long nr_pages)
        if (nr_pages > ARRAY_SIZE(frame_list))
                nr_pages = ARRAY_SIZE(frame_list);
 
-       spin_lock_irqsave(&xen_reservation_lock, flags);
-
        page = balloon_first_page();
        for (i = 0; i < nr_pages; i++) {
                BUG_ON(page == NULL);
@@ -247,14 +250,12 @@ static int increase_reservation(unsigned long nr_pages)
        balloon_stats.current_pages += rc;
 
  out:
-       spin_unlock_irqrestore(&xen_reservation_lock, flags);
-
        return rc < 0 ? rc : rc != nr_pages;
 }
 
 static int decrease_reservation(unsigned long nr_pages)
 {
-       unsigned long  pfn, i, flags;
+       unsigned long  pfn, i;
        struct page   *page;
        int            need_sleep = 0;
        int ret;
@@ -292,8 +293,6 @@ static int decrease_reservation(unsigned long nr_pages)
        kmap_flush_unused();
        flush_tlb_all();
 
-       spin_lock_irqsave(&xen_reservation_lock, flags);
-
        /* No more mappings: invalidate P2M and add to balloon. */
        for (i = 0; i < nr_pages; i++) {
                pfn = mfn_to_pfn(frame_list[i]);
@@ -308,8 +307,6 @@ static int decrease_reservation(unsigned long nr_pages)
 
        balloon_stats.current_pages -= nr_pages;
 
-       spin_unlock_irqrestore(&xen_reservation_lock, flags);
-
        return need_sleep;
 }
 
@@ -395,7 +392,7 @@ static struct notifier_block xenstore_notifier;
 
 static int __init balloon_init(void)
 {
-       unsigned long pfn;
+       unsigned long pfn, extra_pfn_end;
        struct page *page;
 
        if (!xen_pv_domain())
@@ -415,11 +412,24 @@ static int __init balloon_init(void)
 
        register_balloon(&balloon_sysdev);
 
-       /* Initialise the balloon with excess memory space. */
-       for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
+       /*
+        * Initialise the balloon with excess memory space.  We need
+        * to make sure we don't add memory which doesn't exist or
+        * logically exist.  The E820 map can be trimmed to be smaller
+        * than the amount of physical memory due to the mem= command
+        * line parameter.  And if this is a 32-bit non-HIGHMEM kernel
+        * on a system with memory which requires highmem to access,
+        * don't try to use it.
+        */
+       extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
+                           (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
+       for (pfn = PFN_UP(xen_extra_mem_start);
+            pfn < extra_pfn_end;
+            pfn++) {
                page = pfn_to_page(pfn);
-               if (!PageReserved(page))
-                       balloon_append(page);
+               /* totalram_pages doesn't include the boot-time
+                  balloon extension, so don't subtract from it. */
+               __balloon_append(page);
        }
 
        target_watch.callback = watch_target;
index 321a0c8346e581bc3504ac0891b7b4883d98589c..31af0ac31a98bffc310cfb79bcaa2d7e03393e81 100644 (file)
@@ -105,7 +105,6 @@ struct irq_info
 
 static struct irq_info *irq_info;
 static int *pirq_to_irq;
-static int nr_pirqs;
 
 static int *evtchn_to_irq;
 struct cpu_evtchn_s {
@@ -278,17 +277,17 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
        cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu));
 #endif
 
-       __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq)));
-       __set_bit(chn, cpu_evtchn_mask(cpu));
+       clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq)));
+       set_bit(chn, cpu_evtchn_mask(cpu));
 
        irq_info[irq].cpu = cpu;
 }
 
 static void init_evtchn_cpu_bindings(void)
 {
+       int i;
 #ifdef CONFIG_SMP
        struct irq_desc *desc;
-       int i;
 
        /* By default all event channels notify CPU#0. */
        for_each_irq_desc(i, desc) {
@@ -296,7 +295,10 @@ static void init_evtchn_cpu_bindings(void)
        }
 #endif
 
-       memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s));
+       for_each_possible_cpu(i)
+               memset(cpu_evtchn_mask(i),
+                      (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s));
+
 }
 
 static inline void clear_evtchn(int port)
@@ -382,12 +384,17 @@ static int get_nr_hw_irqs(void)
        return ret;
 }
 
-/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
- * succeeded otherwise nr_pirqs won't hold the right value */
-static int find_unbound_pirq(void)
+static int find_unbound_pirq(int type)
 {
-       int i;
-       for (i = nr_pirqs-1; i >= 0; i--) {
+       int rc, i;
+       struct physdev_get_free_pirq op_get_free_pirq;
+       op_get_free_pirq.type = type;
+
+       rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
+       if (!rc)
+               return op_get_free_pirq.pirq;
+
+       for (i = 0; i < nr_irqs; i++) {
                if (pirq_to_irq[i] < 0)
                        return i;
        }
@@ -420,7 +427,7 @@ static int find_unbound_irq(void)
        if (irq == start)
                goto no_irqs;
 
-       res = irq_alloc_desc_at(irq, 0);
+       res = irq_alloc_desc_at(irq, -1);
 
        if (WARN_ON(res != irq))
                return -1;
@@ -608,10 +615,10 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
 
        spin_lock(&irq_mapping_update_lock);
 
-       if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
+       if ((pirq > nr_irqs) || (gsi > nr_irqs)) {
                printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
-                       pirq > nr_pirqs ? "nr_pirqs" :"",
-                       gsi > nr_irqs ? "nr_irqs" : "");
+                       pirq > nr_irqs ? "pirq" :"",
+                       gsi > nr_irqs ? "gsi" : "");
                goto out;
        }
 
@@ -627,7 +634,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
        if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
                                xen_pv_domain())) {
                irq = gsi;
-               irq_alloc_desc_at(irq, 0);
+               irq_alloc_desc_at(irq, -1);
        } else
                irq = find_unbound_irq();
 
@@ -661,17 +668,21 @@ out:
 #include <linux/msi.h>
 #include "../pci/msi.h"
 
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc)
 {
        spin_lock(&irq_mapping_update_lock);
 
-       *irq = find_unbound_irq();
-       if (*irq == -1)
-               goto out;
+       if (alloc & XEN_ALLOC_IRQ) {
+               *irq = find_unbound_irq();
+               if (*irq == -1)
+                       goto out;
+       }
 
-       *pirq = find_unbound_pirq();
-       if (*pirq == -1)
-               goto out;
+       if (alloc & XEN_ALLOC_PIRQ) {
+               *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
+               if (*pirq == -1)
+                       goto out;
+       }
 
        set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
                                      handle_level_irq, name);
@@ -752,13 +763,14 @@ int xen_destroy_irq(int irq)
                goto out;
 
        if (xen_initial_domain()) {
-               unmap_irq.pirq = info->u.pirq.gsi;
+               unmap_irq.pirq = info->u.pirq.pirq;
                unmap_irq.domid = DOMID_SELF;
                rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
                if (rc) {
                        printk(KERN_WARNING "unmap irq failed %d\n", rc);
                        goto out;
                }
+               pirq_to_irq[info->u.pirq.pirq] = -1;
        }
        irq_info[irq] = mk_unbound_info();
 
@@ -779,6 +791,11 @@ int xen_gsi_from_irq(unsigned irq)
        return gsi_from_irq(irq);
 }
 
+int xen_irq_from_pirq(unsigned pirq)
+{
+       return pirq_to_irq[pirq];
+}
+
 int bind_evtchn_to_irq(unsigned int evtchn)
 {
        int irq;
@@ -1276,6 +1293,42 @@ static int retrigger_dynirq(unsigned int irq)
        return ret;
 }
 
+static void restore_cpu_pirqs(void)
+{
+       int pirq, rc, irq, gsi;
+       struct physdev_map_pirq map_irq;
+
+       for (pirq = 0; pirq < nr_irqs; pirq++) {
+               irq = pirq_to_irq[pirq];
+               if (irq == -1)
+                       continue;
+
+               /* save/restore of PT devices doesn't work, so at this point the
+                * only devices present are GSI based emulated devices */
+               gsi = gsi_from_irq(irq);
+               if (!gsi)
+                       continue;
+
+               map_irq.domid = DOMID_SELF;
+               map_irq.type = MAP_PIRQ_TYPE_GSI;
+               map_irq.index = gsi;
+               map_irq.pirq = pirq;
+
+               rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+               if (rc) {
+                       printk(KERN_WARNING "xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n",
+                                       gsi, irq, pirq, rc);
+                       irq_info[irq] = mk_unbound_info();
+                       pirq_to_irq[pirq] = -1;
+                       continue;
+               }
+
+               printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+               startup_pirq(irq);
+       }
+}
+
 static void restore_cpu_virqs(unsigned int cpu)
 {
        struct evtchn_bind_virq bind_virq;
@@ -1419,6 +1472,8 @@ void xen_irq_resume(void)
 
                unmask_evtchn(evtchn);
        }
+
+       restore_cpu_pirqs();
 }
 
 static struct irq_chip xen_dynamic_chip __read_mostly = {
@@ -1503,26 +1558,17 @@ void xen_callback_vector(void) {}
 
 void __init xen_init_IRQ(void)
 {
-       int i, rc;
-       struct physdev_nr_pirqs op_nr_pirqs;
+       int i;
 
        cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
                                    GFP_KERNEL);
        irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
 
-       rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
-       if (rc < 0) {
-               nr_pirqs = nr_irqs;
-               if (rc != -ENOSYS)
-                       printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
-       } else {
-               if (xen_pv_domain() && !xen_initial_domain())
-                       nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
-               else
-                       nr_pirqs = op_nr_pirqs.nr_pirqs;
-       }
-       pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
-       for (i = 0; i < nr_pirqs; i++)
+       /* We are using nr_irqs as the maximum number of pirq available but
+        * that number is actually chosen by Xen and we don't know exactly
+        * what it is. Be careful choosing high pirq numbers. */
+       pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+       for (i = 0; i < nr_irqs; i++)
                pirq_to_irq[i] = -1;
 
        evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
index fec6ba3c08a8e885d663ce3ac9c8b031ff971273..ef11daf0cafe9f086f3944b42fd32ff48811f4b2 100644 (file)
@@ -69,20 +69,51 @@ struct per_user_data {
        const char *name;
 };
 
-/* Who's bound to each port? */
-static struct per_user_data *port_user[NR_EVENT_CHANNELS];
+/*
+ * Who's bound to each port?  This is logically an array of struct
+ * per_user_data *, but we encode the current enabled-state in bit 0.
+ */
+static unsigned long *port_user;
 static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */
 
-irqreturn_t evtchn_interrupt(int irq, void *data)
+static inline struct per_user_data *get_port_user(unsigned port)
+{
+       return (struct per_user_data *)(port_user[port] & ~1);
+}
+
+static inline void set_port_user(unsigned port, struct per_user_data *u)
+{
+       port_user[port] = (unsigned long)u;
+}
+
+static inline bool get_port_enabled(unsigned port)
+{
+       return port_user[port] & 1;
+}
+
+static inline void set_port_enabled(unsigned port, bool enabled)
+{
+       if (enabled)
+               port_user[port] |= 1;
+       else
+               port_user[port] &= ~1;
+}
+
+static irqreturn_t evtchn_interrupt(int irq, void *data)
 {
        unsigned int port = (unsigned long)data;
        struct per_user_data *u;
 
        spin_lock(&port_user_lock);
 
-       u = port_user[port];
+       u = get_port_user(port);
+
+       WARN(!get_port_enabled(port),
+            "Interrupt for port %d, but apparently not enabled; per-user %p\n",
+            port, u);
 
        disable_irq_nosync(irq);
+       set_port_enabled(port, false);
 
        if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
                u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
@@ -92,9 +123,8 @@ irqreturn_t evtchn_interrupt(int irq, void *data)
                        kill_fasync(&u->evtchn_async_queue,
                                    SIGIO, POLL_IN);
                }
-       } else {
+       } else
                u->ring_overflow = 1;
-       }
 
        spin_unlock(&port_user_lock);
 
@@ -198,9 +228,18 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
                goto out;
 
        spin_lock_irq(&port_user_lock);
-       for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
-               if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
-                       enable_irq(irq_from_evtchn(kbuf[i]));
+
+       for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) {
+               unsigned port = kbuf[i];
+
+               if (port < NR_EVENT_CHANNELS &&
+                   get_port_user(port) == u &&
+                   !get_port_enabled(port)) {
+                       set_port_enabled(port, true);
+                       enable_irq(irq_from_evtchn(port));
+               }
+       }
+
        spin_unlock_irq(&port_user_lock);
 
        rc = count;
@@ -222,8 +261,9 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
         * interrupt handler yet, and our caller has already
         * serialized bind operations.)
         */
-       BUG_ON(port_user[port] != NULL);
-       port_user[port] = u;
+       BUG_ON(get_port_user(port) != NULL);
+       set_port_user(port, u);
+       set_port_enabled(port, true); /* start enabled */
 
        rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
                                       u->name, (void *)(unsigned long)port);
@@ -239,10 +279,7 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port)
 
        unbind_from_irqhandler(irq, (void *)(unsigned long)port);
 
-       /* make sure we unbind the irq handler before clearing the port */
-       barrier();
-
-       port_user[port] = NULL;
+       set_port_user(port, NULL);
 }
 
 static long evtchn_ioctl(struct file *file,
@@ -333,15 +370,17 @@ static long evtchn_ioctl(struct file *file,
                spin_lock_irq(&port_user_lock);
 
                rc = -ENOTCONN;
-               if (port_user[unbind.port] != u) {
+               if (get_port_user(unbind.port) != u) {
                        spin_unlock_irq(&port_user_lock);
                        break;
                }
 
-               evtchn_unbind_from_user(u, unbind.port);
+               disable_irq(irq_from_evtchn(unbind.port));
 
                spin_unlock_irq(&port_user_lock);
 
+               evtchn_unbind_from_user(u, unbind.port);
+
                rc = 0;
                break;
        }
@@ -355,7 +394,7 @@ static long evtchn_ioctl(struct file *file,
 
                if (notify.port >= NR_EVENT_CHANNELS) {
                        rc = -EINVAL;
-               } else if (port_user[notify.port] != u) {
+               } else if (get_port_user(notify.port) != u) {
                        rc = -ENOTCONN;
                } else {
                        notify_remote_via_evtchn(notify.port);
@@ -431,7 +470,7 @@ static int evtchn_open(struct inode *inode, struct file *filp)
 
        filp->private_data = u;
 
-       return 0;
+       return nonseekable_open(inode, filp);;
 }
 
 static int evtchn_release(struct inode *inode, struct file *filp)
@@ -444,14 +483,21 @@ static int evtchn_release(struct inode *inode, struct file *filp)
        free_page((unsigned long)u->ring);
 
        for (i = 0; i < NR_EVENT_CHANNELS; i++) {
-               if (port_user[i] != u)
+               if (get_port_user(i) != u)
                        continue;
 
-               evtchn_unbind_from_user(port_user[i], i);
+               disable_irq(irq_from_evtchn(i));
        }
 
        spin_unlock_irq(&port_user_lock);
 
+       for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+               if (get_port_user(i) != u)
+                       continue;
+
+               evtchn_unbind_from_user(get_port_user(i), i);
+       }
+
        kfree(u->name);
        kfree(u);
 
@@ -467,12 +513,12 @@ static const struct file_operations evtchn_fops = {
        .fasync  = evtchn_fasync,
        .open    = evtchn_open,
        .release = evtchn_release,
-       .llseek = noop_llseek,
+       .llseek  = no_llseek,
 };
 
 static struct miscdevice evtchn_miscdev = {
        .minor        = MISC_DYNAMIC_MINOR,
-       .name         = "evtchn",
+       .name         = "xen/evtchn",
        .fops         = &evtchn_fops,
 };
 static int __init evtchn_init(void)
@@ -482,8 +528,11 @@ static int __init evtchn_init(void)
        if (!xen_domain())
                return -ENODEV;
 
+       port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL);
+       if (port_user == NULL)
+               return -ENOMEM;
+
        spin_lock_init(&port_user_lock);
-       memset(port_user, 0, sizeof(port_user));
 
        /* Create '/dev/misc/evtchn'. */
        err = misc_register(&evtchn_miscdev);
@@ -499,6 +548,9 @@ static int __init evtchn_init(void)
 
 static void __exit evtchn_cleanup(void)
 {
+       kfree(port_user);
+       port_user = NULL;
+
        misc_deregister(&evtchn_miscdev);
 }
 
index ef9c7db52077c6d58c0d5f036be0a03bd771dffa..db8c4c4ac88086bf7c2e9d1dfa946da399e91b27 100644 (file)
@@ -49,6 +49,7 @@ static int xen_hvm_suspend(void *data)
 
        if (!*cancelled) {
                xen_irq_resume();
+               xen_console_resume();
                xen_timer_resume();
        }
 
index f80be7f6eb95265d223a40f2166bc29b6fb8d3c6..dbd3b16fd1317adc9f1fa8afedfd0e6d3fc53400 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mman.h>
 #include <linux/uaccess.h>
 #include <linux/swap.h>
-#include <linux/smp_lock.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
@@ -266,9 +265,7 @@ static int mmap_return_errors(void *data, void *state)
        xen_pfn_t *mfnp = data;
        struct mmap_batch_state *st = state;
 
-       put_user(*mfnp, st->user++);
-
-       return 0;
+       return put_user(*mfnp, st->user++);
 }
 
 static struct vm_operations_struct privcmd_vm_ops;
@@ -323,10 +320,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
        up_write(&mm->mmap_sem);
 
        if (state.err > 0) {
-               ret = 0;
-
                state.user = m.arr;
-               traverse_pages(m.num, sizeof(xen_pfn_t),
+               ret = traverse_pages(m.num, sizeof(xen_pfn_t),
                               &pagelist,
                               mmap_return_errors, &state);
        }
@@ -384,8 +379,9 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -ENOSYS;
 
-       /* DONTCOPY is essential for Xen as copy_page_range is broken. */
-       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+       /* DONTCOPY is essential for Xen because copy_page_range doesn't know
+        * how to recreate these mappings */
+       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
        vma->vm_ops = &privcmd_vm_ops;
        vma->vm_private_data = NULL;
 
index f6339d11d59cbdebc8d558f552cc199175003e05..1aa3897198462112a3bc1db479986653cf0a716f 100644 (file)
@@ -12,8 +12,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/magic.h>
-#include <linux/mm.h>
-#include <linux/backing-dev.h>
 
 #include <xen/xen.h>
 
 MODULE_DESCRIPTION("Xen filesystem");
 MODULE_LICENSE("GPL");
 
-static int xenfs_set_page_dirty(struct page *page)
-{
-       return !TestSetPageDirty(page);
-}
-
-static const struct address_space_operations xenfs_aops = {
-       .set_page_dirty = xenfs_set_page_dirty,
-};
-
-static struct backing_dev_info xenfs_backing_dev_info = {
-       .ra_pages       = 0,    /* No readahead */
-       .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
-};
-
 static struct inode *xenfs_make_inode(struct super_block *sb, int mode)
 {
        struct inode *ret = new_inode(sb);
 
        if (ret) {
                ret->i_mode = mode;
-               ret->i_mapping->a_ops = &xenfs_aops;
-               ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info;
                ret->i_uid = ret->i_gid = 0;
                ret->i_blocks = 0;
                ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
@@ -121,9 +103,9 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
        return rc;
 }
 
-static int xenfs_mount(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data)
+static struct dentry *xenfs_mount(struct file_system_type *fs_type,
+                                 int flags, const char *dev_name,
+                                 void *data)
 {
        return mount_single(fs_type, flags, data, xenfs_fill_super);
 }
@@ -137,25 +119,11 @@ static struct file_system_type xenfs_type = {
 
 static int __init xenfs_init(void)
 {
-       int err;
-       if (!xen_domain()) {
-               printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n");
-               return 0;
-       }
-
-       err = register_filesystem(&xenfs_type);
-       if (err) {
-               printk(KERN_ERR "xenfs: Unable to register filesystem!\n");
-               goto out;
-       }
-
-       err = bdi_init(&xenfs_backing_dev_info);
-       if (err)
-               unregister_filesystem(&xenfs_type);
-
- out:
+       if (xen_domain())
+               return register_filesystem(&xenfs_type);
 
-       return err;
+       printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n");
+       return 0;
 }
 
 static void __exit xenfs_exit(void)
index cafc504542927751f25650ce2ea2639dcdbc8bef..e0c84725d3e94e05a33482349dc90f45f59099a9 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/amigahw.h>
 #include <asm/setup.h>
index d5c1401f00310979b117f9eaaecc0e026fd11c93..d34896cfb19f1512855d907b9d4c8c6b4cac2e09 100644 (file)
@@ -980,19 +980,11 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp,
        }
 }
 
-static DEFINE_MUTEX(autofs4_ioctl_mutex);
-
 static long autofs4_root_ioctl(struct file *filp,
                               unsigned int cmd, unsigned long arg)
 {
-       long ret;
        struct inode *inode = filp->f_dentry->d_inode;
-
-       mutex_lock(&autofs4_ioctl_mutex);
-       ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
-       mutex_unlock(&autofs4_ioctl_mutex);
-
-       return ret;
+       return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
 }
 
 #ifdef CONFIG_COMPAT
@@ -1002,13 +994,11 @@ static long autofs4_root_compat_ioctl(struct file *filp,
        struct inode *inode = filp->f_path.dentry->d_inode;
        int ret;
 
-       mutex_lock(&autofs4_ioctl_mutex);
        if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
        else
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
                        (unsigned long)compat_ptr(arg));
-       mutex_unlock(&autofs4_ioctl_mutex);
 
        return ret;
 }
index 06e8ff12b97c8fa74d4b2eb05c900801b3adb150..4230252fd6895c97cb81541741f9e8e584e04322 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/major.h>
-#include <linux/smp_lock.h>
 #include <linux/device_cgroup.h>
 #include <linux/highmem.h>
 #include <linux/blkdev.h>
index 7845d1f7d1d927f79ac45c09af730963a426b8e5..b50bc4bd5c5677e1f77926d30449e4bc32794e21 100644 (file)
@@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root,
 static struct bio *compressed_bio_alloc(struct block_device *bdev,
                                        u64 first_byte, gfp_t gfp_flags)
 {
-       struct bio *bio;
        int nr_vecs;
 
        nr_vecs = bio_get_nr_vecs(bdev);
-       bio = bio_alloc(gfp_flags, nr_vecs);
-
-       if (bio == NULL && (current->flags & PF_MEMALLOC)) {
-               while (!bio && (nr_vecs /= 2))
-                       bio = bio_alloc(gfp_flags, nr_vecs);
-       }
-
-       if (bio) {
-               bio->bi_size = 0;
-               bio->bi_bdev = bdev;
-               bio->bi_sector = first_byte >> 9;
-       }
-       return bio;
+       return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags);
 }
 
 static int check_compressed_csum(struct inode *inode,
index 8db9234f6b418db0cc1f99afa6876f369116a1b8..af52f6d7a4d8ed8269f0cf835ab09c14d9a5c8a1 100644 (file)
@@ -808,9 +808,9 @@ struct btrfs_block_group_cache {
        int extents_thresh;
        int free_extents;
        int total_bitmaps;
-       int ro:1;
-       int dirty:1;
-       int iref:1;
+       unsigned int ro:1;
+       unsigned int dirty:1;
+       unsigned int iref:1;
 
        int disk_cache_state;
 
index fb827d0d71811baff7aec0f49a2584f7eedbaf84..c547cca26a266e962bbb760c0616e0846439d81d 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/freezer.h>
 #include <linux/crc32c.h>
 #include <linux/slab.h>
+#include <linux/migrate.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
        ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
                                             btrfs_header_generation(eb));
        BUG_ON(ret);
+       WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN));
+
        found_start = btrfs_header_bytenr(eb);
        if (found_start != start) {
                WARN_ON(1);
@@ -693,6 +696,29 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                   __btree_submit_bio_done);
 }
 
+static int btree_migratepage(struct address_space *mapping,
+                       struct page *newpage, struct page *page)
+{
+       /*
+        * we can't safely write a btree page from here,
+        * we haven't done the locking hook
+        */
+       if (PageDirty(page))
+               return -EAGAIN;
+       /*
+        * Buffers may be managed in a filesystem specific way.
+        * We must have no buffers or drop them.
+        */
+       if (page_has_private(page) &&
+           !try_to_release_page(page, GFP_KERNEL))
+               return -EAGAIN;
+#ifdef CONFIG_MIGRATION
+       return migrate_page(mapping, newpage, page);
+#else
+       return -ENOSYS;
+#endif
+}
+
 static int btree_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct extent_io_tree *tree;
@@ -707,8 +733,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
        }
 
        redirty_page_for_writepage(wbc, page);
-       eb = btrfs_find_tree_block(root, page_offset(page),
-                                     PAGE_CACHE_SIZE);
+       eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE);
        WARN_ON(!eb);
 
        was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
@@ -799,6 +824,9 @@ static const struct address_space_operations btree_aops = {
        .releasepage    = btree_releasepage,
        .invalidatepage = btree_invalidatepage,
        .sync_page      = block_sync_page,
+#ifdef CONFIG_MIGRATION
+       .migratepage    = btree_migratepage,
+#endif
 };
 
 int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
@@ -1538,10 +1566,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
                                                 GFP_NOFS);
        struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
                                                 GFP_NOFS);
-       struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root),
-                                              GFP_NOFS);
-       struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info),
-                                               GFP_NOFS);
+       struct btrfs_root *tree_root = btrfs_sb(sb);
+       struct btrfs_fs_info *fs_info = tree_root->fs_info;
        struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
                                                GFP_NOFS);
        struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
index 951ef09b82f4abb02d220f259d78c16af180a210..6f0444473594a05df9b08b532c0d9e40f62bdca7 100644 (file)
@@ -232,9 +232,85 @@ fail:
        return ERR_PTR(ret);
 }
 
+static int btrfs_get_name(struct dentry *parent, char *name,
+                         struct dentry *child)
+{
+       struct inode *inode = child->d_inode;
+       struct inode *dir = parent->d_inode;
+       struct btrfs_path *path;
+       struct btrfs_root *root = BTRFS_I(dir)->root;
+       struct btrfs_inode_ref *iref;
+       struct btrfs_root_ref *rref;
+       struct extent_buffer *leaf;
+       unsigned long name_ptr;
+       struct btrfs_key key;
+       int name_len;
+       int ret;
+
+       if (!dir || !inode)
+               return -EINVAL;
+
+       if (!S_ISDIR(dir->i_mode))
+               return -EINVAL;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+               key.objectid = BTRFS_I(inode)->root->root_key.objectid;
+               key.type = BTRFS_ROOT_BACKREF_KEY;
+               key.offset = (u64)-1;
+               root = root->fs_info->tree_root;
+       } else {
+               key.objectid = inode->i_ino;
+               key.offset = dir->i_ino;
+               key.type = BTRFS_INODE_REF_KEY;
+       }
+
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0) {
+               btrfs_free_path(path);
+               return ret;
+       } else if (ret > 0) {
+               if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+                       path->slots[0]--;
+               } else {
+                       btrfs_free_path(path);
+                       return -ENOENT;
+               }
+       }
+       leaf = path->nodes[0];
+
+       if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
+              rref = btrfs_item_ptr(leaf, path->slots[0],
+                                    struct btrfs_root_ref);
+              name_ptr = (unsigned long)(rref + 1);
+              name_len = btrfs_root_ref_name_len(leaf, rref);
+       } else {
+               iref = btrfs_item_ptr(leaf, path->slots[0],
+                                     struct btrfs_inode_ref);
+               name_ptr = (unsigned long)(iref + 1);
+               name_len = btrfs_inode_ref_name_len(leaf, iref);
+       }
+
+       read_extent_buffer(leaf, name, name_ptr, name_len);
+       btrfs_free_path(path);
+
+       /*
+        * have to add the null termination to make sure that reconnect_path
+        * gets the right len for strlen
+        */
+       name[name_len] = '\0';
+
+       return 0;
+}
+
 const struct export_operations btrfs_export_ops = {
        .encode_fh      = btrfs_encode_fh,
        .fh_to_dentry   = btrfs_fh_to_dentry,
        .fh_to_parent   = btrfs_fh_to_parent,
        .get_parent     = btrfs_get_parent,
+       .get_name       = btrfs_get_name,
 };
index 0c097f3aec418564e25df5b7e0af8d9a81a79d1d..bcd59c7dfb574def82517a80affe6a9ddf756a92 100644 (file)
@@ -3412,7 +3412,7 @@ again:
         * our reservation.
         */
        if (unused <= space_info->total_bytes) {
-               unused -= space_info->total_bytes;
+               unused = space_info->total_bytes - unused;
                if (unused >= num_bytes) {
                        if (!reserved)
                                space_info->bytes_reserved += orig_bytes;
index eac10e3260a982e24149957981c3f2a7be792d09..3e86b9f3650736a6e77e5468197815ac5646fb83 100644 (file)
@@ -1828,9 +1828,9 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err)
        bio_put(bio);
 }
 
-static struct bio *
-extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
-                gfp_t gfp_flags)
+struct bio *
+btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
+               gfp_t gfp_flags)
 {
        struct bio *bio;
 
@@ -1919,7 +1919,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
        else
                nr = bio_get_nr_vecs(bdev);
 
-       bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
+       bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
 
        bio_add_page(bio, page, page_size, offset);
        bio->bi_end_io = end_io_func;
@@ -2901,21 +2901,53 @@ out:
 int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                __u64 start, __u64 len, get_extent_t *get_extent)
 {
-       int ret;
+       int ret = 0;
        u64 off = start;
        u64 max = start + len;
        u32 flags = 0;
+       u32 found_type;
+       u64 last;
        u64 disko = 0;
+       struct btrfs_key found_key;
        struct extent_map *em = NULL;
        struct extent_state *cached_state = NULL;
+       struct btrfs_path *path;
+       struct btrfs_file_extent_item *item;
        int end = 0;
        u64 em_start = 0, em_len = 0;
        unsigned long emflags;
-       ret = 0;
+       int hole = 0;
 
        if (len == 0)
                return -EINVAL;
 
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root,
+                                      path, inode->i_ino, -1, 0);
+       if (ret < 0) {
+               btrfs_free_path(path);
+               return ret;
+       }
+       WARN_ON(!ret);
+       path->slots[0]--;
+       item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+                             struct btrfs_file_extent_item);
+       btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]);
+       found_type = btrfs_key_type(&found_key);
+
+       /* No extents, just return */
+       if (found_key.objectid != inode->i_ino ||
+           found_type != BTRFS_EXTENT_DATA_KEY) {
+               btrfs_free_path(path);
+               return 0;
+       }
+       last = found_key.offset;
+       btrfs_free_path(path);
+
        lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
                         &cached_state, GFP_NOFS);
        em = get_extent(inode, NULL, 0, off, max - off, 0);
@@ -2925,11 +2957,18 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                ret = PTR_ERR(em);
                goto out;
        }
+
        while (!end) {
+               hole = 0;
                off = em->start + em->len;
                if (off >= max)
                        end = 1;
 
+               if (em->block_start == EXTENT_MAP_HOLE) {
+                       hole = 1;
+                       goto next;
+               }
+
                em_start = em->start;
                em_len = em->len;
 
@@ -2939,8 +2978,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                if (em->block_start == EXTENT_MAP_LAST_BYTE) {
                        end = 1;
                        flags |= FIEMAP_EXTENT_LAST;
-               } else if (em->block_start == EXTENT_MAP_HOLE) {
-                       flags |= FIEMAP_EXTENT_UNWRITTEN;
                } else if (em->block_start == EXTENT_MAP_INLINE) {
                        flags |= (FIEMAP_EXTENT_DATA_INLINE |
                                  FIEMAP_EXTENT_NOT_ALIGNED);
@@ -2953,10 +2990,10 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
                        flags |= FIEMAP_EXTENT_ENCODED;
 
+next:
                emflags = em->flags;
                free_extent_map(em);
                em = NULL;
-
                if (!end) {
                        em = get_extent(inode, NULL, 0, off, max - off, 0);
                        if (!em)
@@ -2967,15 +3004,23 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        }
                        emflags = em->flags;
                }
+
                if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) {
                        flags |= FIEMAP_EXTENT_LAST;
                        end = 1;
                }
 
-               ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
-                                       em_len, flags);
-               if (ret)
-                       goto out_free;
+               if (em_start == last) {
+                       flags |= FIEMAP_EXTENT_LAST;
+                       end = 1;
+               }
+
+               if (!hole) {
+                       ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
+                                               em_len, flags);
+                       if (ret)
+                               goto out_free;
+               }
        }
 out_free:
        free_extent_map(em);
@@ -3836,8 +3881,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
 
        spin_lock(&tree->buffer_lock);
        eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
-       if (!eb)
-               goto out;
+       if (!eb) {
+               spin_unlock(&tree->buffer_lock);
+               return ret;
+       }
 
        if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
                ret = 0;
index 1c6d4f342ef7e8089ac6f17e3e6ed40e83722e45..4183c8178f01a846f7da0f016f74db5402de12c7 100644 (file)
@@ -310,4 +310,7 @@ int extent_clear_unlock_delalloc(struct inode *inode,
                                struct extent_io_tree *tree,
                                u64 start, u64 end, struct page *locked_page,
                                unsigned long op);
+struct bio *
+btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
+               gfp_t gfp_flags);
 #endif
index e354c33df0824592bb9356be4987fd0ddfbbdc71..c1faded5fca03a7cbcb509908cfdf3cc8362ce1f 100644 (file)
@@ -1047,8 +1047,14 @@ out:
 
                if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
                        trans = btrfs_start_transaction(root, 0);
+                       if (IS_ERR(trans)) {
+                               num_written = PTR_ERR(trans);
+                               goto done;
+                       }
+                       mutex_lock(&inode->i_mutex);
                        ret = btrfs_log_dentry_safe(trans, root,
                                                    file->f_dentry);
+                       mutex_unlock(&inode->i_mutex);
                        if (ret == 0) {
                                ret = btrfs_sync_log(trans, root);
                                if (ret == 0)
@@ -1067,6 +1073,7 @@ out:
                             (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
                }
        }
+done:
        current->backing_dev_info = NULL;
        return num_written ? num_written : err;
 }
index 558cac2dfa547032637bd0a746153eba46d73f8d..8039390bd6a6f7bc1d1026d917dcaeb93aa067e6 100644 (file)
@@ -4501,6 +4501,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        BTRFS_I(inode)->index_cnt = 2;
        BTRFS_I(inode)->root = root;
        BTRFS_I(inode)->generation = trans->transid;
+       inode->i_generation = BTRFS_I(inode)->generation;
        btrfs_set_inode_space_info(root, inode);
 
        if (mode & S_IFDIR)
@@ -4622,12 +4623,12 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
 }
 
 static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
-                           struct dentry *dentry, struct inode *inode,
-                           int backref, u64 index)
+                           struct inode *dir, struct dentry *dentry,
+                           struct inode *inode, int backref, u64 index)
 {
-       int err = btrfs_add_link(trans, dentry->d_parent->d_inode,
-                                inode, dentry->d_name.name,
-                                dentry->d_name.len, backref, index);
+       int err = btrfs_add_link(trans, dir, inode,
+                                dentry->d_name.name, dentry->d_name.len,
+                                backref, index);
        if (!err) {
                d_instantiate(dentry, inode);
                return 0;
@@ -4668,8 +4669,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, mode, &index);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
@@ -4682,7 +4682,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -4730,10 +4730,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino,
-                               objectid, BTRFS_I(dir)->block_group, mode,
-                               &index);
+                               dentry->d_name.len, dir->i_ino, objectid,
+                               BTRFS_I(dir)->block_group, mode, &index);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_unlock;
@@ -4745,7 +4743,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -4787,6 +4785,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                return -EPERM;
 
        btrfs_inc_nlink(inode);
+       inode->i_ctime = CURRENT_TIME;
 
        err = btrfs_set_inode_index(dir, &index);
        if (err)
@@ -4805,15 +4804,17 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        btrfs_set_trans_block_group(trans, dir);
        ihold(inode);
 
-       err = btrfs_add_nondir(trans, dentry, inode, 1, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
 
        if (err) {
                drop_inode = 1;
        } else {
+               struct dentry *parent = dget_parent(dentry);
                btrfs_update_inode_block_group(trans, dir);
                err = btrfs_update_inode(trans, root, inode);
                BUG_ON(err);
-               btrfs_log_new_name(trans, inode, NULL, dentry->d_parent);
+               btrfs_log_new_name(trans, inode, NULL, parent);
+               dput(parent);
        }
 
        nr = trans->blocks_used;
@@ -4853,8 +4854,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, S_IFDIR | mode,
                                &index);
        if (IS_ERR(inode)) {
@@ -4877,9 +4877,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        if (err)
                goto out_fail;
 
-       err = btrfs_add_link(trans, dentry->d_parent->d_inode,
-                                inode, dentry->d_name.name,
-                                dentry->d_name.len, 0, index);
+       err = btrfs_add_link(trans, dir, inode, dentry->d_name.name,
+                            dentry->d_name.len, 0, index);
        if (err)
                goto out_fail;
 
@@ -5535,13 +5534,21 @@ struct btrfs_dio_private {
        u64 bytes;
        u32 *csums;
        void *private;
+
+       /* number of bios pending for this dio */
+       atomic_t pending_bios;
+
+       /* IO errors */
+       int errors;
+
+       struct bio *orig_bio;
 };
 
 static void btrfs_endio_direct_read(struct bio *bio, int err)
 {
+       struct btrfs_dio_private *dip = bio->bi_private;
        struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
        struct bio_vec *bvec = bio->bi_io_vec;
-       struct btrfs_dio_private *dip = bio->bi_private;
        struct inode *inode = dip->inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 start;
@@ -5595,15 +5602,18 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
        struct btrfs_trans_handle *trans;
        struct btrfs_ordered_extent *ordered = NULL;
        struct extent_state *cached_state = NULL;
+       u64 ordered_offset = dip->logical_offset;
+       u64 ordered_bytes = dip->bytes;
        int ret;
 
        if (err)
                goto out_done;
-
-       ret = btrfs_dec_test_ordered_pending(inode, &ordered,
-                                            dip->logical_offset, dip->bytes);
+again:
+       ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
+                                                  &ordered_offset,
+                                                  ordered_bytes);
        if (!ret)
-               goto out_done;
+               goto out_test;
 
        BUG_ON(!ordered);
 
@@ -5663,8 +5673,20 @@ out_unlock:
 out:
        btrfs_delalloc_release_metadata(inode, ordered->len);
        btrfs_end_transaction(trans, root);
+       ordered_offset = ordered->file_offset + ordered->len;
        btrfs_put_ordered_extent(ordered);
        btrfs_put_ordered_extent(ordered);
+
+out_test:
+       /*
+        * our bio might span multiple ordered extents.  If we haven't
+        * completed the accounting for the whole dio, go back and try again
+        */
+       if (ordered_offset < dip->logical_offset + dip->bytes) {
+               ordered_bytes = dip->logical_offset + dip->bytes -
+                       ordered_offset;
+               goto again;
+       }
 out_done:
        bio->bi_private = dip->private;
 
@@ -5684,6 +5706,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
        return 0;
 }
 
+static void btrfs_end_dio_bio(struct bio *bio, int err)
+{
+       struct btrfs_dio_private *dip = bio->bi_private;
+
+       if (err) {
+               printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu "
+                     "disk_bytenr %lu len %u err no %d\n",
+                     dip->inode->i_ino, bio->bi_rw, bio->bi_sector,
+                     bio->bi_size, err);
+               dip->errors = 1;
+
+               /*
+                * before atomic variable goto zero, we must make sure
+                * dip->errors is perceived to be set.
+                */
+               smp_mb__before_atomic_dec();
+       }
+
+       /* if there are more bios still pending for this dio, just exit */
+       if (!atomic_dec_and_test(&dip->pending_bios))
+               goto out;
+
+       if (dip->errors)
+               bio_io_error(dip->orig_bio);
+       else {
+               set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags);
+               bio_endio(dip->orig_bio, 0);
+       }
+out:
+       bio_put(bio);
+}
+
+static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
+                                      u64 first_sector, gfp_t gfp_flags)
+{
+       int nr_vecs = bio_get_nr_vecs(bdev);
+       return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags);
+}
+
+static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
+                                        int rw, u64 file_offset, int skip_sum,
+                                        u32 *csums)
+{
+       int write = rw & REQ_WRITE;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       int ret;
+
+       bio_get(bio);
+       ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
+       if (ret)
+               goto err;
+
+       if (write && !skip_sum) {
+               ret = btrfs_wq_submit_bio(root->fs_info,
+                                  inode, rw, bio, 0, 0,
+                                  file_offset,
+                                  __btrfs_submit_bio_start_direct_io,
+                                  __btrfs_submit_bio_done);
+               goto err;
+       } else if (!skip_sum)
+               btrfs_lookup_bio_sums_dio(root, inode, bio,
+                                         file_offset, csums);
+
+       ret = btrfs_map_bio(root, rw, bio, 0, 1);
+err:
+       bio_put(bio);
+       return ret;
+}
+
+static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
+                                   int skip_sum)
+{
+       struct inode *inode = dip->inode;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
+       struct bio *bio;
+       struct bio *orig_bio = dip->orig_bio;
+       struct bio_vec *bvec = orig_bio->bi_io_vec;
+       u64 start_sector = orig_bio->bi_sector;
+       u64 file_offset = dip->logical_offset;
+       u64 submit_len = 0;
+       u64 map_length;
+       int nr_pages = 0;
+       u32 *csums = dip->csums;
+       int ret = 0;
+
+       bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS);
+       if (!bio)
+               return -ENOMEM;
+       bio->bi_private = dip;
+       bio->bi_end_io = btrfs_end_dio_bio;
+       atomic_inc(&dip->pending_bios);
+
+       map_length = orig_bio->bi_size;
+       ret = btrfs_map_block(map_tree, READ, start_sector << 9,
+                             &map_length, NULL, 0);
+       if (ret) {
+               bio_put(bio);
+               return -EIO;
+       }
+
+       while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) {
+               if (unlikely(map_length < submit_len + bvec->bv_len ||
+                   bio_add_page(bio, bvec->bv_page, bvec->bv_len,
+                                bvec->bv_offset) < bvec->bv_len)) {
+                       /*
+                        * inc the count before we submit the bio so
+                        * we know the end IO handler won't happen before
+                        * we inc the count. Otherwise, the dip might get freed
+                        * before we're done setting it up
+                        */
+                       atomic_inc(&dip->pending_bios);
+                       ret = __btrfs_submit_dio_bio(bio, inode, rw,
+                                                    file_offset, skip_sum,
+                                                    csums);
+                       if (ret) {
+                               bio_put(bio);
+                               atomic_dec(&dip->pending_bios);
+                               goto out_err;
+                       }
+
+                       if (!skip_sum)
+                               csums = csums + nr_pages;
+                       start_sector += submit_len >> 9;
+                       file_offset += submit_len;
+
+                       submit_len = 0;
+                       nr_pages = 0;
+
+                       bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev,
+                                                 start_sector, GFP_NOFS);
+                       if (!bio)
+                               goto out_err;
+                       bio->bi_private = dip;
+                       bio->bi_end_io = btrfs_end_dio_bio;
+
+                       map_length = orig_bio->bi_size;
+                       ret = btrfs_map_block(map_tree, READ, start_sector << 9,
+                                             &map_length, NULL, 0);
+                       if (ret) {
+                               bio_put(bio);
+                               goto out_err;
+                       }
+               } else {
+                       submit_len += bvec->bv_len;
+                       nr_pages ++;
+                       bvec++;
+               }
+       }
+
+       ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum,
+                                    csums);
+       if (!ret)
+               return 0;
+
+       bio_put(bio);
+out_err:
+       dip->errors = 1;
+       /*
+        * before atomic variable goto zero, we must
+        * make sure dip->errors is perceived to be set.
+        */
+       smp_mb__before_atomic_dec();
+       if (atomic_dec_and_test(&dip->pending_bios))
+               bio_io_error(dip->orig_bio);
+
+       /* bio_end_io() will handle error, so we needn't return it */
+       return 0;
+}
+
 static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
                                loff_t file_offset)
 {
@@ -5723,36 +5915,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
 
        dip->disk_bytenr = (u64)bio->bi_sector << 9;
        bio->bi_private = dip;
+       dip->errors = 0;
+       dip->orig_bio = bio;
+       atomic_set(&dip->pending_bios, 0);
 
        if (write)
                bio->bi_end_io = btrfs_endio_direct_write;
        else
                bio->bi_end_io = btrfs_endio_direct_read;
 
-       ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
-       if (ret)
-               goto out_err;
-
-       if (write && !skip_sum) {
-               ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info,
-                                  inode, rw, bio, 0, 0,
-                                  dip->logical_offset,
-                                  __btrfs_submit_bio_start_direct_io,
-                                  __btrfs_submit_bio_done);
-               if (ret)
-                       goto out_err;
+       ret = btrfs_submit_direct_hook(rw, dip, skip_sum);
+       if (!ret)
                return;
-       } else if (!skip_sum)
-               btrfs_lookup_bio_sums_dio(root, inode, bio,
-                                         dip->logical_offset, dip->csums);
-
-       ret = btrfs_map_bio(root, rw, bio, 0, 1);
-       if (ret)
-               goto out_err;
-       return;
-out_err:
-       kfree(dip->csums);
-       kfree(dip);
 free_ordered:
        /*
         * If this is a write, we need to clean up the reserved space and kill
@@ -6607,8 +6781,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        BUG_ON(ret);
 
        if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) {
-               btrfs_log_new_name(trans, old_inode, old_dir,
-                                  new_dentry->d_parent);
+               struct dentry *parent = dget_parent(new_dentry);
+               btrfs_log_new_name(trans, old_inode, old_dir, parent);
+               dput(parent);
                btrfs_end_log_trans(root);
        }
 out_fail:
@@ -6758,8 +6933,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        btrfs_set_trans_block_group(trans, dir);
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
-                               dentry->d_name.len,
-                               dentry->d_parent->d_inode->i_ino, objectid,
+                               dentry->d_name.len, dir->i_ino, objectid,
                                BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO,
                                &index);
        err = PTR_ERR(inode);
@@ -6773,7 +6947,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        }
 
        btrfs_set_trans_block_group(trans, inode);
-       err = btrfs_add_nondir(trans, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
        if (err)
                drop_inode = 1;
        else {
@@ -6844,6 +7018,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_key ins;
        u64 cur_offset = start;
+       u64 i_size;
        int ret = 0;
        bool own_trans = true;
 
@@ -6885,11 +7060,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                    (actual_len > inode->i_size) &&
                    (cur_offset > inode->i_size)) {
                        if (cur_offset > actual_len)
-                               i_size_write(inode, actual_len);
+                               i_size = actual_len;
                        else
-                               i_size_write(inode, cur_offset);
-                       i_size_write(inode, cur_offset);
-                       btrfs_ordered_update_i_size(inode, cur_offset, NULL);
+                               i_size = cur_offset;
+                       i_size_write(inode, i_size);
+                       btrfs_ordered_update_i_size(inode, i_size, NULL);
                }
 
                ret = btrfs_update_inode(trans, root, inode);
@@ -6943,6 +7118,10 @@ static long btrfs_fallocate(struct inode *inode, int mode,
        btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start);
 
        mutex_lock(&inode->i_mutex);
+       ret = inode_newsize_ok(inode, alloc_end);
+       if (ret)
+               goto out;
+
        if (alloc_start > inode->i_size) {
                ret = btrfs_cont_expand(inode, alloc_start);
                if (ret)
@@ -7139,6 +7318,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .getattr        = btrfs_getattr,
        .permission     = btrfs_permission,
        .setxattr       = btrfs_setxattr,
        .getxattr       = btrfs_getxattr,
index 463d91b4dd3a720ece2afb592b2edefca855aaba..f1c9bb4079ed8b3aaf2a01bb5211923f8e231986 100644 (file)
@@ -233,7 +233,8 @@ static noinline int create_subvol(struct btrfs_root *root,
        struct btrfs_inode_item *inode_item;
        struct extent_buffer *leaf;
        struct btrfs_root *new_root;
-       struct inode *dir = dentry->d_parent->d_inode;
+       struct dentry *parent = dget_parent(dentry);
+       struct inode *dir;
        int ret;
        int err;
        u64 objectid;
@@ -242,8 +243,13 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root,
                                       0, &objectid);
-       if (ret)
+       if (ret) {
+               dput(parent);
                return ret;
+       }
+
+       dir = parent->d_inode;
+
        /*
         * 1 - inode item
         * 2 - refs
@@ -251,8 +257,10 @@ static noinline int create_subvol(struct btrfs_root *root,
         * 2 - dir items
         */
        trans = btrfs_start_transaction(root, 6);
-       if (IS_ERR(trans))
+       if (IS_ERR(trans)) {
+               dput(parent);
                return PTR_ERR(trans);
+       }
 
        leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
                                      0, objectid, NULL, 0, 0, 0);
@@ -339,6 +347,7 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
 fail:
+       dput(parent);
        if (async_transid) {
                *async_transid = trans->transid;
                err = btrfs_commit_transaction_async(trans, root, 1);
@@ -354,6 +363,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
                           char *name, int namelen, u64 *async_transid)
 {
        struct inode *inode;
+       struct dentry *parent;
        struct btrfs_pending_snapshot *pending_snapshot;
        struct btrfs_trans_handle *trans;
        int ret;
@@ -396,7 +406,9 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
 
        btrfs_orphan_cleanup(pending_snapshot->snap);
 
-       inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry);
+       parent = dget_parent(dentry);
+       inode = btrfs_lookup_dentry(parent->d_inode, dentry);
+       dput(parent);
        if (IS_ERR(inode)) {
                ret = PTR_ERR(inode);
                goto fail;
@@ -1669,12 +1681,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                olen = len = src->i_size - off;
        /* if we extend to eof, continue to block boundary */
        if (off + len == src->i_size)
-               len = ((src->i_size + bs-1) & ~(bs-1))
-                       - off;
+               len = ALIGN(src->i_size, bs) - off;
 
        /* verify the end result is block aligned */
-       if ((off & (bs-1)) ||
-           ((off + len) & (bs-1)))
+       if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) ||
+           !IS_ALIGNED(destoff, bs))
                goto out_unlock;
 
        /* do any pending delalloc/csum calc on src, one way or
@@ -1874,8 +1885,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                         * but shouldn't round up the file size
                         */
                        endoff = new_key.offset + datal;
-                       if (endoff > off+olen)
-                               endoff = off+olen;
+                       if (endoff > destoff+olen)
+                               endoff = destoff+olen;
                        if (endoff > inode->i_size)
                                btrfs_i_size_write(inode, endoff);
 
index f4621f6deca1d51f91db57ea406c4c7351a7fd5d..ae7737e352c90f7ede523c357f72a92d78c80676 100644 (file)
@@ -248,6 +248,73 @@ int btrfs_add_ordered_sum(struct inode *inode,
        return 0;
 }
 
+/*
+ * this is used to account for finished IO across a given range
+ * of the file.  The IO may span ordered extents.  If
+ * a given ordered_extent is completely done, 1 is returned, otherwise
+ * 0.
+ *
+ * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used
+ * to make sure this function only returns 1 once for a given ordered extent.
+ *
+ * file_offset is updated to one byte past the range that is recorded as
+ * complete.  This allows you to walk forward in the file.
+ */
+int btrfs_dec_test_first_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
+                                  u64 *file_offset, u64 io_size)
+{
+       struct btrfs_ordered_inode_tree *tree;
+       struct rb_node *node;
+       struct btrfs_ordered_extent *entry = NULL;
+       int ret;
+       u64 dec_end;
+       u64 dec_start;
+       u64 to_dec;
+
+       tree = &BTRFS_I(inode)->ordered_tree;
+       spin_lock(&tree->lock);
+       node = tree_search(tree, *file_offset);
+       if (!node) {
+               ret = 1;
+               goto out;
+       }
+
+       entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
+       if (!offset_in_entry(entry, *file_offset)) {
+               ret = 1;
+               goto out;
+       }
+
+       dec_start = max(*file_offset, entry->file_offset);
+       dec_end = min(*file_offset + io_size, entry->file_offset +
+                     entry->len);
+       *file_offset = dec_end;
+       if (dec_start > dec_end) {
+               printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n",
+                      (unsigned long long)dec_start,
+                      (unsigned long long)dec_end);
+       }
+       to_dec = dec_end - dec_start;
+       if (to_dec > entry->bytes_left) {
+               printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n",
+                      (unsigned long long)entry->bytes_left,
+                      (unsigned long long)to_dec);
+       }
+       entry->bytes_left -= to_dec;
+       if (entry->bytes_left == 0)
+               ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
+       else
+               ret = 1;
+out:
+       if (!ret && cached && entry) {
+               *cached = entry;
+               atomic_inc(&entry->refs);
+       }
+       spin_unlock(&tree->lock);
+       return ret == 0;
+}
+
 /*
  * this is used to account for finished IO across a given range
  * of the file.  The IO should not span ordered extents.  If
index 8ac365492a3f4f01ba13aac1bb6f1041a97f3608..61dca83119ddf9a4994fbb107edccb93d3163487 100644 (file)
@@ -141,6 +141,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
 int btrfs_dec_test_ordered_pending(struct inode *inode,
                                   struct btrfs_ordered_extent **cached,
                                   u64 file_offset, u64 io_size);
+int btrfs_dec_test_first_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
+                                  u64 *file_offset, u64 io_size);
 int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
                             u64 start, u64 len, u64 disk_len, int type);
 int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,
index 8299a25ffc8f8313064cbd3e54278e9f5ebbc662..dbb51ea7a13c4b83e46c6c1f03d8d936cf75bed7 100644 (file)
@@ -244,6 +244,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                case Opt_space_cache:
                        printk(KERN_INFO "btrfs: enabling disk space caching\n");
                        btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+                       break;
                case Opt_clear_cache:
                        printk(KERN_INFO "btrfs: force clearing of disk cache\n");
                        btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
@@ -562,12 +563,26 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
 
 static int btrfs_test_super(struct super_block *s, void *data)
 {
-       struct btrfs_fs_devices *test_fs_devices = data;
+       struct btrfs_root *test_root = data;
        struct btrfs_root *root = btrfs_sb(s);
 
-       return root->fs_info->fs_devices == test_fs_devices;
+       /*
+        * If this super block is going away, return false as it
+        * can't match as an existing super block.
+        */
+       if (!atomic_read(&s->s_active))
+               return 0;
+       return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
+}
+
+static int btrfs_set_super(struct super_block *s, void *data)
+{
+       s->s_fs_info = data;
+
+       return set_anon_super(s, data);
 }
 
+
 /*
  * Find a superblock for the given device / mount point.
  *
@@ -581,6 +596,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
        struct super_block *s;
        struct dentry *root;
        struct btrfs_fs_devices *fs_devices = NULL;
+       struct btrfs_root *tree_root = NULL;
+       struct btrfs_fs_info *fs_info = NULL;
        fmode_t mode = FMODE_READ;
        char *subvol_name = NULL;
        u64 subvol_objectid = 0;
@@ -608,8 +625,24 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                goto error_close_devices;
        }
 
+       /*
+        * Setup a dummy root and fs_info for test/set super.  This is because
+        * we don't actually fill this stuff out until open_ctree, but we need
+        * it for searching for existing supers, so this lets us do that and
+        * then open_ctree will properly initialize everything later.
+        */
+       fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
+       tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       if (!fs_info || !tree_root) {
+               error = -ENOMEM;
+               goto error_close_devices;
+       }
+       fs_info->tree_root = tree_root;
+       fs_info->fs_devices = fs_devices;
+       tree_root->fs_info = fs_info;
+
        bdev = fs_devices->latest_bdev;
-       s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
+       s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
        if (IS_ERR(s))
                goto error_s;
 
@@ -675,6 +708,8 @@ error_s:
        error = PTR_ERR(s);
 error_close_devices:
        btrfs_close_devices(fs_devices);
+       kfree(fs_info);
+       kfree(tree_root);
 error_free_subvol_name:
        kfree(subvol_name);
        return ERR_PTR(error);
index 1fffbc017bdfe0451cc2e67ccf5fd85623a12aee..f50e931fc217b978b0bcf1fb54f0d661d3b53562 100644 (file)
@@ -902,6 +902,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct btrfs_root *root = pending->root;
        struct btrfs_root *parent_root;
        struct inode *parent_inode;
+       struct dentry *parent;
        struct dentry *dentry;
        struct extent_buffer *tmp;
        struct extent_buffer *old;
@@ -941,7 +942,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        trans->block_rsv = &pending->block_rsv;
 
        dentry = pending->dentry;
-       parent_inode = dentry->d_parent->d_inode;
+       parent = dget_parent(dentry);
+       parent_inode = parent->d_inode;
        parent_root = BTRFS_I(parent_inode)->root;
        record_root_in_trans(trans, parent_root);
 
@@ -989,6 +991,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                 parent_inode->i_ino, index,
                                 dentry->d_name.name, dentry->d_name.len);
        BUG_ON(ret);
+       dput(parent);
 
        key.offset = (u64)-1;
        pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
index a29f19384a27bc91526d46fb3cbefdbe2bd8a5ce..054744ac571907e4c76a5e35f35b8baba24152e2 100644 (file)
@@ -2869,6 +2869,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        struct btrfs_root *root;
+       struct dentry *old_parent = NULL;
 
        /*
         * for regular files, if its inode is already on disk, we don't
@@ -2910,10 +2911,13 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
                if (IS_ROOT(parent))
                        break;
 
-               parent = parent->d_parent;
+               parent = dget_parent(parent);
+               dput(old_parent);
+               old_parent = parent;
                inode = parent->d_inode;
 
        }
+       dput(old_parent);
 out:
        return ret;
 }
@@ -2945,6 +2949,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
 {
        int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL;
        struct super_block *sb;
+       struct dentry *old_parent = NULL;
        int ret = 0;
        u64 last_committed = root->fs_info->last_trans_committed;
 
@@ -3016,10 +3021,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
                if (IS_ROOT(parent))
                        break;
 
-               parent = parent->d_parent;
+               parent = dget_parent(parent);
+               dput(old_parent);
+               old_parent = parent;
        }
        ret = 0;
 end_trans:
+       dput(old_parent);
        if (ret < 0) {
                BUG_ON(ret != -ENOSPC);
                root->fs_info->last_trans_log_full_commit = trans->transid;
@@ -3039,8 +3047,13 @@ end_no_trans:
 int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root, struct dentry *dentry)
 {
-       return btrfs_log_inode_parent(trans, root, dentry->d_inode,
-                                     dentry->d_parent, 0);
+       struct dentry *parent = dget_parent(dentry);
+       int ret;
+
+       ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0);
+       dput(parent);
+
+       return ret;
 }
 
 /*
index e9c874abc9e1f4a7ec00b68595fdd674a4f1da2e..561438b6a50cd3789b90d54e473562431d528ec8 100644 (file)
@@ -204,7 +204,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
        err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
                                  page->index << PAGE_CACHE_SHIFT, &len,
                                  ci->i_truncate_seq, ci->i_truncate_size,
-                                 &page, 1);
+                                 &page, 1, 0);
        if (err == -ENOENT)
                err = 0;
        if (err < 0) {
@@ -287,7 +287,7 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
        rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
                                 offset, &len,
                                 ci->i_truncate_seq, ci->i_truncate_size,
-                                pages, nr_pages);
+                                pages, nr_pages, 0);
        if (rc == -ENOENT)
                rc = 0;
        if (rc < 0)
@@ -774,7 +774,7 @@ get_more_pages:
                                            snapc, do_sync,
                                            ci->i_truncate_seq,
                                            ci->i_truncate_size,
-                                           &inode->i_mtime, true, 1);
+                                           &inode->i_mtime, true, 1, 0);
                                max_pages = req->r_num_pages;
 
                                alloc_page_vec(fsc, req);
index 98ab13e2b71d9d8ebcbf1715da112d78cb0bac17..60d27bc9eb83d82f61e448031495625e42c752d3 100644 (file)
@@ -1430,8 +1430,8 @@ static int try_nonblocking_invalidate(struct inode *inode)
            invalidating_gen == ci->i_rdcache_gen) {
                /* success. */
                dout("try_nonblocking_invalidate %p success\n", inode);
-               ci->i_rdcache_gen = 0;
-               ci->i_rdcache_revoking = 0;
+               /* save any racing async invalidate some trouble */
+               ci->i_rdcache_revoking = ci->i_rdcache_gen - 1;
                return 0;
        }
        dout("try_nonblocking_invalidate %p failed\n", inode);
@@ -2273,8 +2273,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        int mds = session->s_mds;
-       unsigned seq = le32_to_cpu(grant->seq);
-       unsigned issue_seq = le32_to_cpu(grant->issue_seq);
+       int seq = le32_to_cpu(grant->seq);
        int newcaps = le32_to_cpu(grant->caps);
        int issued, implemented, used, wanted, dirty;
        u64 size = le64_to_cpu(grant->size);
@@ -2286,8 +2285,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        int revoked_rdcache = 0;
        int queue_invalidate = 0;
 
-       dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n",
-            inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps));
+       dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
+            inode, cap, mds, seq, ceph_cap_string(newcaps));
        dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
                inode->i_size);
 
@@ -2383,7 +2382,6 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        }
 
        cap->seq = seq;
-       cap->issue_seq = issue_seq;
 
        /* file layout may have changed */
        ci->i_layout = grant->layout;
@@ -2691,6 +2689,11 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
                     NULL /* no caps context */);
        try_flush_caps(inode, session, NULL);
        up_read(&mdsc->snap_rwsem);
+
+       /* make sure we re-request max_size, if necessary */
+       spin_lock(&inode->i_lock);
+       ci->i_requested_max_size = 0;
+       spin_unlock(&inode->i_lock);
 }
 
 /*
index e0a2dc6fcafcb62266909c5ec71329e58083d1d7..7d447af84ec4861acee8cd82bcecf80a892132b1 100644 (file)
@@ -336,7 +336,10 @@ more:
                if (req->r_reply_info.dir_end) {
                        kfree(fi->last_name);
                        fi->last_name = NULL;
-                       fi->next_offset = 2;
+                       if (ceph_frag_is_rightmost(frag))
+                               fi->next_offset = 2;
+                       else
+                               fi->next_offset = 0;
                } else {
                        rinfo = &req->r_reply_info;
                        err = note_last_dentry(fi,
@@ -355,18 +358,22 @@ more:
                u64 pos = ceph_make_fpos(frag, off);
                struct ceph_mds_reply_inode *in =
                        rinfo->dir_in[off - fi->offset].in;
+               struct ceph_vino vino;
+               ino_t ino;
+
                dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
                     off, off - fi->offset, rinfo->dir_nr, pos,
                     rinfo->dir_dname_len[off - fi->offset],
                     rinfo->dir_dname[off - fi->offset], in);
                BUG_ON(!in);
                ftype = le32_to_cpu(in->mode) >> 12;
+               vino.ino = le64_to_cpu(in->ino);
+               vino.snap = le64_to_cpu(in->snapid);
+               ino = ceph_vino_to_ino(vino);
                if (filldir(dirent,
                            rinfo->dir_dname[off - fi->offset],
                            rinfo->dir_dname_len[off - fi->offset],
-                           pos,
-                           le64_to_cpu(in->ino),
-                           ftype) < 0) {
+                           pos, ino, ftype) < 0) {
                        dout("filldir stopping us...\n");
                        return 0;
                }
@@ -414,6 +421,7 @@ static void reset_readdir(struct ceph_file_info *fi)
                fi->last_readdir = NULL;
        }
        kfree(fi->last_name);
+       fi->last_name = NULL;
        fi->next_offset = 2;  /* compensate for . and .. */
        if (fi->dentry) {
                dput(fi->dentry);
index e77c28cf369059112dd06ee3b7c78c5146f0ffdc..8d79b8912e31e4cb8fcb4961ec1f81d63c3d5070 100644 (file)
@@ -154,11 +154,13 @@ int ceph_open(struct inode *inode, struct file *file)
        }
 
        /*
-        * No need to block if we have any caps.  Update wanted set
+        * No need to block if we have caps on the auth MDS (for
+        * write) or any MDS (for read).  Update wanted set
         * asynchronously.
         */
        spin_lock(&inode->i_lock);
-       if (__ceph_is_any_real_caps(ci)) {
+       if (__ceph_is_any_real_caps(ci) &&
+           (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) {
                int mds_wanted = __ceph_caps_mds_wanted(ci);
                int issued = __ceph_caps_issued(ci, NULL);
 
@@ -280,11 +282,12 @@ int ceph_release(struct inode *inode, struct file *file)
 static int striped_read(struct inode *inode,
                        u64 off, u64 len,
                        struct page **pages, int num_pages,
-                       int *checkeof)
+                       int *checkeof, bool align_to_pages)
 {
        struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_inode_info *ci = ceph_inode(inode);
        u64 pos, this_len;
+       int io_align, page_align;
        int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
        int left, pages_left;
        int read;
@@ -300,14 +303,19 @@ static int striped_read(struct inode *inode,
        page_pos = pages;
        pages_left = num_pages;
        read = 0;
+       io_align = off & ~PAGE_MASK;
 
 more:
+       if (align_to_pages)
+               page_align = (pos - io_align) & ~PAGE_MASK;
+       else
+               page_align = pos & ~PAGE_MASK;
        this_len = left;
        ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode),
                                  &ci->i_layout, pos, &this_len,
                                  ci->i_truncate_seq,
                                  ci->i_truncate_size,
-                                 page_pos, pages_left);
+                                 page_pos, pages_left, page_align);
        hit_stripe = this_len < left;
        was_short = ret >= 0 && ret < this_len;
        if (ret == -ENOENT)
@@ -374,26 +382,25 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
        dout("sync_read on file %p %llu~%u %s\n", file, off, len,
             (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
 
-       if (file->f_flags & O_DIRECT) {
-               pages = ceph_get_direct_page_vector(data, num_pages, off, len);
-
-               /*
-                * flush any page cache pages in this range.  this
-                * will make concurrent normal and O_DIRECT io slow,
-                * but it will at least behave sensibly when they are
-                * in sequence.
-                */
-       } else {
+       if (file->f_flags & O_DIRECT)
+               pages = ceph_get_direct_page_vector(data, num_pages);
+       else
                pages = ceph_alloc_page_vector(num_pages, GFP_NOFS);
-       }
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
+       /*
+        * flush any page cache pages in this range.  this
+        * will make concurrent normal and sync io slow,
+        * but it will at least behave sensibly when they are
+        * in sequence.
+        */
        ret = filemap_write_and_wait(inode->i_mapping);
        if (ret < 0)
                goto done;
 
-       ret = striped_read(inode, off, len, pages, num_pages, checkeof);
+       ret = striped_read(inode, off, len, pages, num_pages, checkeof,
+                          file->f_flags & O_DIRECT);
 
        if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
                ret = ceph_copy_page_vector_to_user(pages, data, off, ret);
@@ -448,6 +455,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        int flags;
        int do_sync = 0;
        int check_caps = 0;
+       int page_align, io_align;
        int ret;
        struct timespec mtime = CURRENT_TIME;
 
@@ -462,6 +470,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        else
                pos = *offset;
 
+       io_align = pos & ~PAGE_MASK;
+
        ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
        if (ret < 0)
                return ret;
@@ -486,20 +496,26 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
         */
 more:
        len = left;
+       if (file->f_flags & O_DIRECT)
+               /* write from beginning of first page, regardless of
+                  io alignment */
+               page_align = (pos - io_align) & ~PAGE_MASK;
+       else
+               page_align = pos & ~PAGE_MASK;
        req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
                                    ceph_vino(inode), pos, &len,
                                    CEPH_OSD_OP_WRITE, flags,
                                    ci->i_snap_realm->cached_context,
                                    do_sync,
                                    ci->i_truncate_seq, ci->i_truncate_size,
-                                   &mtime, false, 2);
+                                   &mtime, false, 2, page_align);
        if (!req)
                return -ENOMEM;
 
        num_pages = calc_pages_for(pos, len);
 
        if (file->f_flags & O_DIRECT) {
-               pages = ceph_get_direct_page_vector(data, num_pages, pos, len);
+               pages = ceph_get_direct_page_vector(data, num_pages);
                if (IS_ERR(pages)) {
                        ret = PTR_ERR(pages);
                        goto out;
index 1d6a45b5a04c696591879d141165627746d6a476..bf1286588f26b3afb039e4036ddb2a469fcad638 100644 (file)
@@ -2,7 +2,6 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
@@ -471,7 +470,9 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 
        if (issued & (CEPH_CAP_FILE_EXCL|
                      CEPH_CAP_FILE_WR|
-                     CEPH_CAP_FILE_BUFFER)) {
+                     CEPH_CAP_FILE_BUFFER|
+                     CEPH_CAP_AUTH_EXCL|
+                     CEPH_CAP_XATTR_EXCL)) {
                if (timespec_compare(ctime, &inode->i_ctime) > 0) {
                        dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
                             inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
@@ -511,7 +512,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
                        warn = 1;
                }
        } else {
-               /* we have no write caps; whatever the MDS says is true */
+               /* we have no write|excl caps; whatever the MDS says is true */
                if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
@@ -567,12 +568,17 @@ static int fill_inode(struct inode *inode,
 
        /*
         * provided version will be odd if inode value is projected,
-        * even if stable.  skip the update if we have a newer info
-        * (e.g., due to inode info racing form multiple MDSs), or if
-        * we are getting projected (unstable) inode info.
+        * even if stable.  skip the update if we have newer stable
+        * info (ours>=theirs, e.g. due to racing mds replies), unless
+        * we are getting projected (unstable) info (in which case the
+        * version is odd, and we want ours>theirs).
+        *   us   them
+        *   2    2     skip
+        *   3    2     skip
+        *   3    3     update
         */
        if (le64_to_cpu(info->version) > 0 &&
-           (ci->i_version & ~1) > le64_to_cpu(info->version))
+           (ci->i_version & ~1) >= le64_to_cpu(info->version))
                goto no_change;
 
        issued = __ceph_caps_issued(ci, &implemented);
@@ -606,7 +612,14 @@ static int fill_inode(struct inode *inode,
                            le32_to_cpu(info->time_warp_seq),
                            &ctime, &mtime, &atime);
 
-       ci->i_max_size = le64_to_cpu(info->max_size);
+       /* only update max_size on auth cap */
+       if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
+           ci->i_max_size != le64_to_cpu(info->max_size)) {
+               dout("max_size %lld -> %llu\n", ci->i_max_size,
+                    le64_to_cpu(info->max_size));
+               ci->i_max_size = le64_to_cpu(info->max_size);
+       }
+
        ci->i_layout = info->layout;
        inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
 
@@ -1055,7 +1068,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                ininfo = rinfo->targeti.in;
                vino.ino = le64_to_cpu(ininfo->ino);
                vino.snap = le64_to_cpu(ininfo->snapid);
-               if (!dn->d_inode) {
+               in = dn->d_inode;
+               if (!in) {
                        in = ceph_get_inode(sb, vino);
                        if (IS_ERR(in)) {
                                pr_err("fill_trace bad get_inode "
@@ -1386,11 +1400,8 @@ static void ceph_invalidate_work(struct work_struct *work)
        spin_lock(&inode->i_lock);
        dout("invalidate_pages %p gen %d revoking %d\n", inode,
             ci->i_rdcache_gen, ci->i_rdcache_revoking);
-       if (ci->i_rdcache_gen == 0 ||
-           ci->i_rdcache_revoking != ci->i_rdcache_gen) {
-               BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen);
+       if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
                /* nevermind! */
-               ci->i_rdcache_revoking = 0;
                spin_unlock(&inode->i_lock);
                goto out;
        }
@@ -1400,15 +1411,16 @@ static void ceph_invalidate_work(struct work_struct *work)
        ceph_invalidate_nondirty_pages(inode->i_mapping);
 
        spin_lock(&inode->i_lock);
-       if (orig_gen == ci->i_rdcache_gen) {
+       if (orig_gen == ci->i_rdcache_gen &&
+           orig_gen == ci->i_rdcache_revoking) {
                dout("invalidate_pages %p gen %d successful\n", inode,
                     ci->i_rdcache_gen);
-               ci->i_rdcache_gen = 0;
-               ci->i_rdcache_revoking = 0;
+               ci->i_rdcache_revoking--;
                check = 1;
        } else {
-               dout("invalidate_pages %p gen %d raced, gen now %d\n",
-                    inode, orig_gen, ci->i_rdcache_gen);
+               dout("invalidate_pages %p gen %d raced, now %d revoking %d\n",
+                    inode, orig_gen, ci->i_rdcache_gen,
+                    ci->i_rdcache_revoking);
        }
        spin_unlock(&inode->i_lock);
 
@@ -1739,7 +1751,7 @@ int ceph_do_getattr(struct inode *inode, int mask)
                return 0;
        }
 
-       dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask));
+       dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode);
        if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
                return 0;
 
index 3142b15940c25656a43ec3a5d72af3e1ee1cece9..098b185084791730ba0143111126bc066fdb9afb 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/sched.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -529,6 +528,9 @@ static void __register_request(struct ceph_mds_client *mdsc,
        ceph_mdsc_get_request(req);
        __insert_request(mdsc, req);
 
+       req->r_uid = current_fsuid();
+       req->r_gid = current_fsgid();
+
        if (dir) {
                struct ceph_inode_info *ci = ceph_inode(dir);
 
@@ -1588,8 +1590,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
        head->op = cpu_to_le32(req->r_op);
-       head->caller_uid = cpu_to_le32(current_fsuid());
-       head->caller_gid = cpu_to_le32(current_fsgid());
+       head->caller_uid = cpu_to_le32(req->r_uid);
+       head->caller_gid = cpu_to_le32(req->r_gid);
        head->args = req->r_args;
 
        ceph_encode_filepath(&p, end, ino1, path1);
index d66d63c7235526ef63d16ff0ea1e9ba3899df586..9341fd4f14320060a395c37f81b4a67b01c020d7 100644 (file)
@@ -170,6 +170,8 @@ struct ceph_mds_request {
 
        union ceph_mds_request_args r_args;
        int r_fmode;        /* file mode, if expecting cap */
+       uid_t r_uid;
+       gid_t r_gid;
 
        /* for choosing which mds to send this request to */
        int r_direct_mode;
index 1886294e12f7a3106c00f3376d92e43330514081..7f01728a46571f2fa22a47fbd062f6eadf4cba83 100644 (file)
@@ -293,9 +293,7 @@ struct ceph_inode_info {
        int i_rd_ref, i_rdcache_ref, i_wr_ref;
        int i_wrbuffer_ref, i_wrbuffer_ref_head;
        u32 i_shared_gen;       /* increment each time we get FILE_SHARED */
-       u32 i_rdcache_gen;      /* we increment this each time we get
-                                  FILE_CACHE.  If it's non-zero, we
-                                  _may_ have cached pages. */
+       u32 i_rdcache_gen;      /* incremented each time we get FILE_CACHE. */
        u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
 
        struct list_head i_unsafe_writes; /* uncommitted sync writes */
index 0ed213970cede228e097a04eec99c94ce97a6146..ee45648b0d1a9fead5722811171c6f5bcc3d8043 100644 (file)
@@ -4,6 +4,7 @@ config CIFS
        select NLS
        select CRYPTO
        select CRYPTO_MD5
+       select CRYPTO_HMAC
        select CRYPTO_ARC4
        help
          This is the client VFS module for the Common Internet File System
@@ -143,6 +144,13 @@ config CIFS_FSCACHE
            to be cached locally on disk through the general filesystem cache
            manager. If unsure, say N.
 
+config CIFS_ACL
+         bool "Provide CIFS ACL support (EXPERIMENTAL)"
+         depends on EXPERIMENTAL && CIFS_XATTR
+         help
+           Allows to fetch CIFS/NTFS ACL from the server.  The DACL blob
+           is handed over to the application/caller.
+
 config CIFS_EXPERIMENTAL
          bool "CIFS Experimental Features (EXPERIMENTAL)"
          depends on CIFS && EXPERIMENTAL
index c9b4792ae82538761b056ffba55173e77a2f2c8c..c6ebea088ac7c2bf6d01d3ac02910f0164a4b4b3 100644 (file)
@@ -560,7 +560,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
        if (IS_ERR(tlink))
-               return NULL;
+               return ERR_CAST(tlink);
 
        xid = GetXid();
        rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
@@ -568,7 +568,9 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
 
        cifs_put_tlink(tlink);
 
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
@@ -583,7 +585,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
        if (IS_ERR(tlink))
-               return NULL;
+               return ERR_CAST(tlink);
 
        tcon = tlink_tcon(tlink);
        xid = GetXid();
@@ -591,23 +593,22 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-       if (rc) {
-               cERROR(1, "Unable to open file to get ACL");
-               goto out;
+       if (!rc) {
+               rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
+               CIFSSMBClose(xid, tcon, fid);
        }
 
-       rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
-
-       CIFSSMBClose(xid, tcon, fid);
- out:
        cifs_put_tlink(tlink);
        FreeXid(xid);
+
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
 /* Retrieve an ACL from the server */
-static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
                                      struct inode *inode, const char *path,
                                      u32 *pacllen)
 {
@@ -695,7 +696,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 }
 
 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
-void
+int
 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                  struct inode *inode, const char *path, const __u16 *pfid)
 {
@@ -711,17 +712,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
 
        /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
-       if (pntsd)
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                rc = parse_sec_desc(pntsd, acllen, fattr);
-       if (rc)
-               cFYI(1, "parse sec desc failed rc = %d", rc);
+               kfree(pntsd);
+               if (rc)
+                       cERROR(1, "parse sec desc failed rc = %d", rc);
+       }
 
-       kfree(pntsd);
-       return;
+       return rc;
 }
 
 /* Convert mode bits to an ACL so we can update the ACL on the server */
-int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
+int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
 {
        int rc = 0;
        __u32 secdesclen = 0;
@@ -736,7 +741,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
        /* Add three ACEs for owner, group, everyone getting rid of
           other ACEs as chmod disables ACEs and set the security descriptor */
 
-       if (pntsd) {
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                /* allocate memory for the smb header,
                   set security descriptor request security descriptor
                   parameters, and secuirty descriptor itself */
index 9c3789762ab7c4c92a7d67859c34b32cb196f1ab..76c8a906a63eee2369123f0ea1f433ad58692b1e 100644 (file)
@@ -458,6 +458,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
                seq_printf(s, ",acl");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
                seq_printf(s, ",mfsymlinks");
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
+               seq_printf(s, ",fsc");
 
        seq_printf(s, ",rsize=%d", cifs_sb->rsize);
        seq_printf(s, ",wsize=%d", cifs_sb->wsize);
index 7ed69b6b5fe6719f66ed5af0a0b38d2cda1aa352..db961dc4fd3d30b4bbdf15924c1e58fded05b10e 100644 (file)
@@ -130,10 +130,12 @@ extern int cifs_get_file_info_unix(struct file *filp);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
                        const unsigned char *search_path,
                        struct super_block *sb, int xid);
-extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
                              struct cifs_fattr *fattr, struct inode *inode,
                              const char *path, const __u16 *pfid);
-extern int mode_to_acl(struct inode *inode, const char *path, __u64);
+extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
+extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
+                                       const char *, u32 *);
 
 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
                        const char *);
index 251a17c03545dfc35e8ab37e1ea5a612e94f7536..32fa4d9b5dbc11537dfc09653215a9540668e109 100644 (file)
@@ -1352,6 +1352,11 @@ cifs_parse_mount_options(char *options, const char *devname,
                                "supported. Instead set "
                                "/proc/fs/cifs/LookupCacheEnabled to 0\n");
                } else if (strnicmp(data, "fsc", 3) == 0) {
+#ifndef CONFIG_CIFS_FSCACHE
+                       cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
+                                 "kernel config option set");
+                       return 1;
+#endif
                        vol->fsc = true;
                } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
                        vol->mfsymlinks = true;
index 0eb87026cad3a4bf1050af0d2409ca0bfd7c928a..548f06230a6df50063b5c747b77330c4815fdd2e 100644 (file)
@@ -66,7 +66,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        /* Search for server name delimiter */
        sep = memchr(hostname, '\\', len);
        if (sep)
-               len = sep - unc;
+               len = sep - hostname;
        else
                cFYI(1, "%s: probably server name is whole unc: %s",
                     __func__, unc);
index 06c3e83fa387fecf63b93e33a0455dac6da45f6d..b857ce5db7755143affed1224c778d34ddc77b99 100644 (file)
@@ -2271,8 +2271,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile)
 
 void cifs_oplock_break_put(struct cifsFileInfo *cfile)
 {
+       struct super_block *sb = cfile->dentry->d_sb;
+
        cifsFileInfo_put(cfile);
-       cifs_sb_deactive(cfile->dentry->d_sb);
+       cifs_sb_deactive(sb);
 }
 
 const struct address_space_operations cifs_addr_ops = {
index a2ad94efcfe65a6eb1fb93c614b59cc3fdfae609..297a43d0ff7f5a4716d13eccd595286b44b3af65 100644 (file)
@@ -2,7 +2,7 @@
  *   fs/cifs/fscache.c - CIFS filesystem cache interface
  *
  *   Copyright (c) 2010 Novell, Inc.
- *   Author(s): Suresh Jayaraman (sjayaraman@suse.de>
+ *   Author(s): Suresh Jayaraman <sjayaraman@suse.de>
  *
  *   This library is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU Lesser General Public License as published
@@ -67,10 +67,12 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
        if (cifsi->fscache)
                return;
 
-       cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
+               cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
                                &cifs_fscache_inode_object_def, cifsi);
-       cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
+               cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
                                cifsi->fscache);
+       }
 }
 
 void cifs_fscache_release_inode_cookie(struct inode *inode)
@@ -101,10 +103,8 @@ void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
 {
        if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
                cifs_fscache_disable_inode_cookie(inode);
-       else {
+       else
                cifs_fscache_enable_inode_cookie(inode);
-               cFYI(1, "CIFS: fscache inode cookie set");
-       }
 }
 
 void cifs_fscache_reset_inode_cookie(struct inode *inode)
index ef3a55bf86b6d3700c521e074954548c6f53223f..28cb6e735943f935d3ed9408f34152ba35f100b7 100644 (file)
@@ -689,8 +689,13 @@ int cifs_get_inode_info(struct inode **pinode,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        /* fill in 0777 bits from ACL */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-               cFYI(1, "Getting mode bits from ACL");
-               cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
+               rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
+                                               pfid);
+               if (rc) {
+                       cFYI(1, "%s: Getting ACL failed with error: %d",
+                               __func__, rc);
+                       goto cgii_exit;
+               }
        }
 #endif
 
@@ -881,8 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
                                                xid, NULL);
 
-       if (!inode)
-               return ERR_PTR(rc);
+       if (!inode) {
+               inode = ERR_PTR(rc);
+               goto out;
+       }
 
 #ifdef CONFIG_CIFS_FSCACHE
        /* populate tcon->resource_id */
@@ -898,13 +905,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                inode->i_uid = cifs_sb->mnt_uid;
                inode->i_gid = cifs_sb->mnt_gid;
        } else if (rc) {
-               kfree(full_path);
-               _FreeXid(xid);
                iget_failed(inode);
-               return ERR_PTR(rc);
+               inode = ERR_PTR(rc);
        }
 
-
+out:
        kfree(full_path);
        /* can not call macro FreeXid here since in a void func
         * TODO: This is no longer true
@@ -1670,7 +1675,9 @@ cifs_inode_needs_reval(struct inode *inode)
        return false;
 }
 
-/* check invalid_mapping flag and zap the cache if it's set */
+/*
+ * Zap the cache. Called when invalid_mapping flag is set.
+ */
 static void
 cifs_invalidate_mapping(struct inode *inode)
 {
@@ -2115,9 +2122,14 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
        if (attrs->ia_valid & ATTR_MODE) {
                rc = 0;
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-                       rc = mode_to_acl(inode, full_path, mode);
-               else
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+                       rc = mode_to_cifs_acl(inode, full_path, mode);
+                       if (rc) {
+                               cFYI(1, "%s: Setting ACL failed with error: %d",
+                                       __func__, rc);
+                               goto cifs_setattr_exit;
+                       }
+               } else
 #endif
                if (((mode & S_IWUGO) == 0) &&
                    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
index ef7bb7b50f58e679ffabb8b8dad65420efb81271..32d300e8f20eb4a6676b8da50187a4b04146fcb8 100644 (file)
@@ -226,26 +226,29 @@ static int initiate_cifs_search(const int xid, struct file *file)
        char *full_path = NULL;
        struct cifsFileInfo *cifsFile;
        struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-       struct tcon_link *tlink;
+       struct tcon_link *tlink = NULL;
        struct cifsTconInfo *pTcon;
 
-       tlink = cifs_sb_tlink(cifs_sb);
-       if (IS_ERR(tlink))
-               return PTR_ERR(tlink);
-       pTcon = tlink_tcon(tlink);
-
-       if (file->private_data == NULL)
-               file->private_data =
-                       kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
        if (file->private_data == NULL) {
-               rc = -ENOMEM;
-               goto error_exit;
+               tlink = cifs_sb_tlink(cifs_sb);
+               if (IS_ERR(tlink))
+                       return PTR_ERR(tlink);
+
+               cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
+               if (cifsFile == NULL) {
+                       rc = -ENOMEM;
+                       goto error_exit;
+               }
+               file->private_data = cifsFile;
+               cifsFile->tlink = cifs_get_tlink(tlink);
+               pTcon = tlink_tcon(tlink);
+       } else {
+               cifsFile = file->private_data;
+               pTcon = tlink_tcon(cifsFile->tlink);
        }
 
-       cifsFile = file->private_data;
        cifsFile->invalidHandle = true;
        cifsFile->srch_inf.endOfSearch = false;
-       cifsFile->tlink = cifs_get_tlink(tlink);
 
        full_path = build_path_from_dentry(file->f_path.dentry);
        if (full_path == NULL) {
index a264b744bb41f4e62d9375b496758d5450520460..eae2a14916080160c4723868dd69d9c3496c99fa 100644 (file)
 
 #define MAX_EA_VALUE_SIZE 65535
 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
+#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
 #define CIFS_XATTR_USER_PREFIX "user."
 #define CIFS_XATTR_SYSTEM_PREFIX "system."
 #define CIFS_XATTR_OS2_PREFIX "os2."
-#define CIFS_XATTR_SECURITY_PREFIX ".security"
+#define CIFS_XATTR_SECURITY_PREFIX "security."
 #define CIFS_XATTR_TRUSTED_PREFIX "trusted."
 #define XATTR_TRUSTED_PREFIX_LEN  8
 #define XATTR_SECURITY_PREFIX_LEN 9
@@ -277,29 +278,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-                       __u16 fid;
-                       int oplock = 0;
-                       struct cifs_ntsd *pacl = NULL;
-                       __u32 buflen = 0;
-                       if (experimEnabled)
-                               rc = CIFSSMBOpen(xid, pTcon, full_path,
-                                       FILE_OPEN, GENERIC_READ, 0, &fid,
-                                       &oplock, NULL, cifs_sb->local_nls,
-                                       cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       /* else rc is EOPNOTSUPP from above */
-
-                       if (rc == 0) {
-                               rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
-                                                     &buflen);
-                               CIFSSMBClose(xid, pTcon, fid);
-                       }
-               }
-#endif /* EXPERIMENTAL */
 #else
-               cFYI(1, "query POSIX ACL not supported yet");
+               cFYI(1, "Query POSIX ACL not supported yet");
 #endif /* CONFIG_CIFS_POSIX */
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                          strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -311,8 +291,33 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else
-               cFYI(1, "query POSIX default ACL not supported yet");
-#endif
+               cFYI(1, "Query POSIX default ACL not supported yet");
+#endif /* CONFIG_CIFS_POSIX */
+       } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
+                               strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
+#ifdef CONFIG_CIFS_ACL
+                       u32 acllen;
+                       struct cifs_ntsd *pacl;
+
+                       pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
+                                               full_path, &acllen);
+                       if (IS_ERR(pacl)) {
+                               rc = PTR_ERR(pacl);
+                               cERROR(1, "%s: error %zd getting sec desc",
+                                               __func__, rc);
+                       } else {
+                               if (ea_value) {
+                                       if (acllen > buf_size)
+                                               acllen = -ERANGE;
+                                       else
+                                               memcpy(ea_value, pacl, acllen);
+                               }
+                               rc = acllen;
+                               kfree(pacl);
+                       }
+#else
+               cFYI(1, "Query CIFS ACL not supported yet");
+#endif /* CONFIG_CIFS_ACL */
        } else if (strncmp(ea_name,
                  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
                cFYI(1, "Trusted xattr namespace not supported yet");
index c580c322fa6b1bab00a8b949cd3284f691bc366a..eb1740ac8c0a1e9e167b5e53e0f49d425774ff3d 100644 (file)
@@ -1350,6 +1350,10 @@ static int compat_count(compat_uptr_t __user *argv, int max)
                        argv++;
                        if (i++ >= max)
                                return -E2BIG;
+
+                       if (fatal_signal_pending(current))
+                               return -ERESTARTNOHAND;
+                       cond_resched();
                }
        }
        return i;
@@ -1391,6 +1395,12 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
                while (len > 0) {
                        int offset, bytes_to_copy;
 
+                       if (fatal_signal_pending(current)) {
+                               ret = -ERESTARTNOHAND;
+                               goto out;
+                       }
+                       cond_resched();
+
                        offset = pos % PAGE_SIZE;
                        if (offset == 0)
                                offset = PAGE_SIZE;
@@ -1407,18 +1417,8 @@ static int compat_copy_strings(int argc, compat_uptr_t __user *argv,
                        if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
                                struct page *page;
 
-#ifdef CONFIG_STACK_GROWSUP
-                               ret = expand_stack_downwards(bprm->vma, pos);
-                               if (ret < 0) {
-                                       /* We've exceed the stack rlimit. */
-                                       ret = -E2BIG;
-                                       goto out;
-                               }
-#endif
-                               ret = get_user_pages(current, bprm->mm, pos,
-                                                    1, 1, 1, &page, NULL);
-                               if (ret <= 0) {
-                                       /* We've exceed the stack rlimit. */
+                               page = get_arg_page(bprm, pos, 1);
+                               if (!page) {
                                        ret = -E2BIG;
                                        goto out;
                                }
@@ -1539,8 +1539,10 @@ int compat_do_execve(char * filename,
        return retval;
 
 out:
-       if (bprm->mm)
+       if (bprm->mm) {
+               acct_arg_size(bprm, 0);
                mmput(bprm->mm);
+       }
 
 out_file:
        if (bprm->file) {
index 410ed188faa1376b7b0b10ed5bff0c36aa9c8806..a60579b007b03f38160ea541b099ab7a914bfbc1 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/compiler.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_bridge.h>
index 253732382d375e848edc61ca40a3eaadb60f80c7..2720178b7718a9335a28d7ed4b0422ab11d6331f 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/key.h>
 #include <linux/slab.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/crypto.h>
 #include "ecryptfs_kernel.h"
index 99d33a1371e9aeaf7298c4548ed18a634b9f2427..d68c378a31375bfb848aaa887fb655a8b08ec080 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -164,7 +164,26 @@ out:
 
 #ifdef CONFIG_MMU
 
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+       struct mm_struct *mm = current->mm;
+       long diff = (long)(pages - bprm->vma_pages);
+
+       if (!mm || !diff)
+               return;
+
+       bprm->vma_pages = pages;
+
+#ifdef SPLIT_RSS_COUNTING
+       add_mm_counter(mm, MM_ANONPAGES, diff);
+#else
+       spin_lock(&mm->page_table_lock);
+       add_mm_counter(mm, MM_ANONPAGES, diff);
+       spin_unlock(&mm->page_table_lock);
+#endif
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                int write)
 {
        struct page *page;
@@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
                struct rlimit *rlim;
 
+               acct_arg_size(bprm, size / PAGE_SIZE);
+
                /*
                 * We've historically supported up to 32 pages (ARG_MAX)
                 * of argument strings even with small stacks
@@ -276,7 +297,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
 
 #else
 
-static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
+struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                int write)
 {
        struct page *page;
@@ -1003,6 +1028,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        /*
         * Release all of the old mmap stuff
         */
+       acct_arg_size(bprm, 0);
        retval = exec_mmap(bprm->mm);
        if (retval)
                goto out;
@@ -1426,8 +1452,10 @@ int do_execve(const char * filename,
        return retval;
 
 out:
-       if (bprm->mm)
-               mmput (bprm->mm);
+       if (bprm->mm) {
+               acct_arg_size(bprm, 0);
+               mmput(bprm->mm);
+       }
 
 out_file:
        if (bprm->file) {
index 2fedaf8b50125bf65ad9b550537742de3109ecd4..acf8695fa8f035935390dd6bc0c8e44e8d3e5961 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/parser.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/vfs.h>
index bf5ae883b1bdc30ff55cbc616bab7c24f9d57dbb..eb3bc2fe647e710de889f04da3afaf5821e00556 100644 (file)
@@ -331,6 +331,30 @@ mext_out:
                return err;
        }
 
+       case FITRIM:
+       {
+               struct super_block *sb = inode->i_sb;
+               struct fstrim_range range;
+               int ret = 0;
+
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               if (copy_from_user(&range, (struct fstrim_range *)arg,
+                   sizeof(range)))
+                       return -EFAULT;
+
+               ret = ext4_trim_fs(sb, &range);
+               if (ret < 0)
+                       return ret;
+
+               if (copy_to_user((struct fstrim_range *)arg, &range,
+                   sizeof(range)))
+                       return -EFAULT;
+
+               return 0;
+       }
+
        default:
                return -ENOTTY;
        }
index 7f5451cd1d38bff2399471750618fc7429ce5c5e..beacce11ac506ff3dd9958d1a3f82db095a36468 100644 (file)
@@ -237,8 +237,6 @@ static void ext4_end_bio(struct bio *bio, int error)
                        } while (bh != head);
                }
 
-               put_io_page(io_end->pages[i]);
-
                /*
                 * If this is a partial write which happened to make
                 * all buffers uptodate then we can optimize away a
@@ -248,6 +246,8 @@ static void ext4_end_bio(struct bio *bio, int error)
                 */
                if (!partial_write)
                        SetPageUptodate(page);
+
+               put_io_page(io_end->pages[i]);
        }
        io_end->num_io_pages = 0;
        inode = io_end->inode;
index 61182fe6254e94ad606a6c67fed1b30ef289ad38..e32195d6aac34656b13a5619c3750e8b30586c08 100644 (file)
@@ -1197,7 +1197,6 @@ static const struct super_operations ext4_sops = {
        .quota_write    = ext4_quota_write,
 #endif
        .bdev_try_to_free_page = bdev_try_to_free_page,
-       .trim_fs        = ext4_trim_fs
 };
 
 static const struct super_operations ext4_nojournal_sops = {
@@ -2799,9 +2798,6 @@ static void ext4_clear_request_list(void)
        struct ext4_li_request *elr;
 
        mutex_lock(&ext4_li_info->li_list_mtx);
-       if (list_empty(&ext4_li_info->li_request_list))
-               return;
-
        list_for_each_safe(pos, n, &ext4_li_info->li_request_list) {
                elr = list_entry(pos, struct ext4_li_request,
                                 lr_request);
@@ -3268,13 +3264,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
         * Test whether we have more sectors than will fit in sector_t,
         * and whether the max offset is addressable by the page cache.
         */
-       ret = generic_check_addressable(sb->s_blocksize_bits,
+       err = generic_check_addressable(sb->s_blocksize_bits,
                                        ext4_blocks_count(es));
-       if (ret) {
+       if (err) {
                ext4_msg(sb, KERN_ERR, "filesystem"
                         " too large to mount safely on this system");
                if (sizeof(sector_t) < 8)
                        ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled");
+               ret = err;
                goto failed_mount;
        }
 
index c8224587123f6e2ff84c8933f8d56a50ffd06c80..9242d294fe90d382fb7a40f1220923baea71c97e 100644 (file)
@@ -134,6 +134,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open);
 void fuse_finish_open(struct inode *inode, struct file *file)
 {
        struct fuse_file *ff = file->private_data;
+       struct fuse_conn *fc = get_fuse_conn(inode);
 
        if (ff->open_flags & FOPEN_DIRECT_IO)
                file->f_op = &fuse_direct_io_file_operations;
@@ -141,6 +142,15 @@ void fuse_finish_open(struct inode *inode, struct file *file)
                invalidate_inode_pages2(inode->i_mapping);
        if (ff->open_flags & FOPEN_NONSEEKABLE)
                nonseekable_open(inode, file);
+       if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
+               struct fuse_inode *fi = get_fuse_inode(inode);
+
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               i_size_write(inode, 0);
+               spin_unlock(&fc->lock);
+               fuse_invalidate_attr(inode);
+       }
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
index 58a9b9998b42d0d9603c7a49ffc746ab4a22ef87..f606baf9ba7247e9a5fd9ccfb2cc9426019e589e 100644 (file)
@@ -631,6 +631,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
                             struct fs_disk_quota *fdq)
 {
        struct inode *inode = &ip->i_inode;
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct address_space *mapping = inode->i_mapping;
        unsigned long index = loc >> PAGE_CACHE_SHIFT;
        unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
@@ -658,11 +659,11 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
        qd->qd_qb.qb_value = qp->qu_value;
        if (fdq) {
                if (fdq->d_fieldmask & FS_DQ_BSOFT) {
-                       qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit);
+                       qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift);
                        qd->qd_qb.qb_warn = qp->qu_warn;
                }
                if (fdq->d_fieldmask & FS_DQ_BHARD) {
-                       qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit);
+                       qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift);
                        qd->qd_qb.qb_limit = qp->qu_limit;
                }
        }
@@ -1497,9 +1498,9 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
        fdq->d_version = FS_DQUOT_VERSION;
        fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
        fdq->d_id = id;
-       fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
-       fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
-       fdq->d_bcount = be64_to_cpu(qlvb->qb_value);
+       fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift;
+       fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift;
+       fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift;
 
        gfs2_glock_dq_uninit(&q_gh);
 out:
@@ -1566,10 +1567,10 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
 
        /* If nothing has changed, this is a no-op */
        if ((fdq->d_fieldmask & FS_DQ_BSOFT) &&
-           (fdq->d_blk_softlimit == be64_to_cpu(qd->qd_qb.qb_warn)))
+           ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn)))
                fdq->d_fieldmask ^= FS_DQ_BSOFT;
        if ((fdq->d_fieldmask & FS_DQ_BHARD) &&
-           (fdq->d_blk_hardlimit == be64_to_cpu(qd->qd_qb.qb_limit)))
+           ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit)))
                fdq->d_fieldmask ^= FS_DQ_BHARD;
        if (fdq->d_fieldmask == 0)
                goto out_i;
index e92fdbb3bc3aebd5b52221d2b0e5ec4094a37fe9..d6cc16476620760b6f01233f87fe5842335ba760 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/syscalls.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/capability.h>
 #include <linux/file.h>
 #include <linux/fs.h>
@@ -530,41 +529,6 @@ static int ioctl_fsthaw(struct file *filp)
        return thaw_super(sb);
 }
 
-static int ioctl_fstrim(struct file *filp, void __user *argp)
-{
-       struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
-       struct fstrim_range range;
-       int ret = 0;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       /* If filesystem doesn't support trim feature, return. */
-       if (sb->s_op->trim_fs == NULL)
-               return -EOPNOTSUPP;
-
-       /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */
-       if (sb->s_bdev == NULL)
-               return -EINVAL;
-
-       if (argp == NULL) {
-               range.start = 0;
-               range.len = ULLONG_MAX;
-               range.minlen = 0;
-       } else if (copy_from_user(&range, argp, sizeof(range)))
-               return -EFAULT;
-
-       ret = sb->s_op->trim_fs(sb, &range);
-       if (ret < 0)
-               return ret;
-
-       if ((argp != NULL) &&
-           (copy_to_user(argp, &range, sizeof(range))))
-               return -EFAULT;
-
-       return 0;
-}
-
 /*
  * When you add any new common ioctls to the switches above and below
  * please update compat_sys_ioctl() too.
@@ -615,10 +579,6 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                error = ioctl_fsthaw(filp);
                break;
 
-       case FITRIM:
-               error = ioctl_fstrim(filp, argp);
-               break;
-
        case FS_IOC_FIEMAP:
                return ioctl_fiemap(filp, arg);
 
index 2f7d05c899220e06d99ac9ecc9f8047903faa3a0..7da2a06508e5448c59aebcee03518d78f2b0599b 100644 (file)
@@ -103,22 +103,15 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
        }
 
        ret = -ESRCH;
-       /*
-        * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic",
-        * so we can't use rcu_read_lock(). See re-copy of ->ioprio
-        * in copy_process().
-        */
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        switch (which) {
                case IOPRIO_WHO_PROCESS:
-                       rcu_read_lock();
                        if (!who)
                                p = current;
                        else
                                p = find_task_by_vpid(who);
                        if (p)
                                ret = set_task_ioprio(p, ioprio);
-                       rcu_read_unlock();
                        break;
                case IOPRIO_WHO_PGRP:
                        if (!who)
@@ -141,12 +134,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
                                break;
 
                        do_each_thread(g, p) {
-                               int match;
-
-                               rcu_read_lock();
-                               match = __task_cred(p)->uid == who;
-                               rcu_read_unlock();
-                               if (!match)
+                               if (__task_cred(p)->uid != who)
                                        continue;
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
@@ -160,7 +148,7 @@ free_uid:
                        ret = -EINVAL;
        }
 
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return ret;
 }
 
@@ -204,17 +192,15 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
        int ret = -ESRCH;
        int tmpio;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        switch (which) {
                case IOPRIO_WHO_PROCESS:
-                       rcu_read_lock();
                        if (!who)
                                p = current;
                        else
                                p = find_task_by_vpid(who);
                        if (p)
                                ret = get_task_ioprio(p);
-                       rcu_read_unlock();
                        break;
                case IOPRIO_WHO_PGRP:
                        if (!who)
@@ -241,12 +227,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
                                break;
 
                        do_each_thread(g, p) {
-                               int match;
-
-                               rcu_read_lock();
-                               match = __task_cred(p)->uid == user->uid;
-                               rcu_read_unlock();
-                               if (!match)
+                               if (__task_cred(p)->uid != user->uid)
                                        continue;
                                tmpio = get_task_ioprio(p);
                                if (tmpio < 0)
@@ -264,6 +245,6 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
                        ret = -EINVAL;
        }
 
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return ret;
 }
index c590d155c0959bfbe1f8ce2f6be9702afd2904f4..f837ba953529690e9de45c1e1731470897edeeb4 100644 (file)
@@ -899,6 +899,14 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
 
        /* journal descriptor can store up to n blocks -bzzz */
        journal->j_blocksize = blocksize;
+       journal->j_dev = bdev;
+       journal->j_fs_dev = fs_dev;
+       journal->j_blk_offset = start;
+       journal->j_maxlen = len;
+       bdevname(journal->j_dev, journal->j_devname);
+       p = journal->j_devname;
+       while ((p = strchr(p, '/')))
+               *p = '!';
        jbd2_stats_proc_init(journal);
        n = journal->j_blocksize / sizeof(journal_block_tag_t);
        journal->j_wbufsize = n;
@@ -908,14 +916,6 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
                        __func__);
                goto out_err;
        }
-       journal->j_dev = bdev;
-       journal->j_fs_dev = fs_dev;
-       journal->j_blk_offset = start;
-       journal->j_maxlen = len;
-       bdevname(journal->j_dev, journal->j_devname);
-       p = journal->j_devname;
-       while ((p = strchr(p, '/')))
-               *p = '!';
 
        bh = __getblk(journal->j_dev, start, journal->j_blocksize);
        if (!bh) {
index d5bb86866e6c19f85a359373742a37e24ad39ad7..25509eb28fd71980fa030aa39a1e81f225da43f9 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
-#include <linux/smp_lock.h>
 #include <linux/kthread.h>
 
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
index 47ea1e1925b8c4fded4b156ea7cef916322377bf..332c54cf75e0f465f5ba91cc66999df386d4d4e0 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/errno.h>
index 25e21e4023b22a3f51ceb9d1c1869c2b7518f6d0..ed0c59fe23cef0dd038dd485545a14209fa11b78 100644 (file)
@@ -124,7 +124,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
                        continue;
                if (host->h_server != ni->server)
                        continue;
-               if (ni->server &&
+               if (ni->server && ni->src_len != 0 &&
                    !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap))
                        continue;
 
@@ -167,6 +167,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
        host->h_addrlen = ni->salen;
        rpc_set_port(nlm_addr(host), 0);
        memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len);
+       host->h_srcaddrlen = ni->src_len;
        host->h_version    = ni->version;
        host->h_proto      = ni->protocol;
        host->h_rpcclnt    = NULL;
@@ -238,9 +239,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
                                     const char *hostname,
                                     int noresvport)
 {
-       const struct sockaddr source = {
-               .sa_family      = AF_UNSPEC,
-       };
        struct nlm_lookup_host_info ni = {
                .server         = 0,
                .sap            = sap,
@@ -249,8 +247,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
                .version        = version,
                .hostname       = hostname,
                .hostname_len   = strlen(hostname),
-               .src_sap        = &source,
-               .src_len        = sizeof(source),
                .noresvport     = noresvport,
        };
 
@@ -357,7 +353,6 @@ nlm_bind_host(struct nlm_host *host)
                        .protocol       = host->h_proto,
                        .address        = nlm_addr(host),
                        .addrsize       = host->h_addrlen,
-                       .saddress       = nlm_srcaddr(host),
                        .timeout        = &timeparms,
                        .servername     = host->h_name,
                        .program        = &nlm_program,
@@ -376,6 +371,8 @@ nlm_bind_host(struct nlm_host *host)
                        args.flags |= RPC_CLNT_CREATE_HARDRTRY;
                if (host->h_noresvport)
                        args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
+               if (host->h_srcaddrlen)
+                       args.saddress = nlm_srcaddr(host);
 
                clnt = rpc_create(&args);
                if (!IS_ERR(clnt))
index a336e832475db7ffd5516a4cbe7e32daff49fd7c..38d261192453b5ee11300d577d0ebe66d3b9be72 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
 
index c462d346acbda920a78ef03c153dc088b70ef7f4..ef5659b211e96cbcc8e4aa03d1cd332fd68c1a85 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/nlm.h>
index c3069f38d60220e82726d5c318d0942e125ddb03..0caea5310ac3f0ea7ba24d36cdacaed03a55f9d3 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
 
index 0e62dd35d088486ee2c04c62f312ffb2b0ca5149..8729347bcd1a1b0ab9953c85e7c3ffa46a1fce9c 100644 (file)
 #include <linux/module.h>
 #include <linux/security.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/time.h>
 #include <linux/rcupdate.h>
index 8a415c9c5e552efd945cdb85af6f74af4b2b6de6..3dbfc072ec70aa0099b79b3ff1040455543c46ca 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/percpu.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/acct.h>
index aac8832e919e9a56cb95af787af658fb03d8d0d1..f22b12e7d337c37abc957ee2b4c2b204f52206b1 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
-#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 
index 6c754f70c5296be3fbe5c323bbb985d7ee326512..cb50aaf981dff5bf32dd2d4993ac14a1202dc27e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
index d290545aa0c4b98c932e316c7dd4fcf3961b1126..8fb93b604e73a3a337a5f43ebc97b25d9f02d7f8 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
index c2a1f9a155c3a6e8f82800334337b1b1b0aaa65a..d40a547e337707da380e752864926a65c70013cc 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/highuid.h>
-#include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
 
index aeec017fe814acbdf17947a68553765a335359ae..93a8b3bd69e37871795b93355e0550970cf7f421 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/completion.h>
 #include <linux/ip.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
index 232a7eead33a488c4a5d67bc83e3a1971d9665df..1fd62fc49be36310b45e54028f69905b4e4f0237 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
 #include <linux/nfs4.h>
index 07ac3847e562b54c26efd30c9a9eabab468c309d..f0a384e2ae633a1dc2de619d102d5935ff32a273 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mount.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
+#include <linux/kmemleak.h>
 
 #include "delegation.h"
 #include "iostat.h"
@@ -161,6 +162,7 @@ struct nfs_cache_array_entry {
        u64 cookie;
        u64 ino;
        struct qstr string;
+       unsigned char d_type;
 };
 
 struct nfs_cache_array {
@@ -170,8 +172,6 @@ struct nfs_cache_array {
        struct nfs_cache_array_entry array[0];
 };
 
-#define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry))
-
 typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
 typedef struct {
        struct file     *file;
@@ -194,9 +194,13 @@ typedef struct {
 static
 struct nfs_cache_array *nfs_readdir_get_array(struct page *page)
 {
+       void *ptr;
        if (page == NULL)
                return ERR_PTR(-EIO);
-       return (struct nfs_cache_array *)kmap(page);
+       ptr = kmap(page);
+       if (ptr == NULL)
+               return ERR_PTR(-ENOMEM);
+       return ptr;
 }
 
 static
@@ -213,6 +217,9 @@ int nfs_readdir_clear_array(struct page *page, gfp_t mask)
 {
        struct nfs_cache_array *array = nfs_readdir_get_array(page);
        int i;
+
+       if (IS_ERR(array))
+               return PTR_ERR(array);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
        nfs_readdir_release_array(page);
@@ -231,6 +238,11 @@ int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int le
        string->name = kmemdup(name, len, GFP_KERNEL);
        if (string->name == NULL)
                return -ENOMEM;
+       /*
+        * Avoid a kmemleak false positive. The pointer to the name is stored
+        * in a page cache page which kmemleak does not scan.
+        */
+       kmemleak_not_leak(string->name);
        string->hash = full_name_hash(name, len);
        return 0;
 }
@@ -244,20 +256,24 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
 
        if (IS_ERR(array))
                return PTR_ERR(array);
-       ret = -EIO;
-       if (array->size >= MAX_READDIR_ARRAY)
-               goto out;
 
        cache_entry = &array->array[array->size];
+
+       /* Check that this entry lies within the page bounds */
+       ret = -ENOSPC;
+       if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE)
+               goto out;
+
        cache_entry->cookie = entry->prev_cookie;
        cache_entry->ino = entry->ino;
+       cache_entry->d_type = entry->d_type;
        ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
        if (ret)
                goto out;
        array->last_cookie = entry->cookie;
+       array->size++;
        if (entry->eof == 1)
                array->eof_index = array->size;
-       array->size++;
 out:
        nfs_readdir_release_array(page);
        return ret;
@@ -272,7 +288,7 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
        if (diff < 0)
                goto out_eof;
        if (diff >= array->size) {
-               if (array->eof_index > 0)
+               if (array->eof_index >= 0)
                        goto out_eof;
                desc->current_index += array->size;
                return -EAGAIN;
@@ -281,8 +297,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
        index = (unsigned int)diff;
        *desc->dir_cookie = array->array[index].cookie;
        desc->cache_entry_index = index;
-       if (index == array->eof_index)
-               desc->eof = 1;
        return 0;
 out_eof:
        desc->eof = 1;
@@ -296,17 +310,17 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
        int status = -EAGAIN;
 
        for (i = 0; i < array->size; i++) {
-               if (i == array->eof_index) {
-                       desc->eof = 1;
-                       status = -EBADCOOKIE;
-               }
                if (array->array[i].cookie == *desc->dir_cookie) {
                        desc->cache_entry_index = i;
                        status = 0;
-                       break;
+                       goto out;
                }
        }
-
+       if (i == array->eof_index) {
+               desc->eof = 1;
+               status = -EBADCOOKIE;
+       }
+out:
        return status;
 }
 
@@ -381,13 +395,9 @@ int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct x
 static
 int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
 {
-       struct nfs_inode *node;
        if (dentry->d_inode == NULL)
                goto different;
-       node = NFS_I(dentry->d_inode);
-       if (node->fh.size != entry->fh->size)
-               goto different;
-       if (strncmp(node->fh.data, entry->fh->data, node->fh.size) != 0)
+       if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0)
                goto different;
        return 1;
 different:
@@ -449,14 +459,15 @@ out:
 
 /* Perform conversion from xdr to cache array */
 static
-void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
+int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
                                void *xdr_page, struct page *page, unsigned int buflen)
 {
        struct xdr_stream stream;
        struct xdr_buf buf;
        __be32 *ptr = xdr_page;
-       int status;
        struct nfs_cache_array *array;
+       unsigned int count = 0;
+       int status;
 
        buf.head->iov_base = xdr_page;
        buf.head->iov_len = buflen;
@@ -471,21 +482,32 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
 
        do {
                status = xdr_decode(desc, entry, &stream);
-               if (status != 0)
+               if (status != 0) {
+                       if (status == -EAGAIN)
+                               status = 0;
                        break;
+               }
+
+               count++;
 
-               if (nfs_readdir_add_to_array(entry, page) == -1)
-                       break;
                if (desc->plus == 1)
                        nfs_prime_dcache(desc->file->f_path.dentry, entry);
+
+               status = nfs_readdir_add_to_array(entry, page);
+               if (status != 0)
+                       break;
        } while (!entry->eof);
 
-       if (status == -EBADCOOKIE && entry->eof) {
+       if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) {
                array = nfs_readdir_get_array(page);
-               array->eof_index = array->size - 1;
-               status = 0;
-               nfs_readdir_release_array(page);
+               if (!IS_ERR(array)) {
+                       array->eof_index = array->size;
+                       status = 0;
+                       nfs_readdir_release_array(page);
+               } else
+                       status = PTR_ERR(array);
        }
+       return status;
 }
 
 static
@@ -537,7 +559,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        struct nfs_entry entry;
        struct file     *file = desc->file;
        struct nfs_cache_array *array;
-       int status = 0;
+       int status = -ENOMEM;
        unsigned int array_size = ARRAY_SIZE(pages);
 
        entry.prev_cookie = 0;
@@ -549,6 +571,10 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
                goto out;
 
        array = nfs_readdir_get_array(page);
+       if (IS_ERR(array)) {
+               status = PTR_ERR(array);
+               goto out;
+       }
        memset(array, 0, sizeof(struct nfs_cache_array));
        array->eof_index = -1;
 
@@ -556,12 +582,19 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        if (!pages_ptr)
                goto out_release_array;
        do {
+               unsigned int pglen;
                status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
 
                if (status < 0)
                        break;
-               nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE);
-       } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY);
+               pglen = status;
+               status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen);
+               if (status < 0) {
+                       if (status == -ENOSPC)
+                               status = 0;
+                       break;
+               }
+       } while (array->eof_index < 0);
 
        nfs_readdir_free_large_page(pages_ptr, pages, array_size);
 out_release_array:
@@ -582,8 +615,10 @@ static
 int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
 {
        struct inode    *inode = desc->file->f_path.dentry->d_inode;
+       int ret;
 
-       if (nfs_readdir_xdr_to_array(desc, page, inode) < 0)
+       ret = nfs_readdir_xdr_to_array(desc, page, inode);
+       if (ret < 0)
                goto error;
        SetPageUptodate(page);
 
@@ -595,7 +630,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
        return 0;
  error:
        unlock_page(page);
-       return -EIO;
+       return ret;
 }
 
 static
@@ -608,12 +643,8 @@ void cache_page_release(nfs_readdir_descriptor_t *desc)
 static
 struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
 {
-       struct page *page;
-       page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
+       return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
                        desc->page_index, (filler_t *)nfs_readdir_filler, desc);
-       if (IS_ERR(page))
-               desc->eof = 1;
-       return page;
 }
 
 /*
@@ -639,8 +670,10 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
 static inline
 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
-       int res = -EAGAIN;
+       int res;
 
+       if (desc->page_index == 0)
+               desc->current_index = 0;
        while (1) {
                res = find_cache_page(desc);
                if (res != -EAGAIN)
@@ -666,35 +699,36 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
        int i = 0;
        int res = 0;
        struct nfs_cache_array *array = NULL;
-       unsigned int d_type = DT_UNKNOWN;
-       struct dentry *dentry = NULL;
 
        array = nfs_readdir_get_array(desc->page);
+       if (IS_ERR(array)) {
+               res = PTR_ERR(array);
+               goto out;
+       }
 
        for (i = desc->cache_entry_index; i < array->size; i++) {
-               d_type = DT_UNKNOWN;
+               struct nfs_cache_array_entry *ent;
 
-               res = filldir(dirent, array->array[i].string.name,
-                       array->array[i].string.len, file->f_pos,
-                       nfs_compat_user_ino64(array->array[i].ino), d_type);
-               if (res < 0)
+               ent = &array->array[i];
+               if (filldir(dirent, ent->string.name, ent->string.len,
+                   file->f_pos, nfs_compat_user_ino64(ent->ino),
+                   ent->d_type) < 0) {
+                       desc->eof = 1;
                        break;
+               }
                file->f_pos++;
                desc->cache_entry_index = i;
                if (i < (array->size-1))
                        *desc->dir_cookie = array->array[i+1].cookie;
                else
                        *desc->dir_cookie = array->last_cookie;
-               if (i == array->eof_index) {
-                       desc->eof = 1;
-                       break;
-               }
        }
+       if (i == array->eof_index)
+               desc->eof = 1;
 
        nfs_readdir_release_array(desc->page);
+out:
        cache_page_release(desc);
-       if (dentry != NULL)
-               dput(dentry);
        dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
                        (unsigned long long)*desc->dir_cookie, res);
        return res;
@@ -729,13 +763,13 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
                goto out;
        }
 
-       if (nfs_readdir_xdr_to_array(desc, page, inode) == -1) {
-               status = -EIO;
-               goto out_release;
-       }
-
        desc->page_index = 0;
        desc->page = page;
+
+       status = nfs_readdir_xdr_to_array(desc, page, inode);
+       if (status < 0)
+               goto out_release;
+
        status = nfs_do_filldir(desc, dirent, filldir);
 
  out:
@@ -786,14 +820,14 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                res = readdir_search_pagecache(desc);
 
                if (res == -EBADCOOKIE) {
+                       res = 0;
                        /* This means either end of directory */
                        if (*desc->dir_cookie && desc->eof == 0) {
                                /* Or that the server has 'lost' a cookie */
                                res = uncached_readdir(desc, dirent, filldir);
-                               if (res >= 0)
+                               if (res == 0)
                                        continue;
                        }
-                       res = 0;
                        break;
                }
                if (res == -ETOOSMALL && desc->plus) {
@@ -808,10 +842,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        break;
 
                res = nfs_do_filldir(desc, dirent, filldir);
-               if (res < 0) {
-                       res = 0;
+               if (res < 0)
                        break;
-               }
        }
 out:
        nfs_unblock_sillyrename(dentry);
@@ -1345,12 +1377,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
-                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
+                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                res = ERR_CAST(inode);
index 84d3c8b902068a057805e33c9533ffda7f6c0100..e6ace0d93c71485870be33434830740941aa43ac 100644 (file)
@@ -867,7 +867,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
                goto out;
        nfs_alloc_commit_data(dreq);
 
-       if (dreq->commit_data == NULL || count < wsize)
+       if (dreq->commit_data == NULL || count <= wsize)
                sync = NFS_FILE_SYNC;
 
        dreq->inode = inode;
index db08ff3ff454d840baf84ea8b7ce8e5583c6cdf9..e6356b750b777ae6224b8821fc253b1b4da30de6 100644 (file)
@@ -361,6 +361,15 @@ unsigned int nfs_page_length(struct page *page)
        return 0;
 }
 
+/*
+ * Convert a umode to a dirent->d_type
+ */
+static inline
+unsigned char nfs_umode_to_dtype(umode_t mode)
+{
+       return (mode >> 12) & 15;
+}
+
 /*
  * Determine the number of pages in an array of length 'len' and
  * with a base offset of 'base'
index e6bf45710cc7fcd0348459ed7a27cc9454ee7e88..5914a1911c951dda6839e5c0490164e2e6d13bbc 100644 (file)
@@ -423,7 +423,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        struct page **page;
        size_t hdrlen;
        unsigned int pglen, recvd;
-       int status, nr = 0;
+       int status;
 
        if ((status = ntohl(*p++)))
                return nfs_stat_to_errno(status);
@@ -443,7 +443,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       return nr;
+       return pglen;
 }
 
 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
@@ -485,6 +485,8 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se
        entry->prev_cookie        = entry->cookie;
        entry->cookie     = ntohl(*p++);
 
+       entry->d_type = DT_UNKNOWN;
+
        p = xdr_inline_peek(xdr, 8);
        if (p != NULL)
                entry->eof = !p[0] && p[1];
@@ -495,7 +497,7 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se
 
 out_overflow:
        print_overflow_msg(__func__, xdr);
-       return ERR_PTR(-EIO);
+       return ERR_PTR(-EAGAIN);
 }
 
 /*
index d9a5e832c2579f9b20c0164944ae139509d8fb79..f6cc60f06dac4e517f7743bb3c0c148106807120 100644 (file)
@@ -555,7 +555,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
        struct page **page;
        size_t hdrlen;
        u32 recvd, pglen;
-       int status, nr = 0;
+       int status;
 
        status = ntohl(*p++);
        /* Decode post_op_attrs */
@@ -586,7 +586,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
                pglen = recvd;
        page = rcvbuf->pages;
 
-       return nr;
+       return pglen;
 }
 
 __be32 *
@@ -622,11 +622,13 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s
        entry->prev_cookie = entry->cookie;
        p = xdr_decode_hyper(p, &entry->cookie);
 
+       entry->d_type = DT_UNKNOWN;
        if (plus) {
                entry->fattr->valid = 0;
                p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
                if (IS_ERR(p))
                        goto out_overflow_exit;
+               entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
                /* In fact, a post_op_fh3: */
                p = xdr_inline_decode(xdr, 4);
                if (unlikely(!p))
@@ -656,7 +658,7 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s
 out_overflow:
        print_overflow_msg(__func__, xdr);
 out_overflow_exit:
-       return ERR_PTR(-EIO);
+       return ERR_PTR(-EAGAIN);
 }
 
 /*
index 0f24cdf2cb132b1ad7018a520a7abbea753ce330..6a653ffd8e4e121e37c29d88ff2f5b0b4dbe264f 100644 (file)
@@ -2852,8 +2852,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
        res.pgbase = args.pgbase;
        status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
-       if (status == 0)
+       if (status >= 0) {
                memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
+               status += args.pgbase;
+       }
 
        nfs_invalidate_atime(dir);
 
index f313c4cce7e4d1d087b8a1b47b55f769edf40a21..9f1826b012e63bb2bf11486e1a2a8ba0dd58ff9b 100644 (file)
@@ -4518,7 +4518,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        xdr_read_pages(xdr, pglen);
 
 
-       return 0;
+       return pglen;
 }
 
 static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
@@ -6208,6 +6208,10 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
        if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
                entry->ino = entry->fattr->fileid;
 
+       entry->d_type = DT_UNKNOWN;
+       if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE)
+               entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
+
        if (verify_attr_len(xdr, p, len) < 0)
                goto out_overflow;
 
@@ -6221,7 +6225,7 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
 
 out_overflow:
        print_overflow_msg(__func__, xdr);
-       return ERR_PTR(-EIO);
+       return ERR_PTR(-EAGAIN);
 }
 
 /*
index 0a42e8f4adcbc1723b57a7dac93c78b0a34b975e..3c045044fca25183147704f3689c744549ebd77b 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/nfs_mount.h>
 #include <linux/nfs4_mount.h>
 #include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
 #include <linux/mnt_namespace.h>
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
 
+#ifdef CONFIG_NFS_V3
+#define NFS_DEFAULT_VERSION 3
+#else
+#define NFS_DEFAULT_VERSION 2
+#endif
+
 enum {
        /* Mount options that take no arguments */
        Opt_soft, Opt_hard,
@@ -2277,7 +2282,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        };
        int error = -ENOMEM;
 
-       data = nfs_alloc_parsed_mount_data(3);
+       data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
        mntfh = nfs_alloc_fhandle();
        if (data == NULL || mntfh == NULL)
                goto out_free_fh;
index ad2bfa68d534d28531c3788b955734b5d9a76985..116cab970e0f3d737c8377bde9c3d97192568c71 100644 (file)
@@ -2262,7 +2262,7 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
  * Spawn a thread to perform a recall on the delegation represented
  * by the lease (file_lock)
  *
- * Called from break_lease() with lock_kernel() held.
+ * Called from break_lease() with lock_flocks() held.
  * Note: we assume break_lease will only call this *once* for any given
  * lease.
  */
@@ -2286,7 +2286,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
        list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
        spin_unlock(&recall_lock);
 
-       /* only place dl_time is set. protected by lock_kernel*/
+       /* only place dl_time is set. protected by lock_flocks*/
        dp->dl_time = get_seconds();
 
        /*
@@ -2303,7 +2303,7 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
 /*
  * The file_lock is being reapd.
  *
- * Called by locks_free_lock() with lock_kernel() held.
+ * Called by locks_free_lock() with lock_flocks() held.
  */
 static
 void nfsd_release_deleg_cb(struct file_lock *fl)
@@ -2318,7 +2318,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
 }
 
 /*
- * Called from setlease() with lock_kernel() held
+ * Called from setlease() with lock_flocks() held
  */
 static
 int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
index 49c844dab33ac63d829d63ff151ab8b5403631fd..59e5fe742f7bd7bcc6d6aa88dbdcf595e4c64019 100644 (file)
@@ -335,7 +335,7 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
         * the device at this point.
         *
         * To prevent nilfs_dat_translate() from returning the
-        * uncommited block number, this makes a copy of the entry
+        * uncommitted block number, this makes a copy of the entry
         * buffer and redirects nilfs_dat_translate() to the copy.
         */
        if (!buffer_nilfs_redirected(entry_bh)) {
index 3e90f86d5bfeeaae741f3475a32ebe7666e46aa7..e00d9457c256179279b141868d6ed86494dec24e 100644 (file)
@@ -349,8 +349,8 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
                ino = vdesc->vd_ino;
                cno = vdesc->vd_cno;
                inode = nilfs_iget_for_gc(sb, ino, cno);
-               if (unlikely(inode == NULL)) {
-                       ret = -ENOMEM;
+               if (IS_ERR(inode)) {
+                       ret = PTR_ERR(inode);
                        goto failed;
                }
                do {
index 52c7557f3e25ad4cce288883ed070eb48f970a4e..9f26ac9be2a45d38e340bed6d51164492fab0ca6 100644 (file)
@@ -1964,8 +1964,10 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
        if (reg == NULL)
                return ERR_PTR(-ENOMEM);
 
-       if (strlen(name) > O2HB_MAX_REGION_NAME_LEN)
-               return ERR_PTR(-ENAMETOOLONG);
+       if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) {
+               ret = -ENAMETOOLONG;
+               goto free;
+       }
 
        spin_lock(&o2hb_live_lock);
        reg->hr_region_num = 0;
@@ -1974,7 +1976,8 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
                                                         O2NM_MAX_REGIONS);
                if (reg->hr_region_num >= O2NM_MAX_REGIONS) {
                        spin_unlock(&o2hb_live_lock);
-                       return ERR_PTR(-EFBIG);
+                       ret = -EFBIG;
+                       goto free;
                }
                set_bit(reg->hr_region_num, o2hb_region_bitmap);
        }
@@ -1986,10 +1989,13 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
        ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
        if (ret) {
                config_item_put(&reg->hr_item);
-               return ERR_PTR(ret);
+               goto free;
        }
 
        return &reg->hr_item;
+free:
+       kfree(reg);
+       return ERR_PTR(ret);
 }
 
 static void o2hb_heartbeat_group_drop_item(struct config_group *group,
index edaded48e7e9f083ac7c67e72a9f031123f7844a..895532ac4d983376ed122f016ef13ad36e3c95b3 100644 (file)
@@ -476,7 +476,6 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
 
 out:
        iput(inode);
-       ocfs2_dentry_attach_gen(dentry);
 }
 
 /*
index 58a93b953735ebcaeda134794195449da4e98a53..cc2aaa96cfe5c58540c23f863701102a0c8096a8 100644 (file)
@@ -959,7 +959,7 @@ static int dlm_match_regions(struct dlm_ctxt *dlm,
                r += O2HB_MAX_REGION_NAME_LEN;
        }
 
-       local = kmalloc(sizeof(qr->qr_regions), GFP_KERNEL);
+       local = kmalloc(sizeof(qr->qr_regions), GFP_ATOMIC);
        if (!local) {
                status = -ENOMEM;
                goto bail;
index 1efea3615589ae1d5c30509d73cd03c09ccc973e..70dd3b1798f136130f4ef5ab5198012c2e3bc82d 100644 (file)
@@ -159,9 +159,9 @@ struct ocfs2_lock_res {
        char                     l_name[OCFS2_LOCK_ID_MAX_LEN];
        unsigned int             l_ro_holders;
        unsigned int             l_ex_holders;
-       char                     l_level;
-       char                     l_requested;
-       char                     l_blocking;
+       signed char              l_level;
+       signed char              l_requested;
+       signed char              l_blocking;
 
        /* Data packed - type enum ocfs2_lock_type */
        unsigned char            l_type;
index 252e7c82f929c203aca6a294d24b49dd17612cee..a5ebe421195fea3df8d66f2dc3573534a3bc298a 100644 (file)
@@ -190,7 +190,7 @@ static struct ocfs2_live_connection *ocfs2_connection_find(const char *name)
                        return c;
        }
 
-       return c;
+       return NULL;
 }
 
 /*
index f02c0ef315788427e1f8b51e964f9b9dec513a10..cfeab7ce36974b6d448e7e0b7d96fd0a992dbaa5 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/mount.h>
 #include <linux/seq_file.h>
 #include <linux/quotaops.h>
-#include <linux/smp_lock.h>
 
 #define MLOG_MASK_PREFIX ML_SUPER
 #include <cluster/masklog.h>
index a8012a955720418eb059b237ac68bd98760891bb..04629f36e3978dc44ec1611994664f157cc9d4f8 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1199,12 +1199,24 @@ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
        return ret;
 }
 
+/*
+ * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
+ * location, so checking ->i_pipe is not enough to verify that this is a
+ * pipe.
+ */
+struct pipe_inode_info *get_pipe_info(struct file *file)
+{
+       struct inode *i = file->f_path.dentry->d_inode;
+
+       return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL;
+}
+
 long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct pipe_inode_info *pipe;
        long ret;
 
-       pipe = file->f_path.dentry->d_inode->i_pipe;
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
index f3d02ca461ecfcc341eb783fd15da8df486fde11..182845147fe45bde8f5607a799f23cc1e2818117 100644 (file)
@@ -1574,7 +1574,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
        if (!tmp)
                return -ENOMEM;
 
-       pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE);
+       pathname = d_path(path, tmp, PAGE_SIZE);
        len = PTR_ERR(pathname);
        if (IS_ERR(pathname))
                goto out;
index 9c2b5f484879ad37a1633a6023524e2cb0151a3f..3ddb6068177c9a7d359f45b8aa60d6fb92dec9b4 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/limits.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/sysctl.h>
 #include <linux/slab.h>
 
index da6b01d70f019506face0dae73f0b78c3200d299..c126c83b9a45bc838125d1ac12b44e13f89d8b26 100644 (file)
@@ -706,6 +706,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
  * skip over unmapped regions.
  */
 #define PAGEMAP_WALK_SIZE      (PMD_SIZE)
+#define PAGEMAP_WALK_MASK      (PMD_MASK)
 static ssize_t pagemap_read(struct file *file, char __user *buf,
                            size_t count, loff_t *ppos)
 {
@@ -776,7 +777,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
                unsigned long end;
 
                pm.pos = 0;
-               end = start_vaddr + PAGEMAP_WALK_SIZE;
+               end = (start_vaddr + PAGEMAP_WALK_SIZE) & PAGEMAP_WALK_MASK;
                /* overflow ? */
                if (end < start_vaddr || end > end_vaddr)
                        end = end_vaddr;
index 431a0ed610c83a8750592e516ff23ac35ffbe524..5d431bacbea967e7a66755bf9320f20d9f464902 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/fcntl.h>
 #include <linux/file.h>
 #include <linux/uio.h>
-#include <linux/smp_lock.h>
 #include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/module.h>
index 41656d40dc5c87fc8bcfd9ec5aea4bc635ebc092..0bae036831e2ca2aeeae94eb78d74f2aa769b54d 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/reiserfs_acl.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/exportfs.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
index adf22b485ceac01e0f5ed7b0a8d1593956a7b81f..79265fdc317a09889c6ce3c2343bb17594bce40e 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/time.h>
 #include <asm/uaccess.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/compat.h>
 
 /*
@@ -184,12 +183,11 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
                return 0;
        }
 
-       /* we need to make sure nobody is changing the file size beneath
-        ** us
-        */
-       reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
        depth = reiserfs_write_lock_once(inode->i_sb);
 
+       /* we need to make sure nobody is changing the file size beneath us */
+       reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
+
        write_from = inode->i_size & (blocksize - 1);
        /* if we are on a block boundary, we are already unpacked.  */
        if (write_from == 0) {
index 076c8b19468297dc71add1987b249ab054d6e20d..d31bce1a9f908e1df4c8046f371bec748c215440 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
index 3bf7a6457f4d3f021db9d561a34ab7fb07bf1e01..b243117b8752d0a9c81fa8f12773ca202a9cfabb 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/crc32.h>
-#include <linux/smp_lock.h>
 
 struct file_system_type reiserfs_fs_type;
 
index 536d697a8a283102f57053fcbb3338bd784bf559..90d2fcb67a314633a4f3855dc08e057a43390a40 100644 (file)
@@ -472,7 +472,9 @@ int reiserfs_acl_chmod(struct inode *inode)
                struct reiserfs_transaction_handle th;
                size_t size = reiserfs_xattr_nblocks(inode,
                                             reiserfs_acl_size(clone->a_count));
-               reiserfs_write_lock(inode->i_sb);
+               int depth;
+
+               depth = reiserfs_write_lock_once(inode->i_sb);
                error = journal_begin(&th, inode->i_sb, size * 2);
                if (!error) {
                        int error2;
@@ -482,7 +484,7 @@ int reiserfs_acl_chmod(struct inode *inode)
                        if (error2)
                                error = error2;
                }
-               reiserfs_write_unlock(inode->i_sb);
+               reiserfs_write_unlock_once(inode->i_sb, depth);
        }
        posix_acl_release(clone);
        return error;
index 8f1dfaecc8f06125429d3bc66b052d779f61f446..ce2f02579e3539ff504f564564077b0641691e6d 100644 (file)
@@ -1311,18 +1311,6 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
                               struct pipe_inode_info *opipe,
                               size_t len, unsigned int flags);
-/*
- * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
- * location, so checking ->i_pipe is not enough to verify that this is a
- * pipe.
- */
-static inline struct pipe_inode_info *pipe_info(struct inode *inode)
-{
-       if (S_ISFIFO(inode->i_mode))
-               return inode->i_pipe;
-
-       return NULL;
-}
 
 /*
  * Determine where to splice to/from.
@@ -1336,8 +1324,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
        loff_t offset, *off;
        long ret;
 
-       ipipe = pipe_info(in->f_path.dentry->d_inode);
-       opipe = pipe_info(out->f_path.dentry->d_inode);
+       ipipe = get_pipe_info(in);
+       opipe = get_pipe_info(out);
 
        if (ipipe && opipe) {
                if (off_in || off_out)
@@ -1555,7 +1543,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
        int error;
        long ret;
 
-       pipe = pipe_info(file->f_path.dentry->d_inode);
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
@@ -1642,7 +1630,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
        };
        long ret;
 
-       pipe = pipe_info(file->f_path.dentry->d_inode);
+       pipe = get_pipe_info(file);
        if (!pipe)
                return -EBADF;
 
@@ -2022,8 +2010,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
 static long do_tee(struct file *in, struct file *out, size_t len,
                   unsigned int flags)
 {
-       struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode);
-       struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode);
+       struct pipe_inode_info *ipipe = get_pipe_info(in);
+       struct pipe_inode_info *opipe = get_pipe_info(out);
        int ret = -EINVAL;
 
        /*
index 7d287afccde58ac16c854ee5dc2eb31f2f7b1637..691f61223ed628137bfeb2ed2856a3ccbcf71894 100644 (file)
@@ -934,7 +934,6 @@ xfs_aops_discard_page(
        struct xfs_inode        *ip = XFS_I(inode);
        struct buffer_head      *bh, *head;
        loff_t                  offset = page_offset(page);
-       ssize_t                 len = 1 << inode->i_blkbits;
 
        if (!xfs_is_delayed_page(page, IO_DELAY))
                goto out_invalidate;
@@ -949,58 +948,14 @@ xfs_aops_discard_page(
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        bh = head = page_buffers(page);
        do {
-               int             done;
-               xfs_fileoff_t   offset_fsb;
-               xfs_bmbt_irec_t imap;
-               int             nimaps = 1;
                int             error;
-               xfs_fsblock_t   firstblock;
-               xfs_bmap_free_t flist;
+               xfs_fileoff_t   start_fsb;
 
                if (!buffer_delay(bh))
                        goto next_buffer;
 
-               offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
-
-               /*
-                * Map the range first and check that it is a delalloc extent
-                * before trying to unmap the range. Otherwise we will be
-                * trying to remove a real extent (which requires a
-                * transaction) or a hole, which is probably a bad idea...
-                */
-               error = xfs_bmapi(NULL, ip, offset_fsb, 1,
-                               XFS_BMAPI_ENTIRE,  NULL, 0, &imap,
-                               &nimaps, NULL);
-
-               if (error) {
-                       /* something screwed, just bail */
-                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
-                               "page discard failed delalloc mapping lookup.");
-                       }
-                       break;
-               }
-               if (!nimaps) {
-                       /* nothing there */
-                       goto next_buffer;
-               }
-               if (imap.br_startblock != DELAYSTARTBLOCK) {
-                       /* been converted, ignore */
-                       goto next_buffer;
-               }
-               WARN_ON(imap.br_blockcount == 0);
-
-               /*
-                * Note: while we initialise the firstblock/flist pair, they
-                * should never be used because blocks should never be
-                * allocated or freed for a delalloc extent and hence we need
-                * don't cancel or finish them after the xfs_bunmapi() call.
-                */
-               xfs_bmap_init(&flist, &firstblock);
-               error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock,
-                                       &flist, &done);
-
-               ASSERT(!flist.xbf_count && !flist.xbf_first);
+               start_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+               error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 1);
                if (error) {
                        /* something screwed, just bail */
                        if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
@@ -1010,7 +965,7 @@ xfs_aops_discard_page(
                        break;
                }
 next_buffer:
-               offset += len;
+               offset += 1 << inode->i_blkbits;
 
        } while ((bh = bh->b_this_page) != head);
 
@@ -1505,11 +1460,42 @@ xfs_vm_write_failed(
        struct inode            *inode = mapping->host;
 
        if (to > inode->i_size) {
-               struct iattr    ia = {
-                       .ia_valid       = ATTR_SIZE | ATTR_FORCE,
-                       .ia_size        = inode->i_size,
-               };
-               xfs_setattr(XFS_I(inode), &ia, XFS_ATTR_NOLOCK);
+               /*
+                * punch out the delalloc blocks we have already allocated. We
+                * don't call xfs_setattr() to do this as we may be in the
+                * middle of a multi-iovec write and so the vfs inode->i_size
+                * will not match the xfs ip->i_size and so it will zero too
+                * much. Hence we jus truncate the page cache to zero what is
+                * necessary and punch the delalloc blocks directly.
+                */
+               struct xfs_inode        *ip = XFS_I(inode);
+               xfs_fileoff_t           start_fsb;
+               xfs_fileoff_t           end_fsb;
+               int                     error;
+
+               truncate_pagecache(inode, to, inode->i_size);
+
+               /*
+                * Check if there are any blocks that are outside of i_size
+                * that need to be trimmed back.
+                */
+               start_fsb = XFS_B_TO_FSB(ip->i_mount, inode->i_size) + 1;
+               end_fsb = XFS_B_TO_FSB(ip->i_mount, to);
+               if (end_fsb <= start_fsb)
+                       return;
+
+               xfs_ilock(ip, XFS_ILOCK_EXCL);
+               error = xfs_bmap_punch_delalloc_range(ip, start_fsb,
+                                                       end_fsb - start_fsb);
+               if (error) {
+                       /* something screwed, just bail */
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       "xfs_vm_write_failed: unable to clean up ino %lld",
+                                               ip->i_ino);
+                       }
+               }
+               xfs_iunlock(ip, XFS_ILOCK_EXCL);
        }
 }
 
index aa1d353def29c64903cf02db9af159d612259b87..4c5deb6e9e3192f1bd279ca9e7b02e824fe9e7cc 100644 (file)
@@ -488,29 +488,16 @@ found:
        spin_unlock(&pag->pag_buf_lock);
        xfs_perag_put(pag);
 
-       /* Attempt to get the semaphore without sleeping,
-        * if this does not work then we need to drop the
-        * spinlock and do a hard attempt on the semaphore.
-        */
-       if (down_trylock(&bp->b_sema)) {
+       if (xfs_buf_cond_lock(bp)) {
+               /* failed, so wait for the lock if requested. */
                if (!(flags & XBF_TRYLOCK)) {
-                       /* wait for buffer ownership */
                        xfs_buf_lock(bp);
                        XFS_STATS_INC(xb_get_locked_waited);
                } else {
-                       /* We asked for a trylock and failed, no need
-                        * to look at file offset and length here, we
-                        * know that this buffer at least overlaps our
-                        * buffer and is locked, therefore our buffer
-                        * either does not exist, or is this buffer.
-                        */
                        xfs_buf_rele(bp);
                        XFS_STATS_INC(xb_busy_locked);
                        return NULL;
                }
-       } else {
-               /* trylock worked */
-               XB_SET_OWNER(bp);
        }
 
        if (bp->b_flags & XBF_STALE) {
@@ -876,10 +863,18 @@ xfs_buf_rele(
  */
 
 /*
- *     Locks a buffer object, if it is not already locked.
- *     Note that this in no way locks the underlying pages, so it is only
- *     useful for synchronizing concurrent use of buffer objects, not for
- *     synchronizing independent access to the underlying pages.
+ *     Locks a buffer object, if it is not already locked.  Note that this in
+ *     no way locks the underlying pages, so it is only useful for
+ *     synchronizing concurrent use of buffer objects, not for synchronizing
+ *     independent access to the underlying pages.
+ *
+ *     If we come across a stale, pinned, locked buffer, we know that we are
+ *     being asked to lock a buffer that has been reallocated. Because it is
+ *     pinned, we know that the log has not been pushed to disk and hence it
+ *     will still be locked.  Rather than continuing to have trylock attempts
+ *     fail until someone else pushes the log, push it ourselves before
+ *     returning.  This means that the xfsaild will not get stuck trying
+ *     to push on stale inode buffers.
  */
 int
 xfs_buf_cond_lock(
@@ -890,6 +885,8 @@ xfs_buf_cond_lock(
        locked = down_trylock(&bp->b_sema) == 0;
        if (locked)
                XB_SET_OWNER(bp);
+       else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
+               xfs_log_force(bp->b_target->bt_mount, 0);
 
        trace_xfs_buf_cond_lock(bp, _RET_IP_);
        return locked ? 0 : -EBUSY;
index 8abd12e32e133578441ac9eab1a4ab46cdb55035..4111cd3966c764b3c41300d1e7a51a7579ead435 100644 (file)
@@ -5471,8 +5471,13 @@ xfs_getbmap(
                        if (error)
                                goto out_unlock_iolock;
                }
-
-               ASSERT(ip->i_delayed_blks == 0);
+               /*
+                * even after flushing the inode, there can still be delalloc
+                * blocks on the inode beyond EOF due to speculative
+                * preallocation. These are not removed until the release
+                * function is called or the inode is inactivated. Hence we
+                * cannot assert here that ip->i_delayed_blks == 0.
+                */
        }
 
        lock = xfs_ilock_map_shared(ip);
@@ -6070,3 +6075,79 @@ xfs_bmap_disk_count_leaves(
                *count += xfs_bmbt_disk_get_blockcount(frp);
        }
 }
+
+/*
+ * dead simple method of punching delalyed allocation blocks from a range in
+ * the inode. Walks a block at a time so will be slow, but is only executed in
+ * rare error cases so the overhead is not critical. This will alays punch out
+ * both the start and end blocks, even if the ranges only partially overlap
+ * them, so it is up to the caller to ensure that partial blocks are not
+ * passed in.
+ */
+int
+xfs_bmap_punch_delalloc_range(
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           start_fsb,
+       xfs_fileoff_t           length)
+{
+       xfs_fileoff_t           remaining = length;
+       int                     error = 0;
+
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+       do {
+               int             done;
+               xfs_bmbt_irec_t imap;
+               int             nimaps = 1;
+               xfs_fsblock_t   firstblock;
+               xfs_bmap_free_t flist;
+
+               /*
+                * Map the range first and check that it is a delalloc extent
+                * before trying to unmap the range. Otherwise we will be
+                * trying to remove a real extent (which requires a
+                * transaction) or a hole, which is probably a bad idea...
+                */
+               error = xfs_bmapi(NULL, ip, start_fsb, 1,
+                               XFS_BMAPI_ENTIRE,  NULL, 0, &imap,
+                               &nimaps, NULL);
+
+               if (error) {
+                       /* something screwed, just bail */
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       "Failed delalloc mapping lookup ino %lld fsb %lld.",
+                                               ip->i_ino, start_fsb);
+                       }
+                       break;
+               }
+               if (!nimaps) {
+                       /* nothing there */
+                       goto next_block;
+               }
+               if (imap.br_startblock != DELAYSTARTBLOCK) {
+                       /* been converted, ignore */
+                       goto next_block;
+               }
+               WARN_ON(imap.br_blockcount == 0);
+
+               /*
+                * Note: while we initialise the firstblock/flist pair, they
+                * should never be used because blocks should never be
+                * allocated or freed for a delalloc extent and hence we need
+                * don't cancel or finish them after the xfs_bunmapi() call.
+                */
+               xfs_bmap_init(&flist, &firstblock);
+               error = xfs_bunmapi(NULL, ip, start_fsb, 1, 0, 1, &firstblock,
+                                       &flist, &done);
+               if (error)
+                       break;
+
+               ASSERT(!flist.xbf_count && !flist.xbf_first);
+next_block:
+               start_fsb++;
+               remaining--;
+       } while(remaining > 0);
+
+       return error;
+}
index 71ec9b6ecdfcbb15e65d7857681cd3f9126cc9b1..3651191daea10cd99bae79443a2b1b9305940250 100644 (file)
@@ -394,6 +394,11 @@ xfs_bmap_count_blocks(
        int                     whichfork,
        int                     *count);
 
+int
+xfs_bmap_punch_delalloc_range(
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           start_fsb,
+       xfs_fileoff_t           length);
 #endif /* __KERNEL__ */
 
 #endif /* __XFS_BMAP_H__ */
index 3b9582c60a225117f7b6d4180e4287b0118375ed..e60490bc00a61b6c8bc1bfbe04df4e56e536596c 100644 (file)
@@ -377,6 +377,19 @@ xfs_swap_extents(
        ip->i_d.di_format = tip->i_d.di_format;
        tip->i_d.di_format = tmp;
 
+       /*
+        * The extents in the source inode could still contain speculative
+        * preallocation beyond EOF (e.g. the file is open but not modified
+        * while defrag is in progress). In that case, we need to copy over the
+        * number of delalloc blocks the data fork in the source inode is
+        * tracking beyond EOF so that when the fork is truncated away when the
+        * temporary inode is unlinked we don't underrun the i_delayed_blks
+        * counter on that inode.
+        */
+       ASSERT(tip->i_delayed_blks == 0);
+       tip->i_delayed_blks = ip->i_delayed_blks;
+       ip->i_delayed_blks = 0;
+
        ilf_fields = XFS_ILOG_CORE;
 
        switch(ip->i_d.di_format) {
index ed99902676615e166a8e08371bf79c3a33d98021..c78cc6a3d87c0bb061092564c9f27c52d48519fa 100644 (file)
@@ -58,6 +58,7 @@ xfs_error_trap(int e)
 int    xfs_etest[XFS_NUM_INJECT_ERROR];
 int64_t        xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
 char * xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
+int    xfs_error_test_active;
 
 int
 xfs_error_test(int error_tag, int *fsidp, char *expression,
@@ -108,6 +109,7 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
                        len = strlen(mp->m_fsname);
                        xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
                        strcpy(xfs_etest_fsname[i], mp->m_fsname);
+                       xfs_error_test_active++;
                        return 0;
                }
        }
@@ -137,6 +139,7 @@ xfs_errortag_clearall(xfs_mount_t *mp, int loud)
                        xfs_etest_fsid[i] = 0LL;
                        kmem_free(xfs_etest_fsname[i]);
                        xfs_etest_fsname[i] = NULL;
+                       xfs_error_test_active--;
                }
        }
 
index c2c1a072bb82493bc210c50c9f6980633f8c9732..f338847f80b8d36c5c017214ec9538dab795459b 100644 (file)
@@ -127,13 +127,14 @@ extern void xfs_corruption_error(const char *tag, int level,
 #define        XFS_RANDOM_BMAPIFORMAT                          XFS_RANDOM_DEFAULT
 
 #ifdef DEBUG
+extern int xfs_error_test_active;
 extern int xfs_error_test(int, int *, char *, int, char *, unsigned long);
 
 #define        XFS_NUM_INJECT_ERROR                            10
 #define XFS_TEST_ERROR(expr, mp, tag, rf)              \
-       ((expr) || \
+       ((expr) || (xfs_error_test_active && \
         xfs_error_test((tag), (mp)->m_fixedfsid, "expr", __LINE__, __FILE__, \
-                       (rf)))
+                       (rf))))
 
 extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
 extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
index c7ac020705df1fbad86550c58784ba34cf2ee3ba..7c8d30c453c340de5afbab276505487ddbbf3373 100644 (file)
@@ -657,18 +657,37 @@ xfs_inode_item_unlock(
 }
 
 /*
- * This is called to find out where the oldest active copy of the
- * inode log item in the on disk log resides now that the last log
- * write of it completed at the given lsn.  Since we always re-log
- * all dirty data in an inode, the latest copy in the on disk log
- * is the only one that matters.  Therefore, simply return the
- * given lsn.
+ * This is called to find out where the oldest active copy of the inode log
+ * item in the on disk log resides now that the last log write of it completed
+ * at the given lsn.  Since we always re-log all dirty data in an inode, the
+ * latest copy in the on disk log is the only one that matters.  Therefore,
+ * simply return the given lsn.
+ *
+ * If the inode has been marked stale because the cluster is being freed, we
+ * don't want to (re-)insert this inode into the AIL. There is a race condition
+ * where the cluster buffer may be unpinned before the inode is inserted into
+ * the AIL during transaction committed processing. If the buffer is unpinned
+ * before the inode item has been committed and inserted, then it is possible
+ * for the buffer to be written and IO completions before the inode is inserted
+ * into the AIL. In that case, we'd be inserting a clean, stale inode into the
+ * AIL which will never get removed. It will, however, get reclaimed which
+ * triggers an assert in xfs_inode_free() complaining about freein an inode
+ * still in the AIL.
+ *
+ * To avoid this, return a lower LSN than the one passed in so that the
+ * transaction committed code will not move the inode forward in the AIL but
+ * will still unpin it properly.
  */
 STATIC xfs_lsn_t
 xfs_inode_item_committed(
        struct xfs_log_item     *lip,
        xfs_lsn_t               lsn)
 {
+       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+       struct xfs_inode        *ip = iip->ili_inode;
+
+       if (xfs_iflags_test(ip, XFS_ISTALE))
+               return lsn - 1;
        return lsn;
 }
 
index 8c641bed9bbd36526870b6741fdd16f780e3b0ec..a2776e2807a4ce39051df02b7384da32d58c1545 100644 (file)
@@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXECBUF2          9
 #define I915_PARAM_HAS_BSD              10
 #define I915_PARAM_HAS_BLT              11
+#define I915_PARAM_HAS_RELAXED_FENCING  12
+#define I915_PARAM_HAS_COHERENT_RINGS   13
 
 typedef struct drm_i915_getparam {
        int param;
index 01a7141195068c8e0fd384c0dde661adfb9601b6..bc5590b1a1acbe852314995f11b479e221ba6281 100644 (file)
@@ -80,6 +80,7 @@ struct drm_nouveau_gpuobj_free {
 #define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
 #define NOUVEAU_GETPARAM_GRAPH_UNITS     13
 #define NOUVEAU_GETPARAM_PTIMER_TIME     14
+#define NOUVEAU_GETPARAM_HAS_BO_USAGE    15
 struct drm_nouveau_getparam {
        uint64_t param;
        uint64_t value;
@@ -95,6 +96,12 @@ struct drm_nouveau_setparam {
 #define NOUVEAU_GEM_DOMAIN_GART      (1 << 2)
 #define NOUVEAU_GEM_DOMAIN_MAPPABLE  (1 << 3)
 
+#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00
+#define NOUVEAU_GEM_TILE_16BPP       0x00000001
+#define NOUVEAU_GEM_TILE_32BPP       0x00000002
+#define NOUVEAU_GEM_TILE_ZETA        0x00000004
+#define NOUVEAU_GEM_TILE_NONCONTIG   0x00000008
+
 struct drm_nouveau_gem_info {
        uint32_t handle;
        uint32_t domain;
index a065612fc928768268cf0352c91c34dc3f7c448a..64a7114a939427b5a7e74c761c27c0bdd9ee6d05 100644 (file)
@@ -29,6 +29,7 @@ struct linux_binprm{
        char buf[BINPRM_BUF_SIZE];
 #ifdef CONFIG_MMU
        struct vm_area_struct *vma;
+       unsigned long vma_pages;
 #else
 # define MAX_ARG_PAGES 32
        struct page *page[MAX_ARG_PAGES];
@@ -59,6 +60,10 @@ struct linux_binprm{
        unsigned long loader, exec;
 };
 
+extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages);
+extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+                                       int write);
+
 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
 
index f22b2e941686fc370f85b942526ee392f1f9ead6..9e76d35670d204d6425b20d17595737fde4453ff 100644 (file)
@@ -227,8 +227,7 @@ extern int ceph_open_session(struct ceph_client *client);
 extern void ceph_release_page_vector(struct page **pages, int num_pages);
 
 extern struct page **ceph_get_direct_page_vector(const char __user *data,
-                                           int num_pages,
-                                           loff_t off, size_t len);
+                                                int num_pages);
 extern void ceph_put_page_vector(struct page **pages, int num_pages);
 extern void ceph_release_page_vector(struct page **pages, int num_pages);
 extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
index 5956d62c3057139ac6634df8e13556659d07725e..a108b425fee25aff2cbf4dd1924c047b925f7ab0 100644 (file)
@@ -82,6 +82,7 @@ struct ceph_msg {
        struct ceph_buffer *middle;
        struct page **pages;            /* data payload.  NOT OWNER. */
        unsigned nr_pages;              /* size of page array */
+       unsigned page_alignment;        /* io offset in first page */
        struct ceph_pagelist *pagelist; /* instead of pages */
        struct list_head list_head;
        struct kref kref;
index 6c91fb032c39cd907a3ac509db75a3a860e564c1..a1af29648fb54be5c0b5ac1cfc62879314145d56 100644 (file)
@@ -79,6 +79,7 @@ struct ceph_osd_request {
        struct ceph_file_layout r_file_layout;
        struct ceph_snap_context *r_snapc;    /* snap context for writes */
        unsigned          r_num_pages;        /* size of page array (follows) */
+       unsigned          r_page_alignment;   /* io offset in first page */
        struct page     **r_pages;            /* pages for data payload */
        int               r_pages_from_pool;
        int               r_own_pages;        /* if true, i own page list */
@@ -194,7 +195,8 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
                                      int do_sync, u32 truncate_seq,
                                      u64 truncate_size,
                                      struct timespec *mtime,
-                                     bool use_mempool, int num_reply);
+                                     bool use_mempool, int num_reply,
+                                     int page_align);
 
 static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
 {
@@ -218,7 +220,8 @@ extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                               struct ceph_file_layout *layout,
                               u64 off, u64 *plen,
                               u32 truncate_seq, u64 truncate_size,
-                              struct page **pages, int nr_pages);
+                              struct page **pages, int nr_pages,
+                              int page_align);
 
 extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
                                struct ceph_vino vino,
index 4823af64e9db2148c23e1ae4d0ad3fe21de4368a..5f09323ee8808abaa39ea0ab44e6f438591282c4 100644 (file)
  *
  * CPUs are exported via sysfs in the class/cpu/devices/
  * directory. 
- *
- * Per-cpu interfaces can be implemented using a struct device_interface. 
- * See the following for how to do this: 
- * - drivers/base/intf.c 
- * - Documentation/driver-model/interface.txt
  */
 #ifndef _LINUX_CPU_H_
 #define _LINUX_CPU_H_
index a7d9dc21391d276e94c7a008107d31a0c56d8dc6..7b776d71d36d0e465dfb4b6384899026253540cc 100644 (file)
@@ -175,10 +175,21 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
        return 0;
 }
 
-#define enable_intr_remapping(mode)    (-1)
-#define disable_intr_remapping()       (0)
-#define reenable_intr_remapping(mode)  (0)
 #define intr_remapping_enabled         (0)
+
+static inline int enable_intr_remapping(int eim)
+{
+       return -1;
+}
+
+static inline void disable_intr_remapping(void)
+{
+}
+
+static inline int reenable_intr_remapping(int eim)
+{
+       return 0;
+}
 #endif
 
 /* Can't use the common MSI interrupt functions
index 7fca3dc4e47581ef77afc0096b36a7613a1acdb9..d1631d37e9e0361cf12039d26ec611184692ced5 100644 (file)
@@ -1122,6 +1122,7 @@ extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags);
 extern void fb_dealloc_cmap(struct fb_cmap *cmap);
 extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to);
 extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to);
index 334d68a171081472a25f98baa510bc7eb4cfeb8e..c9e06cc70dad585c6c185db2d1503d3fad4a5a48 100644 (file)
@@ -34,9 +34,9 @@
 #define SEEK_MAX       SEEK_END
 
 struct fstrim_range {
-       uint64_t start;
-       uint64_t len;
-       uint64_t minlen;
+       __u64 start;
+       __u64 len;
+       __u64 minlen;
 };
 
 /* And dynamically-tunable limits and defaults: */
@@ -1612,7 +1612,6 @@ struct super_operations {
        ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
 #endif
        int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
-       int (*trim_fs) (struct super_block *, struct fstrim_range *);
 };
 
 /*
index e8713d55360ab90d85af0daca3b36bdfbcd430d1..f54adfcbec9c9ea1e8a44003bcf880f4ce8fe9cd 100644 (file)
@@ -360,7 +360,7 @@ void drain_local_pages(void *dummy);
 
 extern gfp_t gfp_allowed_mask;
 
-extern void set_gfp_allowed_mask(gfp_t mask);
-extern gfp_t clear_gfp_allowed_mask(gfp_t mask);
+extern void pm_restrict_gfp_mask(void);
+extern void pm_restore_gfp_mask(void);
 
 #endif /* __LINUX_GFP_H */
index ce73a30113b4d0181ef7a2131c060ca18f1de027..dd1a56fbe9241235f4baa059394d5d36bd050de7 100644 (file)
@@ -16,6 +16,8 @@ struct gpio_keys_button {
 struct gpio_keys_platform_data {
        struct gpio_keys_button *buttons;
        int nbuttons;
+       unsigned int poll_interval;     /* polling interval in msecs -
+                                          for polling driver only */
        unsigned int rep:1;             /* enable input subsystem auto repeat */
        int (*enable)(struct device *dev);
        void (*disable)(struct device *dev);
index 41cb31f14ee3068cd3c232fb07e385676f2f9ba0..32f9fd6619b4160c997bba07e2661382f3afaacf 100644 (file)
@@ -2,9 +2,6 @@
 #define LINUX_HARDIRQ_H
 
 #include <linux/preempt.h>
-#ifdef CONFIG_PREEMPT
-#include <linux/smp_lock.h>
-#endif
 #include <linux/lockdep.h>
 #include <linux/ftrace_irq.h>
 #include <asm/hardirq.h>
@@ -97,7 +94,8 @@
 #define in_nmi()       (preempt_count() & NMI_MASK)
 
 #if defined(CONFIG_PREEMPT) && defined(CONFIG_BKL)
-# define PREEMPT_INATOMIC_BASE kernel_locked()
+# include <linux/sched.h>
+# define PREEMPT_INATOMIC_BASE (current->lock_depth >= 0)
 #else
 # define PREEMPT_INATOMIC_BASE 0
 #endif
index 6ef44465db8ddc31c41be1de00eeef38c53b5fa5..a8af21d42bc146cc6f6ee186894e623b01a884ff 100644 (file)
@@ -47,6 +47,25 @@ struct input_id {
        __u16 version;
 };
 
+/**
+ * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
+ * @value: latest reported value for the axis.
+ * @minimum: specifies minimum value for the axis.
+ * @maximum: specifies maximum value for the axis.
+ * @fuzz: specifies fuzz value that is used to filter noise from
+ *     the event stream.
+ * @flat: values that are within this value will be discarded by
+ *     joydev interface and reported as 0 instead.
+ * @resolution: specifies resolution for the values reported for
+ *     the axis.
+ *
+ * Note that input core does not clamp reported values to the
+ * [minimum, maximum] limits, such task is left to userspace.
+ *
+ * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
+ * units per millimeter (units/mm), resolution for rotational axes
+ * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
+ */
 struct input_absinfo {
        __s32 value;
        __s32 minimum;
@@ -624,6 +643,10 @@ struct input_keymap_entry {
 #define KEY_CAMERA_FOCUS       0x210
 #define KEY_WPS_BUTTON         0x211   /* WiFi Protected Setup key */
 
+#define KEY_TOUCHPAD_TOGGLE    0x212   /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON                0x213
+#define KEY_TOUCHPAD_OFF       0x214
+
 #define BTN_TRIGGER_HAPPY              0x2c0
 #define BTN_TRIGGER_HAPPY1             0x2c0
 #define BTN_TRIGGER_HAPPY2             0x2c1
@@ -1130,7 +1153,7 @@ struct input_mt_slot {
  *     of tracked contacts
  * @mtsize: number of MT slots the device uses
  * @slot: MT slot currently being transmitted
- * @absinfo: array of &struct absinfo elements holding information
+ * @absinfo: array of &struct input_absinfo elements holding information
  *     about absolute axes (current value, min, max, flat, fuzz,
  *     resolution)
  * @key: reflects current state of device's keys/buttons
index 15b77b8dc7e11f529b93cc9ba629f464627d3a74..d947b1231662b9f69b388d0c5e3393972285faa3 100644 (file)
@@ -986,7 +986,7 @@ extern void ata_host_init(struct ata_host *, struct device *,
                          unsigned long, struct ata_port_operations *);
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
-extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
                            int cmd, void __user *arg);
 extern void ata_sas_port_destroy(struct ata_port *);
index a34dea46b62953cb2675f6b17c7539431f54114b..2dee05e5119a42138dda84e6aca032215994cfa0 100644 (file)
@@ -43,6 +43,7 @@ struct nlm_host {
        struct sockaddr_storage h_addr;         /* peer address */
        size_t                  h_addrlen;
        struct sockaddr_storage h_srcaddr;      /* our address (optional) */
+       size_t                  h_srcaddrlen;
        struct rpc_clnt         *h_rpcclnt;     /* RPC client to talk to peer */
        char                    *h_name;                /* remote hostname */
        u32                     h_version;      /* interface version */
index 1ff81b51b656a13f32c4d8b5253f803593cd033b..dd3c34ebca9a67e05c2e59649da81486210e802c 100644 (file)
@@ -11,6 +11,7 @@
 #define MARVELL_PHY_ID_88E1118         0x01410e10
 #define MARVELL_PHY_ID_88E1121R                0x01410cb0
 #define MARVELL_PHY_ID_88E1145         0x01410cd0
+#define MARVELL_PHY_ID_88E1149R                0x01410e50
 #define MARVELL_PHY_ID_88E1240         0x01410e30
 #define MARVELL_PHY_ID_88E1318S                0x01410e90
 
index 4307231bd22fb23ad9732295f472bc4b8564e200..31c237a00c48e472b7c8e6c435fe66de9b0e232a 100644 (file)
@@ -161,6 +161,9 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
 extern void put_page_bootmem(struct page *page);
 #endif
 
+void lock_memory_hotplug(void);
+void unlock_memory_hotplug(void);
+
 #else /* ! CONFIG_MEMORY_HOTPLUG */
 /*
  * Stub functions for when hotplug is off
@@ -192,6 +195,9 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
 {
 }
 
+static inline void lock_memory_hotplug(void) {}
+static inline void unlock_memory_hotplug(void) {}
+
 #endif /* ! CONFIG_MEMORY_HOTPLUG */
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
index a95141eafce390d7586c17c4eb3f3777c20669db..bd581c6fa0855bf9014a5cb061d5dc78df204e21 100644 (file)
 #define WM8350_MCLK_SEL_PLL_32K                        3
 #define WM8350_MCLK_SEL_MCLK                   5
 
-#define WM8350_MCLK_DIR_OUT                    0
-#define WM8350_MCLK_DIR_IN                     1
-
 /* clock divider id's */
 #define WM8350_ADC_CLKDIV                      0
 #define WM8350_DAC_CLKDIV                      1
index 6d87f68ce4b6b70b8ff573f3e73e2550e9ca4acb..30f6fad99a58bb7f3a42e51606269a019826fbaa 100644 (file)
@@ -168,6 +168,7 @@ struct mmc_host {
                                                /* DDR mode at 1.8V */
 #define MMC_CAP_1_2V_DDR       (1 << 12)       /* can support */
                                                /* DDR mode at 1.2V */
+#define MMC_CAP_POWER_OFF_CARD (1 << 13)       /* Can power off after boot */
 
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
 
index b29e7458b96642b2f36162aa755b10ff76b15abe..7575bbbdf2a2b8e6a716fb6252c3d8e958756f52 100644 (file)
@@ -517,7 +517,7 @@ static inline void __module_get(struct module *module)
 #define symbol_put_addr(p) do { } while(0)
 
 #endif /* CONFIG_MODULE_UNLOAD */
-int use_module(struct module *a, struct module *b);
+int ref_module(struct module *a, struct module *b);
 
 /* This is a #define so the string doesn't get put in every .o file */
 #define module_name(mod)                       \
index bba26684acdc5e0e9364419db9cc3fb7802c1109..c66fdb7d6998129701f6eaa653f1d28dd641e332 100644 (file)
@@ -593,12 +593,6 @@ nfs_fileid_to_ino_t(u64 fileid)
        return ino;
 }
 
-#define nfs_wait_event(clnt, wq, condition)                            \
-({                                                                     \
-       int __retval = wait_event_killable(wq, condition);              \
-       __retval;                                                       \
-})
-
 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
 
 #endif /* __KERNEL__ */
index ba6cc8f223c94190a13a2e1ef2316f993c205010..80f07198a31a682814684d7946915cedd1df5d56 100644 (file)
@@ -483,6 +483,7 @@ struct nfs_entry {
        int                     eof;
        struct nfs_fh *         fh;
        struct nfs_fattr *      fattr;
+       unsigned char           d_type;
 };
 
 /*
index 06292dac3eab15ea6f4b82ddc868e7f955889e7e..1466945cc9ef46c252fe7cd7834758fb3ddf9e19 100644 (file)
  *
  * Nodes are exported via driverfs in the class/node/devices/
  * directory. 
- *
- * Per-node interfaces can be implemented using a struct device_interface. 
- * See the following for how to do this: 
- * - drivers/base/intf.c 
- * - Documentation/driver-model/interface.txt
  */
 #ifndef _LINUX_NODE_H_
 #define _LINUX_NODE_H_
index 5bb13b3db84d46ee155784a26acfd850e94c91ff..b02195dfc1b0d3eb3044972db401b50acb0ad27d 100644 (file)
@@ -59,8 +59,6 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc)     \
 static inline int TestClearPageCgroup##uname(struct page_cgroup *pc)   \
        { return test_and_clear_bit(PCG_##lname, &pc->flags);  }
 
-TESTPCGFLAG(Locked, LOCK)
-
 /* Cache flag is set only once (at allocation) */
 TESTPCGFLAG(Cache, CACHE)
 CLEARPCGFLAG(Cache, CACHE)
@@ -104,6 +102,11 @@ static inline void unlock_page_cgroup(struct page_cgroup *pc)
        bit_spin_unlock(PCG_LOCK, &pc->flags);
 }
 
+static inline int page_is_cgroup_locked(struct page_cgroup *pc)
+{
+       return bit_spin_is_locked(PCG_LOCK, &pc->flags);
+}
+
 #else /* CONFIG_CGROUP_MEM_RES_CTLR */
 struct page_cgroup;
 
index c6bcfe93b9cab9deeab76844ce8b76e2a2adf5bb..cb845c16ad7d22fe2bd7f22eb9320085ff09c1ca 100644 (file)
 #define PCI_DEVICE_ID_AFAVLAB_P030     0x2182
 #define PCI_SUBDEVICE_ID_AFAVLAB_P061          0x2150
 
+#define PCI_VENDOR_ID_BCM_GVC          0x14a4
 #define PCI_VENDOR_ID_BROADCOM         0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752      0x1600
 #define PCI_DEVICE_ID_TIGON3_5752M     0x1601
 #define PCI_DEVICE_ID_INTEL_MFD_SDIO2  0x0822
 #define PCI_DEVICE_ID_INTEL_MFD_EMMC0  0x0823
 #define PCI_DEVICE_ID_INTEL_MFD_EMMC1  0x0824
+#define PCI_DEVICE_ID_INTEL_MRST_SD2   0x084F
 #define PCI_DEVICE_ID_INTEL_I960       0x0960
 #define PCI_DEVICE_ID_INTEL_I960RM     0x0962
 #define PCI_DEVICE_ID_INTEL_8257X_SOL  0x1062
index 445796945ac9d1c491c1d740f0f2ca7bfa1ae22b..bb27d7ec2fb95cac4599351532f482d1df129fab 100644 (file)
@@ -160,5 +160,6 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
 
 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
 long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
+struct pipe_inode_info *get_pipe_info(struct file *file);
 
 #endif
index 5ca47e59b7278ffbb0dd4fc624d9e4cf1697d0ae..c21072adbfad7e84417b8cf925e2fc0b21172cea 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/unaligned.h>
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/reiserfs_fs_i.h>
 #include <linux/reiserfs_fs_sb.h>
index d42f274418b884ea72f8de09cda464af817fd774..bbad657a37259c0f35e99341761a789731435e25 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/if_link.h>
 #include <linux/if_addr.h>
 #include <linux/neighbour.h>
-#include <linux/netdevice.h>
 
 /* rtnetlink families. Values up to 127 are reserved for real address
  * families, values above 128 may be used arbitrarily.
@@ -606,6 +605,7 @@ struct tcamsg {
 #ifdef __KERNEL__
 
 #include <linux/mutex.h>
+#include <linux/netdevice.h>
 
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 {
index d0036e52a24a1c28eaef9e60bb5aa100aaa18af1..2c79e921a68baeb9d5afa9b0deaa731232685ed5 100644 (file)
@@ -862,6 +862,7 @@ struct sched_group {
         * single CPU.
         */
        unsigned int cpu_power, cpu_power_orig;
+       unsigned int group_weight;
 
        /*
         * The CPUs this group covers.
index cea0c38e7a63dfad2544043c49fca25aea9a7563..9a52f72527dc5a38831686cb824bf043258c8a19 100644 (file)
@@ -19,11 +19,13 @@ struct clk_mapping {
 };
 
 struct clk_ops {
+#ifdef CONFIG_SH_CLK_CPG_LEGACY
        void (*init)(struct clk *clk);
+#endif
        int (*enable)(struct clk *clk);
        void (*disable)(struct clk *clk);
        unsigned long (*recalc)(struct clk *clk);
-       int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
+       int (*set_rate)(struct clk *clk, unsigned long rate);
        int (*set_parent)(struct clk *clk, struct clk *parent);
        long (*round_rate)(struct clk *clk, unsigned long rate);
 };
@@ -67,36 +69,6 @@ int clk_register(struct clk *);
 void clk_unregister(struct clk *);
 void clk_enable_init_clocks(void);
 
-/**
- * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
- * @clk: clock source
- * @rate: desired clock rate in Hz
- * @algo_id: algorithm id to be passed down to ops->set_rate
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
-
-enum clk_sh_algo_id {
-       NO_CHANGE = 0,
-
-       IUS_N1_N1,
-       IUS_322,
-       IUS_522,
-       IUS_N11,
-
-       SB_N1,
-
-       SB3_N1,
-       SB3_32,
-       SB3_43,
-       SB3_54,
-
-       BP_N1,
-
-       IP_N1,
-};
-
 struct clk_div_mult_table {
        unsigned int *divisors;
        unsigned int nr_divisors;
index 291f721144c2e23c51e4fbb92288f89e6b68dc11..3a1988202731e55563315703ed3f5cfb52f8abc9 100644 (file)
@@ -4,8 +4,6 @@
 #ifdef CONFIG_LOCK_KERNEL
 #include <linux/sched.h>
 
-#define kernel_locked()                (current->lock_depth >= 0)
-
 extern int __lockfunc __reacquire_kernel_lock(void);
 extern void __lockfunc __release_kernel_lock(void);
 
@@ -58,7 +56,6 @@ static inline void cycle_kernel_lock(void)
 #define lock_kernel()
 #define unlock_kernel()
 #define cycle_kernel_lock()                    do { } while(0)
-#define kernel_locked()                                1
 #endif /* CONFIG_BKL */
 
 #define release_kernel_lock(task)              do { } while(0)
index c7ea9bc8897cb638208a88bcb6352814b4639dc8..54e4eaaa05610d8b101a97f1c3faa11d11399861 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/tty_driver.h>
 #include <linux/tty_ldisc.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 
@@ -367,6 +366,7 @@ struct tty_file_private {
 #define TTY_HUPPED             18      /* Post driver->hangup() */
 #define TTY_FLUSHING           19      /* Flushing to ldisc in progress */
 #define TTY_FLUSHPENDING       20      /* Queued buffer flush pending */
+#define TTY_HUPPING            21      /* ->hangup() in progress */
 
 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
 
index d6188e5a52df900e9829461538b9c4976356d6b0..665517c05eaf2470f57b546a801b8e8bcac03e52 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
  * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
  * Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
  *
  * Userspace IO driver.
index 24300d8a1bc16eaf18c647056842102b47283980..a28eb25925778b3b156d9ccf8da5d3a593b97a3f 100644 (file)
@@ -313,6 +313,10 @@ struct usb_bus {
        int busnum;                     /* Bus number (in order of reg) */
        const char *bus_name;           /* stable id (PCI slot_name etc) */
        u8 uses_dma;                    /* Does the host controller use DMA? */
+       u8 uses_pio_for_control;        /*
+                                        * Does the host controller use PIO
+                                        * for control transfers?
+                                        */
        u8 otg_port;                    /* 0, or number of OTG/HNP port */
        unsigned is_b_host:1;           /* true during some HNP roleswitches */
        unsigned b_hnp_enable:1;        /* OTG: did A-Host enable HNP? */
index a03dcf62ca9d591d00290ced4394f7873b81329e..44b54f619ac6b29ef26b6bae7f7b10c05a536bc1 100644 (file)
@@ -7,8 +7,6 @@
 
 struct vm_area_struct;         /* vma defining user mapping in mm_types.h */
 
-extern bool vmap_lazy_unmap;
-
 /* bits in flags of vmalloc's vm_struct below */
 #define VM_IOREMAP     0x00000001      /* ioremap() and friends */
 #define VM_ALLOC       0x00000002      /* vmalloc() */
index 41dd480e45f105e78eecd7ba47bffc909d550186..239125af3ea3ae08ca0a09cf0d19c7aee2fe825e 100644 (file)
@@ -137,31 +137,27 @@ struct v4l2_subdev_ops;
 
 
 /* Load an i2c module and return an initialized v4l2_subdev struct.
-   Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                int irq, void *platform_data,
                u8 addr, const unsigned short *probe_addrs);
 
 /* Load an i2c module and return an initialized v4l2_subdev struct.
-   Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
 static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter,
-               const char *module_name, const char *client_type,
+               struct i2c_adapter *adapter, const char *client_type,
                u8 addr, const unsigned short *probe_addrs)
 {
-       return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name,
-                               client_type, 0, NULL, addr, probe_addrs);
+       return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, client_type, 0, NULL,
+                                      addr, probe_addrs);
 }
 
 struct i2c_board_info;
 
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
-               struct i2c_adapter *adapter, const char *module_name,
-               struct i2c_board_info *info, const unsigned short *probe_addrs);
+               struct i2c_adapter *adapter, struct i2c_board_info *info,
+               const unsigned short *probe_addrs);
 
 /* Initialize an v4l2_subdev with data from an i2c_client struct */
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
index 90c9e2872f27214b4727ecf4f440e4975be1f1df..18e5c3f675804eb6fbc84bb4aa0781944807c260 100644 (file)
@@ -10,6 +10,7 @@ extern void unix_inflight(struct file *fp);
 extern void unix_notinflight(struct file *fp);
 extern void unix_gc(void);
 extern void wait_for_unix_gc(void);
+extern struct sock *unix_get_socket(struct file *filp);
 
 #define UNIX_HASH_SIZE 256
 
@@ -56,6 +57,7 @@ struct unix_sock {
        spinlock_t              lock;
        unsigned int            gc_candidate : 1;
        unsigned int            gc_maybe_cycle : 1;
+       unsigned char           recursion_level;
        struct socket_wq        peer_wq;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
index 2a7936d7851d55de60251fc708672a87d5beb81b..97b8b7c9b63cf9854e3b8c2e83154c8ecb0bea06 100644 (file)
@@ -1355,7 +1355,7 @@ enum wiphy_flags {
        WIPHY_FLAG_4ADDR_AP                     = BIT(5),
        WIPHY_FLAG_4ADDR_STATION                = BIT(6),
        WIPHY_FLAG_CONTROL_PORT_PROTOCOL        = BIT(7),
-       WIPHY_FLAG_IBSS_RSN                     = BIT(7),
+       WIPHY_FLAG_IBSS_RSN                     = BIT(8),
 };
 
 struct mac_address {
index 55590ab16b3ed5192413b4b6415a8785c1d1a5bb..6beb1ffc2b7fcfe9d360717ccde3f70bd8ac0e3d 100644 (file)
@@ -303,7 +303,7 @@ static inline void neigh_confirm(struct neighbour *neigh)
 
 static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
-       unsigned long now = ACCESS_ONCE(jiffies);
+       unsigned long now = jiffies;
        
        if (neigh->used != now)
                neigh->used = now;
index f986ab7ffe6f040e9e00ac23d404bd8ad31e1f4e..5c4c1678f7be65d2d57d314dc5f583a974a1526e 100644 (file)
@@ -1006,8 +1006,7 @@ void fc_fcp_destroy(struct fc_lport *);
 /*
  * SCSI INTERACTION LAYER
  *****************************/
-int fc_queuecommand(struct scsi_cmnd *,
-                   void (*done)(struct scsi_cmnd *));
+int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fc_eh_abort(struct scsi_cmnd *);
 int fc_eh_device_reset(struct scsi_cmnd *);
 int fc_eh_host_reset(struct scsi_cmnd *);
index ae5196aae1a5311421e72ba22d9b9f43cb748500..b81d969ddc67cbbfde3f4522cf11a7b2f7487509 100644 (file)
@@ -341,8 +341,7 @@ extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
 extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
-extern int iscsi_queuecommand(struct scsi_cmnd *sc,
-                             void (*done)(struct scsi_cmnd *));
+extern int iscsi_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *sc);
 
 /*
  * iSCSI host helpers.
index 3dec1949f69cd75890368d40700f68399ac68427..90ce527ecf3d02c5c214308dc30098301d9892d5 100644 (file)
@@ -621,8 +621,7 @@ int sas_set_phy_speed(struct sas_phy *phy,
 int sas_phy_enable(struct sas_phy *phy, int enabled);
 int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 int sas_queue_up(struct sas_task *task);
-extern int sas_queuecommand(struct scsi_cmnd *,
-                    void (*scsi_done)(struct scsi_cmnd *));
+extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
 extern int sas_target_alloc(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
index d0a6a845f2045fb874481539e0c55d21a70fe7bb..e7e385842a38746d348eee460af6bc3d9e1a2ab6 100644 (file)
@@ -127,8 +127,7 @@ struct scsi_host_template {
         *
         * STATUS: REQUIRED
         */
-       int (* queuecommand)(struct scsi_cmnd *,
-                            void (*done)(struct scsi_cmnd *));
+       int (* queuecommand)(struct Scsi_Host *, struct scsi_cmnd *);
 
        /*
         * The transfer functions are used to queue a scsi command to
@@ -504,6 +503,25 @@ struct scsi_host_template {
        u64 vendor_id;
 };
 
+/*
+ * Temporary #define for host lock push down. Can be removed when all
+ * drivers have been updated to take advantage of unlocked
+ * queuecommand.
+ *
+ */
+#define DEF_SCSI_QCMD(func_name) \
+       int func_name(struct Scsi_Host *shost, struct scsi_cmnd *cmd)   \
+       {                                                               \
+               unsigned long irq_flags;                                \
+               int rc;                                                 \
+               spin_lock_irqsave(shost->host_lock, irq_flags);         \
+               scsi_cmd_get_serial(shost, cmd);                        \
+               rc = func_name##_lck (cmd, cmd->scsi_done);                     \
+               spin_unlock_irqrestore(shost->host_lock, irq_flags);    \
+               return rc;                                              \
+       }
+
+
 /*
  * shost state: If you alter this, you also need to alter scsi_sysfs.c
  * (for the ascii descriptions) and the state model enforcer:
@@ -752,6 +770,7 @@ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
 extern void scsi_host_put(struct Scsi_Host *t);
 extern struct Scsi_Host *scsi_host_lookup(unsigned short);
 extern const char *scsi_host_state_name(enum scsi_host_state);
+extern void scsi_cmd_get_serial(struct Scsi_Host *, struct scsi_cmnd *);
 
 extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
 
index fa60cbda90a4553f69b9b1ce94e51fd7df9fa880..d79894192ae3e10cb5f072c51f2ed640c7ba76fd 100644 (file)
@@ -85,7 +85,9 @@
  *     ACK_MD (FSI2)
  *     CKG1   (FSI)
  *
- * err:  return value < 0
+ * err         : return value <  0
+ * no change   : return value == 0
+ * change xMD  : return value >  0
  *
  * 0x-00000AB
  *
 struct sh_fsi_platform_info {
        unsigned long porta_flags;
        unsigned long portb_flags;
-       int (*set_rate)(int is_porta, int rate); /* for master mode */
+       int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
 };
 
 #endif /* __SOUND_FSI_H */
index 6316cdabf73f5756a300ef501fe5a1aa11acef53..89d43b3d4cb9e3fe713fe5b8eaeb2de0616eb9fa 100644 (file)
@@ -99,7 +99,6 @@ struct lcd_sync_arg {
 #define FBIPUT_COLOR           _IOW('F', 6, int)
 #define FBIPUT_HSYNC           _IOW('F', 9, int)
 #define FBIPUT_VSYNC           _IOW('F', 10, int)
-#define FBIO_WAITFORVSYNC      _IOW('F', 0x20, u_int32_t)
 
 #endif  /* ifndef DA8XX_FB_H */
 
index 646dd17d3aa4263c1eb0a530a9057b2fa35383a2..00f53ddcc06284658d33ff80d66908e2b394d4ca 100644 (file)
@@ -76,7 +76,9 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
 
 #ifdef CONFIG_PCI_MSI
 /* Allocate an irq and a pirq to be used with MSIs. */
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq);
+#define XEN_ALLOC_PIRQ (1 << 0)
+#define XEN_ALLOC_IRQ  (1 << 1)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_mask);
 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type);
 #endif
 
@@ -89,4 +91,7 @@ int xen_vector_from_irq(unsigned pirq);
 /* Return gsi allocated to pirq */
 int xen_gsi_from_irq(unsigned pirq);
 
+/* Return irq from pirq */
+int xen_irq_from_pirq(unsigned pirq);
+
 #endif /* _XEN_EVENTS_H */
index d7a6c13bde69cf505bef40027bcd555a4463d57f..eac3ce1537190228ba8dc74f0398d8e6e4795572 100644 (file)
@@ -140,6 +140,19 @@ struct xen_machphys_mfn_list {
 };
 DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);
 
+/*
+ * Returns the location in virtual address space of the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table, or which do not
+ * map it by default into guest address space, do not implement this command.
+ * arg == addr of xen_machphys_mapping_t.
+ */
+#define XENMEM_machphys_mapping     12
+struct xen_machphys_mapping {
+    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
+    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
+
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
  * pseudophysical address space.
index 2b2c66c3df0073e21535e3acdb5e54908b9ca116..534cac89a77deb20242aaf0b567c9a663c2db1d5 100644 (file)
@@ -188,6 +188,16 @@ struct physdev_nr_pirqs {
     uint32_t nr_pirqs;
 };
 
+/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
+ * the hypercall returns a free pirq */
+#define PHYSDEVOP_get_free_pirq    23
+struct physdev_get_free_pirq {
+    /* IN */ 
+    int type;
+    /* OUT */
+    uint32_t pirq;
+};
+
 /*
  * Notify that some PIRQ-bound event channels have been unmasked.
  * ** This command is obsolete since interface version 0x00030202 and is **
index eaf85fab12632d45cc00d8976d9108a3eacc2850..0be36b976f4b02905034532919e7fc576eba19d7 100644 (file)
@@ -1 +1,8 @@
+#ifndef _XEN_PAGE_H
+#define _XEN_PAGE_H
+
 #include <asm/xen/page.h>
+
+extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
+
+#endif /* _XEN_PAGE_H */
index b42cdfd92fee5becfa065aeaeec36b743b9664e8..17857fb4d5509b24a475609e2806af53c79d5317 100644 (file)
 #define __LINUX_PUBLIC_PRIVCMD_H__
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 typedef unsigned long xen_pfn_t;
 
-#ifndef __user
-#define __user
-#endif
-
 struct privcmd_hypercall {
        __u64 op;
        __u64 arg[5];
index 88c10468db467bb862554aab55f5d4891e4b0f03..c9728992a776356e043d21df7b33aa045c2d7904 100644 (file)
@@ -613,6 +613,19 @@ config CGROUP_MEM_RES_CTLR_SWAP
          if boot option "noswapaccount" is set, swap will not be accounted.
          Now, memory usage of swap_cgroup is 2 bytes per entry. If swap page
          size is 4096bytes, 512k per 1Gbytes of swap.
+config CGROUP_MEM_RES_CTLR_SWAP_ENABLED
+       bool "Memory Resource Controller Swap Extension enabled by default"
+       depends on CGROUP_MEM_RES_CTLR_SWAP
+       default y
+       help
+         Memory Resource Controller Swap Extension comes with its price in
+         a bigger memory consumption. General purpose distribution kernels
+         which want to enable the feautre but keep it disabled by default
+         and let the user enable it by swapaccount boot command line
+         parameter should have this option unselected.
+         For those who want to have the feature enabled by default should
+         select this option (if, for some reason, they need to disable it
+         then noswapaccount does the trick).
 
 menuconfig CGROUP_SCHED
        bool "Group CPU scheduler"
index e59af24a0b7c0dbb8417ff3b5c0818d544ac8060..8646401f7a0e4b77579aa13f8de6ac191787be73 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
index 37755d621924e5256b3494d5e94b57415be5a3f1..a6e729766821307c7440fd4d321d3decdc3182d6 100644 (file)
@@ -82,7 +82,7 @@ static kdbtab_t kdb_base_commands[50];
 #define for_each_kdbcmd(cmd, num)                                      \
        for ((cmd) = kdb_base_commands, (num) = 0;                      \
             num < kdb_max_commands;                                    \
-            num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++, num++)
+            num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++)
 
 typedef struct _kdbmsg {
        int     km_diag;        /* kdb diagnostic */
@@ -646,7 +646,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0)
        }
        if (!s->usable)
                return KDB_NOTIMP;
-       s->command = kmalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB);
+       s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB);
        if (!s->command) {
                kdb_printf("Could not allocate new kdb_defcmd table for %s\n",
                           cmdstr);
@@ -2361,7 +2361,7 @@ static int kdb_pid(int argc, const char **argv)
  */
 static int kdb_ll(int argc, const char **argv)
 {
-       int diag;
+       int diag = 0;
        unsigned long addr;
        long offset = 0;
        unsigned long va;
@@ -2400,20 +2400,21 @@ static int kdb_ll(int argc, const char **argv)
                char buf[80];
 
                if (KDB_FLAG(CMD_INTERRUPT))
-                       return 0;
+                       goto out;
 
                sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va);
                diag = kdb_parse(buf);
                if (diag)
-                       return diag;
+                       goto out;
 
                addr = va + linkoffset;
                if (kdb_getword(&va, addr, sizeof(va)))
-                       return 0;
+                       goto out;
        }
-       kfree(command);
 
-       return 0;
+out:
+       kfree(command);
+       return diag;
 }
 
 static int kdb_kgdb(int argc, const char **argv)
@@ -2739,13 +2740,13 @@ int kdb_register_repeat(char *cmd,
                }
                if (kdb_commands) {
                        memcpy(new, kdb_commands,
-                              kdb_max_commands * sizeof(*new));
+                         (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new));
                        kfree(kdb_commands);
                }
                memset(new + kdb_max_commands, 0,
                       kdb_command_extend * sizeof(*new));
                kdb_commands = new;
-               kp = kdb_commands + kdb_max_commands;
+               kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX;
                kdb_max_commands += kdb_command_extend;
        }
 
index 21aa7b3001fb49edce43446dd85898f62ab33d98..676149a4ac5ff497367a484e2b66c01e915ccefd 100644 (file)
@@ -914,6 +914,15 @@ NORET_TYPE void do_exit(long code)
        if (unlikely(!tsk->pid))
                panic("Attempted to kill the idle task!");
 
+       /*
+        * If do_exit is called because this processes oopsed, it's possible
+        * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
+        * continuing. Amongst other possible reasons, this is to prevent
+        * mm_release()->clear_child_tid() from writing to a user-controlled
+        * kernel address.
+        */
+       set_fs(USER_DS);
+
        tracehook_report_exit(&code);
 
        validate_creds_for_do_exit(tsk);
index 6c683b37f2ce25291a5a0c8f490a16c08c84d674..40a8777a27d0d85e173f4b7a3efbd4ecff1c9654 100644 (file)
@@ -2489,7 +2489,8 @@ void exit_robust_list(struct task_struct *curr)
 {
        struct robust_list_head __user *head = curr->robust_list;
        struct robust_list __user *entry, *next_entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+       unsigned int uninitialized_var(next_pi);
        unsigned long futex_offset;
        int rc;
 
index 06da4dfc339b7362716858f92bec749962241808..a7934ac75e5bf4b2b7f5b819d24e8f6f08a1ff1a 100644 (file)
@@ -49,7 +49,8 @@ void compat_exit_robust_list(struct task_struct *curr)
 {
        struct compat_robust_list_head __user *head = curr->compat_robust_list;
        struct robust_list __user *entry, *next_entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT, pi, next_pi, pip;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+       unsigned int uninitialized_var(next_pi);
        compat_uptr_t uentry, next_uentry, upending;
        compat_long_t futex_offset;
        int rc;
index 01b1d3a88983f92c189e0c9b27f23ffe0e73f88f..6c8a2a9f8a7bf802f72527831e0f5f32b773e964 100644 (file)
@@ -214,7 +214,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v)
 
 static int irq_spurious_proc_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, irq_spurious_proc_show, NULL);
+       return single_open(file, irq_spurious_proc_show, PDE(inode)->data);
 }
 
 static const struct file_operations irq_spurious_proc_fops = {
index c7a8f453919e65a42e0251b968a2d3652e0a4c3a..aeaa7f8468216eb1d8795b14ff74cfc502318771 100644 (file)
@@ -121,10 +121,10 @@ static inline int pm_qos_get_value(struct pm_qos_object *o)
 
        switch (o->type) {
        case PM_QOS_MIN:
-               return plist_last(&o->requests)->prio;
+               return plist_first(&o->requests)->prio;
 
        case PM_QOS_MAX:
-               return plist_first(&o->requests)->prio;
+               return plist_last(&o->requests)->prio;
 
        default:
                /* runtime check for not using enum */
index 6842eeba58798276d61b469072e50e0d6116bbac..05bb7173850e065a0899821d8e41c922d3548c07 100644 (file)
@@ -37,13 +37,13 @@ static int check_clock(const clockid_t which_clock)
        if (pid == 0)
                return 0;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = find_task_by_vpid(pid);
        if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
-                  same_thread_group(p, current) : thread_group_leader(p))) {
+                  same_thread_group(p, current) : has_group_leader_pid(p))) {
                error = -EINVAL;
        }
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        return error;
 }
@@ -390,7 +390,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
 
        INIT_LIST_HEAD(&new_timer->it.cpu.entry);
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        if (CPUCLOCK_PERTHREAD(new_timer->it_clock)) {
                if (pid == 0) {
                        p = current;
@@ -404,7 +404,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
                        p = current->group_leader;
                } else {
                        p = find_task_by_vpid(pid);
-                       if (p && !thread_group_leader(p))
+                       if (p && !has_group_leader_pid(p))
                                p = NULL;
                }
        }
@@ -414,7 +414,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
        } else {
                ret = -EINVAL;
        }
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        return ret;
 }
index 29bff6117abca747d31131424f58927e1a30558d..a5aff3ebad38b68629d341cb5a28856afb970796 100644 (file)
@@ -246,9 +246,13 @@ config PM_OPS
        depends on PM_SLEEP || PM_RUNTIME
        default y
 
+config ARCH_HAS_OPP
+       bool
+
 config PM_OPP
        bool "Operating Performance Point (OPP) Layer library"
        depends on PM
+       depends on ARCH_HAS_OPP
        ---help---
          SOCs have a standard set of tuples consisting of frequency and
          voltage pairs that the device will support per voltage domain. This
index 657272e91d0a0af648a892fd64ca2111a100dfb4..048d0b5148319db70883ee0c9963459c22048385 100644 (file)
@@ -327,7 +327,6 @@ static int create_image(int platform_mode)
 int hibernation_snapshot(int platform_mode)
 {
        int error;
-       gfp_t saved_mask;
 
        error = platform_begin(platform_mode);
        if (error)
@@ -339,7 +338,7 @@ int hibernation_snapshot(int platform_mode)
                goto Close;
 
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        error = dpm_suspend_start(PMSG_FREEZE);
        if (error)
                goto Recover_platform;
@@ -348,7 +347,10 @@ int hibernation_snapshot(int platform_mode)
                goto Recover_platform;
 
        error = create_image(platform_mode);
-       /* Control returns here after successful restore */
+       /*
+        * Control returns here (1) after the image has been created or the
+        * image creation has failed and (2) after a successful restore.
+        */
 
  Resume_devices:
        /* We may need to release the preallocated image pages here. */
@@ -357,7 +359,10 @@ int hibernation_snapshot(int platform_mode)
 
        dpm_resume_end(in_suspend ?
                (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
-       set_gfp_allowed_mask(saved_mask);
+
+       if (error || !in_suspend)
+               pm_restore_gfp_mask();
+
        resume_console();
  Close:
        platform_end(platform_mode);
@@ -452,17 +457,16 @@ static int resume_target_kernel(bool platform_mode)
 int hibernation_restore(int platform_mode)
 {
        int error;
-       gfp_t saved_mask;
 
        pm_prepare_console();
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        error = dpm_suspend_start(PMSG_QUIESCE);
        if (!error) {
                error = resume_target_kernel(platform_mode);
                dpm_resume_end(PMSG_RECOVER);
        }
-       set_gfp_allowed_mask(saved_mask);
+       pm_restore_gfp_mask();
        resume_console();
        pm_restore_console();
        return error;
@@ -476,7 +480,6 @@ int hibernation_restore(int platform_mode)
 int hibernation_platform_enter(void)
 {
        int error;
-       gfp_t saved_mask;
 
        if (!hibernation_ops)
                return -ENOSYS;
@@ -492,7 +495,6 @@ int hibernation_platform_enter(void)
 
        entering_platform_hibernation = true;
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
        error = dpm_suspend_start(PMSG_HIBERNATE);
        if (error) {
                if (hibernation_ops->recover)
@@ -536,7 +538,6 @@ int hibernation_platform_enter(void)
  Resume_devices:
        entering_platform_hibernation = false;
        dpm_resume_end(PMSG_RESTORE);
-       set_gfp_allowed_mask(saved_mask);
        resume_console();
 
  Close:
@@ -646,6 +647,7 @@ int hibernate(void)
                swsusp_free();
                if (!error)
                        power_down();
+               pm_restore_gfp_mask();
        } else {
                pr_debug("PM: Image restored successfully.\n");
        }
index 7335952ee473956e6a1e7b57f3d397220e6c5536..ecf770509d0d1bb9dce2381716d6e7583ee6c492 100644 (file)
@@ -197,7 +197,6 @@ static int suspend_enter(suspend_state_t state)
 int suspend_devices_and_enter(suspend_state_t state)
 {
        int error;
-       gfp_t saved_mask;
 
        if (!suspend_ops)
                return -ENOSYS;
@@ -208,7 +207,7 @@ int suspend_devices_and_enter(suspend_state_t state)
                        goto Close;
        }
        suspend_console();
-       saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
+       pm_restrict_gfp_mask();
        suspend_test_start();
        error = dpm_suspend_start(PMSG_SUSPEND);
        if (error) {
@@ -225,7 +224,7 @@ int suspend_devices_and_enter(suspend_state_t state)
        suspend_test_start();
        dpm_resume_end(PMSG_RESUME);
        suspend_test_finish("resume devices");
-       set_gfp_allowed_mask(saved_mask);
+       pm_restore_gfp_mask();
        resume_console();
  Close:
        if (suspend_ops->end)
index a0e4a86ccf94887a6f64ae985db131608def8952..baf667bb2794c6880a834e060fd3a32943c80d68 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
  * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ * Copyright (C) 2010 Bojan Smojver <bojan@rexursive.com>
  *
  * This file is released under the GPLv2.
  *
@@ -753,30 +754,43 @@ static int load_image_lzo(struct swap_map_handle *handle,
 {
        unsigned int m;
        int error = 0;
+       struct bio *bio;
        struct timeval start;
        struct timeval stop;
        unsigned nr_pages;
-       size_t off, unc_len, cmp_len;
-       unsigned char *unc, *cmp, *page;
+       size_t i, off, unc_len, cmp_len;
+       unsigned char *unc, *cmp, *page[LZO_CMP_PAGES];
 
-       page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
-       if (!page) {
-               printk(KERN_ERR "PM: Failed to allocate LZO page\n");
-               return -ENOMEM;
+       for (i = 0; i < LZO_CMP_PAGES; i++) {
+               page[i] = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
+               if (!page[i]) {
+                       printk(KERN_ERR "PM: Failed to allocate LZO page\n");
+
+                       while (i)
+                               free_page((unsigned long)page[--i]);
+
+                       return -ENOMEM;
+               }
        }
 
        unc = vmalloc(LZO_UNC_SIZE);
        if (!unc) {
                printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
-               free_page((unsigned long)page);
+
+               for (i = 0; i < LZO_CMP_PAGES; i++)
+                       free_page((unsigned long)page[i]);
+
                return -ENOMEM;
        }
 
        cmp = vmalloc(LZO_CMP_SIZE);
        if (!cmp) {
                printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
+
                vfree(unc);
-               free_page((unsigned long)page);
+               for (i = 0; i < LZO_CMP_PAGES; i++)
+                       free_page((unsigned long)page[i]);
+
                return -ENOMEM;
        }
 
@@ -787,6 +801,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
        if (!m)
                m = 1;
        nr_pages = 0;
+       bio = NULL;
        do_gettimeofday(&start);
 
        error = snapshot_write_next(snapshot);
@@ -794,11 +809,11 @@ static int load_image_lzo(struct swap_map_handle *handle,
                goto out_finish;
 
        for (;;) {
-               error = swap_read_page(handle, page, NULL); /* sync */
+               error = swap_read_page(handle, page[0], NULL); /* sync */
                if (error)
                        break;
 
-               cmp_len = *(size_t *)page;
+               cmp_len = *(size_t *)page[0];
                if (unlikely(!cmp_len ||
                             cmp_len > lzo1x_worst_compress(LZO_UNC_SIZE))) {
                        printk(KERN_ERR "PM: Invalid LZO compressed length\n");
@@ -806,13 +821,20 @@ static int load_image_lzo(struct swap_map_handle *handle,
                        break;
                }
 
-               memcpy(cmp, page, PAGE_SIZE);
-               for (off = PAGE_SIZE; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
-                       error = swap_read_page(handle, page, NULL); /* sync */
+               for (off = PAGE_SIZE, i = 1;
+                    off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+                       error = swap_read_page(handle, page[i], &bio);
                        if (error)
                                goto out_finish;
+               }
 
-                       memcpy(cmp + off, page, PAGE_SIZE);
+               error = hib_wait_on_bio_chain(&bio); /* need all data now */
+               if (error)
+                       goto out_finish;
+
+               for (off = 0, i = 0;
+                    off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
+                       memcpy(cmp + off, page[i], PAGE_SIZE);
                }
 
                unc_len = LZO_UNC_SIZE;
@@ -857,7 +879,8 @@ out_finish:
 
        vfree(cmp);
        vfree(unc);
-       free_page((unsigned long)page);
+       for (i = 0; i < LZO_CMP_PAGES; i++)
+               free_page((unsigned long)page[i]);
 
        return error;
 }
index e819e17877ca9cd2540440a67919b2b019222976..1b2ea31e6bd8c0eca7eaaf985bc84337a1e750d0 100644 (file)
@@ -263,6 +263,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
        case SNAPSHOT_UNFREEZE:
                if (!data->frozen || data->ready)
                        break;
+               pm_restore_gfp_mask();
                thaw_processes();
                usermodehelper_enable();
                data->frozen = 0;
@@ -275,6 +276,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                        error = -EPERM;
                        break;
                }
+               pm_restore_gfp_mask();
                error = hibernation_snapshot(data->platform_support);
                if (!error)
                        error = put_user(in_suspend, (int __user *)arg);
index 9a2264fc42cafac30d9264d569e4e673e9617f19..a23315dc4498844c113cecc9792eabd063e1d87b 100644 (file)
@@ -1082,13 +1082,15 @@ void printk_tick(void)
 
 int printk_needs_cpu(int cpu)
 {
+       if (unlikely(cpu_is_offline(cpu)))
+               printk_tick();
        return per_cpu(printk_pending, cpu);
 }
 
 void wake_up_klogd(void)
 {
        if (waitqueue_active(&log_wait))
-               __raw_get_cpu_var(printk_pending) = 1;
+               this_cpu_write(printk_pending, 1);
 }
 
 /**
index aa14a56f9d037cde21ae19ef86b142e1c23fe736..dc91a4d09ac3b71a3c347187ff2a1691c952cebd 100644 (file)
@@ -560,18 +560,8 @@ struct rq {
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
 
-static inline
-void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
-{
-       rq->curr->sched_class->check_preempt_curr(rq, p, flags);
 
-       /*
-        * A queue event has occurred, and we're going to schedule.  In
-        * this case, we can save a useless back to back clock update.
-        */
-       if (test_tsk_need_resched(p))
-               rq->skip_clock_update = 1;
-}
+static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags);
 
 static inline int cpu_of(struct rq *rq)
 {
@@ -2118,6 +2108,31 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
                p->sched_class->prio_changed(rq, p, oldprio, running);
 }
 
+static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
+{
+       const struct sched_class *class;
+
+       if (p->sched_class == rq->curr->sched_class) {
+               rq->curr->sched_class->check_preempt_curr(rq, p, flags);
+       } else {
+               for_each_class(class) {
+                       if (class == rq->curr->sched_class)
+                               break;
+                       if (class == p->sched_class) {
+                               resched_task(rq->curr);
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * A queue event has occurred, and we're going to schedule.  In
+        * this case, we can save a useless back to back clock update.
+        */
+       if (test_tsk_need_resched(rq->curr))
+               rq->skip_clock_update = 1;
+}
+
 #ifdef CONFIG_SMP
 /*
  * Is this task likely cache-hot:
@@ -6960,6 +6975,8 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
        if (cpu != group_first_cpu(sd->groups))
                return;
 
+       sd->groups->group_weight = cpumask_weight(sched_group_cpus(sd->groups));
+
        child = sd->child;
 
        sd->groups->cpu_power = 0;
index f4f6a8326dd01ffc0353b369bbfddf5a4f0e2fde..00ebd7686676bd87a6e5b3be513d27028e518796 100644 (file)
@@ -1654,12 +1654,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
        int scale = cfs_rq->nr_running >= sched_nr_latency;
 
-       if (unlikely(rt_prio(p->prio)))
-               goto preempt;
-
-       if (unlikely(p->sched_class != &fair_sched_class))
-               return;
-
        if (unlikely(se == pse))
                return;
 
@@ -1764,10 +1758,6 @@ static void pull_task(struct rq *src_rq, struct task_struct *p,
        set_task_cpu(p, this_cpu);
        activate_task(this_rq, p, 0);
        check_preempt_curr(this_rq, p, 0);
-
-       /* re-arm NEWIDLE balancing when moving tasks */
-       src_rq->avg_idle = this_rq->avg_idle = 2*sysctl_sched_migration_cost;
-       this_rq->idle_stamp = 0;
 }
 
 /*
@@ -2035,13 +2025,16 @@ struct sd_lb_stats {
        unsigned long this_load_per_task;
        unsigned long this_nr_running;
        unsigned long this_has_capacity;
+       unsigned int  this_idle_cpus;
 
        /* Statistics of the busiest group */
+       unsigned int  busiest_idle_cpus;
        unsigned long max_load;
        unsigned long busiest_load_per_task;
        unsigned long busiest_nr_running;
        unsigned long busiest_group_capacity;
        unsigned long busiest_has_capacity;
+       unsigned int  busiest_group_weight;
 
        int group_imb; /* Is there imbalance in this sd */
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -2063,6 +2056,8 @@ struct sg_lb_stats {
        unsigned long sum_nr_running; /* Nr tasks running in the group */
        unsigned long sum_weighted_load; /* Weighted load of group's tasks */
        unsigned long group_capacity;
+       unsigned long idle_cpus;
+       unsigned long group_weight;
        int group_imb; /* Is there an imbalance in the group ? */
        int group_has_capacity; /* Is there extra capacity in the group? */
 };
@@ -2431,7 +2426,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
                sgs->group_load += load;
                sgs->sum_nr_running += rq->nr_running;
                sgs->sum_weighted_load += weighted_cpuload(i);
-
+               if (idle_cpu(i))
+                       sgs->idle_cpus++;
        }
 
        /*
@@ -2469,6 +2465,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
        sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, SCHED_LOAD_SCALE);
        if (!sgs->group_capacity)
                sgs->group_capacity = fix_small_capacity(sd, group);
+       sgs->group_weight = group->group_weight;
 
        if (sgs->group_capacity > sgs->sum_nr_running)
                sgs->group_has_capacity = 1;
@@ -2576,13 +2573,16 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
                        sds->this_nr_running = sgs.sum_nr_running;
                        sds->this_load_per_task = sgs.sum_weighted_load;
                        sds->this_has_capacity = sgs.group_has_capacity;
+                       sds->this_idle_cpus = sgs.idle_cpus;
                } else if (update_sd_pick_busiest(sd, sds, sg, &sgs, this_cpu)) {
                        sds->max_load = sgs.avg_load;
                        sds->busiest = sg;
                        sds->busiest_nr_running = sgs.sum_nr_running;
+                       sds->busiest_idle_cpus = sgs.idle_cpus;
                        sds->busiest_group_capacity = sgs.group_capacity;
                        sds->busiest_load_per_task = sgs.sum_weighted_load;
                        sds->busiest_has_capacity = sgs.group_has_capacity;
+                       sds->busiest_group_weight = sgs.group_weight;
                        sds->group_imb = sgs.group_imb;
                }
 
@@ -2860,8 +2860,26 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
        if (sds.this_load >= sds.avg_load)
                goto out_balanced;
 
-       if (100 * sds.max_load <= sd->imbalance_pct * sds.this_load)
-               goto out_balanced;
+       /*
+        * In the CPU_NEWLY_IDLE, use imbalance_pct to be conservative.
+        * And to check for busy balance use !idle_cpu instead of
+        * CPU_NOT_IDLE. This is because HT siblings will use CPU_NOT_IDLE
+        * even when they are idle.
+        */
+       if (idle == CPU_NEWLY_IDLE || !idle_cpu(this_cpu)) {
+               if (100 * sds.max_load <= sd->imbalance_pct * sds.this_load)
+                       goto out_balanced;
+       } else {
+               /*
+                * This cpu is idle. If the busiest group load doesn't
+                * have more tasks than the number of available cpu's and
+                * there is no imbalance between this and busiest group
+                * wrt to idle cpu's, it is balanced.
+                */
+               if ((sds.this_idle_cpus  <= sds.busiest_idle_cpus + 1) &&
+                   sds.busiest_nr_running <= sds.busiest_group_weight)
+                       goto out_balanced;
+       }
 
 force_balance:
        /* Looks like there is an imbalance. Compute it */
@@ -3197,8 +3215,10 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
                interval = msecs_to_jiffies(sd->balance_interval);
                if (time_after(next_balance, sd->last_balance + interval))
                        next_balance = sd->last_balance + interval;
-               if (pulled_task)
+               if (pulled_task) {
+                       this_rq->idle_stamp = 0;
                        break;
+               }
        }
 
        raw_spin_lock(&this_rq->lock);
index 45bddc0c104857f23e06c9126ed6dcb1d452450b..2bf6b47058c19f79a326a6b4f82d4baf7950cb1a 100644 (file)
@@ -19,14 +19,14 @@ select_task_rq_stop(struct rq *rq, struct task_struct *p,
 static void
 check_preempt_curr_stop(struct rq *rq, struct task_struct *p, int flags)
 {
-       resched_task(rq->curr); /* we preempt everything */
+       /* we're never preempted */
 }
 
 static struct task_struct *pick_next_task_stop(struct rq *rq)
 {
        struct task_struct *stop = rq->stop;
 
-       if (stop && stop->state == TASK_RUNNING)
+       if (stop && stop->se.on_rq)
                return stop;
 
        return NULL;
index b65bf634035ed0684693b9c7c02b3229c8d68e0d..5abfa151855493735a91fd45a255a45727c8ba97 100644 (file)
@@ -702,7 +702,6 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &ten_thousand,
        },
-#endif
        {
                .procname       = "dmesg_restrict",
                .data           = &dmesg_restrict,
@@ -712,6 +711,7 @@ static struct ctl_table kern_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
+#endif
        {
                .procname       = "ngroups_max",
                .data           = &ngroups_max,
index e04b8bcdef88dc92a3c52c9c53808528b0266b09..ea37e2ff416429d04cea3829e835ced7f0f35fc0 100644 (file)
@@ -126,7 +126,7 @@ if FTRACE
 config FUNCTION_TRACER
        bool "Kernel Function Tracer"
        depends on HAVE_FUNCTION_TRACER
-       select FRAME_POINTER if (!ARM_UNWIND)
+       select FRAME_POINTER if !ARM_UNWIND && !S390
        select KALLSYMS
        select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
index ee6a7339cf0e63d84076dc271b9b79144316b693..c380612273bf75d683ddebcf5e7863b30bece806 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/writeback.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 #include <linux/notifier.h>
 #include <linux/irqflags.h>
 #include <linux/debugfs.h>
index 5bf0020b9248801236d1a1ca7a3233e1bf2b2bb7..b1c17730767745f81d9990effd5078cdc769dc08 100644 (file)
@@ -8,7 +8,6 @@
  *
  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#include <linux/kernel.h>
 #include <linux/rwsem.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
@@ -39,7 +38,6 @@ int debug_locks_off(void)
 {
        if (__debug_locks_off()) {
                if (!debug_locks_silent) {
-                       oops_in_progress = 1;
                        console_verbose();
                        return 1;
                }
index c4a3558589ab15de3ac9abb135ee499d17544142..85855240933d7cf195ce1548faa75d8120c21478 100644 (file)
@@ -2738,7 +2738,8 @@ out_page_table_lock:
                unlock_page(pagecache_page);
                put_page(pagecache_page);
        }
-       unlock_page(page);
+       if (page != pagecache_page)
+               unlock_page(page);
 
 out_mutex:
        mutex_unlock(&hugetlb_instantiation_mutex);
index 65ab5c7067d994ad934c4f4bd5fd5809235a0756..43bc893470b40512e26bdd129fb2194708bfbbdc 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1724,8 +1724,13 @@ static int ksm_memory_callback(struct notifier_block *self,
                /*
                 * Keep it very simple for now: just lock out ksmd and
                 * MADV_UNMERGEABLE while any memory is going offline.
+                * mutex_lock_nested() is necessary because lockdep was alarmed
+                * that here we take ksm_thread_mutex inside notifier chain
+                * mutex, and later take notifier chain mutex inside
+                * ksm_thread_mutex to unlock it.   But that's safe because both
+                * are inside mem_hotplug_mutex.
                 */
-               mutex_lock(&ksm_thread_mutex);
+               mutex_lock_nested(&ksm_thread_mutex, SINGLE_DEPTH_NESTING);
                break;
 
        case MEM_OFFLINE:
index 2efa8ea07ff7d931577da964c190f5524088da3d..7a22b41292115f78dc039ebf5e271090dc5a8f9d 100644 (file)
@@ -61,7 +61,14 @@ struct mem_cgroup *root_mem_cgroup __read_mostly;
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
 /* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */
 int do_swap_account __read_mostly;
-static int really_do_swap_account __initdata = 1; /* for remember boot option*/
+
+/* for remember boot option*/
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED
+static int really_do_swap_account __initdata = 1;
+#else
+static int really_do_swap_account __initdata = 0;
+#endif
+
 #else
 #define do_swap_account                (0)
 #endif
@@ -278,13 +285,14 @@ enum move_type {
 
 /* "mc" and its members are protected by cgroup_mutex */
 static struct move_charge_struct {
-       spinlock_t        lock; /* for from, to, moving_task */
+       spinlock_t        lock; /* for from, to */
        struct mem_cgroup *from;
        struct mem_cgroup *to;
        unsigned long precharge;
        unsigned long moved_charge;
        unsigned long moved_swap;
        struct task_struct *moving_task;        /* a task moving charges */
+       struct mm_struct *mm;
        wait_queue_head_t waitq;                /* a waitq for other context */
 } mc = {
        .lock = __SPIN_LOCK_UNLOCKED(mc.lock),
@@ -2152,7 +2160,7 @@ static void __mem_cgroup_move_account(struct page_cgroup *pc,
 {
        VM_BUG_ON(from == to);
        VM_BUG_ON(PageLRU(pc->page));
-       VM_BUG_ON(!PageCgroupLocked(pc));
+       VM_BUG_ON(!page_is_cgroup_locked(pc));
        VM_BUG_ON(!PageCgroupUsed(pc));
        VM_BUG_ON(pc->mem_cgroup != from);
 
@@ -4631,7 +4639,7 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
        unsigned long precharge;
        struct vm_area_struct *vma;
 
-       down_read(&mm->mmap_sem);
+       /* We've already held the mmap_sem */
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                struct mm_walk mem_cgroup_count_precharge_walk = {
                        .pmd_entry = mem_cgroup_count_precharge_pte_range,
@@ -4643,7 +4651,6 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
                walk_page_range(vma->vm_start, vma->vm_end,
                                        &mem_cgroup_count_precharge_walk);
        }
-       up_read(&mm->mmap_sem);
 
        precharge = mc.precharge;
        mc.precharge = 0;
@@ -4694,11 +4701,16 @@ static void mem_cgroup_clear_mc(void)
 
                mc.moved_swap = 0;
        }
+       if (mc.mm) {
+               up_read(&mc.mm->mmap_sem);
+               mmput(mc.mm);
+       }
        spin_lock(&mc.lock);
        mc.from = NULL;
        mc.to = NULL;
-       mc.moving_task = NULL;
        spin_unlock(&mc.lock);
+       mc.moving_task = NULL;
+       mc.mm = NULL;
        mem_cgroup_end_move(from);
        memcg_oom_recover(from);
        memcg_oom_recover(to);
@@ -4724,12 +4736,21 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                        return 0;
                /* We move charges only when we move a owner of the mm */
                if (mm->owner == p) {
+                       /*
+                        * We do all the move charge works under one mmap_sem to
+                        * avoid deadlock with down_write(&mmap_sem)
+                        * -> try_charge() -> if (mc.moving_task) -> sleep.
+                        */
+                       down_read(&mm->mmap_sem);
+
                        VM_BUG_ON(mc.from);
                        VM_BUG_ON(mc.to);
                        VM_BUG_ON(mc.precharge);
                        VM_BUG_ON(mc.moved_charge);
                        VM_BUG_ON(mc.moved_swap);
                        VM_BUG_ON(mc.moving_task);
+                       VM_BUG_ON(mc.mm);
+
                        mem_cgroup_start_move(from);
                        spin_lock(&mc.lock);
                        mc.from = from;
@@ -4737,14 +4758,16 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                        mc.precharge = 0;
                        mc.moved_charge = 0;
                        mc.moved_swap = 0;
-                       mc.moving_task = current;
                        spin_unlock(&mc.lock);
+                       mc.moving_task = current;
+                       mc.mm = mm;
 
                        ret = mem_cgroup_precharge_mc(mm);
                        if (ret)
                                mem_cgroup_clear_mc();
-               }
-               mmput(mm);
+                       /* We call up_read() and mmput() in clear_mc(). */
+               } else
+                       mmput(mm);
        }
        return ret;
 }
@@ -4832,7 +4855,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm)
        struct vm_area_struct *vma;
 
        lru_add_drain_all();
-       down_read(&mm->mmap_sem);
+       /* We've already held the mmap_sem */
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                int ret;
                struct mm_walk mem_cgroup_move_charge_walk = {
@@ -4851,7 +4874,6 @@ static void mem_cgroup_move_charge(struct mm_struct *mm)
                         */
                        break;
        }
-       up_read(&mm->mmap_sem);
 }
 
 static void mem_cgroup_move_task(struct cgroup_subsys *ss,
@@ -4860,17 +4882,11 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
                                struct task_struct *p,
                                bool threadgroup)
 {
-       struct mm_struct *mm;
-
-       if (!mc.to)
+       if (!mc.mm)
                /* no need to move charge */
                return;
 
-       mm = get_task_mm(p);
-       if (mm) {
-               mem_cgroup_move_charge(mm);
-               mmput(mm);
-       }
+       mem_cgroup_move_charge(mc.mm);
        mem_cgroup_clear_mc();
 }
 #else  /* !CONFIG_MMU */
@@ -4911,10 +4927,20 @@ struct cgroup_subsys mem_cgroup_subsys = {
 };
 
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
+static int __init enable_swap_account(char *s)
+{
+       /* consider enabled if no parameter or 1 is given */
+       if (!s || !strcmp(s, "1"))
+               really_do_swap_account = 1;
+       else if (!strcmp(s, "0"))
+               really_do_swap_account = 0;
+       return 1;
+}
+__setup("swapaccount", enable_swap_account);
 
 static int __init disable_swap_account(char *s)
 {
-       really_do_swap_account = 0;
+       enable_swap_account("0");
        return 1;
 }
 __setup("noswapaccount", disable_swap_account);
index 124324134ff67b3c4a0bc06661b4f70f2406840f..46ab2c044b0e657ad1844dd291a3b537c97d58b6 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/slab.h>
 #include <linux/swapops.h>
 #include <linux/hugetlb.h>
+#include <linux/memory_hotplug.h>
 #include "internal.h"
 
 int sysctl_memory_failure_early_kill __read_mostly = 0;
@@ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
                return 1;
 
        /*
-        * The lock_system_sleep prevents a race with memory hotplug,
-        * because the isolation assumes there's only a single user.
+        * The lock_memory_hotplug prevents a race with memory hotplug.
         * This is a big hammer, a better would be nicer.
         */
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        /*
         * Isolate the page, so that it doesn't get reallocated if it
@@ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags)
                ret = 1;
        }
        unset_migratetype_isolate(p);
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
index 9260314a221e0720d5cc3ecf5f00325c7ec3fba6..2c6523af54738faba3dd37eef938315503275de4 100644 (file)
 
 #include "internal.h"
 
+DEFINE_MUTEX(mem_hotplug_mutex);
+
+void lock_memory_hotplug(void)
+{
+       mutex_lock(&mem_hotplug_mutex);
+
+       /* for exclusive hibernation if CONFIG_HIBERNATION=y */
+       lock_system_sleep();
+}
+
+void unlock_memory_hotplug(void)
+{
+       unlock_system_sleep();
+       mutex_unlock(&mem_hotplug_mutex);
+}
+
+
 /* add this memory to iomem resource */
 static struct resource *register_memory_resource(u64 start, u64 size)
 {
@@ -493,7 +510,7 @@ int mem_online_node(int nid)
        pg_data_t       *pgdat;
        int     ret;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
        pgdat = hotadd_new_pgdat(nid, 0);
        if (pgdat) {
                ret = -ENOMEM;
@@ -504,7 +521,7 @@ int mem_online_node(int nid)
        BUG_ON(ret);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
@@ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
        struct resource *res;
        int ret;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        res = register_memory_resource(start, size);
        ret = -EEXIST;
@@ -563,7 +580,7 @@ error:
                release_memory_resource(res);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 EXPORT_SYMBOL_GPL(add_memory);
@@ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn,
        if (!test_pages_in_a_zone(start_pfn, end_pfn))
                return -EINVAL;
 
-       lock_system_sleep();
+       lock_memory_hotplug();
 
        zone = page_zone(pfn_to_page(start_pfn));
        node = zone_to_nid(zone);
@@ -880,7 +897,7 @@ repeat:
        writeback_set_ratelimit();
 
        memory_notify(MEM_OFFLINE, &arg);
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return 0;
 
 failed_removal:
@@ -891,7 +908,7 @@ failed_removal:
        undo_isolate_page_range(start_pfn, end_pfn);
 
 out:
-       unlock_system_sleep();
+       unlock_memory_hotplug();
        return ret;
 }
 
index 4a57f135b76e74741e7c7d285642067a3e18efe6..11ff260fb282b778657a872aec0947d5f15616c6 100644 (file)
@@ -1307,15 +1307,18 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
                goto out;
 
        /* Find the mm_struct */
+       rcu_read_lock();
        read_lock(&tasklist_lock);
        task = pid ? find_task_by_vpid(pid) : current;
        if (!task) {
                read_unlock(&tasklist_lock);
+               rcu_read_unlock();
                err = -ESRCH;
                goto out;
        }
        mm = get_task_mm(task);
        read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        err = -EINVAL;
        if (!mm)
index 3613517c75929b17e1b3d93a650e5d9957c2315a..27a9ac58851678d30c7c477d00a857cf2f63bc35 100644 (file)
@@ -1717,6 +1717,7 @@ void exit_mmap(struct mm_struct *mm)
                mm->mmap = vma->vm_next;
                delete_vma_from_mm(vma);
                delete_vma(mm, vma);
+               cond_resched();
        }
 
        kleave("");
index 07a654486f75cfdfe13035f7bf501e2d2dbf0a4a..ff7e158723987d4355ec84a2c090716ec8accbe9 100644 (file)
@@ -104,19 +104,24 @@ gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
  * only be modified with pm_mutex held, unless the suspend/hibernate code is
  * guaranteed not to run in parallel with that modification).
  */
-void set_gfp_allowed_mask(gfp_t mask)
+
+static gfp_t saved_gfp_mask;
+
+void pm_restore_gfp_mask(void)
 {
        WARN_ON(!mutex_is_locked(&pm_mutex));
-       gfp_allowed_mask = mask;
+       if (saved_gfp_mask) {
+               gfp_allowed_mask = saved_gfp_mask;
+               saved_gfp_mask = 0;
+       }
 }
 
-gfp_t clear_gfp_allowed_mask(gfp_t mask)
+void pm_restrict_gfp_mask(void)
 {
-       gfp_t ret = gfp_allowed_mask;
-
        WARN_ON(!mutex_is_locked(&pm_mutex));
-       gfp_allowed_mask &= ~mask;
-       return ret;
+       WARN_ON(saved_gfp_mask);
+       saved_gfp_mask = gfp_allowed_mask;
+       gfp_allowed_mask &= ~GFP_IOFS;
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -3008,14 +3013,6 @@ static __init_refok int __build_all_zonelists(void *data)
                build_zonelist_cache(pgdat);
        }
 
-#ifdef CONFIG_MEMORY_HOTPLUG
-       /* Setup real pagesets for the new zone */
-       if (data) {
-               struct zone *zone = data;
-               setup_zone_pageset(zone);
-       }
-#endif
-
        /*
         * Initialize the boot_pagesets that are going to be used
         * for bootstrapping processors. The real pagesets for
@@ -3064,7 +3061,11 @@ void build_all_zonelists(void *data)
        } else {
                /* we have to stop all cpus to guarantee there is no user
                   of zonelist */
-               stop_machine(__build_all_zonelists, data, NULL);
+#ifdef CONFIG_MEMORY_HOTPLUG
+               if (data)
+                       setup_zone_pageset((struct zone *)data);
+#endif
+               stop_machine(__build_all_zonelists, NULL, NULL);
                /* cpuset refresh routine should be here */
        }
        vm_total_pages = nr_free_pagecache_pages();
index 8b1a2ce21ee53f3a6ea598759faf02c21c4c5dd2..38cc58b8b2b0d37340f6e327c56c796bd7c24516 100644 (file)
@@ -139,7 +139,6 @@ int walk_page_range(unsigned long addr, unsigned long end,
        pgd_t *pgd;
        unsigned long next;
        int err = 0;
-       struct vm_area_struct *vma;
 
        if (addr >= end)
                return err;
@@ -149,15 +148,17 @@ int walk_page_range(unsigned long addr, unsigned long end,
 
        pgd = pgd_offset(walk->mm, addr);
        do {
+               struct vm_area_struct *uninitialized_var(vma);
+
                next = pgd_addr_end(addr, end);
 
+#ifdef CONFIG_HUGETLB_PAGE
                /*
                 * handle hugetlb vma individually because pagetable walk for
                 * the hugetlb page is dependent on the architecture and
                 * we can't handled it in the same manner as non-huge pages.
                 */
                vma = find_vma(walk->mm, addr);
-#ifdef CONFIG_HUGETLB_PAGE
                if (vma && is_vm_hugetlb_page(vma)) {
                        if (vma->vm_end < next)
                                next = vma->vm_end;
index 981fb730aa04d82ef7b739497beb22d10fe9f98c..bec0e355fbadfda52fe317d053f191c178df478b 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3401,13 +3401,13 @@ static int validate_slab(struct kmem_cache *s, struct page *page,
 
        for_each_free_object(p, s, page->freelist) {
                set_bit(slab_index(p, s, addr), map);
-               if (!check_object(s, page, p, 0))
+               if (!check_object(s, page, p, SLUB_RED_INACTIVE))
                        return 0;
        }
 
        for_each_object(p, s, addr, page->objects)
                if (!test_bit(slab_index(p, s, addr), map))
-                       if (!check_object(s, page, p, 1))
+                       if (!check_object(s, page, p, SLUB_RED_ACTIVE))
                                return 0;
        return 1;
 }
index a3d66b3dc5cb0c9136b13764958d6aedf5b10526..eb5cc7d00c5a7c0443f9ff663317cf229ab74353 100644 (file)
@@ -31,8 +31,6 @@
 #include <asm/tlbflush.h>
 #include <asm/shmparam.h>
 
-bool vmap_lazy_unmap __read_mostly = true;
-
 /*** Page table manipulation functions ***/
 
 static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
@@ -503,9 +501,6 @@ static unsigned long lazy_max_pages(void)
 {
        unsigned int log;
 
-       if (!vmap_lazy_unmap)
-               return 0;
-
        log = fls(num_online_cpus());
 
        return log * (32UL * 1024 * 1024 / PAGE_SIZE);
@@ -566,7 +561,6 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
                        if (va->va_end > *end)
                                *end = va->va_end;
                        nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
-                       unmap_vmap_area(va);
                        list_add_tail(&va->purge_list, &valist);
                        va->flags |= VM_LAZY_FREEING;
                        va->flags &= ~VM_LAZY_FREE;
@@ -611,10 +605,11 @@ static void purge_vmap_area_lazy(void)
 }
 
 /*
- * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
- * called for the correct range previously.
+ * Free a vmap area, caller ensuring that the area has been unmapped
+ * and flush_cache_vunmap had been called for the correct range
+ * previously.
  */
-static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+static void free_vmap_area_noflush(struct vmap_area *va)
 {
        va->flags |= VM_LAZY_FREE;
        atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
@@ -622,6 +617,16 @@ static void free_unmap_vmap_area_noflush(struct vmap_area *va)
                try_purge_vmap_area_lazy();
 }
 
+/*
+ * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been
+ * called for the correct range previously.
+ */
+static void free_unmap_vmap_area_noflush(struct vmap_area *va)
+{
+       unmap_vmap_area(va);
+       free_vmap_area_noflush(va);
+}
+
 /*
  * Free and unmap a vmap area
  */
@@ -798,7 +803,7 @@ static void free_vmap_block(struct vmap_block *vb)
        spin_unlock(&vmap_block_tree_lock);
        BUG_ON(tmp != vb);
 
-       free_unmap_vmap_area_noflush(vb->va);
+       free_vmap_area_noflush(vb->va);
        call_rcu(&vb->rcu_head, rcu_free_vb);
 }
 
@@ -936,6 +941,8 @@ static void vb_free(const void *addr, unsigned long size)
        rcu_read_unlock();
        BUG_ON(!vb);
 
+       vunmap_page_range((unsigned long)addr, (unsigned long)addr + size);
+
        spin_lock(&vb->lock);
        BUG_ON(bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order));
 
@@ -988,7 +995,6 @@ void vm_unmap_aliases(void)
 
                                s = vb->va->va_start + (i << PAGE_SHIFT);
                                e = vb->va->va_start + (j << PAGE_SHIFT);
-                               vunmap_page_range(s, e);
                                flush = 1;
 
                                if (s < start)
index 42eac4d33216b81c307a87016e821051bc86146e..8f62f17ee1c726fec7fc683082b0807a15b848aa 100644 (file)
@@ -750,8 +750,6 @@ static const char * const vmstat_text[] = {
        "nr_shmem",
        "nr_dirtied",
        "nr_written",
-       "nr_dirty_threshold",
-       "nr_dirty_background_threshold",
 
 #ifdef CONFIG_NUMA
        "numa_hit",
@@ -761,6 +759,8 @@ static const char * const vmstat_text[] = {
        "numa_local",
        "numa_other",
 #endif
+       "nr_dirty_threshold",
+       "nr_dirty_background_threshold",
 
 #ifdef CONFIG_VM_EVENT_COUNTERS
        "pgpgin",
index aab1cabb803598f82893676e991e2743a74f5bf4..5f19415ec9c0dfb893d6f03b94ad03cdbca3307d 100644 (file)
@@ -1,9 +1,6 @@
 #
 # Makefile for CEPH filesystem.
 #
-
-ifneq ($(KERNELRELEASE),)
-
 obj-$(CONFIG_CEPH_LIB) += libceph.o
 
 libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
@@ -16,22 +13,3 @@ libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        ceph_fs.o ceph_strings.o ceph_hash.o \
        pagevec.o
 
-else
-#Otherwise we were called directly from the command
-# line; invoke the kernel build system.
-
-KERNELDIR ?= /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-
-default: all
-
-all:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules
-
-modules_install:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules_install
-
-clean:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
-
-endif
index 53d8abfa25d5ede4b487c88a5341b376c4921c26..bf3e6a13c215cd61cd7372e85ba19e7fc7974e9a 100644 (file)
@@ -19,7 +19,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
        if (b->vec.iov_base) {
                b->is_vmalloc = false;
        } else {
-               b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+               b->vec.iov_base = __vmalloc(len, gfp | __GFP_HIGHMEM, PAGE_KERNEL);
                if (!b->vec.iov_base) {
                        kfree(b);
                        return NULL;
index 0e8157ee5d4382a32992f34c2b1cf0d78f2868b4..1c7a2ec4f3cc81ee608821ddf589fc0b27db4dcc 100644 (file)
@@ -540,8 +540,7 @@ static void prepare_write_message(struct ceph_connection *con)
                /* initialize page iterator */
                con->out_msg_pos.page = 0;
                if (m->pages)
-                       con->out_msg_pos.page_pos =
-                               le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK;
+                       con->out_msg_pos.page_pos = m->page_alignment;
                else
                        con->out_msg_pos.page_pos = 0;
                con->out_msg_pos.data_pos = 0;
@@ -1491,7 +1490,7 @@ static int read_partial_message(struct ceph_connection *con)
        struct ceph_msg *m = con->in_msg;
        int ret;
        int to, left;
-       unsigned front_len, middle_len, data_len, data_off;
+       unsigned front_len, middle_len, data_len;
        int datacrc = con->msgr->nocrc;
        int skip;
        u64 seq;
@@ -1527,19 +1526,17 @@ static int read_partial_message(struct ceph_connection *con)
        data_len = le32_to_cpu(con->in_hdr.data_len);
        if (data_len > CEPH_MSG_MAX_DATA_LEN)
                return -EIO;
-       data_off = le16_to_cpu(con->in_hdr.data_off);
 
        /* verify seq# */
        seq = le64_to_cpu(con->in_hdr.seq);
        if ((s64)seq - (s64)con->in_seq < 1) {
-               pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
+               pr_info("skipping %s%lld %s seq %lld expected %lld\n",
                        ENTITY_NAME(con->peer_name),
                        ceph_pr_addr(&con->peer_addr.in_addr),
                        seq, con->in_seq + 1);
                con->in_base_pos = -front_len - middle_len - data_len -
                        sizeof(m->footer);
                con->in_tag = CEPH_MSGR_TAG_READY;
-               con->in_seq++;
                return 0;
        } else if ((s64)seq - (s64)con->in_seq > 1) {
                pr_err("read_partial_message bad seq %lld expected %lld\n",
@@ -1576,7 +1573,7 @@ static int read_partial_message(struct ceph_connection *con)
 
                con->in_msg_pos.page = 0;
                if (m->pages)
-                       con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
+                       con->in_msg_pos.page_pos = m->page_alignment;
                else
                        con->in_msg_pos.page_pos = 0;
                con->in_msg_pos.data_pos = 0;
@@ -2301,6 +2298,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
 
        /* data */
        m->nr_pages = 0;
+       m->page_alignment = 0;
        m->pages = NULL;
        m->pagelist = NULL;
        m->bio = NULL;
@@ -2370,6 +2368,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
                               type, front_len);
                        return NULL;
                }
+               msg->page_alignment = le16_to_cpu(hdr->data_off);
        }
        memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
 
index 79391994b3edee7d531b823c0720262090db6618..3e20a122ffa2f2bf40a91596fe12bb93e6874b64 100644 (file)
@@ -71,6 +71,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
                op->extent.length = objlen;
        }
        req->r_num_pages = calc_pages_for(off, *plen);
+       req->r_page_alignment = off & ~PAGE_MASK;
        if (op->op == CEPH_OSD_OP_WRITE)
                op->payload_len = *plen;
 
@@ -390,6 +391,8 @@ void ceph_osdc_build_request(struct ceph_osd_request *req,
                req->r_request->hdr.data_len = cpu_to_le32(data_len);
        }
 
+       req->r_request->page_alignment = req->r_page_alignment;
+
        BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
        msg_size = p - msg->front.iov_base;
        msg->front.iov_len = msg_size;
@@ -419,7 +422,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
                                               u32 truncate_seq,
                                               u64 truncate_size,
                                               struct timespec *mtime,
-                                              bool use_mempool, int num_reply)
+                                              bool use_mempool, int num_reply,
+                                              int page_align)
 {
        struct ceph_osd_req_op ops[3];
        struct ceph_osd_request *req;
@@ -447,6 +451,10 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
        calc_layout(osdc, vino, layout, off, plen, req, ops);
        req->r_file_layout = *layout;  /* keep a copy */
 
+       /* in case it differs from natural alignment that calc_layout
+          filled in for us */
+       req->r_page_alignment = page_align;
+
        ceph_osdc_build_request(req, off, plen, ops,
                                snapc,
                                mtime,
@@ -1489,7 +1497,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
                        struct ceph_vino vino, struct ceph_file_layout *layout,
                        u64 off, u64 *plen,
                        u32 truncate_seq, u64 truncate_size,
-                       struct page **pages, int num_pages)
+                       struct page **pages, int num_pages, int page_align)
 {
        struct ceph_osd_request *req;
        int rc = 0;
@@ -1499,15 +1507,15 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
        req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
                                    CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
                                    NULL, 0, truncate_seq, truncate_size, NULL,
-                                   false, 1);
+                                   false, 1, page_align);
        if (!req)
                return -ENOMEM;
 
        /* it may be a short read due to an object boundary */
        req->r_pages = pages;
 
-       dout("readpages  final extent is %llu~%llu (%d pages)\n",
-            off, *plen, req->r_num_pages);
+       dout("readpages  final extent is %llu~%llu (%d pages align %d)\n",
+            off, *plen, req->r_num_pages, page_align);
 
        rc = ceph_osdc_start_request(osdc, req, false);
        if (!rc)
@@ -1533,6 +1541,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
 {
        struct ceph_osd_request *req;
        int rc = 0;
+       int page_align = off & ~PAGE_MASK;
 
        BUG_ON(vino.snap != CEPH_NOSNAP);
        req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
@@ -1541,7 +1550,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
                                            CEPH_OSD_FLAG_WRITE,
                                    snapc, do_sync,
                                    truncate_seq, truncate_size, mtime,
-                                   nofail, 1);
+                                   nofail, 1, page_align);
        if (!req)
                return -ENOMEM;
 
@@ -1638,8 +1647,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
        m = ceph_msg_get(req->r_reply);
 
        if (data_len > 0) {
-               unsigned data_off = le16_to_cpu(hdr->data_off);
-               int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
+               int want = calc_pages_for(req->r_page_alignment, data_len);
 
                if (unlikely(req->r_num_pages < want)) {
                        pr_warning("tid %lld reply %d > expected %d pages\n",
@@ -1651,6 +1659,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
                }
                m->pages = req->r_pages;
                m->nr_pages = req->r_num_pages;
+               m->page_alignment = req->r_page_alignment;
 #ifdef CONFIG_BLOCK
                m->bio = req->r_bio;
 #endif
index 54caf06871559adb490018023cea7163f2451706..ac34feeb2b3ab2202e02aeab2a0367f29ac6a2b2 100644 (file)
@@ -13,8 +13,7 @@
  * build a vector of user pages
  */
 struct page **ceph_get_direct_page_vector(const char __user *data,
-                                                int num_pages,
-                                                loff_t off, size_t len)
+                                         int num_pages)
 {
        struct page **pages;
        int rc;
index 23e9b2a6b4c8ade67fff929c78cea57483b49964..c1ee800bc080c3faf33033e1659021a0a356f7ce 100644 (file)
@@ -589,7 +589,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
 EXPORT_SYMBOL(sk_chk_filter);
 
 /**
- *     sk_filter_rcu_release: Release a socket filter by rcu_head
+ *     sk_filter_rcu_release - Release a socket filter by rcu_head
  *     @rcu: rcu_head that contains the sk_filter to free
  */
 static void sk_filter_rcu_release(struct rcu_head *rcu)
index a5ff5a89f376bb1299dec78fa34abe9480ae01f1..7f902cad10f8b13d7096f53905e3a47bb3c12d25 100644 (file)
@@ -712,15 +712,21 @@ static void rx_queue_release(struct kobject *kobj)
 
 
        map = rcu_dereference_raw(queue->rps_map);
-       if (map)
+       if (map) {
+               RCU_INIT_POINTER(queue->rps_map, NULL);
                call_rcu(&map->rcu, rps_map_release);
+       }
 
        flow_table = rcu_dereference_raw(queue->rps_flow_table);
-       if (flow_table)
+       if (flow_table) {
+               RCU_INIT_POINTER(queue->rps_flow_table, NULL);
                call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
+       }
 
        if (atomic_dec_and_test(&first->count))
                kfree(first);
+       else
+               memset(kobj, 0, sizeof(*kobj));
 }
 
 static struct kobj_type rx_queue_ktype = {
index 7552495aff7aef090d99654312d5365afa421e95..fceeb37d7161697922dd46e00d62e3c1cd89eb4b 100644 (file)
@@ -45,9 +45,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
        nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);
        lopt_size += nr_table_entries * sizeof(struct request_sock *);
        if (lopt_size > PAGE_SIZE)
-               lopt = __vmalloc(lopt_size,
-                       GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
-                       PAGE_KERNEL);
+               lopt = vzalloc(lopt_size);
        else
                lopt = kzalloc(lopt_size, GFP_KERNEL);
        if (lopt == NULL)
index 265985370fa1de664b1b7f3de427cb043fc74665..e424a09e83f61e6410607c01a2623ee5f8dea854 100644 (file)
@@ -239,7 +239,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                dccp_update_gsr(sk, seqno);
 
                if (dh->dccph_type != DCCP_PKT_SYNC &&
-                   (ackno != DCCP_PKT_WITHOUT_ACK_SEQ))
+                   ackno != DCCP_PKT_WITHOUT_ACK_SEQ &&
+                   after48(ackno, dp->dccps_gar))
                        dp->dccps_gar = ackno;
        } else {
                unsigned long now = jiffies;
index a76b78de679fa7e928cfae7b62c0a7e73c2256dd..6f97268ed85fe5de5b5d3318a038f49d0f65629e 100644 (file)
@@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
                        if (r_len > sizeof(struct linkinfo_dn))
                                r_len = sizeof(struct linkinfo_dn);
 
+                       memset(&link, 0, sizeof(link));
+
                        switch(sock->state) {
                                case SS_CONNECTING:
                                        link.idn_linkstate = LL_CONNECTING;
index f8c1ae4b41f03641f7bb7db11feb88893df65519..13992e1d2726cd29f9d84d9f782d0eb8cf3fbd5d 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/skbuff.h>
 #include <linux/udp.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 #endif
 #ifdef CONFIG_ECONET_AUNUDP
        struct msghdr udpmsg;
-       struct iovec iov[msg->msg_iovlen+1];
+       struct iovec iov[2];
        struct aunhdr ah;
        struct sockaddr_in udpdest;
        __kernel_size_t size;
-       int i;
        mm_segment_t oldfs;
+       char *userbuf;
 #endif
 
        /*
@@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        mutex_lock(&econet_mutex);
 
-       if (saddr == NULL) {
-               struct econet_sock *eo = ec_sk(sk);
-
-               addr.station = eo->station;
-               addr.net     = eo->net;
-               port         = eo->port;
-               cb           = eo->cb;
-       } else {
-               if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
-                       mutex_unlock(&econet_mutex);
-                       return -EINVAL;
-               }
-               addr.station = saddr->addr.station;
-               addr.net = saddr->addr.net;
-               port = saddr->port;
-               cb = saddr->cb;
-       }
+        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+                mutex_unlock(&econet_mutex);
+                return -EINVAL;
+        }
+        addr.station = saddr->addr.station;
+        addr.net = saddr->addr.net;
+        port = saddr->port;
+        cb = saddr->cb;
 
        /* Look for a device with the right network number. */
        dev = net2dev_map[addr.net];
@@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
                }
        }
 
-       if (len + 15 > dev->mtu) {
-               mutex_unlock(&econet_mutex);
-               return -EMSGSIZE;
-       }
-
        if (dev->type == ARPHRD_ECONET) {
                /* Real hardware Econet.  We're not worthy etc. */
 #ifdef CONFIG_ECONET_NATIVE
                unsigned short proto = 0;
                int res;
 
+               if (len + 15 > dev->mtu) {
+                       mutex_unlock(&econet_mutex);
+                       return -EMSGSIZE;
+               }
+
                dev_hold(dev);
 
                skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
@@ -351,7 +343,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
                eb = (struct ec_cb *)&skb->cb;
 
-               /* BUG: saddr may be NULL */
                eb->cookie = saddr->cookie;
                eb->sec = *saddr;
                eb->sent = ec_tx_done;
@@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
                return -ENETDOWN;               /* No socket - can't send */
        }
 
+       if (len > 32768) {
+               err = -E2BIG;
+               goto error;
+       }
+
        /* Make up a UDP datagram and hand it off to some higher intellect. */
 
        memset(&udpdest, 0, sizeof(udpdest));
@@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        /* tack our header on the front of the iovec */
        size = sizeof(struct aunhdr);
-       /*
-        * XXX: that is b0rken.  We can't mix userland and kernel pointers
-        * in iovec, since on a lot of platforms copy_from_user() will
-        * *not* work with the kernel and userland ones at the same time,
-        * regardless of what we do with set_fs().  And we are talking about
-        * econet-over-ethernet here, so "it's only ARM anyway" doesn't
-        * apply.  Any suggestions on fixing that code?         -- AV
-        */
        iov[0].iov_base = (void *)&ah;
        iov[0].iov_len = size;
-       for (i = 0; i < msg->msg_iovlen; i++) {
-               void __user *base = msg->msg_iov[i].iov_base;
-               size_t iov_len = msg->msg_iov[i].iov_len;
-               /* Check it now since we switch to KERNEL_DS later. */
-               if (!access_ok(VERIFY_READ, base, iov_len)) {
-                       mutex_unlock(&econet_mutex);
-                       return -EFAULT;
-               }
-               iov[i+1].iov_base = base;
-               iov[i+1].iov_len = iov_len;
-               size += iov_len;
+
+       userbuf = vmalloc(len);
+       if (userbuf == NULL) {
+               err = -ENOMEM;
+               goto error;
        }
 
+       iov[1].iov_base = userbuf;
+       iov[1].iov_len = len;
+       err = memcpy_fromiovec(userbuf, msg->msg_iov, len);
+       if (err)
+               goto error_free_buf;
+
        /* Get a skbuff (no data, just holds our cb information) */
        if ((skb = sock_alloc_send_skb(sk, 0,
                                       msg->msg_flags & MSG_DONTWAIT,
-                                      &err)) == NULL) {
-               mutex_unlock(&econet_mutex);
-               return err;
-       }
+                                      &err)) == NULL)
+               goto error_free_buf;
 
        eb = (struct ec_cb *)&skb->cb;
 
@@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        udpmsg.msg_name = (void *)&udpdest;
        udpmsg.msg_namelen = sizeof(udpdest);
        udpmsg.msg_iov = &iov[0];
-       udpmsg.msg_iovlen = msg->msg_iovlen + 1;
+       udpmsg.msg_iovlen = 2;
        udpmsg.msg_control = NULL;
        udpmsg.msg_controllen = 0;
        udpmsg.msg_flags=0;
@@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
        oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
        err = sock_sendmsg(udpsock, &udpmsg, size);
        set_fs(oldfs);
+
+error_free_buf:
+       vfree(userbuf);
 #else
        err = -EPROTOTYPE;
 #endif
+       error:
        mutex_unlock(&econet_mutex);
 
        return err;
@@ -671,6 +661,9 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
        err = 0;
        switch (cmd) {
        case SIOCSIFADDR:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+
                edev = dev->ec_ptr;
                if (edev == NULL) {
                        /* Magic up a new one. */
index 200eb538fbb3f77101fe9646893dddbd9e83117b..0f280348e0fdad70adb37f3b33bdbe6fedd99025 100644 (file)
@@ -365,7 +365,7 @@ static struct tnode *tnode_alloc(size_t size)
        if (size <= PAGE_SIZE)
                return kzalloc(size, GFP_KERNEL);
        else
-               return __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+               return vzalloc(size);
 }
 
 static void __tnode_vfree(struct work_struct *arg)
index 96bc7f9475a3f2f0124685cc1b7afb7b58c23d8d..e5d1a44bcbdf04b851d441ea5ebd8fbe44514704 100644 (file)
@@ -569,6 +569,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                /* No need to clone since we're just using its address. */
                rt2 = rt;
 
+               if (!fl.nl_u.ip4_u.saddr)
+                       fl.nl_u.ip4_u.saddr = rt->rt_src;
+
                err = xfrm_lookup(net, (struct dst_entry **)&rt, &fl, NULL, 0);
                switch (err) {
                case 0:
index 1b344f30b463fab9ed70a8f19a19d348d7c626f7..3c0369a3a663693ac24e6acdd2730909ae5ddf4a 100644 (file)
@@ -133,8 +133,7 @@ int __inet_inherit_port(struct sock *sk, struct sock *child)
                        }
                }
        }
-       sk_add_bind_node(child, &tb->owners);
-       inet_csk(child)->icsk_bind_hash = tb;
+       inet_bind_hash(child, tb, port);
        spin_unlock(&head->lock);
 
        return 0;
index e91911d7aae26656f940a747a6d0ccb91739f39a..1b4ec21497a49756025965e4e17e4bc9466f4f5c 100644 (file)
@@ -26,6 +26,8 @@ static int zero;
 static int tcp_retr1_max = 255;
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
+static int tcp_adv_win_scale_min = -31;
+static int tcp_adv_win_scale_max = 31;
 
 /* Update system visible IP port range */
 static void set_local_port_range(int range[2])
@@ -426,7 +428,9 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_adv_win_scale,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &tcp_adv_win_scale_min,
+               .extra2         = &tcp_adv_win_scale_max,
        },
        {
                .procname       = "tcp_tw_reuse",
index 0814199694854e534eb4ff12671e02313dced8e9..f15c36a706ecb07385d46a7d8eeb1233cfbb2daa 100644 (file)
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                /* Values greater than interface MTU won't take effect. However
                 * at the point when this call is done we typically don't yet
                 * know which interface is going to be used */
-               if (val < 64 || val > MAX_TCP_WINDOW) {
+               if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) {
                        err = -EINVAL;
                        break;
                }
index 69ccbc1dde9cdfed2719e243fd6091cc9781a876..e13da6de1fc79e26dc6d03b671e1becf9e6c8754 100644 (file)
@@ -2043,7 +2043,9 @@ get_req:
        }
 get_sk:
        sk_nulls_for_each_from(sk, node) {
-               if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) {
+               if (!net_eq(sock_net(sk), net))
+                       continue;
+               if (sk->sk_family == st->family) {
                        cur = sk;
                        goto out;
                }
index b41ce0f0d514154597753d549b5a29a3bc7e7ae0..23cc8e1ce8d4995a551ca93d98434e9150ad1740 100644 (file)
 #endif
 
 #define        INFINITY_LIFE_TIME      0xFFFFFFFF
-#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b)))
+
+static inline u32 cstamp_delta(unsigned long cstamp)
+{
+       return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
+}
 
 #define ADDRCONF_TIMER_FUZZ_MINUS      (HZ > 50 ? HZ/50 : 1)
 #define ADDRCONF_TIMER_FUZZ            (HZ / 4)
@@ -2754,13 +2758,13 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                        ifa->state = INET6_IFADDR_STATE_DEAD;
                        spin_unlock_bh(&ifa->state_lock);
 
-                       if (state == INET6_IFADDR_STATE_DEAD) {
-                               in6_ifa_put(ifa);
-                       } else {
+                       if (state != INET6_IFADDR_STATE_DEAD) {
                                __ipv6_ifa_notify(RTM_DELADDR, ifa);
                                atomic_notifier_call_chain(&inet6addr_chain,
                                                           NETDEV_DOWN, ifa);
                        }
+
+                       in6_ifa_put(ifa);
                        write_lock_bh(&idev->lock);
                }
        }
@@ -3444,10 +3448,8 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
 {
        struct ifa_cacheinfo ci;
 
-       ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100
-                       + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
-       ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
-                       + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+       ci.cstamp = cstamp_delta(cstamp);
+       ci.tstamp = cstamp_delta(tstamp);
        ci.ifa_prefered = preferred;
        ci.ifa_valid = valid;
 
@@ -3798,8 +3800,10 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_AUTOCONF] = cnf->autoconf;
        array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
        array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
-       array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
-       array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
+       array[DEVCONF_RTR_SOLICIT_INTERVAL] =
+               jiffies_to_msecs(cnf->rtr_solicit_interval);
+       array[DEVCONF_RTR_SOLICIT_DELAY] =
+               jiffies_to_msecs(cnf->rtr_solicit_delay);
        array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
 #ifdef CONFIG_IPV6_PRIVACY
        array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
@@ -3813,7 +3817,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
 #ifdef CONFIG_IPV6_ROUTER_PREF
        array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
-       array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval;
+       array[DEVCONF_RTR_PROBE_INTERVAL] =
+               jiffies_to_msecs(cnf->rtr_probe_interval);
 #ifdef CONFIG_IPV6_ROUTE_INFO
        array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
 #endif
@@ -3929,10 +3934,9 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
        NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
 
        ci.max_reasm_len = IPV6_MAXPLEN;
-       ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
-                   + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
-       ci.reachable_time = idev->nd_parms->reachable_time;
-       ci.retrans_time = idev->nd_parms->retrans_time;
+       ci.tstamp = cstamp_delta(idev->tstamp);
+       ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
+       ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
        NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
 
        nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
index 7f097989cde2149714eab1ea7b1de02280531ed2..a6de3059746ddd3f3039d564f20acf394225e3ad 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/slab.h>
index 7fa86373de414a810be41e6973027d0b31c12168..7c567b8aa89a9e938dc442487b70d5e099bc2ade 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include "irnet_ppp.h"         /* Private header */
 /* Please put other headers in irnet.h - Thanks */
 
index 285761e77d90f98ee15c6b47b34c8ead10692e33..f6054f9ccbe33c2fbd9aef8c88551c84bb5fbf62 100644 (file)
@@ -550,22 +550,30 @@ EXPORT_SYMBOL(irttp_close_tsap);
  */
 int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
 {
+       int ret;
+
        IRDA_ASSERT(self != NULL, return -1;);
        IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
        IRDA_ASSERT(skb != NULL, return -1;);
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
+       /* Take shortcut on zero byte packets */
+       if (skb->len == 0) {
+               ret = 0;
+               goto err;
+       }
+
        /* Check that nothing bad happens */
-       if ((skb->len == 0) || (!self->connected)) {
-               IRDA_DEBUG(1, "%s(), No data, or not connected\n",
-                          __func__);
+       if (!self->connected) {
+               IRDA_WARNING("%s(), Not connected\n", __func__);
+               ret = -ENOTCONN;
                goto err;
        }
 
        if (skb->len > self->max_seg_size) {
-               IRDA_DEBUG(1, "%s(), UData is too large for IrLAP!\n",
-                          __func__);
+               IRDA_ERROR("%s(), UData is too large for IrLAP!\n", __func__);
+               ret = -EMSGSIZE;
                goto err;
        }
 
@@ -576,7 +584,7 @@ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
 
 err:
        dev_kfree_skb(skb);
-       return -1;
+       return ret;
 }
 EXPORT_SYMBOL(irttp_udata_request);
 
@@ -599,9 +607,15 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
        IRDA_DEBUG(2, "%s() : queue len = %d\n", __func__,
                   skb_queue_len(&self->tx_queue));
 
+       /* Take shortcut on zero byte packets */
+       if (skb->len == 0) {
+               ret = 0;
+               goto err;
+       }
+
        /* Check that nothing bad happens */
-       if ((skb->len == 0) || (!self->connected)) {
-               IRDA_WARNING("%s: No data, or not connected\n", __func__);
+       if (!self->connected) {
+               IRDA_WARNING("%s: Not connected\n", __func__);
                ret = -ENOTCONN;
                goto err;
        }
index 4d6f8653ec8819a7e69cdb9cb447b77c1e7e7047..8e8ea9cb7093185b4645a6bf7d23467e15ee518b 100644 (file)
@@ -92,7 +92,7 @@ config MAC80211_MESH
 config MAC80211_LEDS
        bool "Enable LED triggers"
        depends on MAC80211
-       select NEW_LEDS
+       depends on LEDS_CLASS
        select LEDS_TRIGGERS
        ---help---
          This option enables a few LED triggers for different
index a22dac227055e7499bfd9d8dd509ee5fba3e1c9b..70bd1d0774c6bdb6b1f9d4d1f07284cfe43500dd 100644 (file)
@@ -4,6 +4,7 @@
 menuconfig IP_VS
        tristate "IP virtual server support"
        depends on NET && INET && NETFILTER
+       depends on (NF_CONNTRACK || NF_CONNTRACK=n)
        ---help---
          IP Virtual Server support will let you build a high-performance
          virtual server based on cluster of two or more real servers. This
index 8920f2a83327a42f10d20acdfb651f9c1b9620a3..4e37c1cbe8b2faf5928af6be551f3f5551684411 100644 (file)
@@ -567,7 +567,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
                goto out;
        }
 
-       if (args->nr_local > (u64)UINT_MAX) {
+       if (args->nr_local > UIO_MAXIOV) {
                ret = -EMSGSIZE;
                goto out;
        }
index 9dab9573be4146feafd1fb2db584faa3b61b0b0b..92ce94f5146b3cfb924d0103d62a2f0d51fdf84e 100644 (file)
@@ -989,20 +989,26 @@ call_refreshresult(struct rpc_task *task)
        dprint_status(task);
 
        task->tk_status = 0;
-       task->tk_action = call_allocate;
-       if (status >= 0 && rpcauth_uptodatecred(task))
-               return;
+       task->tk_action = call_refresh;
        switch (status) {
-       case -EACCES:
-               rpc_exit(task, -EACCES);
-               return;
-       case -ENOMEM:
-               rpc_exit(task, -ENOMEM);
+       case 0:
+               if (rpcauth_uptodatecred(task))
+                       task->tk_action = call_allocate;
                return;
        case -ETIMEDOUT:
                rpc_delay(task, 3*HZ);
+       case -EAGAIN:
+               status = -EACCES;
+               if (!task->tk_cred_retry)
+                       break;
+               task->tk_cred_retry--;
+               dprintk("RPC: %5u %s: retry refresh creds\n",
+                               task->tk_pid, __func__);
+               return;
        }
-       task->tk_action = call_refresh;
+       dprintk("RPC: %5u %s: refresh creds failed with error %d\n",
+                               task->tk_pid, __func__, status);
+       rpc_exit(task, status);
 }
 
 /*
index f71a73107ae94adeae35303f95f0b3409aee9e07..80df89d957ba02dce1b977ec19f96b51d2c657b0 100644 (file)
@@ -115,9 +115,7 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
  */
 struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
 {
-       struct rpc_iostats *new;
-       new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
-       return new;
+       return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
 
index c82fe739fbdcc685fae1e59f1fdb7c9e5afd30b0..ea2ff78dcf7b7ec4f2555210af82379017e6e291 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
index 3c95304a08174f550f64f36346ce031419f6a4c8..2268e6798124c9300cd4c10f5a65376898252210 100644 (file)
@@ -1343,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb)
        sock_wfree(skb);
 }
 
+#define MAX_RECURSION_LEVEL 4
+
 static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 {
        int i;
+       unsigned char max_level = 0;
+       int unix_sock_count = 0;
+
+       for (i = scm->fp->count - 1; i >= 0; i--) {
+               struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+
+               if (sk) {
+                       unix_sock_count++;
+                       max_level = max(max_level,
+                                       unix_sk(sk)->recursion_level);
+               }
+       }
+       if (unlikely(max_level > MAX_RECURSION_LEVEL))
+               return -ETOOMANYREFS;
 
        /*
         * Need to duplicate file references for the sake of garbage
@@ -1356,9 +1372,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
        if (!UNIXCB(skb).fp)
                return -ENOMEM;
 
-       for (i = scm->fp->count-1; i >= 0; i--)
-               unix_inflight(scm->fp->fp[i]);
-       return 0;
+       if (unix_sock_count) {
+               for (i = scm->fp->count - 1; i >= 0; i--)
+                       unix_inflight(scm->fp->fp[i]);
+       }
+       return max_level;
 }
 
 static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
@@ -1393,6 +1411,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sk_buff *skb;
        long timeo;
        struct scm_cookie tmp_scm;
+       int max_level;
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1431,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto out;
 
        err = unix_scm_to_skb(siocb->scm, skb, true);
-       if (err)
+       if (err < 0)
                goto out_free;
+       max_level = err + 1;
        unix_get_secdata(siocb->scm, skb);
 
        skb_reset_transport_header(skb);
@@ -1514,6 +1534,8 @@ restart:
        if (sock_flag(other, SOCK_RCVTSTAMP))
                __net_timestamp(skb);
        skb_queue_tail(&other->sk_receive_queue, skb);
+       if (max_level > unix_sk(other)->recursion_level)
+               unix_sk(other)->recursion_level = max_level;
        unix_state_unlock(other);
        other->sk_data_ready(other, len);
        sock_put(other);
@@ -1544,6 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        int sent = 0;
        struct scm_cookie tmp_scm;
        bool fds_sent = false;
+       int max_level;
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1607,10 +1630,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 
                /* Only send the fds in the first buffer */
                err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
-               if (err) {
+               if (err < 0) {
                        kfree_skb(skb);
                        goto out_err;
                }
+               max_level = err + 1;
                fds_sent = true;
 
                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
@@ -1626,6 +1650,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        goto pipe_err_free;
 
                skb_queue_tail(&other->sk_receive_queue, skb);
+               if (max_level > unix_sk(other)->recursion_level)
+                       unix_sk(other)->recursion_level = max_level;
                unix_state_unlock(other);
                other->sk_data_ready(other, size);
                sent += size;
@@ -1845,6 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                unix_state_lock(sk);
                skb = skb_dequeue(&sk->sk_receive_queue);
                if (skb == NULL) {
+                       unix_sk(sk)->recursion_level = 0;
                        if (copied >= target)
                                goto unlock;
 
index c8df6fda0b1fcf124b65812f600710a3b3f17069..f89f83bf828ee0e713ded75c84da22a1c1b2426e 100644 (file)
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
 unsigned int unix_tot_inflight;
 
 
-static struct sock *unix_get_socket(struct file *filp)
+struct sock *unix_get_socket(struct file *filp)
 {
        struct sock *u_sock = NULL;
        struct inode *inode = filp->f_path.dentry->d_inode;
@@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
 }
 
 static bool gc_in_progress = false;
+#define UNIX_INFLIGHT_TRIGGER_GC 16000
 
 void wait_for_unix_gc(void)
 {
+       /*
+        * If number of inflight sockets is insane,
+        * force a garbage collect right now.
+        */
+       if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
+               unix_gc();
        wait_event(unix_gc_wait, gc_in_progress == false);
 }
 
index d0c92dddb26bddb5b3d55a82ebf39fa8917e446c..17cd0c04d139045bbb0802a74d9628731d9428dc 100644 (file)
@@ -44,6 +44,38 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
        return chan;
 }
 
+static bool can_beacon_sec_chan(struct wiphy *wiphy,
+                               struct ieee80211_channel *chan,
+                               enum nl80211_channel_type channel_type)
+{
+       struct ieee80211_channel *sec_chan;
+       int diff;
+
+       switch (channel_type) {
+       case NL80211_CHAN_HT40PLUS:
+               diff = 20;
+               break;
+       case NL80211_CHAN_HT40MINUS:
+               diff = -20;
+               break;
+       default:
+               return false;
+       }
+
+       sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff);
+       if (!sec_chan)
+               return false;
+
+       /* we'll need a DFS capability later */
+       if (sec_chan->flags & (IEEE80211_CHAN_DISABLED |
+                              IEEE80211_CHAN_PASSIVE_SCAN |
+                              IEEE80211_CHAN_NO_IBSS |
+                              IEEE80211_CHAN_RADAR))
+               return false;
+
+       return true;
+}
+
 int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
                      struct wireless_dev *wdev, int freq,
                      enum nl80211_channel_type channel_type)
@@ -68,6 +100,28 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
        if (!chan)
                return -EINVAL;
 
+       /* Both channels should be able to initiate communication */
+       if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC ||
+                    wdev->iftype == NL80211_IFTYPE_AP ||
+                    wdev->iftype == NL80211_IFTYPE_AP_VLAN ||
+                    wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
+                    wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
+               switch (channel_type) {
+               case NL80211_CHAN_HT40PLUS:
+               case NL80211_CHAN_HT40MINUS:
+                       if (!can_beacon_sec_chan(&rdev->wiphy, chan,
+                                                channel_type)) {
+                               printk(KERN_DEBUG
+                                      "cfg80211: Secondary channel not "
+                                      "allowed to initiate communication\n");
+                               return -EINVAL;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
        result = rdev->ops->set_channel(&rdev->wiphy,
                                        wdev ? wdev->netdev : NULL,
                                        chan, channel_type);
index a2023ec52329ef66b95e14dc94f7086e5683e534..1e98bc0fe0a54bbca2a7fc1f94ab9344af0fbded 100644 (file)
@@ -19,7 +19,7 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz)
        if (sz <= PAGE_SIZE)
                n = kzalloc(sz, GFP_KERNEL);
        else if (hashdist)
-               n = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+               n = vzalloc(sz);
        else
                n = (struct hlist_head *)
                        __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
index d81b968d864e5009d89f11bff18cfc3b344bdd00..c9230e158a8f60c0a9206b3db4df3dc21f372cf4 100644 (file)
@@ -63,7 +63,12 @@ fi
 
 # Extract GFP flags from the kernel source
 TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1
-grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
+grep -q ___GFP $SOURCE/include/linux/gfp.h
+if [ $? -eq 0 ]; then
+       grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE
+else
+       grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
+fi
 
 # Parse the flags
 IFS="
index 184eb6a0b505cc50e7435950b7a770923ba06cb2..e57826ced3800bb596945a708b648d3f68006dec 100644 (file)
@@ -164,6 +164,7 @@ struct menu {
        struct menu *list;
        struct symbol *sym;
        struct property *prompt;
+       struct expr *visibility;
        struct expr *dep;
        unsigned int flags;
        char *help;
index 753cdbd7b80590abf05a0c86a6eb06153b11e774..3f7240df0f3b969f63956a06cf899091c47e70cb 100644 (file)
@@ -107,6 +107,7 @@ void menu_end_menu(void);
 void menu_add_entry(struct symbol *sym);
 void menu_end_entry(void);
 void menu_add_dep(struct expr *dep);
+void menu_add_visibility(struct expr *dep);
 struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
index 7e83aef42c6d41c63051664b2669c922356bff3a..b9d9aa18e6d62bbaa40c34cf7062c00c8bb15e35 100644 (file)
@@ -152,6 +152,12 @@ struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr
        return menu_add_prop(type, prompt, NULL, dep);
 }
 
+void menu_add_visibility(struct expr *expr)
+{
+       current_entry->visibility = expr_alloc_and(current_entry->visibility,
+           expr);
+}
+
 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
 {
        menu_add_prop(type, NULL, expr, dep);
@@ -410,6 +416,11 @@ bool menu_is_visible(struct menu *menu)
        if (!menu->prompt)
                return false;
 
+       if (menu->visibility) {
+               if (expr_calc_value(menu->visibility) == no)
+                       return no;
+       }
+
        sym = menu->sym;
        if (sym) {
                sym_calc_value(sym);
index d8bc7424962296f2370cba1e9a594bf9de04f6d6..c9e690eb75451fa5f87b2c7d4f4d15f71c83c33f 100644 (file)
@@ -38,6 +38,7 @@ hex,          T_TYPE,         TF_COMMAND, S_HEX
 string,                T_TYPE,         TF_COMMAND, S_STRING
 select,                T_SELECT,       TF_COMMAND
 range,         T_RANGE,        TF_COMMAND
+visible,       T_VISIBLE,      TF_COMMAND
 option,                T_OPTION,       TF_COMMAND
 on,            T_ON,           TF_PARAM
 modules,       T_OPT_MODULES,  TF_OPTION
index c1748faf46340525706f0f25f867ffa01c3f9b19..4055d5de1750261453c46d752f09ace7b17df74d 100644 (file)
@@ -32,7 +32,7 @@
 struct kconf_id;
 
 static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-/* maximum key range = 47, duplicates = 0 */
+/* maximum key range = 50, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -46,32 +46,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
 {
   static unsigned char asso_values[] =
     {
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 11,  5,
-       0,  0,  5, 49,  5, 20, 49, 49,  5, 20,
-       5,  0, 30, 49,  0, 15,  0, 10,  0, 49,
-      25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-      49, 49, 49, 49, 49, 49
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 40,  5,
+       0,  0,  5, 52,  0, 20, 52, 52, 10, 20,
+       5,  0, 35, 52,  0, 30,  0, 15,  0, 52,
+      15, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+      52, 52, 52, 52, 52, 52
     };
   register int hval = len;
 
@@ -102,25 +102,26 @@ struct kconf_id_strings_t
     char kconf_id_strings_str12[sizeof("default")];
     char kconf_id_strings_str13[sizeof("def_bool")];
     char kconf_id_strings_str14[sizeof("help")];
-    char kconf_id_strings_str15[sizeof("bool")];
     char kconf_id_strings_str16[sizeof("config")];
     char kconf_id_strings_str17[sizeof("def_tristate")];
-    char kconf_id_strings_str18[sizeof("boolean")];
+    char kconf_id_strings_str18[sizeof("hex")];
     char kconf_id_strings_str19[sizeof("defconfig_list")];
-    char kconf_id_strings_str21[sizeof("string")];
     char kconf_id_strings_str22[sizeof("if")];
     char kconf_id_strings_str23[sizeof("int")];
-    char kconf_id_strings_str26[sizeof("select")];
     char kconf_id_strings_str27[sizeof("modules")];
     char kconf_id_strings_str28[sizeof("tristate")];
     char kconf_id_strings_str29[sizeof("menu")];
-    char kconf_id_strings_str31[sizeof("source")];
     char kconf_id_strings_str32[sizeof("comment")];
-    char kconf_id_strings_str33[sizeof("hex")];
     char kconf_id_strings_str35[sizeof("menuconfig")];
-    char kconf_id_strings_str36[sizeof("prompt")];
-    char kconf_id_strings_str37[sizeof("depends")];
+    char kconf_id_strings_str36[sizeof("string")];
+    char kconf_id_strings_str37[sizeof("visible")];
+    char kconf_id_strings_str41[sizeof("prompt")];
+    char kconf_id_strings_str42[sizeof("depends")];
+    char kconf_id_strings_str44[sizeof("bool")];
+    char kconf_id_strings_str46[sizeof("select")];
+    char kconf_id_strings_str47[sizeof("boolean")];
     char kconf_id_strings_str48[sizeof("mainmenu")];
+    char kconf_id_strings_str51[sizeof("source")];
   };
 static struct kconf_id_strings_t kconf_id_strings_contents =
   {
@@ -136,25 +137,26 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
     "default",
     "def_bool",
     "help",
-    "bool",
     "config",
     "def_tristate",
-    "boolean",
+    "hex",
     "defconfig_list",
-    "string",
     "if",
     "int",
-    "select",
     "modules",
     "tristate",
     "menu",
-    "source",
     "comment",
-    "hex",
     "menuconfig",
+    "string",
+    "visible",
     "prompt",
     "depends",
-    "mainmenu"
+    "bool",
+    "select",
+    "boolean",
+    "mainmenu",
+    "source"
   };
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
 #ifdef __GNUC__
@@ -168,11 +170,11 @@ kconf_id_lookup (register const char *str, register unsigned int len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 31,
+      TOTAL_KEYWORDS = 32,
       MIN_WORD_LENGTH = 2,
       MAX_WORD_LENGTH = 14,
       MIN_HASH_VALUE = 2,
-      MAX_HASH_VALUE = 48
+      MAX_HASH_VALUE = 51
     };
 
   static struct kconf_id wordlist[] =
@@ -191,31 +193,35 @@ kconf_id_lookup (register const char *str, register unsigned int len)
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,   T_DEFAULT,      TF_COMMAND, S_UNKNOWN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,   T_DEFAULT,      TF_COMMAND, S_BOOLEAN},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,           T_HELP,         TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,           T_CONFIG,       TF_COMMAND},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,   T_DEFAULT,      TF_COMMAND, S_TRISTATE},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,           T_TYPE,         TF_COMMAND, S_HEX},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19,   T_OPT_DEFCONFIG_LIST,TF_OPTION},
-      {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,           T_TYPE,         TF_COMMAND, S_STRING},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,           T_IF,           TF_COMMAND|TF_PARAM},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,           T_TYPE,         TF_COMMAND, S_INT},
-      {-1}, {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,           T_SELECT,       TF_COMMAND},
+      {-1}, {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,   T_OPT_MODULES,  TF_OPTION},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,   T_TYPE,         TF_COMMAND, S_TRISTATE},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,           T_MENU,         TF_COMMAND},
-      {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,           T_SOURCE,       TF_COMMAND},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,   T_COMMENT,      TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,           T_TYPE,         TF_COMMAND, S_HEX},
-      {-1},
+      {-1}, {-1},
       {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,   T_MENUCONFIG,   TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,           T_PROMPT,       TF_COMMAND},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,   T_DEPENDS,      TF_COMMAND},
-      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,           T_TYPE,         TF_COMMAND, S_STRING},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,   T_VISIBLE,      TF_COMMAND},
+      {-1}, {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,           T_PROMPT,       TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,   T_DEPENDS,      TF_COMMAND},
       {-1},
-      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,   T_MAINMENU,     TF_COMMAND}
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str44,           T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,           T_SELECT,       TF_COMMAND},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47,   T_TYPE,         TF_COMMAND, S_BOOLEAN},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48,   T_MAINMENU,     TF_COMMAND},
+      {-1}, {-1},
+      {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51,           T_SOURCE,       TF_COMMAND}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index 699d4b2651865cdb218951e211a131cda69020fc..4c5495ea205e646ef9c4efff923dd6a678dbda4b 100644 (file)
@@ -160,18 +160,19 @@ static struct menu *current_menu, *current_entry;
      T_DEFAULT = 275,
      T_SELECT = 276,
      T_RANGE = 277,
-     T_OPTION = 278,
-     T_ON = 279,
-     T_WORD = 280,
-     T_WORD_QUOTE = 281,
-     T_UNEQUAL = 282,
-     T_CLOSE_PAREN = 283,
-     T_OPEN_PAREN = 284,
-     T_EOL = 285,
-     T_OR = 286,
-     T_AND = 287,
-     T_EQUAL = 288,
-     T_NOT = 289
+     T_VISIBLE = 278,
+     T_OPTION = 279,
+     T_ON = 280,
+     T_WORD = 281,
+     T_WORD_QUOTE = 282,
+     T_UNEQUAL = 283,
+     T_CLOSE_PAREN = 284,
+     T_OPEN_PAREN = 285,
+     T_EOL = 286,
+     T_OR = 287,
+     T_AND = 288,
+     T_EQUAL = 289,
+     T_NOT = 290
    };
 #endif
 
@@ -419,20 +420,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  11
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   277
+#define YYLAST   290
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  35
+#define YYNTOKENS  36
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  48
+#define YYNNTS  50
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  113
+#define YYNRULES  118
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  185
+#define YYNSTATES  191
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   289
+#define YYMAXUTOK   290
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -468,7 +469,8 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    34
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35
 };
 
 #if YYDEBUG
@@ -478,72 +480,73 @@ static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     6,     8,    11,    13,    14,    17,    20,
       23,    26,    31,    36,    40,    42,    44,    46,    48,    50,
-      52,    54,    56,    58,    60,    62,    64,    66,    70,    73,
-      77,    80,    84,    87,    88,    91,    94,    97,   100,   103,
-     106,   110,   115,   120,   125,   131,   135,   136,   140,   141,
-     144,   148,   151,   153,   157,   158,   161,   164,   167,   170,
-     173,   178,   182,   185,   190,   191,   194,   198,   200,   204,
-     205,   208,   211,   214,   218,   222,   225,   227,   231,   232,
-     235,   238,   241,   245,   249,   252,   255,   258,   259,   262,
-     265,   268,   273,   274,   277,   279,   281,   284,   287,   290,
-     292,   295,   296,   299,   301,   305,   309,   313,   316,   320,
-     324,   326,   328,   329
+      52,    54,    56,    58,    60,    62,    64,    66,    68,    72,
+      75,    79,    82,    86,    89,    90,    93,    96,    99,   102,
+     105,   108,   112,   117,   122,   127,   133,   137,   138,   142,
+     143,   146,   150,   153,   155,   159,   160,   163,   166,   169,
+     172,   175,   180,   184,   187,   192,   193,   196,   200,   202,
+     206,   207,   210,   213,   216,   220,   224,   228,   230,   234,
+     235,   238,   241,   244,   248,   252,   255,   258,   261,   262,
+     265,   268,   271,   276,   277,   280,   283,   286,   287,   290,
+     292,   294,   297,   300,   303,   305,   308,   309,   312,   314,
+     318,   322,   326,   329,   333,   337,   339,   341,   342
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      36,     0,    -1,    78,    37,    -1,    37,    -1,    62,    38,
-      -1,    38,    -1,    -1,    38,    40,    -1,    38,    54,    -1,
-      38,    66,    -1,    38,    77,    -1,    38,    25,     1,    30,
-      -1,    38,    39,     1,    30,    -1,    38,     1,    30,    -1,
+      37,     0,    -1,    81,    38,    -1,    38,    -1,    63,    39,
+      -1,    39,    -1,    -1,    39,    41,    -1,    39,    55,    -1,
+      39,    67,    -1,    39,    80,    -1,    39,    26,     1,    31,
+      -1,    39,    40,     1,    31,    -1,    39,     1,    31,    -1,
       16,    -1,    18,    -1,    19,    -1,    21,    -1,    17,    -1,
-      22,    -1,    20,    -1,    30,    -1,    60,    -1,    70,    -1,
-      43,    -1,    45,    -1,    68,    -1,    25,     1,    30,    -1,
-       1,    30,    -1,    10,    25,    30,    -1,    42,    46,    -1,
-      11,    25,    30,    -1,    44,    46,    -1,    -1,    46,    47,
-      -1,    46,    48,    -1,    46,    74,    -1,    46,    72,    -1,
-      46,    41,    -1,    46,    30,    -1,    19,    75,    30,    -1,
-      18,    76,    79,    30,    -1,    20,    80,    79,    30,    -1,
-      21,    25,    79,    30,    -1,    22,    81,    81,    79,    30,
-      -1,    23,    49,    30,    -1,    -1,    49,    25,    50,    -1,
-      -1,    33,    76,    -1,     7,    82,    30,    -1,    51,    55,
-      -1,    77,    -1,    52,    57,    53,    -1,    -1,    55,    56,
-      -1,    55,    74,    -1,    55,    72,    -1,    55,    30,    -1,
-      55,    41,    -1,    18,    76,    79,    30,    -1,    19,    75,
-      30,    -1,    17,    30,    -1,    20,    25,    79,    30,    -1,
-      -1,    57,    40,    -1,    14,    80,    78,    -1,    77,    -1,
-      58,    61,    59,    -1,    -1,    61,    40,    -1,    61,    66,
-      -1,    61,    54,    -1,     3,    76,    78,    -1,     4,    76,
-      30,    -1,    63,    73,    -1,    77,    -1,    64,    67,    65,
-      -1,    -1,    67,    40,    -1,    67,    66,    -1,    67,    54,
-      -1,     6,    76,    30,    -1,     9,    76,    30,    -1,    69,
-      73,    -1,    12,    30,    -1,    71,    13,    -1,    -1,    73,
-      74,    -1,    73,    30,    -1,    73,    41,    -1,    16,    24,
-      80,    30,    -1,    -1,    76,    79,    -1,    25,    -1,    26,
-      -1,     5,    30,    -1,     8,    30,    -1,    15,    30,    -1,
-      30,    -1,    78,    30,    -1,    -1,    14,    80,    -1,    81,
-      -1,    81,    33,    81,    -1,    81,    27,    81,    -1,    29,
-      80,    28,    -1,    34,    80,    -1,    80,    31,    80,    -1,
-      80,    32,    80,    -1,    25,    -1,    26,    -1,    -1,    25,
-      -1
+      22,    -1,    20,    -1,    23,    -1,    31,    -1,    61,    -1,
+      71,    -1,    44,    -1,    46,    -1,    69,    -1,    26,     1,
+      31,    -1,     1,    31,    -1,    10,    26,    31,    -1,    43,
+      47,    -1,    11,    26,    31,    -1,    45,    47,    -1,    -1,
+      47,    48,    -1,    47,    49,    -1,    47,    75,    -1,    47,
+      73,    -1,    47,    42,    -1,    47,    31,    -1,    19,    78,
+      31,    -1,    18,    79,    82,    31,    -1,    20,    83,    82,
+      31,    -1,    21,    26,    82,    31,    -1,    22,    84,    84,
+      82,    31,    -1,    24,    50,    31,    -1,    -1,    50,    26,
+      51,    -1,    -1,    34,    79,    -1,     7,    85,    31,    -1,
+      52,    56,    -1,    80,    -1,    53,    58,    54,    -1,    -1,
+      56,    57,    -1,    56,    75,    -1,    56,    73,    -1,    56,
+      31,    -1,    56,    42,    -1,    18,    79,    82,    31,    -1,
+      19,    78,    31,    -1,    17,    31,    -1,    20,    26,    82,
+      31,    -1,    -1,    58,    41,    -1,    14,    83,    81,    -1,
+      80,    -1,    59,    62,    60,    -1,    -1,    62,    41,    -1,
+      62,    67,    -1,    62,    55,    -1,     3,    79,    81,    -1,
+       4,    79,    31,    -1,    64,    76,    74,    -1,    80,    -1,
+      65,    68,    66,    -1,    -1,    68,    41,    -1,    68,    67,
+      -1,    68,    55,    -1,     6,    79,    31,    -1,     9,    79,
+      31,    -1,    70,    74,    -1,    12,    31,    -1,    72,    13,
+      -1,    -1,    74,    75,    -1,    74,    31,    -1,    74,    42,
+      -1,    16,    25,    83,    31,    -1,    -1,    76,    77,    -1,
+      76,    31,    -1,    23,    82,    -1,    -1,    79,    82,    -1,
+      26,    -1,    27,    -1,     5,    31,    -1,     8,    31,    -1,
+      15,    31,    -1,    31,    -1,    81,    31,    -1,    -1,    14,
+      83,    -1,    84,    -1,    84,    34,    84,    -1,    84,    28,
+      84,    -1,    30,    83,    29,    -1,    35,    83,    -1,    83,
+      32,    83,    -1,    83,    33,    83,    -1,    26,    -1,    27,
+      -1,    -1,    26,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   107,   107,   107,   109,   109,   111,   113,   114,   115,
-     116,   117,   118,   122,   126,   126,   126,   126,   126,   126,
-     126,   130,   131,   132,   133,   134,   135,   139,   140,   146,
-     154,   160,   168,   178,   180,   181,   182,   183,   184,   185,
-     188,   196,   202,   212,   218,   224,   227,   229,   240,   241,
-     246,   255,   260,   268,   271,   273,   274,   275,   276,   277,
-     280,   286,   297,   303,   313,   315,   320,   328,   336,   339,
-     341,   342,   343,   348,   355,   362,   367,   375,   378,   380,
-     381,   382,   385,   393,   400,   407,   413,   420,   422,   423,
-     424,   427,   435,   437,   442,   443,   446,   447,   448,   452,
-     453,   456,   457,   460,   461,   462,   463,   464,   465,   466,
-     469,   470,   473,   474
+       0,   108,   108,   108,   110,   110,   112,   114,   115,   116,
+     117,   118,   119,   123,   127,   127,   127,   127,   127,   127,
+     127,   127,   131,   132,   133,   134,   135,   136,   140,   141,
+     147,   155,   161,   169,   179,   181,   182,   183,   184,   185,
+     186,   189,   197,   203,   213,   219,   225,   228,   230,   241,
+     242,   247,   256,   261,   269,   272,   274,   275,   276,   277,
+     278,   281,   287,   298,   304,   314,   316,   321,   329,   337,
+     340,   342,   343,   344,   349,   356,   363,   368,   376,   379,
+     381,   382,   383,   386,   394,   401,   408,   414,   421,   423,
+     424,   425,   428,   436,   438,   439,   442,   449,   451,   456,
+     457,   460,   461,   462,   466,   467,   470,   471,   474,   475,
+     476,   477,   478,   479,   480,   483,   484,   487,   488
 };
 #endif
 
@@ -556,7 +559,7 @@ static const char *const yytname[] =
   "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
   "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
   "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
-  "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+  "T_VISIBLE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
   "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
   "T_NOT", "$accept", "input", "start", "stmt_list", "option_name",
   "common_stmt", "option_error", "config_entry_start", "config_stmt",
@@ -567,8 +570,8 @@ static const char *const yytname[] =
   "if_entry", "if_end", "if_stmt", "if_block", "mainmenu_stmt", "menu",
   "menu_entry", "menu_end", "menu_stmt", "menu_block", "source_stmt",
   "comment", "comment_stmt", "help_start", "help", "depends_list",
-  "depends", "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr",
-  "symbol", "word_opt", 0
+  "depends", "visibility_list", "visible", "prompt_stmt_opt", "prompt",
+  "end", "nl", "if_expr", "expr", "symbol", "word_opt", 0
 };
 #endif
 
@@ -580,25 +583,25 @@ static const yytype_uint16 yytoknum[] =
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,   287,   288,   289
+     285,   286,   287,   288,   289,   290
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    35,    36,    36,    37,    37,    38,    38,    38,    38,
-      38,    38,    38,    38,    39,    39,    39,    39,    39,    39,
-      39,    40,    40,    40,    40,    40,    40,    41,    41,    42,
-      43,    44,    45,    46,    46,    46,    46,    46,    46,    46,
-      47,    47,    47,    47,    47,    48,    49,    49,    50,    50,
-      51,    52,    53,    54,    55,    55,    55,    55,    55,    55,
-      56,    56,    56,    56,    57,    57,    58,    59,    60,    61,
-      61,    61,    61,    62,    63,    64,    65,    66,    67,    67,
-      67,    67,    68,    69,    70,    71,    72,    73,    73,    73,
-      73,    74,    75,    75,    76,    76,    77,    77,    77,    78,
-      78,    79,    79,    80,    80,    80,    80,    80,    80,    80,
-      81,    81,    82,    82
+       0,    36,    37,    37,    38,    38,    39,    39,    39,    39,
+      39,    39,    39,    39,    40,    40,    40,    40,    40,    40,
+      40,    40,    41,    41,    41,    41,    41,    41,    42,    42,
+      43,    44,    45,    46,    47,    47,    47,    47,    47,    47,
+      47,    48,    48,    48,    48,    48,    49,    50,    50,    51,
+      51,    52,    53,    54,    55,    56,    56,    56,    56,    56,
+      56,    57,    57,    57,    57,    58,    58,    59,    60,    61,
+      62,    62,    62,    62,    63,    64,    65,    66,    67,    68,
+      68,    68,    68,    69,    70,    71,    72,    73,    74,    74,
+      74,    74,    75,    76,    76,    76,    77,    78,    78,    79,
+      79,    80,    80,    80,    81,    81,    82,    82,    83,    83,
+      83,    83,    83,    83,    83,    84,    84,    85,    85
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -606,16 +609,16 @@ static const yytype_uint8 yyr2[] =
 {
        0,     2,     2,     1,     2,     1,     0,     2,     2,     2,
        2,     4,     4,     3,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     3,     2,     3,
-       2,     3,     2,     0,     2,     2,     2,     2,     2,     2,
-       3,     4,     4,     4,     5,     3,     0,     3,     0,     2,
-       3,     2,     1,     3,     0,     2,     2,     2,     2,     2,
-       4,     3,     2,     4,     0,     2,     3,     1,     3,     0,
-       2,     2,     2,     3,     3,     2,     1,     3,     0,     2,
-       2,     2,     3,     3,     2,     2,     2,     0,     2,     2,
-       2,     4,     0,     2,     1,     1,     2,     2,     2,     1,
-       2,     0,     2,     1,     3,     3,     3,     2,     3,     3,
-       1,     1,     0,     1
+       1,     1,     1,     1,     1,     1,     1,     1,     3,     2,
+       3,     2,     3,     2,     0,     2,     2,     2,     2,     2,
+       2,     3,     4,     4,     4,     5,     3,     0,     3,     0,
+       2,     3,     2,     1,     3,     0,     2,     2,     2,     2,
+       2,     4,     3,     2,     4,     0,     2,     3,     1,     3,
+       0,     2,     2,     2,     3,     3,     3,     1,     3,     0,
+       2,     2,     2,     3,     3,     2,     2,     2,     0,     2,
+       2,     2,     4,     0,     2,     2,     2,     0,     2,     1,
+       1,     2,     2,     2,     1,     2,     0,     2,     1,     3,
+       3,     3,     2,     3,     3,     1,     1,     0,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -623,165 +626,172 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       6,     0,    99,     0,     3,     0,     6,     6,    94,    95,
-       0,     1,     0,     0,     0,     0,   112,     0,     0,     0,
+       6,     0,   104,     0,     3,     0,     6,     6,    99,   100,
+       0,     1,     0,     0,     0,     0,   117,     0,     0,     0,
        0,     0,     0,    14,    18,    15,    16,    20,    17,    19,
-       0,    21,     0,     7,    33,    24,    33,    25,    54,    64,
-       8,    69,    22,    87,    78,     9,    26,    87,    23,    10,
-       0,   100,     2,    73,    13,     0,    96,     0,   113,     0,
-      97,     0,     0,     0,   110,   111,     0,     0,     0,   103,
-      98,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    74,    82,    50,    83,    29,    31,     0,   107,     0,
-       0,    66,     0,     0,    11,    12,     0,     0,     0,     0,
-      92,     0,     0,     0,    46,     0,    39,    38,    34,    35,
-       0,    37,    36,     0,     0,    92,     0,    58,    59,    55,
-      57,    56,    65,    53,    52,    70,    72,    68,    71,    67,
-      89,    90,    88,    79,    81,    77,    80,    76,   106,   108,
-     109,   105,   104,    28,    85,     0,   101,     0,   101,   101,
-     101,     0,     0,     0,    86,    62,   101,     0,   101,     0,
-       0,     0,    40,    93,     0,     0,   101,    48,    45,    27,
-       0,    61,     0,    91,   102,    41,    42,    43,     0,     0,
-      47,    60,    63,    44,    49
+      21,     0,    22,     0,     7,    34,    25,    34,    26,    55,
+      65,     8,    70,    23,    93,    79,     9,    27,    88,    24,
+      10,     0,   105,     2,    74,    13,     0,   101,     0,   118,
+       0,   102,     0,     0,     0,   115,   116,     0,     0,     0,
+     108,   103,     0,     0,     0,     0,     0,     0,     0,    88,
+       0,     0,    75,    83,    51,    84,    30,    32,     0,   112,
+       0,     0,    67,     0,     0,    11,    12,     0,     0,     0,
+       0,    97,     0,     0,     0,    47,     0,    40,    39,    35,
+      36,     0,    38,    37,     0,     0,    97,     0,    59,    60,
+      56,    58,    57,    66,    54,    53,    71,    73,    69,    72,
+      68,   106,    95,     0,    94,    80,    82,    78,    81,    77,
+      90,    91,    89,   111,   113,   114,   110,   109,    29,    86,
+       0,   106,     0,   106,   106,   106,     0,     0,     0,    87,
+      63,   106,     0,   106,     0,    96,     0,     0,    41,    98,
+       0,     0,   106,    49,    46,    28,     0,    62,     0,   107,
+      92,    42,    43,    44,     0,     0,    48,    61,    64,    45,
+      50
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     3,     4,     5,    32,    33,   107,    34,    35,    36,
-      37,    73,   108,   109,   152,   180,    38,    39,   123,    40,
-      75,   119,    76,    41,   127,    42,    77,     6,    43,    44,
-     135,    45,    79,    46,    47,    48,   110,   111,    78,   112,
-     147,   148,    49,     7,   161,    68,    69,    59
+      -1,     3,     4,     5,    33,    34,   108,    35,    36,    37,
+      38,    74,   109,   110,   157,   186,    39,    40,   124,    41,
+      76,   120,    77,    42,   128,    43,    78,     6,    44,    45,
+     137,    46,    80,    47,    48,    49,   111,   112,    81,   113,
+      79,   134,   152,   153,    50,     7,   165,    69,    70,    60
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -89
+#define YYPACT_NINF -90
 static const yytype_int16 yypact[] =
 {
-       3,     4,   -89,    20,   -89,   100,   -89,     7,   -89,   -89,
-      -8,   -89,    17,     4,    28,     4,    37,    36,     4,    68,
-      87,   -18,    69,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     128,   -89,   138,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     127,   -89,   -89,   110,   -89,   126,   -89,   136,   -89,   137,
-     -89,   147,   150,   152,   -89,   -89,   -18,   -18,   171,   -14,
-     -89,   153,   157,    34,    67,   180,   233,   220,   207,   220,
-     154,   -89,   -89,   -89,   -89,   -89,   -89,     0,   -89,   -18,
-     -18,   110,    44,    44,   -89,   -89,   163,   174,   182,     4,
-       4,   -18,   194,    44,   -89,   219,   -89,   -89,   -89,   -89,
-     223,   -89,   -89,   203,     4,     4,   215,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   213,
-     -89,   -89,   -89,   -89,   -89,   -18,   232,   227,   232,    -5,
-     232,    44,    35,   234,   -89,   -89,   232,   235,   232,   224,
-     -18,   236,   -89,   -89,   237,   238,   232,   216,   -89,   -89,
-     240,   -89,   241,   -89,    71,   -89,   -89,   -89,   242,     4,
-     -89,   -89,   -89,   -89,   -89
+       4,    42,   -90,    96,   -90,   111,   -90,    15,   -90,   -90,
+      75,   -90,    82,    42,   104,    42,   110,   107,    42,   115,
+     125,    -4,   121,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   162,   -90,   163,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   139,   -90,   -90,   138,   -90,   142,   -90,   143,   -90,
+     152,   -90,   164,   167,   168,   -90,   -90,    -4,    -4,    77,
+     -18,   -90,   177,   185,    33,    71,   195,   247,   236,    -2,
+     236,   171,   -90,   -90,   -90,   -90,   -90,   -90,    41,   -90,
+      -4,    -4,   138,    97,    97,   -90,   -90,   186,   187,   194,
+      42,    42,    -4,   196,    97,   -90,   219,   -90,   -90,   -90,
+     -90,   210,   -90,   -90,   204,    42,    42,   199,   -90,   -90,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   222,   -90,   223,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -90,   -90,   -90,   215,   -90,   -90,   -90,   -90,   -90,
+      -4,   222,   228,   222,    -5,   222,    97,    35,   229,   -90,
+     -90,   222,   232,   222,    -4,   -90,   135,   233,   -90,   -90,
+     234,   235,   222,   240,   -90,   -90,   237,   -90,   239,   -13,
+     -90,   -90,   -90,   -90,   244,    42,   -90,   -90,   -90,   -90,
+     -90
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -89,   -89,   255,   267,   -89,    47,   -57,   -89,   -89,   -89,
-     -89,   239,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   130,
-     -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,   -89,
-     -89,   181,   -89,   -89,   -89,   -89,   -89,   199,   229,    16,
-     162,    -1,    74,    -7,   103,   -65,   -88,   -89
+     -90,   -90,   269,   271,   -90,    23,   -70,   -90,   -90,   -90,
+     -90,   243,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -48,
+     -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,   -90,
+     -90,   -20,   -90,   -90,   -90,   -90,   -90,   206,   205,   -68,
+     -90,   -90,   169,    -1,    27,    -7,   118,   -66,   -89,   -90
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -85
+#define YYTABLE_NINF -86
 static const yytype_int16 yytable[] =
 {
-      10,    87,    88,    53,   141,   142,     1,    64,    65,   160,
-       1,    66,    55,    92,    57,   151,    67,    61,   118,    93,
-      11,   131,     2,   131,   139,   140,    89,    90,   138,     8,
-       9,    89,    90,     2,   -30,    96,   149,    51,   -30,   -30,
-     -30,   -30,   -30,   -30,   -30,   -30,    97,    54,   -30,   -30,
-      98,   -30,    99,   100,   101,   102,   103,   104,    56,   105,
-     167,    91,    58,   166,   106,   168,    60,   -32,    96,    64,
-      65,   -32,   -32,   -32,   -32,   -32,   -32,   -32,   -32,    97,
-     159,   -32,   -32,    98,   -32,    99,   100,   101,   102,   103,
-     104,   121,   105,    62,   132,   174,   132,   106,   146,    70,
-      -5,    12,    89,    90,    13,    14,    15,    16,    17,    18,
-      19,    20,    63,   156,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,   122,   125,    30,   133,    -4,    12,    71,
-      31,    13,    14,    15,    16,    17,    18,    19,    20,    72,
-      51,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-     124,   129,    30,   137,   -84,    96,    81,    31,   -84,   -84,
-     -84,   -84,   -84,   -84,   -84,   -84,    82,    83,   -84,   -84,
-      98,   -84,   -84,   -84,   -84,   -84,   -84,    84,   184,   105,
-      85,    96,    86,    94,   130,   -51,   -51,    95,   -51,   -51,
-     -51,   -51,    97,   143,   -51,   -51,    98,   113,   114,   115,
-     116,     2,    89,    90,   144,   105,   145,   126,    96,   134,
-     117,   -75,   -75,   -75,   -75,   -75,   -75,   -75,   -75,   150,
-     153,   -75,   -75,    98,    13,    14,    15,    16,    17,    18,
-      19,    20,   105,   155,    21,    22,   154,   130,    14,    15,
-     158,    17,    18,    19,    20,    90,   160,    21,    22,   179,
-      31,   163,   164,   165,   173,    89,    90,   162,   128,   170,
-     136,   172,    52,    31,   169,   171,   175,   176,   177,   178,
-     181,   182,   183,    50,   120,    74,    80,   157
+      10,    88,    89,    54,   146,   147,   119,     1,   122,   164,
+      93,   141,    56,   142,    58,   156,    94,    62,     1,    90,
+      91,   131,    65,    66,   144,   145,    67,    90,    91,   132,
+     127,    68,   136,   -31,    97,     2,   154,   -31,   -31,   -31,
+     -31,   -31,   -31,   -31,   -31,    98,    52,   -31,   -31,    99,
+     -31,   100,   101,   102,   103,   104,   -31,   105,   129,   106,
+     138,   173,    92,   141,   107,   142,   174,   172,     8,     9,
+     143,   -33,    97,    90,    91,   -33,   -33,   -33,   -33,   -33,
+     -33,   -33,   -33,    98,   166,   -33,   -33,    99,   -33,   100,
+     101,   102,   103,   104,   -33,   105,    11,   106,   179,   151,
+     123,   126,   107,   135,   125,   130,     2,   139,     2,    90,
+      91,    -5,    12,    55,   161,    13,    14,    15,    16,    17,
+      18,    19,    20,    65,    66,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    57,    59,    31,    61,    -4,
+      12,    63,    32,    13,    14,    15,    16,    17,    18,    19,
+      20,    64,    71,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    72,    73,    31,   180,    90,    91,    52,
+      32,   -85,    97,    82,    83,   -85,   -85,   -85,   -85,   -85,
+     -85,   -85,   -85,    84,   190,   -85,   -85,    99,   -85,   -85,
+     -85,   -85,   -85,   -85,   -85,    85,    97,   106,    86,    87,
+     -52,   -52,   140,   -52,   -52,   -52,   -52,    98,    95,   -52,
+     -52,    99,   114,   115,   116,   117,    96,   148,   149,   150,
+     158,   106,   155,   159,    97,   163,   118,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   160,   164,   -76,   -76,    99,
+      13,    14,    15,    16,    17,    18,    19,    20,    91,   106,
+      21,    22,    14,    15,   140,    17,    18,    19,    20,   168,
+     175,    21,    22,   177,   181,   182,   183,    32,   187,   167,
+     188,   169,   170,   171,   185,   189,    53,    51,    32,   176,
+      75,   178,   121,     0,   133,   162,     0,     0,     0,     0,
+     184
 };
 
-static const yytype_uint8 yycheck[] =
+static const yytype_int16 yycheck[] =
 {
-       1,    66,    67,    10,    92,    93,     3,    25,    26,    14,
-       3,    29,    13,    27,    15,   103,    34,    18,    75,    33,
-       0,    78,    30,    80,    89,    90,    31,    32,    28,    25,
-      26,    31,    32,    30,     0,     1,   101,    30,     4,     5,
-       6,     7,     8,     9,    10,    11,    12,    30,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    30,    25,
-      25,    68,    25,   151,    30,    30,    30,     0,     1,    25,
-      26,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-     145,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    75,    25,    25,    78,   160,    80,    30,    99,    30,
-       0,     1,    31,    32,     4,     5,     6,     7,     8,     9,
-      10,    11,    25,   114,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    76,    77,    25,    79,     0,     1,     1,
-      30,     4,     5,     6,     7,     8,     9,    10,    11,     1,
-      30,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      76,    77,    25,    79,     0,     1,    30,    30,     4,     5,
-       6,     7,     8,     9,    10,    11,    30,    30,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    30,   179,    25,
-      30,     1,    30,    30,    30,     5,     6,    30,     8,     9,
-      10,    11,    12,    30,    14,    15,    16,    17,    18,    19,
-      20,    30,    31,    32,    30,    25,    24,    77,     1,    79,
-      30,     4,     5,     6,     7,     8,     9,    10,    11,    25,
-       1,    14,    15,    16,     4,     5,     6,     7,     8,     9,
-      10,    11,    25,    30,    14,    15,    13,    30,     5,     6,
-      25,     8,     9,    10,    11,    32,    14,    14,    15,    33,
-      30,   148,   149,   150,    30,    31,    32,    30,    77,   156,
-      79,   158,     7,    30,    30,    30,    30,    30,    30,   166,
-      30,    30,    30,     6,    75,    36,    47,   115
+       1,    67,    68,    10,    93,    94,    76,     3,    76,    14,
+      28,    81,    13,    81,    15,   104,    34,    18,     3,    32,
+      33,    23,    26,    27,    90,    91,    30,    32,    33,    31,
+      78,    35,    80,     0,     1,    31,   102,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    31,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    78,    26,
+      80,    26,    69,   133,    31,   133,    31,   156,    26,    27,
+      29,     0,     1,    32,    33,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,   150,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,     0,    26,   164,   100,
+      77,    78,    31,    80,    77,    78,    31,    80,    31,    32,
+      33,     0,     1,    31,   115,     4,     5,     6,     7,     8,
+       9,    10,    11,    26,    27,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    31,    26,    26,    31,     0,
+       1,    26,    31,     4,     5,     6,     7,     8,     9,    10,
+      11,    26,    31,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,     1,     1,    26,    31,    32,    33,    31,
+      31,     0,     1,    31,    31,     4,     5,     6,     7,     8,
+       9,    10,    11,    31,   185,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    31,     1,    26,    31,    31,
+       5,     6,    31,     8,     9,    10,    11,    12,    31,    14,
+      15,    16,    17,    18,    19,    20,    31,    31,    31,    25,
+       1,    26,    26,    13,     1,    26,    31,     4,     5,     6,
+       7,     8,     9,    10,    11,    31,    14,    14,    15,    16,
+       4,     5,     6,     7,     8,     9,    10,    11,    33,    26,
+      14,    15,     5,     6,    31,     8,     9,    10,    11,    31,
+      31,    14,    15,    31,    31,    31,    31,    31,    31,   151,
+      31,   153,   154,   155,    34,    31,     7,     6,    31,   161,
+      37,   163,    76,    -1,    79,   116,    -1,    -1,    -1,    -1,
+     172
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,    30,    36,    37,    38,    62,    78,    25,    26,
-      76,     0,     1,     4,     5,     6,     7,     8,     9,    10,
+       0,     3,    31,    37,    38,    39,    63,    81,    26,    27,
+      79,     0,     1,     4,     5,     6,     7,     8,     9,    10,
       11,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      25,    30,    39,    40,    42,    43,    44,    45,    51,    52,
-      54,    58,    60,    63,    64,    66,    68,    69,    70,    77,
-      38,    30,    37,    78,    30,    76,    30,    76,    25,    82,
-      30,    76,    25,    25,    25,    26,    29,    34,    80,    81,
-      30,     1,     1,    46,    46,    55,    57,    61,    73,    67,
-      73,    30,    30,    30,    30,    30,    30,    80,    80,    31,
-      32,    78,    27,    33,    30,    30,     1,    12,    16,    18,
-      19,    20,    21,    22,    23,    25,    30,    41,    47,    48,
-      71,    72,    74,    17,    18,    19,    20,    30,    41,    56,
-      72,    74,    40,    53,    77,    40,    54,    59,    66,    77,
-      30,    41,    74,    40,    54,    65,    66,    77,    28,    80,
-      80,    81,    81,    30,    30,    24,    76,    75,    76,    80,
-      25,    81,    49,     1,    13,    30,    76,    75,    25,    80,
-      14,    79,    30,    79,    79,    79,    81,    25,    30,    30,
-      79,    30,    79,    30,    80,    30,    30,    30,    79,    33,
-      50,    30,    30,    30,    76
+      23,    26,    31,    40,    41,    43,    44,    45,    46,    52,
+      53,    55,    59,    61,    64,    65,    67,    69,    70,    71,
+      80,    39,    31,    38,    81,    31,    79,    31,    79,    26,
+      85,    31,    79,    26,    26,    26,    27,    30,    35,    83,
+      84,    31,     1,     1,    47,    47,    56,    58,    62,    76,
+      68,    74,    31,    31,    31,    31,    31,    31,    83,    83,
+      32,    33,    81,    28,    34,    31,    31,     1,    12,    16,
+      18,    19,    20,    21,    22,    24,    26,    31,    42,    48,
+      49,    72,    73,    75,    17,    18,    19,    20,    31,    42,
+      57,    73,    75,    41,    54,    80,    41,    55,    60,    67,
+      80,    23,    31,    74,    77,    41,    55,    66,    67,    80,
+      31,    42,    75,    29,    83,    83,    84,    84,    31,    31,
+      25,    79,    78,    79,    83,    26,    84,    50,     1,    13,
+      31,    79,    78,    26,    14,    82,    83,    82,    31,    82,
+      82,    82,    84,    26,    31,    31,    82,    31,    82,    83,
+      31,    31,    31,    31,    82,    34,    51,    31,    31,    31,
+      79
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1292,7 +1302,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 
   switch (yytype)
     {
-      case 52: /* "choice_entry" */
+      case 53: /* "choice_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1302,7 +1312,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 };
 
        break;
-      case 58: /* "if_entry" */
+      case 59: /* "if_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1312,7 +1322,7 @@ yydestruct (yymsg, yytype, yyvaluep)
 };
 
        break;
-      case 64: /* "menu_entry" */
+      case 65: /* "menu_entry" */
 
        {
        fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -1644,17 +1654,17 @@ yyreduce:
     { zconf_error("invalid statement"); ;}
     break;
 
-  case 27:
+  case 28:
 
     { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
     break;
 
-  case 28:
+  case 29:
 
     { zconf_error("invalid option"); ;}
     break;
 
-  case 29:
+  case 30:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1664,7 +1674,7 @@ yyreduce:
 ;}
     break;
 
-  case 30:
+  case 31:
 
     {
        menu_end_entry();
@@ -1672,7 +1682,7 @@ yyreduce:
 ;}
     break;
 
-  case 31:
+  case 32:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
@@ -1682,7 +1692,7 @@ yyreduce:
 ;}
     break;
 
-  case 32:
+  case 33:
 
     {
        if (current_entry->prompt)
@@ -1694,7 +1704,7 @@ yyreduce:
 ;}
     break;
 
-  case 40:
+  case 41:
 
     {
        menu_set_type((yyvsp[(1) - (3)].id)->stype);
@@ -1704,7 +1714,7 @@ yyreduce:
 ;}
     break;
 
-  case 41:
+  case 42:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1712,7 +1722,7 @@ yyreduce:
 ;}
     break;
 
-  case 42:
+  case 43:
 
     {
        menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
@@ -1724,7 +1734,7 @@ yyreduce:
 ;}
     break;
 
-  case 43:
+  case 44:
 
     {
        menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
@@ -1732,7 +1742,7 @@ yyreduce:
 ;}
     break;
 
-  case 44:
+  case 45:
 
     {
        menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
@@ -1740,7 +1750,7 @@ yyreduce:
 ;}
     break;
 
-  case 47:
+  case 48:
 
     {
        struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
@@ -1752,17 +1762,17 @@ yyreduce:
 ;}
     break;
 
-  case 48:
+  case 49:
 
     { (yyval.string) = NULL; ;}
     break;
 
-  case 49:
+  case 50:
 
     { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
     break;
 
-  case 50:
+  case 51:
 
     {
        struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), SYMBOL_CHOICE);
@@ -1773,14 +1783,14 @@ yyreduce:
 ;}
     break;
 
-  case 51:
+  case 52:
 
     {
        (yyval.menu) = menu_add_menu();
 ;}
     break;
 
-  case 52:
+  case 53:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
@@ -1790,7 +1800,7 @@ yyreduce:
 ;}
     break;
 
-  case 60:
+  case 61:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
@@ -1798,7 +1808,7 @@ yyreduce:
 ;}
     break;
 
-  case 61:
+  case 62:
 
     {
        if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
@@ -1811,7 +1821,7 @@ yyreduce:
 ;}
     break;
 
-  case 62:
+  case 63:
 
     {
        current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1819,7 +1829,7 @@ yyreduce:
 ;}
     break;
 
-  case 63:
+  case 64:
 
     {
        if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
@@ -1831,7 +1841,7 @@ yyreduce:
 ;}
     break;
 
-  case 66:
+  case 67:
 
     {
        printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
@@ -1841,7 +1851,7 @@ yyreduce:
 ;}
     break;
 
-  case 67:
+  case 68:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
@@ -1851,14 +1861,14 @@ yyreduce:
 ;}
     break;
 
-  case 73:
+  case 74:
 
     {
        menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
 ;}
     break;
 
-  case 74:
+  case 75:
 
     {
        menu_add_entry(NULL);
@@ -1867,14 +1877,14 @@ yyreduce:
 ;}
     break;
 
-  case 75:
+  case 76:
 
     {
        (yyval.menu) = menu_add_menu();
 ;}
     break;
 
-  case 76:
+  case 77:
 
     {
        if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
@@ -1884,7 +1894,7 @@ yyreduce:
 ;}
     break;
 
-  case 82:
+  case 83:
 
     {
        printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
@@ -1892,7 +1902,7 @@ yyreduce:
 ;}
     break;
 
-  case 83:
+  case 84:
 
     {
        menu_add_entry(NULL);
@@ -1901,14 +1911,14 @@ yyreduce:
 ;}
     break;
 
-  case 84:
+  case 85:
 
     {
        menu_end_entry();
 ;}
     break;
 
-  case 85:
+  case 86:
 
     {
        printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1916,14 +1926,14 @@ yyreduce:
 ;}
     break;
 
-  case 86:
+  case 87:
 
     {
        current_entry->help = (yyvsp[(2) - (2)].string);
 ;}
     break;
 
-  case 91:
+  case 92:
 
     {
        menu_add_dep((yyvsp[(3) - (4)].expr));
@@ -1931,84 +1941,91 @@ yyreduce:
 ;}
     break;
 
-  case 93:
+  case 96:
+
+    {
+       menu_add_visibility((yyvsp[(2) - (2)].expr));
+;}
+    break;
+
+  case 98:
 
     {
        menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
 ;}
     break;
 
-  case 96:
+  case 101:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 97:
+  case 102:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 98:
+  case 103:
 
     { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
     break;
 
-  case 101:
+  case 106:
 
     { (yyval.expr) = NULL; ;}
     break;
 
-  case 102:
+  case 107:
 
     { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
     break;
 
-  case 103:
+  case 108:
 
     { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
     break;
 
-  case 104:
+  case 109:
 
     { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
     break;
 
-  case 105:
+  case 110:
 
     { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
     break;
 
-  case 106:
+  case 111:
 
     { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
     break;
 
-  case 107:
+  case 112:
 
     { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
     break;
 
-  case 108:
+  case 113:
 
     { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
     break;
 
-  case 109:
+  case 114:
 
     { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
     break;
 
-  case 110:
+  case 115:
 
     { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
     break;
 
-  case 111:
+  case 116:
 
     { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), SYMBOL_CONST); free((yyvsp[(1) - (1)].string)); ;}
     break;
 
-  case 112:
+  case 117:
 
     { (yyval.string) = NULL; ;}
     break;
@@ -2278,6 +2295,7 @@ static const char *zconf_tokenname(int token)
        case T_IF:              return "if";
        case T_ENDIF:           return "endif";
        case T_DEPENDS:         return "depends";
+       case T_VISIBLE:         return "visible";
        }
        return "<token>";
 }
index 2abd3c7ff15d91d25679a4cec6f1ff21da38fb23..49fb4ab664c39b555692896f97fc8d6bfad36cd1 100644 (file)
@@ -36,7 +36,7 @@ static struct menu *current_menu, *current_entry;
 #define YYERROR_VERBOSE
 #endif
 %}
-%expect 28
+%expect 30
 
 %union
 {
@@ -68,6 +68,7 @@ static struct menu *current_menu, *current_entry;
 %token <id>T_DEFAULT
 %token <id>T_SELECT
 %token <id>T_RANGE
+%token <id>T_VISIBLE
 %token <id>T_OPTION
 %token <id>T_ON
 %token <string> T_WORD
@@ -123,7 +124,7 @@ stmt_list:
 ;
 
 option_name:
-       T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
+       T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT | T_VISIBLE
 ;
 
 common_stmt:
@@ -359,7 +360,7 @@ menu: T_MENU prompt T_EOL
        printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
 };
 
-menu_entry: menu depends_list
+menu_entry: menu visibility_list depends_list
 {
        $$ = menu_add_menu();
 };
@@ -430,6 +431,19 @@ depends: T_DEPENDS T_ON expr T_EOL
        printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
 };
 
+/* visibility option */
+
+visibility_list:
+         /* empty */
+       | visibility_list visible
+       | visibility_list T_EOL
+;
+
+visible: T_VISIBLE if_expr
+{
+       menu_add_visibility($2);
+};
+
 /* prompt statement */
 
 prompt_stmt_opt:
@@ -526,6 +540,7 @@ static const char *zconf_tokenname(int token)
        case T_IF:              return "if";
        case T_ENDIF:           return "endif";
        case T_DEPENDS:         return "depends";
+       case T_VISIBLE:         return "visible";
        }
        return "<token>";
 }
index cdb6dc1f6458ba4634c0f8584ae3da615ce10696..39580a5dc5df6083a5766ae8853c6610e417474f 100755 (executable)
@@ -5,7 +5,7 @@ use strict;
 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
 ## Copyright (C) 2001  Simon Huggins                             ##
-## Copyright (C) 2005-2009  Randy Dunlap                         ##
+## Copyright (C) 2005-2010  Randy Dunlap                         ##
 ##                                                              ##
 ## #define enhancements by Armin Kuster <akuster@mvista.com>    ##
 ## Copyright (c) 2000 MontaVista Software, Inc.                         ##
@@ -453,7 +453,7 @@ sub output_highlight {
     if ($output_mode eq "html" || $output_mode eq "xml") {
        $contents = local_unescape($contents);
        # convert data read & converted thru xml_escape() into &xyz; format:
-       $contents =~ s/\\\\\\/&/g;
+       $contents =~ s/\\\\\\/\&/g;
     }
 #   print STDERR "contents b4:$contents\n";
     eval $dohighlight;
@@ -770,7 +770,11 @@ sub output_struct_xml(%) {
     print $args{'type'} . " " . $args{'struct'} . " {\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
        if ($parameter =~ /^#/) {
-           print "$parameter\n";
+           my $prm = $parameter;
+           # convert data read & converted thru xml_escape() into &xyz; format:
+           # This allows us to have #define macros interspersed in a struct.
+           $prm =~ s/\\\\\\/\&/g;
+           print "$prm\n";
            next;
        }
 
@@ -1701,6 +1705,8 @@ sub push_parameter($$$) {
        }
        }
 
+       $param = xml_escape($param);
+
        # strip spaces from $param so that it is one continous string
        # on @parameterlist;
        # this fixes a problem where check_sections() cannot find
index f2f41c8542211143cc56e83328092d1bcb27a2bf..6e24091818950edc9c298241be2d28a751b39f83 100644 (file)
@@ -420,9 +420,9 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
                return PTR_ERR(pclk);
        }
        sample_clk = clk_get(&pdev->dev, "sample_clk");
-       if (IS_ERR(pclk)) {
+       if (IS_ERR(sample_clk)) {
                dev_dbg(&pdev->dev, "no sample clock\n");
-               retval = PTR_ERR(pclk);
+               retval = PTR_ERR(sample_clk);
                goto out_put_pclk;
        }
        clk_enable(pclk);
index b70564ed8b37821aa0f336d3585acf58da5854e3..7077f601da5a66a279bed9be77159f2ec80dfc78 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
index 5c8c7dff8ede8a3989301ce083319e75cbffe808..b753ec661fcfd149d079f530e05729d8d0cc524b 100644 (file)
@@ -1510,16 +1510,19 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
 static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
 {
        struct snd_pcm_substream *substream;
+       struct snd_pcm_runtime *runtime;
+       int i;
 
-       substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
-       if (substream != NULL) {
-               snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
-               substream->runtime->oss.prepare = 1;
-       }
-       substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
-       if (substream != NULL) {
+       for (i = 0; i < 2; i++) { 
+               substream = pcm_oss_file->streams[i];
+               if (!substream)
+                       continue;
+               runtime = substream->runtime;
                snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
-               substream->runtime->oss.prepare = 1;
+               runtime->oss.prepare = 1;
+               runtime->oss.buffer_used = 0;
+               runtime->oss.prev_hw_ptr_period = 0;
+               runtime->oss.period_ptr = 0;
        }
        return 0;
 }
index a1707cca9c6635c8b4cd7e79b5cebe21bffc2d9e..b75db8e9cc0f36fff03d0ecf1884b23b3bad724b 100644 (file)
@@ -223,7 +223,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
        entry->jiffies = jiffies;
        entry->pos = pos;
        entry->period_size = runtime->period_size;
-       entry->buffer_size = runtime->buffer_size;;
+       entry->buffer_size = runtime->buffer_size;
        entry->old_hw_ptr = runtime->status->hw_ptr;
        entry->hw_ptr_base = runtime->hw_ptr_base;
        log->idx = (log->idx + 1) % XRUN_LOG_CNT;
index 8bc7cb3db33056abce9a03cec36a4266305aa12c..e82c1f97d99e9736b20523f7bf6eca63498f2587 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/pm_qos_params.h>
 #include <linux/uio.h>
index 62a093efb453cc5d9657e4a3ce822ce42ca07748..66691fe437e63315fad4a1af8c073e9fbba058e5 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
index 727bdb9ba2dc1bc9b0cc62fd8abde19403ca292d..d8cf3e58dc76aa1017ef5b9424e862e95498ee6d 100644 (file)
@@ -71,7 +71,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
        if (sound_nblocks >= MAX_MEM_BLOCKS)
                sound_nblocks = MAX_MEM_BLOCKS - 1;
 
-       op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations)));
+       op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations)));
        sound_nblocks++;
        if (sound_nblocks >= MAX_MEM_BLOCKS)
                sound_nblocks = MAX_MEM_BLOCKS - 1;
@@ -81,7 +81,6 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
                sound_unload_audiodev(num);
                return -(ENOMEM);
        }
-       memset((char *) op, 0, sizeof(struct audio_operations));
        init_waitqueue_head(&op->in_sleeper);
        init_waitqueue_head(&op->out_sleeper);  
        init_waitqueue_head(&op->poll_sleeper);
@@ -128,7 +127,7 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
        /* FIXME: This leaks a mixer_operations struct every time its called
           until you unload sound! */
           
-       op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations)));
+       op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct mixer_operations)));
        sound_nblocks++;
        if (sound_nblocks >= MAX_MEM_BLOCKS)
                sound_nblocks = MAX_MEM_BLOCKS - 1;
@@ -137,7 +136,6 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
                printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
                return -ENOMEM;
        }
-       memset((char *) op, 0, sizeof(struct mixer_operations));
        memcpy((char *) op, (char *) driver, driver_size);
 
        strlcpy(op->name, name, sizeof(op->name));
index 782b3b84dac68ccd036c52ee3533336f243ac15b..ceedb1eff203812e85049f7cdb46b92a588fc557 100644 (file)
@@ -178,7 +178,7 @@ int MIDIbuf_open(int dev, struct file *file)
                return err;
 
        parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
-       midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
+       midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf));
 
        if (midi_in_buf[dev] == NULL)
        {
@@ -188,7 +188,7 @@ int MIDIbuf_open(int dev, struct file *file)
        }
        midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
 
-       midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
+       midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf));
 
        if (midi_out_buf[dev] == NULL)
        {
index e19dd5dcc2debd9e3b4a7fa9ec481849f8442a30..9b800ce5100ef286864234b308fb646c7d5dc9a1 100644 (file)
@@ -859,7 +859,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
                        return 0;
 
                case SNDCTL_COPR_LOAD:
-                       buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+                       buf = vmalloc(sizeof(copr_buffer));
                        if (buf == NULL)
                                return -ENOSPC;
                        if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
@@ -871,7 +871,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
                        return err;
                
                case SNDCTL_COPR_SENDMSG:
-                       mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+                       mbuf = vmalloc(sizeof(copr_msg));
                        if (mbuf == NULL)
                                return -ENOSPC;
                        if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
@@ -895,7 +895,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
 
                case SNDCTL_COPR_RCVMSG:
                        err = 0;
-                       mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+                       mbuf = vmalloc(sizeof(copr_msg));
                        if (mbuf == NULL)
                                return -ENOSPC;
                        data = (unsigned short *)mbuf->data;
index e85789e53816640f8e7e7224fdd0199787e5f4de..5ea1098ac427a5546bdf9f211587bbe8030d1821 100644 (file)
@@ -1646,13 +1646,13 @@ void sequencer_init(void)
 {
        if (sequencer_ok)
                return;
-       queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
+       queue = vmalloc(SEQ_MAX_QUEUE * EV_SZ);
        if (queue == NULL)
        {
                printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
                return;
        }
-       iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
+       iqueue = vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
        if (iqueue == NULL)
        {
                printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n");
index 62895a719fcbcce841b05f44fce0a90813d70477..22dbd91811a4e61398a9b9077c5cbe26c0139119 100644 (file)
@@ -435,7 +435,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
        struct hpi_message hm;
        struct hpi_response hr;
        struct hpi_adapter *pa;
-       pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev);
+       pa = pci_get_drvdata(pci_dev);
 
        hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
                HPI_SUBSYS_DELETE_ADAPTER);
index 4679ed83a43b8687402b7efca98ed47a0518ac98..2f3cacbd5528da80cccca5791147d6f516dcdf82 100644 (file)
@@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
 
                count_areas = size/2;
                addr_area2 = addr+count_areas;
-               count_areas--; /* max. index */
                snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
                                addr, count_areas, addr_area2, count_areas);
 
+               count_areas--; /* max. index */
+
                /* build combined I/O buffer length word */
                lengths = (count_areas << 16) | (count_areas);
                spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware =
        .rate_max =             AZF_FREQ_66200,
        .channels_min =         1,
        .channels_max =         2,
-       .buffer_bytes_max =     65536,
-       .period_bytes_min =     64,
-       .period_bytes_max =     65536,
-       .periods_min =          1,
-       .periods_max =          1024,
+       .buffer_bytes_max =     (64*1024),
+       .period_bytes_min =     1024,
+       .period_bytes_max =     (32*1024),
+       /* We simply have two DMA areas (instead of a list of descriptors
+          such as other cards); I believe that this is a fixed hardware
+          attribute and there isn't much driver magic to be done to expand it.
+          Thus indicate that we have at least and at most 2 periods. */
+       .periods_min =          2,
+       .periods_max =          2,
        /* FIXME: maybe that card actually has a FIFO?
         * Hmm, it seems newer revisions do have one, but we still don't know
         * its size... */
@@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
        chip = snd_timer_chip(timer);
        spin_lock_irqsave(&chip->reg_lock, flags);
        /* disable timer countdown and interrupt */
-       /* FIXME: should we write TIMER_IRQ_ACK here? */
-       snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
+       /* Hmm, should we write TIMER_IRQ_ACK here?
+          YES indeed, otherwise a rogue timer operation - which prompts
+          ALSA(?) to call repeated stop() in vain, but NOT start() -
+          will never end (value 0x03 is kept shown in control byte).
+          Simply manually poking 0x04 _once_ immediately successfully stops
+          the hardware/ALSA interrupt activity. */
+       snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
        spin_unlock_irqrestore(&chip->reg_lock, flags);
        snd_azf3328_dbgcallleave();
        return 0;
index 85ab43e89212c6724c1e70f3cad3de33e9816935..457d21189b0db1fc5b2fcd2af22e30d20089dcb1 100644 (file)
@@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
 
        apcm->substream = substream;
        apcm->interrupt = ct_atc_pcm_interrupt;
-       runtime->private_data = apcm;
-       runtime->private_free = ct_atc_pcm_free_substream;
        if (IEC958 == substream->pcm->device) {
                runtime->hw = ct_spdif_passthru_playback_hw;
                atc->spdif_out_passthru(atc, 1);
@@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
        }
 
        apcm->timer = ct_timer_instance_new(atc->timer, apcm);
-       if (!apcm->timer)
+       if (!apcm->timer) {
+               kfree(apcm);
                return -ENOMEM;
+       }
+       runtime->private_data = apcm;
+       runtime->private_free = ct_atc_pcm_free_substream;
 
        return 0;
 }
@@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
        apcm->started = 0;
        apcm->substream = substream;
        apcm->interrupt = ct_atc_pcm_interrupt;
-       runtime->private_data = apcm;
-       runtime->private_free = ct_atc_pcm_free_substream;
        runtime->hw = ct_pcm_capture_hw;
        runtime->hw.rate_max = atc->rsr * atc->msr;
 
@@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
        }
 
        apcm->timer = ct_timer_instance_new(atc->timer, apcm);
-       if (!apcm->timer)
+       if (!apcm->timer) {
+               kfree(apcm);
                return -ENOMEM;
+       }
+       runtime->private_data = apcm;
+       runtime->private_free = ct_atc_pcm_free_substream;
 
        return 0;
 }
index 6361f752b5f35cfddff7f8423f0d5d185a9003d8..846d1ead47fdf1c184fb92f37ae1faf099ec45af 100644 (file)
@@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
+       SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP),
        SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
@@ -3110,6 +3111,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
index 5f00589cb791aebed2d7aa1f0bd908819b9123b8..8fddc9d08726670c8d67dc1ce9f31dd1f82a56c4 100644 (file)
@@ -1614,6 +1614,7 @@ do_sku:
                spec->init_amp = ALC_INIT_GPIO3;
                break;
        case 5:
+       default:
                spec->init_amp = ALC_INIT_DEFAULT;
                break;
        }
@@ -2013,6 +2014,36 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
        { }
 };
 
+/*
+ *ALC888 Acer Aspire 7730G model
+ */
+
+static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
+/* Bias voltage on for external mic port */
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
+/* Front Mic: set to PIN_IN (empty by default) */
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+/* Unselect Front Mic by default in input mixer 3 */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
+/* Enable unsolicited event for HP jack */
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+/* Enable speaker output */
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+/* Enable headphone output */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+/*Enable internal subwoofer */
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
+       {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
+       { }
+};
+
 /*
  * ALC889 Acer Aspire 8930G model
  */
@@ -2200,6 +2231,16 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
        spec->autocfg.speaker_pins[2] = 0x17;
 }
 
+static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->autocfg.speaker_pins[1] = 0x16;
+       spec->autocfg.speaker_pins[2] = 0x17;
+}
+
 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -9524,13 +9565,6 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
        { }
 };
 
-static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-       { } /* end */
-};
-
 static void alc888_6st_dell_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -9831,7 +9865,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
-       SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
@@ -10328,7 +10361,7 @@ static struct alc_config_preset alc882_presets[] = {
                .const_channel_count = 6,
                .input_mux = &alc883_capture_source,
                .unsol_event = alc_automute_amp_unsol_event,
-               .setup = alc888_acer_aspire_6530g_setup,
+               .setup = alc888_acer_aspire_7730g_setup,
                .init_hook = alc_automute_amp,
        },
        [ALC883_MEDION] = {
@@ -14623,7 +14656,10 @@ static int alc275_setup_dual_adc(struct hda_codec *codec)
 /* different alc269-variants */
 enum {
        ALC269_TYPE_NORMAL,
+       ALC269_TYPE_ALC258,
        ALC269_TYPE_ALC259,
+       ALC269_TYPE_ALC269VB,
+       ALC269_TYPE_ALC270,
        ALC269_TYPE_ALC271X,
 };
 
@@ -15023,7 +15059,7 @@ static int alc269_fill_coef(struct hda_codec *codec)
 static int patch_alc269(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config;
+       int board_config, coef;
        int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -15034,14 +15070,23 @@ static int patch_alc269(struct hda_codec *codec)
 
        alc_auto_parse_customize_define(codec);
 
-       if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
+       coef = alc_read_coef_idx(codec, 0);
+       if ((coef & 0x00f0) == 0x0010) {
                if (codec->bus->pci->subsystem_vendor == 0x1025 &&
                    spec->cdefine.platform_type == 1) {
                        alc_codec_rename(codec, "ALC271X");
                        spec->codec_variant = ALC269_TYPE_ALC271X;
-               } else {
+               } else if ((coef & 0xf000) == 0x1000) {
+                       spec->codec_variant = ALC269_TYPE_ALC270;
+               } else if ((coef & 0xf000) == 0x2000) {
                        alc_codec_rename(codec, "ALC259");
                        spec->codec_variant = ALC269_TYPE_ALC259;
+               } else if ((coef & 0xf000) == 0x3000) {
+                       alc_codec_rename(codec, "ALC258");
+                       spec->codec_variant = ALC269_TYPE_ALC258;
+               } else {
+                       alc_codec_rename(codec, "ALC269VB");
+                       spec->codec_variant = ALC269_TYPE_ALC269VB;
                }
        } else
                alc_fix_pll_init(codec, 0x20, 0x04, 15);
@@ -15104,7 +15149,7 @@ static int patch_alc269(struct hda_codec *codec)
        spec->stream_digital_capture = &alc269_pcm_digital_capture;
 
        if (!spec->adc_nids) { /* wasn't filled automatically? use default */
-               if (spec->codec_variant != ALC269_TYPE_NORMAL) {
+               if (spec->codec_variant == ALC269_TYPE_NORMAL) {
                        spec->adc_nids = alc269_adc_nids;
                        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
                        spec->capsrc_nids = alc269_capsrc_nids;
@@ -16898,7 +16943,7 @@ static struct alc_config_preset alc861vd_presets[] = {
 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
                                                const struct auto_pin_cfg *cfg)
 {
-       return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
+       return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
 }
 
 
@@ -18952,6 +18997,8 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
                return 0x02;
        else if (nid >= 0x0c && nid <= 0x0e)
                return nid - 0x0c + 0x02;
+       else if (nid == 0x26) /* ALC887-VD has this DAC too */
+               return 0x25;
        else
                return 0;
 }
@@ -18960,7 +19007,7 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
                                   hda_nid_t dac)
 {
-       hda_nid_t mix[4];
+       hda_nid_t mix[5];
        int i, num;
 
        num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
@@ -19298,6 +19345,7 @@ static const struct alc_fixup alc662_fixups[] = {
 
 static struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
+       SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
        {}
@@ -19419,7 +19467,10 @@ static int patch_alc888(struct hda_codec *codec)
 {
        if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
                kfree(codec->chip_name);
-               codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
+               if (codec->vendor_id == 0x10ec0887)
+                       codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
+               else
+                       codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
                if (!codec->chip_name) {
                        alc_free(codec);
                        return -ENOMEM;
@@ -19909,7 +19960,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
          .patch = patch_alc882 },
        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
-       { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
+       { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
          .patch = patch_alc882 },
        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
index 93fa59cc60ef9ba0f5b2315c6461d3966608994c..efa4225f5fd6c95f9f0218d38002d1ca12d88bd3 100644 (file)
@@ -389,6 +389,11 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
        0x11, 0x20, 0
 };
 
+#define STAC92HD87B_NUM_DMICS   1
+static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
+       0x11, 0
+};
+
 #define STAC92HD83XXX_NUM_CAPS 2
 static unsigned long stac92hd83xxx_capvols[] = {
        HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
@@ -1622,6 +1627,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
 static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
                      "Alienware M17x", STAC_ALIENWARE_M17X),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
+                     "Alienware M17x", STAC_ALIENWARE_M17X),
        {} /* terminator */
 };
 
@@ -3486,10 +3493,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
                                return err;
                }
 
-               if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) {
+               if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
                        snd_hda_add_imux_item(imux, label, index, NULL);
-                       spec->num_analog_muxes++;
-               }
        }
 
        return 0;
@@ -5452,12 +5457,17 @@ again:
                                stac92hd83xxx_brd_tbl[spec->board_config]);
 
        switch (codec->vendor_id) {
+       case 0x111d76d1:
+       case 0x111d76d9:
+               spec->dmic_nids = stac92hd87b_dmic_nids;
+               spec->num_dmics = stac92xx_connected_ports(codec,
+                               stac92hd87b_dmic_nids,
+                               STAC92HD87B_NUM_DMICS);
+               /* Fall through */
        case 0x111d7666:
        case 0x111d7667:
        case 0x111d7668:
        case 0x111d7669:
-       case 0x111d76d1:
-       case 0x111d76d9:
                spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
                spec->pin_nids = stac92hd88xxx_pin_nids;
                spec->mono_nid = 0;
index 400f9ebd243e84ebf595cb4cba69f6a3cb3552b7..629a5494347a021600ed6f2dbf82feb5971d10ac 100644 (file)
@@ -1864,6 +1864,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .name = "Dell Inspiron 8600",   /* STAC9750/51 */
                .type = AC97_TUNE_HP_ONLY
        },
+       {
+               .subvendor = 0x1028,
+               .subdevice = 0x0182,
+               .name = "Dell Latitude D610",   /* STAC9750/51 */
+               .type = AC97_TUNE_HP_ONLY
+       },
        {
                .subvendor = 0x1028,
                .subdevice = 0x0186,
index a46f5083db99229c88797895b9de5170bede8245..812e288ef2e76eb58de27118a7522700f0f21a38 100644 (file)
 
 #include <sound/hwdep.h>
 
+#ifndef readl_be
 #define readl_be(x) be32_to_cpu(__raw_readl(x))
+#endif
+
+#ifndef writel_be
 #define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
+#endif
 
+#ifndef readl_le
 #define readl_le(x) le32_to_cpu(__raw_readl(x))
+#endif
+
+#ifndef writel_le
 #define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
+#endif
 
 #define MIXART_MEM(mgr,x)      ((mgr)->mem[0].virt + (x))
 #define MIXART_REG(mgr,x)      ((mgr)->mem[1].virt + (x))
index 85081172403f25ec056a99eb58a341fbd5d57370..b47cfd45b3b98f04b2c6d89135de310fb3b264ef 100644 (file)
@@ -1228,10 +1228,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
                                               chip->rsrc[i].start + 1,
                                               rnames[i]) == NULL) {
                                printk(KERN_ERR "snd: can't request rsrc "
-                                      " %d (%s: 0x%016llx:%016llx)\n",
-                                      i, rnames[i],
-                                      (unsigned long long)chip->rsrc[i].start,
-                                      (unsigned long long)chip->rsrc[i].end);
+                                      " %d (%s: %pR)\n",
+                                      i, rnames[i], &chip->rsrc[i]);
                                err = -ENODEV;
                                goto __error;
                        }
@@ -1256,10 +1254,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
                                               chip->rsrc[i].start + 1,
                                               rnames[i]) == NULL) {
                                printk(KERN_ERR "snd: can't request rsrc "
-                                      " %d (%s: 0x%016llx:%016llx)\n",
-                                      i, rnames[i],
-                                      (unsigned long long)chip->rsrc[i].start,
-                                      (unsigned long long)chip->rsrc[i].end);
+                                      " %d (%s: %pR)\n",
+                                      i, rnames[i], &chip->rsrc[i]);
                                err = -ENODEV;
                                goto __error;
                        }
index e720d5e6f04cfdd135ea42e5b74ed74e75724bed..bee3c94f58b0736c57f361141e0ed32e58640317 100644 (file)
@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC
 
 config SND_AT91_SOC_SAM9G20_WM8731
        tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
-       depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
+       depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
+                   AT91_PROGRAMMABLE_CLOCKS
        select SND_ATMEL_SOC_SSC
        select SND_SOC_WM8731
        help
@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
 
 config SND_AT32_SOC_PLAYPAQ
         tristate "SoC Audio support for PlayPaq with WM8510"
-        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
+        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
         select SND_ATMEL_SOC_SSC
         select SND_SOC_WM8510
         help
index 293569dfd0edec6d70551d90e610a93bba74ad7f..e521ada80542512e124822ef11db5bfbd5bddb3a 100644 (file)
@@ -222,9 +222,9 @@ static int __init at91sam9g20ek_init(void)
        }
 
        pllb = clk_get(NULL, "pllb");
-       if (IS_ERR(mclk)) {
+       if (IS_ERR(pllb)) {
                printk(KERN_ERR "ASoC: Failed to get PLLB\n");
-               ret = PTR_ERR(mclk);
+               ret = PTR_ERR(pllb);
                goto err_mclk;
        }
        ret = clk_set_parent(mclk, pllb);
@@ -240,6 +240,7 @@ static int __init at91sam9g20ek_init(void)
        if (!at91sam9g20ek_snd_device) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
                ret = -ENOMEM;
+               goto err_mclk;
        }
 
        platform_set_drvdata(at91sam9g20ek_snd_device,
@@ -248,11 +249,13 @@ static int __init at91sam9g20ek_init(void)
        ret = platform_device_add(at91sam9g20ek_snd_device);
        if (ret) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               platform_device_put(at91sam9g20ek_snd_device);
+               goto err_device_add;
        }
 
        return ret;
 
+err_device_add:
+       platform_device_put(at91sam9g20ek_snd_device);
 err_mclk:
        clk_put(mclk);
        mclk = NULL;
index e3d283561c196a8198e97d6bf2cc3b1b11987624..86e0f8586dc362f0f6edadf1995bb6176c436fe6 100644 (file)
@@ -167,7 +167,6 @@ static int __init afeb9260_soc_init(void)
 
        return 0;
 err1:
-       platform_device_del(afeb9260_snd_device);
        platform_device_put(afeb9260_snd_device);
        return err;
 }
index bc22ee93a75daf3c852ce65f9767df519445251c..d63e28773eb1841ac7bdd06af0d37a0d5c03013b 100644 (file)
 #include <sound/max98088.h>
 #include "max98088.h"
 
+enum max98088_type {
+       MAX98088,
+       MAX98089,
+};
+
 struct max98088_cdata {
        unsigned int rate;
        unsigned int fmt;
@@ -36,6 +41,7 @@ struct max98088_cdata {
 
 struct max98088_priv {
        u8 reg_cache[M98088_REG_CNT];
+       enum max98088_type devtype;
        void *control_data;
        struct max98088_pdata *pdata;
        unsigned int sysclk;
@@ -2013,7 +2019,10 @@ err_access:
 
 static int max98088_remove(struct snd_soc_codec *codec)
 {
+       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+
        max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       kfree(max98088->eq_texts);
 
        return 0;
 }
@@ -2040,6 +2049,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
        if (max98088 == NULL)
                return -ENOMEM;
 
+       max98088->devtype = id->driver_data;
+
        i2c_set_clientdata(i2c, max98088);
        max98088->control_data = i2c;
        max98088->pdata = i2c->dev.platform_data;
@@ -2059,7 +2070,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id max98088_i2c_id[] = {
-       { "max98088", 0 },
+       { "max98088", MAX98088 },
+       { "max98089", MAX98089 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
index 00d67cc8e2062a9071dcb78ee0fb2d64b5a77166..061f9e5a497bc3280b42a7a55838709e24cbb35b 100644 (file)
@@ -383,6 +383,7 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
        .reg_cache_size = sizeof(stac9766_reg),
        .reg_word_size = sizeof(u16),
        .reg_cache_step = 2,
+       .reg_cache_default = stac9766_reg,
 };
 
 static __devinit int stac9766_probe(struct platform_device *pdev)
index fc687790188b2f1ee2b33f48f2dab0b831f3ffa9..77b8f9ae29be5fcd2a64b5d2bba0b1803f43602d 100644 (file)
@@ -1176,7 +1176,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_gpio);
 int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
 {
        u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
-       u8 val, bit = gpio ? 2: 1;
+       u8 val = 0, bit = gpio ? 2 : 1;
 
        aic3x_read(codec, reg, &val);
        return (val >> bit) & 1;
@@ -1204,7 +1204,7 @@ EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
 
 int aic3x_headset_detected(struct snd_soc_codec *codec)
 {
-       u8 val;
+       u8 val = 0;
        aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
        return (val >> 4) & 1;
 }
@@ -1212,7 +1212,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
 
 int aic3x_button_pressed(struct snd_soc_codec *codec)
 {
-       u8 val;
+       u8 val = 0;
        aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
        return (val >> 5) & 1;
 }
index ee4fb201de60ca9ceb969fd00ce1292aad0a9330..d2c24309567303667dfcae14d79a6809e4ce1e7b 100644 (file)
@@ -78,8 +78,10 @@ static int tpa6130a2_i2c_write(int reg, u8 value)
 
        if (data->power_state) {
                val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
-               if (val < 0)
+               if (val < 0) {
                        dev_err(&tpa6130a2_client->dev, "Write failed\n");
+                       return val;
+               }
        }
 
        /* Either powered on or off, we save the context */
index 7540a509a6f58acec8c29aad5c76b65a86a5f83a..464f0cfa4c7a538b7eef3a86752d57f551952d54 100644 (file)
@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
        .resume =       uda134x_soc_resume,
        .reg_cache_size = sizeof(uda134x_reg),
        .reg_word_size = sizeof(u8),
+       .reg_cache_default = uda134x_reg,
        .reg_cache_step = 1,
        .read = uda134x_read_reg_cache,
        .write = uda134x_write,
index f4f1fba38eb9458176f5bda41cc93d12c87722eb..7611add7f8c38751806684a521d891ede746197f 100644 (file)
@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        }
 
        /* MCLK direction */
-       if (dir == WM8350_MCLK_DIR_OUT)
+       if (dir == SND_SOC_CLOCK_OUT)
                wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
                                WM8350_MCLK_DIR);
        else
@@ -1586,6 +1586,13 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
        wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
                        WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
 
+       /* Make sure AIF tristating is disabled by default */
+       wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
+
+       /* Make sure we've got a sane companding setup too */
+       wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
+                         WM8350_DAC_COMP | WM8350_LOOPBACK);
+
        /* Make sure jack detect is disabled to start off with */
        wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
                          WM8350_JDL_ENA | WM8350_JDR_ENA);
index 712ef7c76f90bbde579229ea85716dd14f7acb10..9a433a5396cb781727e39a4c1c6005f1bbc9a421 100644 (file)
@@ -146,7 +146,6 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       return 0;
        snd_pcm_hw_constraint_list(substream->runtime, 0,
                                   SNDRV_PCM_HW_PARAM_RATE,
                                   &wm8523->rate_constraint);
index 631385802eb44a587f5fe375d8f1c61e89ba9d02..e725c09a3e79bf7bafa6fda17ee6112fd629e6ee 100644 (file)
@@ -526,7 +526,7 @@ static int wm8731_probe(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
 
        /* Disable bypass path by default */
-       snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
+       snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
 
        snd_soc_add_controls(codec, wm8731_snd_controls,
                             ARRAY_SIZE(wm8731_snd_controls));
index 04182c464e35ffeffb069ad06242dca74da52248..0132a27140ae539c85c822b06b984b0733d84e41 100644 (file)
@@ -34,7 +34,6 @@
 /* codec private data */
 struct wm8776_priv {
        enum snd_soc_control_type control_type;
-       u16 reg_cache[WM8776_CACHEREGNUM];
        int sysclk[2];
 };
 
index 33be84e506ea7d4e2927a4e44a06e49ab648f156..fca60a0b57b83a807a946b86576093237b090f1f 100644 (file)
@@ -2498,6 +2498,8 @@ static int wm8904_remove(struct snd_soc_codec *codec)
 
        wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
+       kfree(wm8904->retune_mobile_texts);
+       kfree(wm8904->drc_texts);
 
        return 0;
 }
index 4f326f6041042742255731ba078574b37a48a6f3..8340485c985145a2ad1614bedaf39f2377276d88 100644 (file)
@@ -711,7 +711,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
        if (fs <= 24000)
                reg |= WM8961_DACSLOPE;
        else
-               reg &= WM8961_DACSLOPE;
+               reg &= ~WM8961_DACSLOPE;
        snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
 
        return 0;
@@ -736,7 +736,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
                freq /= 2;
        } else {
                dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
-               reg &= WM8961_MCLKDIV;
+               reg &= ~WM8961_MCLKDIV;
        }
 
        snd_soc_write(codec, WM8961_CLOCKING1, reg);
index 894d0cd3aa9b95896fbaff30db883b1fe39bc668..e8092745a207674caaf4351d815870e7367b4003 100644 (file)
@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev,
 {
        struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
        long int time;
+       int ret;
 
-       strict_strtol(buf, 10, &time);
+       ret = strict_strtol(buf, 10, &time);
+       if (ret != 0)
+               return ret;
 
        input_event(wm8962->beep, EV_SND, SND_TONE, time);
 
index 0db59c3aa5d4dbb6cd2a821d29eaa75887290977..4d3e6f1ac5843f7a6f28ed0a9490bacea4ba3ad0 100644 (file)
@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                return -ENOMEM;
        snd_soc_codec_set_drvdata(codec, wm8994);
 
+       codec->reg_cache = &wm8994->reg_cache;
+
        wm8994->pdata = dev_get_platdata(codec->dev->parent);
        wm8994->codec = codec;
 
@@ -4059,6 +4061,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
+       kfree(wm8994->retune_mobile_texts);
+       kfree(wm8994->drc_texts);
        kfree(wm8994);
 
        return 0;
@@ -4071,6 +4075,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .resume =       wm8994_resume,
        .read = wm8994_read,
        .write = wm8994_write,
+       .readable_register = wm8994_readable,
+       .volatile_register = wm8994_volatile,
        .set_bias_level = wm8994_set_bias_level,
 };
 
index 2b07b17a6b2d68f3173380bc16de4eb07b921689..bc9e6b0b3f6fd67c4061ce364198a272d7a557d3 100644 (file)
@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 }
 
 /* davinci-evm digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link evm_dai = {
+static struct snd_soc_dai_link dm6446_evm_dai = {
        .name = "TLV320AIC3X",
        .stream_name = "AIC3X",
-       .cpu_dai_name = "davinci-mcasp.0",
+       .cpu_dai_name = "davinci-mcbsp",
        .codec_dai_name = "tlv320aic3x-hifi",
-       .codec_name = "tlv320aic3x-codec.0-001a",
+       .codec_name = "tlv320aic3x-codec.1-001b",
+       .platform_name = "davinci-pcm-audio",
+       .init = evm_aic3x_init,
+       .ops = &evm_ops,
+};
+
+static struct snd_soc_dai_link dm355_evm_dai = {
+       .name = "TLV320AIC3X",
+       .stream_name = "AIC3X",
+       .cpu_dai_name = "davinci-mcbsp.1",
+       .codec_dai_name = "tlv320aic3x-hifi",
+       .codec_name = "tlv320aic3x-codec.1-001b",
        .platform_name = "davinci-pcm-audio",
        .init = evm_aic3x_init,
        .ops = &evm_ops,
@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = {
 #ifdef CONFIG_SND_DM365_AIC3X_CODEC
        .name = "TLV320AIC3X",
        .stream_name = "AIC3X",
-       .cpu_dai_name = "davinci-i2s",
+       .cpu_dai_name = "davinci-mcbsp",
        .codec_dai_name = "tlv320aic3x-hifi",
        .init = evm_aic3x_init,
-       .codec_name = "tlv320aic3x-codec.0-001a",
+       .codec_name = "tlv320aic3x-codec.1-0018",
        .ops = &evm_ops,
 #elif defined(CONFIG_SND_DM365_VOICE_CODEC)
        .name = "Voice Codec - CQ93VC",
@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
        .ops = &evm_ops,
 };
 
-/* davinci dm6446, dm355 evm audio machine driver */
-static struct snd_soc_card snd_soc_card_evm = {
-       .name = "DaVinci EVM",
-       .dai_link = &evm_dai,
+/* davinci dm6446 evm audio machine driver */
+static struct snd_soc_card dm6446_snd_soc_card_evm = {
+       .name = "DaVinci DM6446 EVM",
+       .dai_link = &dm6446_evm_dai,
+       .num_links = 1,
+};
+
+/* davinci dm355 evm audio machine driver */
+static struct snd_soc_card dm355_snd_soc_card_evm = {
+       .name = "DaVinci DM355 EVM",
+       .dai_link = &dm355_evm_dai,
        .num_links = 1,
 };
 
@@ -261,10 +279,10 @@ static int __init evm_init(void)
        int ret;
 
        if (machine_is_davinci_evm()) {
-               evm_snd_dev_data = &snd_soc_card_evm;
+               evm_snd_dev_data = &dm6446_snd_soc_card_evm;
                index = 0;
        } else if (machine_is_davinci_dm355_evm()) {
-               evm_snd_dev_data = &snd_soc_card_evm;
+               evm_snd_dev_data = &dm355_snd_soc_card_evm;
                index = 1;
        } else if (machine_is_davinci_dm365_evm()) {
                evm_snd_dev_data = &dm365_snd_soc_card_evm;
index d46b545d41f432f037c58eb6c3b4b0f1b13cc2a2..9e0e565e6ed9c2e9308e74e80f2bad50d8f58b28 100644 (file)
@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
        snd_pcm_format_t fmt;
        unsigned element_cnt = 1;
 
-       dai->capture_dma_data = dev->dma_params;
-       dai->playback_dma_data = dev->dma_params;
-
        /* general line settings */
        spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        return ret;
 }
 
+static int davinci_i2s_startup(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
+{
+       struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+       return 0;
+}
+
 static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
                struct snd_soc_dai *dai)
 {
@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 #define DAVINCI_I2S_RATES      SNDRV_PCM_RATE_8000_96000
 
 static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+       .startup        = davinci_i2s_startup,
        .shutdown       = davinci_i2s_shutdown,
        .prepare        = davinci_i2s_prepare,
        .trigger        = davinci_i2s_trigger,
@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = {
        .probe          = davinci_i2s_probe,
        .remove         = davinci_i2s_remove,
        .driver         = {
-               .name   = "davinci-i2s",
+               .name   = "davinci-mcbsp",
                .owner  = THIS_MODULE,
        },
 };
index 86918ee12419e7fd3ff626bdb2ccd18a1bd09021..fb55d2c5d704ff25983fd5ef4d16dfc461e60a76 100644 (file)
@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
        int word_length;
        u8 fifo_level;
 
-       cpu_dai->capture_dma_data = dev->dma_params;
-       cpu_dai->playback_dma_data = dev->dma_params;
-
        davinci_hw_common_param(dev, substream->stream);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                fifo_level = dev->txnumevt;
@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
        return ret;
 }
 
+static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
+                                struct snd_soc_dai *dai)
+{
+       struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+       return 0;
+}
+
 static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+       .startup        = davinci_mcasp_startup,
        .trigger        = davinci_mcasp_trigger,
        .hw_params      = davinci_mcasp_hw_params,
        .set_fmt        = davinci_mcasp_set_dai_fmt,
index 009b6521a1bf9f3731e9d597f09ff3644126b967..6c6666a1f942682907cae74b6bf4aa382ad955e8 100644 (file)
@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = {
 static struct snd_soc_dai_link sffsdr_dai = {
        .name = "PCM3008", /* Codec name */
        .stream_name = "PCM3008 HiFi",
-       .cpu_dai_name = "davinci-asp.0",
+       .cpu_dai_name = "davinci-mcbsp",
        .codec_dai_name = "pcm3008-hifi",
        .codec_name = "pcm3008-codec",
        .platform_name = "davinci-pcm-audio",
index ea232f6a2c21912e408a69ea2d1f8df28e4552dd..9d2afccc3a2d645dceb1e263ef7158f4c7667934 100644 (file)
@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
                        &davinci_vcif_dev->dma_params[substream->stream];
        u32 w;
 
-       dai->capture_dma_data = davinci_vcif_dev->dma_params;
-       dai->playback_dma_data = davinci_vcif_dev->dma_params;
-
        /* Restart the codec before setup */
        davinci_vcif_stop(substream);
        davinci_vcif_start(substream);
@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
        return ret;
 }
 
+static int davinci_vcif_startup(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+       snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+       return 0;
+}
+
 #define DAVINCI_VCIF_RATES     SNDRV_PCM_RATE_8000_48000
 
 static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
+       .startup        = davinci_vcif_startup,
        .trigger        = davinci_vcif_trigger,
        .hw_params      = davinci_vcif_hw_params,
 };
@@ -240,7 +247,10 @@ fail:
 
 static int davinci_vcif_remove(struct platform_device *pdev)
 {
+       struct davinci_vcif_dev *davinci_vcif_dev = dev_get_drvdata(&pdev->dev);
+
        snd_soc_unregister_dai(&pdev->dev);
+       kfree(davinci_vcif_dev);
 
        return 0;
 }
index 4b0d199137286c5b2ff17491e6ac501acb53ccbc..286817946c5674c6a4536d4afda7507316e99883 100644 (file)
@@ -54,24 +54,26 @@ static int __init simone_init(void)
 
        ret = platform_device_add(simone_snd_ac97_device);
        if (ret)
-               goto fail;
+               goto fail1;
 
        simone_snd_device = platform_device_alloc("soc-audio", -1);
        if (!simone_snd_device) {
                ret = -ENOMEM;
-               goto fail;
+               goto fail2;
        }
 
        platform_set_drvdata(simone_snd_device, &snd_soc_simone);
        ret = platform_device_add(simone_snd_device);
-       if (ret) {
-               platform_device_put(simone_snd_device);
-               goto fail;
-       }
+       if (ret)
+               goto fail3;
 
-       return ret;
+       return 0;
 
-fail:
+fail3:
+       platform_device_put(simone_snd_device);
+fail2:
+       platform_device_del(simone_snd_ac97_device);
+fail1:
        platform_device_put(simone_snd_ac97_device);
        return ret;
 }
index 53251e6b5bd509303dc17500e8f4d64feeea7021..108b5d8bd0e944bc2f0525c930c35df643e1a500 100644 (file)
@@ -76,6 +76,7 @@ static __init int efika_fabric_init(void)
        rc = platform_device_add(pdev);
        if (rc) {
                pr_err("efika_fabric_init: platform_device_add() failed\n");
+               platform_device_put(pdev);
                return -ENODEV;
        }
        return 0;
index dce6b551cd7816be84c5dbd77db74be4c88e8315..f92dca07cd35ffdcb46bb16e7c0a4f6db8bc29fe 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
-#include <linux/of_device.h>
 #include <linux/of_platform.h>
 
 #include <sound/soc.h>
index 74ffed41340ff00c5d9ba97dc927059731b80673..9018fa5bf0db8db93737ef946073613f20b279df 100644 (file)
@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op,
        rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
        if (rc != 0) {
                pr_err("Failed to register DAI\n");
-               return 0;
+               return rc;
        }
 
        psc_dma = dev_get_drvdata(&op->dev);
index 0d7dcf1e4863592c439a626b7fe449b56669f45d..7d7847a1e66bbba18bf583137808b2e751e29cd9 100644 (file)
@@ -498,6 +498,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "platform device add failed\n");
                goto error;
        }
+       dev_set_drvdata(&pdev->dev, sound_device);
 
        of_node_put(codec_np);
 
index 63b9eaa1ebc202d68eda5d18904816f8a86a458b..026b756961e0eaa84dc995c8b3a2aaf6f1a9b3a2 100644 (file)
@@ -498,6 +498,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "platform device add failed\n");
                goto error;
        }
+       dev_set_drvdata(&pdev->dev, sound_device);
 
        of_node_put(codec_np);
 
index 25f27ec1dd6e4bba2590b869745d575c1d5b3545..ba4d85e317ed459907601b1df426738ddf88ee68 100644 (file)
@@ -76,6 +76,7 @@ static __init int pcm030_fabric_init(void)
        rc = platform_device_add(pdev);
        if (rc) {
                pr_err("pcm030_fabric_init: platform_device_add() failed\n");
+               platform_device_put(pdev);
                return -ENODEV;
        }
        return 0;
index b59675257ce55b61b6410f04008f12d6d705e37d..dd4fffdbd17751d496a388dd38606fcd08ec319a 100644 (file)
@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        int ret;
 
        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
 static struct snd_soc_dai_link eukrea_tlv320_dai = {
        .name           = "tlv320aic23",
        .stream_name    = "TLV320AIC23",
-       .codec_dai      = "tlv320aic23-hifi",
+       .codec_dai_name = "tlv320aic23-hifi",
        .platform_name  = "imx-pcm-audio.0",
        .codec_name     = "tlv320aic23-codec.0-001a",
-       .cpu_dai = "imx-ssi.0",
+       .cpu_dai_name   = "imx-ssi.0",
        .ops            = &eukrea_tlv320_snd_ops,
 };
 
index fd493ee1428e2a977ac96ba7f7acc3a88d226025..671ef8dd524cb81b7ef8fae3dd6b033bd644e143 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/dmaengine.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
-#include <mach/dma-mx1-mx2.h>
+#include <mach/dma.h>
 
 #include "imx-ssi.h"
 
 struct imx_pcm_runtime_data {
-       int sg_count;
-       struct scatterlist *sg_list;
-       int period;
+       int period_bytes;
        int periods;
-       unsigned long dma_addr;
        int dma;
-       struct snd_pcm_substream *substream;
        unsigned long offset;
        unsigned long size;
-       unsigned long period_cnt;
        void *buf;
        int period_time;
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *dma_chan;
+       struct imx_dma_data dma_data;
 };
 
-/* Called by the DMA framework when a period has elapsed */
-static void imx_ssi_dma_progression(int channel, void *data,
-                                       struct scatterlist *sg)
+static void audio_dma_irq(void *data)
 {
-       struct snd_pcm_substream *substream = data;
+       struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
-       if (!sg)
-               return;
-
-       runtime = iprtd->substream->runtime;
+       iprtd->offset += iprtd->period_bytes;
+       iprtd->offset %= iprtd->period_bytes * iprtd->periods;
 
-       iprtd->offset = sg->dma_address - runtime->dma_addr;
-
-       snd_pcm_period_elapsed(iprtd->substream);
+       snd_pcm_period_elapsed(substream);
 }
 
-static void imx_ssi_dma_callback(int channel, void *data)
+static bool filter(struct dma_chan *chan, void *param)
 {
-       pr_err("%s shouldn't be called\n", __func__);
-}
+       struct imx_pcm_runtime_data *iprtd = param;
 
-static void snd_imx_dma_err_callback(int channel, void *data, int err)
-{
-       struct snd_pcm_substream *substream = data;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = 
-               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-       int ret;
+       if (!imx_dma_is_general_purpose(chan))
+               return false;
 
-       pr_err("DMA timeout on channel %d -%s%s%s%s\n",
-                channel,
-                err & IMX_DMA_ERR_BURST ?    " burst" : "",
-                err & IMX_DMA_ERR_REQUEST ?  " request" : "",
-                err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
-                err & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+        chan->private = &iprtd->dma_data;
 
-       imx_dma_disable(iprtd->dma);
-       ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
-                       IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
-                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-                       DMA_MODE_WRITE : DMA_MODE_READ);
-       if (!ret)
-               imx_dma_enable(iprtd->dma);
+        return true;
 }
 
-static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
+static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct imx_pcm_dma_params *dma_params;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+       struct dma_slave_config slave_config;
+       dma_cap_mask_t mask;
+       enum dma_slave_buswidth buswidth;
        int ret;
 
        dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
-       iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
-       if (iprtd->dma < 0) {
-               pr_err("Failed to claim the audio DMA\n");
-               return -ENODEV;
-       }
+       iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI;
+       iprtd->dma_data.priority = DMA_PRIO_HIGH;
+       iprtd->dma_data.dma_request = dma_params->dma;
 
-       ret = imx_dma_setup_handlers(iprtd->dma,
-                               imx_ssi_dma_callback,
-                               snd_imx_dma_err_callback, substream);
-       if (ret)
-               goto out;
+       /* Try to grab a DMA channel */
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+       iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
+       if (!iprtd->dma_chan)
+               return -EINVAL;
 
-       ret = imx_dma_setup_progression_handler(iprtd->dma,
-                       imx_ssi_dma_progression);
-       if (ret) {
-               pr_err("Failed to setup the DMA handler\n");
-               goto out;
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+       case SNDRV_PCM_FORMAT_S24_LE:
+               buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+               break;
+       default:
+               return 0;
        }
 
-       ret = imx_dma_config_channel(iprtd->dma,
-                       IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
-                       IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
-                       dma_params->dma, 1);
-       if (ret < 0) {
-               pr_err("Cannot configure DMA channel: %d\n", ret);
-               goto out;
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               slave_config.direction = DMA_TO_DEVICE;
+               slave_config.dst_addr = dma_params->dma_addr;
+               slave_config.dst_addr_width = buswidth;
+               slave_config.dst_maxburst = dma_params->burstsize;
+       } else {
+               slave_config.direction = DMA_FROM_DEVICE;
+               slave_config.src_addr = dma_params->dma_addr;
+               slave_config.src_addr_width = buswidth;
+               slave_config.src_maxburst = dma_params->burstsize;
        }
 
-       imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
+       ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
+       if (ret)
+               return ret;
 
        return 0;
-out:
-       imx_dma_free(iprtd->dma);
-       return ret;
 }
 
 static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params)
 {
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-       int i;
        unsigned long dma_addr;
+       struct dma_chan *chan;
+       struct imx_pcm_dma_params *dma_params;
+       int ret;
 
-       imx_ssi_dma_alloc(substream);
+       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+       ret = imx_ssi_dma_alloc(substream, params);
+       if (ret)
+               return ret;
+       chan = iprtd->dma_chan;
 
        iprtd->size = params_buffer_bytes(params);
        iprtd->periods = params_periods(params);
-       iprtd->period = params_period_bytes(params);
+       iprtd->period_bytes = params_period_bytes(params);
        iprtd->offset = 0;
        iprtd->period_time = HZ / (params_rate(params) /
                        params_period_size(params));
 
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
-       if (iprtd->sg_count != iprtd->periods) {
-               kfree(iprtd->sg_list);
-
-               iprtd->sg_list = kcalloc(iprtd->periods + 1,
-                               sizeof(struct scatterlist), GFP_KERNEL);
-               if (!iprtd->sg_list)
-                       return -ENOMEM;
-               iprtd->sg_count = iprtd->periods + 1;
-       }
-
-       sg_init_table(iprtd->sg_list, iprtd->sg_count);
        dma_addr = runtime->dma_addr;
 
-       for (i = 0; i < iprtd->periods; i++) {
-               iprtd->sg_list[i].page_link = 0;
-               iprtd->sg_list[i].offset = 0;
-               iprtd->sg_list[i].dma_address = dma_addr;
-               iprtd->sg_list[i].length = iprtd->period;
-               dma_addr += iprtd->period;
+       iprtd->buf = (unsigned int *)substream->dma_buffer.area;
+
+       iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
+                       iprtd->period_bytes * iprtd->periods,
+                       iprtd->period_bytes,
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                       DMA_TO_DEVICE : DMA_FROM_DEVICE);
+       if (!iprtd->desc) {
+               dev_err(&chan->dev->device, "cannot prepare slave dma\n");
+               return -EINVAL;
        }
 
-       /* close the loop */
-       iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
-       iprtd->sg_list[iprtd->sg_count - 1].length = 0;
-       iprtd->sg_list[iprtd->sg_count - 1].page_link =
-                       ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
+       iprtd->desc->callback = audio_dma_irq;
+       iprtd->desc->callback_param = substream;
+
        return 0;
 }
 
@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
-       if (iprtd->dma >= 0) {
-               imx_dma_free(iprtd->dma);
-               iprtd->dma = -EINVAL;
+       if (iprtd->dma_chan) {
+               dma_release_channel(iprtd->dma_chan);
+               iprtd->dma_chan = NULL;
        }
 
-       kfree(iprtd->sg_list);
-       iprtd->sg_list = NULL;
-
        return 0;
 }
 
 static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct imx_pcm_dma_params *dma_params;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-       int err;
 
        dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
-       iprtd->substream = substream;
-       iprtd->buf = (unsigned int *)substream->dma_buffer.area;
-       iprtd->period_cnt = 0;
-
-       pr_debug("%s: buf: %p period: %d periods: %d\n",
-                       __func__, iprtd->buf, iprtd->period, iprtd->periods);
-
-       err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
-                       IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
-                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-                       DMA_MODE_WRITE : DMA_MODE_READ);
-       if (err)
-               return err;
-
        return 0;
 }
 
@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               imx_dma_enable(iprtd->dma);
+               dmaengine_submit(iprtd->desc);
 
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               imx_dma_disable(iprtd->dma);
+               dmaengine_terminate_all(iprtd->dma_chan);
 
                break;
        default:
@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
+       pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
+                       bytes_to_frames(substream->runtime, iprtd->offset));
+
        return bytes_to_frames(substream->runtime, iprtd->offset);
 }
 
@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
        .channels_max = 2,
        .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
        .period_bytes_min = 128,
-       .period_bytes_max = 16 * 1024,
+       .period_bytes_max = 65535, /* Limited by SDMA engine */
        .periods_min = 2,
        .periods_max = 255,
        .fifo_size = 0,
@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
        }
 
        snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+
+       return 0;
+}
+
+static int snd_imx_close(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+       kfree(iprtd);
+
        return 0;
 }
 
 static struct snd_pcm_ops imx_pcm_ops = {
        .open           = snd_imx_open,
+       .close          = snd_imx_close,
        .ioctl          = snd_pcm_lib_ioctl,
        .hw_params      = snd_imx_pcm_hw_params,
        .hw_free        = snd_imx_pcm_hw_free,
@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = {
                        .name = "imx-pcm-audio",
                        .owner = THIS_MODULE,
        },
-
        .probe = imx_soc_platform_probe,
        .remove = __devexit_p(imx_soc_platform_remove),
 };
@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void)
        platform_driver_unregister(&imx_pcm_driver);
 }
 module_exit(snd_imx_pcm_exit);
-
index d4bd345b0a8d4ba891222f5752fe6eca56aec7b4..390b6ffc26581477599b03efa08ebf9379d6d2b7 100644 (file)
@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm)
 }
 EXPORT_SYMBOL_GPL(imx_pcm_free);
 
+static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
+{
+       struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
+       uint32_t val;
+
+       snd_soc_dai_set_drvdata(dai, ssi);
+
+       val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
+               SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
+       writel(val, ssi->base + SSI_SFCSR);
+
+       return 0;
+}
+
 static struct snd_soc_dai_driver imx_ssi_dai = {
+       .probe = imx_ssi_dai_probe,
        .playback = {
                .channels_min = 2,
                .channels_max = 2,
@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = {
        .ops = &imx_ssi_pcm_dai_ops,
 };
 
-static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
-{
-       struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
-       uint32_t val;
-
-       snd_soc_dai_set_drvdata(dai, ssi);
-
-       val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
-               SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
-       writel(val, ssi->base + SSI_SFCSR);
-
-       return 0;
-}
-
 static struct snd_soc_dai_driver imx_ac97_dai = {
        .probe = imx_ssi_dai_probe,
        .ac97_control = 1,
@@ -677,9 +678,25 @@ static int imx_ssi_probe(struct platform_device *pdev)
                goto failed_register;
        }
 
-       ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev)
+       ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
+       if (!ssi->soc_platform_pdev_fiq) {
+               ret = -ENOMEM;
+               goto failed_pdev_fiq_alloc;
+       }
+
+       platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
+       ret = platform_device_add(ssi->soc_platform_pdev_fiq);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add platform device\n");
+               goto failed_pdev_fiq_add;
+       }
+
+       ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
+       if (!ssi->soc_platform_pdev) {
+               ret = -ENOMEM;
                goto failed_pdev_alloc;
+       }
+
        platform_set_drvdata(ssi->soc_platform_pdev, ssi);
        ret = platform_device_add(ssi->soc_platform_pdev);
        if (ret) {
@@ -692,6 +709,10 @@ static int imx_ssi_probe(struct platform_device *pdev)
 failed_pdev_add:
        platform_device_put(ssi->soc_platform_pdev);
 failed_pdev_alloc:
+       platform_device_del(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_add:
+       platform_device_put(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_alloc:
        snd_soc_unregister_dai(&pdev->dev);
 failed_register:
 failed_ac97:
@@ -712,8 +733,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct imx_ssi *ssi = platform_get_drvdata(pdev);
 
-       platform_device_del(ssi->soc_platform_pdev);
-       platform_device_put(ssi->soc_platform_pdev);
+       platform_device_unregister(ssi->soc_platform_pdev);
+       platform_device_unregister(ssi->soc_platform_pdev_fiq);
 
        snd_soc_unregister_dai(&pdev->dev);
 
index 53b780d9b2b09375fdc7bf7f60a81af5045ab406..a4406a13489279280a1635f0dab2563475c7426f 100644 (file)
 
 #define DRV_NAME "imx-ssi"
 
+#include <linux/dmaengine.h>
+#include <mach/dma.h>
+
 struct imx_pcm_dma_params {
        int dma;
        unsigned long dma_addr;
@@ -212,6 +215,7 @@ struct imx_ssi {
        int enabled;
 
        struct platform_device *soc_platform_pdev;
+       struct platform_device *soc_platform_pdev_fiq;
 };
 
 struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
index 6a65dd7055199febc9a63393430461d086e2d4e8..9eabc28667e681b41d8ce800d00db7367bb56b1d 100644 (file)
@@ -20,9 +20,6 @@
 #include <sound/soc-dapm.h>
 #include <asm/mach-types.h>
 
-#include "../codecs/wm9712.h"
-#include "imx-ssi.h"
-
 static struct snd_soc_card imx_phycore;
 
 static struct snd_soc_ops imx_phycore_hifi_ops = {
@@ -41,11 +38,12 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
 };
 
 static struct snd_soc_card imx_phycore = {
-       .name           = "PhyCORE-audio",
+       .name           = "PhyCORE-ac97-audio",
        .dai_link       = imx_phycore_dai_ac97,
        .num_links      = ARRAY_SIZE(imx_phycore_dai_ac97),
 };
 
+static struct platform_device *imx_phycore_snd_ac97_device;
 static struct platform_device *imx_phycore_snd_device;
 
 static int __init imx_phycore_init(void)
@@ -56,29 +54,42 @@ static int __init imx_phycore_init(void)
                /* return happy. We might run on a totally different machine */
                return 0;
 
-       imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!imx_phycore_snd_device)
+       imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
+       if (!imx_phycore_snd_ac97_device)
                return -ENOMEM;
 
-       platform_set_drvdata(imx_phycore_snd_device, &imx_phycore);
-       ret = platform_device_add(imx_phycore_snd_device);
+       platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
+       ret = platform_device_add(imx_phycore_snd_ac97_device);
+       if (ret)
+               goto fail1;
 
        imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
-       if (!imx_phycore_snd_device)
-               return -ENOMEM;
+       if (!imx_phycore_snd_device) {
+               ret = -ENOMEM;
+               goto fail2;
+       }
        ret = platform_device_add(imx_phycore_snd_device);
 
        if (ret) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-               platform_device_put(imx_phycore_snd_device);
+               goto fail3;
        }
 
+       return 0;
+
+fail3:
+       platform_device_put(imx_phycore_snd_device);
+fail2:
+       platform_device_del(imx_phycore_snd_ac97_device);
+fail1:
+       platform_device_put(imx_phycore_snd_ac97_device);
        return ret;
 }
 
 static void __exit imx_phycore_exit(void)
 {
        platform_device_unregister(imx_phycore_snd_device);
+       platform_device_unregister(imx_phycore_snd_ac97_device);
 }
 
 late_initcall(imx_phycore_init);
index 293dc748797c51cf11a63b6b0afa548521ff2898..dac6732da9695dfda940e78c98a5d58961b93955 100644 (file)
@@ -49,7 +49,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
        mutex_lock(&ac97_mutex);
 
        val = nuc900_checkready();
-       if (!!val) {
+       if (val) {
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
                goto out;
        }
@@ -102,7 +102,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
        mutex_lock(&ac97_mutex);
 
        tmp = nuc900_checkready();
-       if (!!tmp)
+       if (tmp)
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
 
        /* clear the R_WB bit and write register index */
@@ -149,7 +149,7 @@ static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
        udelay(100);
 
        val = nuc900_checkready();
-       if (!!val)
+       if (val)
                dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
 
        mutex_unlock(&ac97_mutex);
@@ -263,8 +263,7 @@ static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
        return ret;
 }
 
-static int nuc900_ac97_probe(struct platform_device *pdev,
-                                       struct snd_soc_dai *dai)
+static int nuc900_ac97_probe(struct snd_soc_dai *dai)
 {
        struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
        unsigned long val;
@@ -284,12 +283,12 @@ static int nuc900_ac97_probe(struct platform_device *pdev,
        return 0;
 }
 
-static void nuc900_ac97_remove(struct platform_device *pdev,
-                                               struct snd_soc_dai *dai)
+static int nuc900_ac97_remove(struct snd_soc_dai *dai)
 {
        struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
 
        clk_disable(nuc900_audio->clk);
+       return 0;
 }
 
 static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
@@ -313,7 +312,7 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = {
                .channels_max   = 2,
        },
        .ops = &nuc900_ac97_dai_ops,
-}
+};
 
 static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
 {
@@ -384,7 +383,6 @@ out0:
 
 static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
 {
-
        snd_soc_unregister_dai(&pdev->dev);
 
        clk_put(nuc900_ac97_data->clk);
@@ -392,6 +390,7 @@ static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
        release_mem_region(nuc900_ac97_data->res->start,
                                resource_size(nuc900_ac97_data->res));
 
+       kfree(nuc900_ac97_data);
        nuc900_ac97_data = NULL;
 
        return 0;
index aeed8ead2b2bcc42fcb5e06200a807f68cc6ce63..59f7e8ed1a6898937e3472016bce5e4bdc11e3de 100644 (file)
@@ -110,4 +110,6 @@ struct nuc900_audio {
 
 };
 
+extern struct nuc900_audio *nuc900_ac97_data;
+
 #endif /*end _NUC900_AUDIO_H */
index 195d1ac94771808c0eda8075255efff787cdfd59..8263f56dc665f4aa2dd04ecf6cba5ca7244283dd 100644 (file)
@@ -50,12 +50,12 @@ static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&nuc900_audio->lock, flags);
-
        ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
        if (ret < 0)
                return ret;
 
+       spin_lock_irqsave(&nuc900_audio->lock, flags);
+
        nuc900_audio->substream = substream;
        nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
        nuc900_audio->buffersize[substream->stream] =
@@ -169,6 +169,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct nuc900_audio *nuc900_audio = runtime->private_data;
        unsigned long flags, val;
+       int ret = 0;
 
        spin_lock_irqsave(&nuc900_audio->lock, flags);
 
@@ -197,10 +198,10 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
                AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
        spin_unlock_irqrestore(&nuc900_audio->lock, flags);
-       return 0;
+       return ret;
 }
 
 static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -332,7 +333,7 @@ static struct snd_soc_platform_driver nuc900_soc_platform = {
        .ops            = &nuc900_dma_ops,
        .pcm_new        = nuc900_dma_new,
        .pcm_free       = nuc900_dma_free_dma_buffers,
-}
+};
 
 static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
 {
index d542ea2ff6bec2e1117003a580cee7f6fe9db2e4..a088db6d50911799780838c0388cf9435d2c3a31 100644 (file)
@@ -12,8 +12,8 @@ config SND_OMAP_SOC_MCPDM
 config SND_OMAP_SOC_N810
        tristate "SoC Audio support for Nokia N810"
        depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
+       depends on OMAP_MUX
        select SND_OMAP_SOC_MCBSP
-       select OMAP_MUX
        select SND_SOC_TLV320AIC3X
        help
          Say Y if you want to add support for SoC audio on Nokia N810.
index d211c9fa5a914774534de29f51f40035320bfafb..7e84f24b9a88bf56ef0d000901d6c69d39f7461c 100644 (file)
@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 
 
        case OMAP_MCBSP_CLKR_SRC_CLKR:
+               if (cpu_class_is_omap1())
+                       break;
                omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
                break;
        case OMAP_MCBSP_CLKR_SRC_CLKX:
+               if (cpu_class_is_omap1())
+                       break;
                omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
                break;
        case OMAP_MCBSP_FSR_SRC_FSR:
+               if (cpu_class_is_omap1())
+                       break;
                omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
                break;
        case OMAP_MCBSP_FSR_SRC_FSX:
+               if (cpu_class_is_omap1())
+                       break;
                omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
                break;
        default:
index dbd9d96b5f9243c3e0cd0aafd3181e08cce84a3a..4ee33ce2cb98a6135b310f0f9279d8bdf5a16cae 100644 (file)
@@ -306,6 +306,7 @@ static int __init omap3pandora_soc_init(void)
                pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
                        dev_name(&omap3pandora_snd_device->dev),
                        PTR_ERR(omap3pandora_dac_reg));
+               ret = PTR_ERR(omap3pandora_dac_reg);
                goto fail3;
        }
 
index f0e6625564287df0b33643395af20c1849b8a596..65ae00e976eff14eb67d3b14428bdf7ec9d8360b 100644 (file)
@@ -177,7 +177,8 @@ static int __init osk_soc_init(void)
        tlv320aic23_mclk = clk_get(dev, "mclk");
        if (IS_ERR(tlv320aic23_mclk)) {
                printk(KERN_ERR "Could not get mclk clock\n");
-               return -ENODEV;
+               err = PTR_ERR(tlv320aic23_mclk);
+               goto err2;
        }
 
        /*
@@ -188,7 +189,7 @@ static int __init osk_soc_init(void)
                if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
                        printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
                        err = -ECANCELED;
-                       goto err1;
+                       goto err3;
                }
        }
 
@@ -196,9 +197,12 @@ static int __init osk_soc_init(void)
               (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
 
        return 0;
-err1:
+
+err3:
        clk_put(tlv320aic23_mclk);
+err2:
        platform_device_del(osk_snd_device);
+err1:
        platform_device_put(osk_snd_device);
 
        return err;
@@ -207,6 +211,7 @@ err1:
 
 static void __exit osk_soc_exit(void)
 {
+       clk_put(tlv320aic23_mclk);
        platform_device_unregister(osk_snd_device);
 }
 
index 37f191bbfdd91edd64bb4abd7636600f4d694d0c..580f48571303a0023e65fba304080058ce11bd8d 100644 (file)
@@ -1,6 +1,7 @@
 config SND_PXA2XX_SOC
        tristate "SoC Audio for the Intel PXA2xx chip"
        depends on ARCH_PXA
+       select SND_ARM
        select SND_PXA2XX_LIB
        help
          Say Y or M if you want to add support for codecs attached to
index 97e9423615c9c84d859a2b5b5b31695d73f4ab2f..f451acd4935b81db8d04d67da8e99c4e650f4a5d 100644 (file)
@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
 
+       mutex_lock(&codec->mutex);
+
        /* check the jack status at stream startup */
        corgi_ext_control(codec);
+
+       mutex_unlock(&codec->mutex);
+
        return 0;
 }
 
index b8207ced40729b0b375f28566b09de404313f28a..5ef0526924b9e3b2f20d56d181d7fc3781468df3 100644 (file)
@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
 
+       mutex_lock(&codec->mutex);
+
        /* check the jack status at stream startup */
        magician_ext_control(codec);
 
+       mutex_unlock(&codec->mutex);
+
        return 0;
 }
 
index af84ee9c5e11edde0c8a253e3a5072e5f3ac0e36..84edd0385a21fb39f3dfa7f429fa69df5c1dcdf1 100644 (file)
@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
 
+       mutex_lock(&codec->mutex);
+
        /* check the jack status at stream startup */
        poodle_ext_control(codec);
+
+       mutex_unlock(&codec->mutex);
+
        return 0;
 }
 
index f470f360f4dda9a3193b5f5011a7b9688cfb3b32..0b30d7de24ecc20e4adf3924257fe6a070741953 100644 (file)
@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
 
+       mutex_lock(&codec->mutex);
+
        /* check the jack status at stream startup */
        spitz_ext_control(codec);
+
+       mutex_unlock(&codec->mutex);
+
        return 0;
 }
 
index 73d0edd8ded9de053db82b27c60433fe1a7b8686..7b983f935454159d0a3569d6f747285231cbc6ae 100644 (file)
@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
 
+       mutex_lock(&codec->mutex);
+
        /* check the jack status at stream startup */
        tosa_ext_control(codec);
+
+       mutex_unlock(&codec->mutex);
+
        return 0;
 }
 
index 8a6b53ccd203e0a8dfe14dd7579325284e736591..d85bf8a0abb2935941b008ab12dfcf5831536e73 100644 (file)
@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC
        tristate "SoC Audio for the Samsung S3CXXXX chips"
        depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
        select S3C64XX_DMA if ARCH_S3C64XX
+       select S3C2410_DMA if ARCH_S3C2410
        help
          Say Y or M if you want to add support for codecs attached to
          the S3C24XX AC97 or I2S interfaces. You will also need to
index ffd5cf2fb0a91c3ebbb45d7c58951e3915670a69..468cc11fdf47abf84bc7a6b2dbcc5298bd6f16ce 100644 (file)
@@ -50,7 +50,6 @@ static unsigned int rates[] = {
        16000,
        44100,
        48000,
-       88200,
 };
 
 static struct snd_pcm_hw_constraint_list hw_rates = {
@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
 };
 
 static struct platform_device *s3c24xx_snd_device;
-static struct clk *xtal;
 
 static int rx1950_startup(struct snd_pcm_substream *substream)
 {
@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
        case 44100:
        case 88200:
                clk_source = S3C24XX_CLKSRC_MPLL;
-               fs_mode = S3C2410_IISMOD_256FS;
-               div = clk_get_rate(xtal) / (256 * rate);
-               if (clk_get_rate(xtal) % (256 * rate) > (128 * rate))
-                       div++;
+               fs_mode = S3C2410_IISMOD_384FS;
+               div = 1;
                break;
        default:
                printk(KERN_ERR "%s: rate %d is not supported\n",
@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
 
        /* set MCLK division for sample rate */
        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
-               S3C2410_IISMOD_384FS);
+               fs_mode);
        if (ret < 0)
                return ret;
 
@@ -295,17 +291,8 @@ static int __init rx1950_init(void)
                goto err_plat_add;
        }
 
-       xtal = clk_get(&s3c24xx_snd_device->dev, "xtal");
-
-       if (IS_ERR(xtal)) {
-               ret = PTR_ERR(xtal);
-               platform_device_unregister(s3c24xx_snd_device);
-               goto err_clk;
-       }
-
        return 0;
 
-err_clk:
 err_plat_add:
 err_plat_alloc:
 err_gpio_conf:
@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void)
        platform_device_unregister(s3c24xx_snd_device);
        snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
                hp_jack_gpios);
-       clk_put(xtal);
        gpio_free(S3C2410_GPA(1));
 }
 
index f31d22ad7c88997dfc9c4511f62b2a5aa7652a27..c8bd90488a87385d33b168813878893bfa5b9266 100644 (file)
@@ -38,7 +38,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
        }
 
        mout_epll = clk_get(NULL, "mout_epll");
-       if (IS_ERR(fout_epll)) {
+       if (IS_ERR(mout_epll)) {
                printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
                                __func__);
                ret = -EINVAL;
@@ -54,7 +54,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
        }
 
        sclk_spdif = clk_get(NULL, "sclk_spdif");
-       if (IS_ERR(fout_epll)) {
+       if (IS_ERR(sclk_spdif)) {
                printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n",
                                __func__);
                ret = -EINVAL;
index 8778faa174a6cb66da33e1e81430c6aae2c59973..3052f64b2403929a62fec3c8257aedec40c8a7a2 100644 (file)
@@ -434,7 +434,7 @@ static struct snd_soc_dai_driver s6000_i2s_dai = {
                .rate_max = 1562500,
        },
        .ops = &s6000_i2s_dai_ops,
-}
+};
 
 static int __devinit s6000_i2s_probe(struct platform_device *pdev)
 {
index 271fd222bf1997f92cac08b6c8b27f8f604b5147..ab3ccaec72d2158d41270ee22df7f95db683eb4a 100644 (file)
@@ -473,7 +473,7 @@ static int s6000_pcm_new(struct snd_card *card,
        }
 
        res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
-                         s6000_soc_platform.name, pcm);
+                         "s6000-audio", pcm);
        if (res) {
                printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
                return res;
index 96c05e1375386ebf6f11fd8d6ebcaa7dd118ac07..c1244c5bc730c478035756a9aab04309dcf8cc24 100644 (file)
@@ -167,7 +167,7 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 
        snd_soc_dapm_sync(codec);
 
-       snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+       snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
 
        return 0;
 }
index 507e709f2807c52995bed6c8dfaad09981ce471d..4c2404b1b8625455358347b65ba15f9414956b1a 100644 (file)
@@ -132,6 +132,8 @@ struct fsi_priv {
        struct fsi_stream playback;
        struct fsi_stream capture;
 
+       long rate;
+
        u32 mst_ctrl;
 };
 
@@ -854,10 +856,17 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
 {
        struct fsi_priv *fsi = fsi_get_priv(substream);
        int is_play = fsi_is_play(substream);
+       struct fsi_master *master = fsi_get_master(fsi);
+       int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
 
        fsi_irq_disable(fsi, is_play);
        fsi_clk_ctrl(fsi, 0);
 
+       set_rate = master->info->set_rate;
+       if (set_rate && fsi->rate)
+               set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
+       fsi->rate = 0;
+
        pm_runtime_put_sync(dai->dev);
 }
 
@@ -891,20 +900,20 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
 {
        struct fsi_priv *fsi = fsi_get_priv(substream);
        struct fsi_master *master = fsi_get_master(fsi);
-       int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
+       int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
        int fsi_ver = master->core->ver;
-       int is_play = fsi_is_play(substream);
+       long rate = params_rate(params);
        int ret;
 
-       /* if slave mode, set_rate is not needed */
-       if (!fsi_is_master_mode(fsi, is_play))
+       set_rate = master->info->set_rate;
+       if (!set_rate)
                return 0;
 
-       /* it is error if no set_rate */
-       if (!set_rate)
-               return -EIO;
+       ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
+       if (ret < 0) /* error */
+               return ret;
 
-       ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
+       fsi->rate = rate;
        if (ret > 0) {
                u32 data = 0;
 
index 40bbdf1591dca351631f8bdbbcc5f514e9c99139..05192d97b377f586e5eab56f0e38ec841d35378d 100644 (file)
@@ -387,7 +387,7 @@ static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
 
 static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_dai(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
+       snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
        return 0;
 }
 
index 614a8b30d87bdefdb99414f06d1d74438e60cd18..441285ade024ff33589cd22204ef5cb82a1f14ea 100644 (file)
@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev,
        for (i = 0; i < count; i++) {
 
                dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
-               if (dai == NULL)
-                       return -ENOMEM;
+               if (dai == NULL) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
 
                /* create DAI component name */
                dai->name = fmt_multiple_name(dev, &dai_drv[i]);
@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev,
        return 0;
 
 error:
-       for (i--; i >= 0; i--)
-               snd_soc_unregister_dai(dev);
-
        if (codec->reg_cache)
                kfree(codec->reg_cache);
        kfree(codec->name);
index 7d85c6496afa432cbd9791be5f1a9510e7cb78c7..75ed6491222d1d283d69d5881560a823c958d253 100644 (file)
@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
                            struct snd_soc_dapm_widget *b,
                            int sort[])
 {
-       if (a->codec != b->codec)
-               return (unsigned long)a - (unsigned long)b;
        if (sort[a->id] != sort[b->id])
                return sort[a->id] - sort[b->id];
        if (a->reg != b->reg)
                return a->reg - b->reg;
+       if (a->codec != b->codec)
+               return (unsigned long)a->codec - (unsigned long)b->codec;
 
        return 0;
 }
index c03bbaefdbc36c623e3f5b76cea86f6ad59e46cc..5580aced87308202e00d181194a6d4aa6689b920 100644 (file)
@@ -104,7 +104,6 @@ module_exit(cleanup_soundcore);
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sound.h>
index 1bc56b2b94e29f9143baa9911f72fa962202d17a..337a00241a1f3a406506c4baad93e0f10a8ac7d8 100644 (file)
@@ -155,7 +155,7 @@ static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip)
        if (max_tries < 1)
                max_tries = 1;
 
-       /* ssc_div must be a power of 2. */
+       /* ssc_div must be even. */
        ssc_div = (ssc_div + 1) & ~1UL;
 
        if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) {
index 792a750d9441af80cd16e4d797234159875babc4..c14322d1c0cfb9d7ad70bf70adce5f77dd8fe921 100644 (file)
 */
 
 #include <linux/stringify.h>
+#include <asm-generic/vmlinux.lds.h>
 
 .section .init.ramfs,"a"
 __irf_start:
 .incbin __stringify(INITRAMFS_IMAGE)
 __irf_end:
 .section .init.ramfs.info,"a"
-.globl __initramfs_size
-__initramfs_size:
+.globl VMLINUX_SYMBOL(__initramfs_size)
+VMLINUX_SYMBOL(__initramfs_size):
 #ifdef CONFIG_64BIT
        .quad __irf_end - __irf_start
 #else